(Grav GitSync) Automatic Commit from RealStickman

This commit is contained in:
RealStickman 2022-11-19 18:59:01 +01:00 committed by GitSync
parent ebc3582688
commit a2ac378047
191 changed files with 0 additions and 22637 deletions

View File

@ -1,38 +0,0 @@
# v1.1.0
## 12/02/2020
1. [](#new)
* Support for indent-sensitive notices [#17](https://github.com/getgrav/grav-plugin-markdown-notices/pull/17)
* Pass phpstan level 1 tests
* Require Grav v1.6
# v1.0.4
## 09/10/2019
1. [](#improved)
* Reverted PR#10 which was breaking multiline notices and also unintentionally marking up notices with `<space>!<space>` in paragraphs
# v1.0.3
## 08/16/2019
1. [](#improved)
* Fixed issue where PR#10 clobbered PR#9
# v1.0.2
## 08/11/2019
1. [](#new)
* Ability to specify your own base classes [#9](https://github.com/getgrav/grav-plugin-markdown-notices/pull/9)
* Allow adding inline notices inside tables [#10](https://github.com/getgrav/grav-plugin-markdown-notices/pull/10)
# v1.0.1
## 03/09/2018
1. [](#improved)
* Updated blueprint file
# v1.0.0
## 12/22/2015
1. [](#new)
* ChangeLog started...

View File

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2016 Grav
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,62 +0,0 @@
# Grav Markdown Notices Plugin
The **markdown-notices plugin** for [Grav](http://github.com/getgrav/grav) allows generation of notice blocks of text via markdown:
![](assets/screenshot.png)
# Installation
This plugin is easy to install with GPM.
```
$ bin/gpm install markdown-notices
```
# Configuration
Simply copy the `user/plugins/markdown-notices/markdown-notices.yaml` into `user/config/plugins/markdown-notices.yaml` and make your modifications.
```
enabled: true
built_in_css: true
base_classes: 'notices'
level_classes: [yellow, red, blue, green]
```
# Examples
Using one level of `!`
```
! Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris feugiat quam erat, ut iaculis diam posuere nec.
! Vestibulum eu condimentum urna. Vestibulum feugiat odio ut sodales porta. Donec sit amet ante mi. Donec lobortis
! orci dolor. Donec tristique volutpat ultricies. Nullam tempus, enim sit amet fringilla facilisis, ipsum ex
! tincidunt ipsum, vel placerat sem sem vitae risus. Aenean posuere sed purus nec pretium.
```
You will output the following HTML
```
<div class="notices yellow">
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris feugiat quam erat, ut iaculis diam posuere nec.
Vestibulum eu condimentum urna. Vestibulum feugiat odio ut sodales porta. Donec sit amet ante mi. Donec lobortis
orci dolor. Donec tristique volutpat ultricies. Nullam tempus, enim sit amet fringilla facilisis, ipsum ex
tincidunt ipsum, vel placerat sem sem vitae risus. Aenean posuere sed purus nec pretium.
</p>
</div>
```
The `notices` class determined by the `base_classes` and `yellow` class is determined by the `level_classes` in the configuration. You can customize this as you need.
```
!! Lorem ipsum dolor sit amet, **consectetur adipiscing** elit. Mauris feugiat quam erat, ut iaculis diam posuere nec.
!!
!! * List item a
!! * List item b
!!
!! orci dolor. Donec tristique volutpat ultricies. Nullam tempus, enim sit amet fringilla facilisis, ipsum ex
!! tincidunt ipsum, vel placerat sem sem vitae risus. Aenean posuere sed purus nec pretium.
```
Two levels of `!!` will use the second level class etc. You can also use complex markdown inside the notices.

View File

@ -1,32 +0,0 @@
.notices {
padding: 1px 1px 1px 30px;
margin: 15px 0;
}
.notices p {
}
.notices.yellow {
border-left: 10px solid #f0ad4e;
background: #fcf8f2;
color: #df8a13;
}
.notices.red {
border-left: 10px solid #d9534f;
background: #fdf7f7;
color: #b52b27;
}
.notices.blue {
border-left: 10px solid #5bc0de;
background: #f4f8fa;
color: #28a1c5;
}
.notices.green {
border-left: 10px solid #5cb85c;
background: #f1f9f1;
color: #3d8b3d;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

View File

@ -1,59 +0,0 @@
name: 'Markdown Notices'
type: plugin
slug: markdown-notices
version: 1.1.0
description: 'Adds the ability to render notices blocks in Markdown'
icon: asterisk
author:
name: Team Grav
email: devs@getgrav.org
url: http://getgrav.org
homepage: https://github.com/getgrav/grav-plugin-markdown-notices
license: MIT
dependencies:
- { name: grav, version: '>=1.6.0' }
form:
validation: strict
fields:
enabled:
type: toggle
label: PLUGIN_ADMIN.PLUGIN_STATUS
highlight: 1
default: 0
options:
1: PLUGIN_ADMIN.ENABLED
0: PLUGIN_ADMIN.DISABLED
validate:
type: bool
built_in_css:
type: toggle
label: PLUGIN_MARKDOWN_NOTICES.USE_BUILT_IN_CSS
highlight: 1
default: 1
options:
1: PLUGIN_ADMIN.ENABLED
0: PLUGIN_ADMIN.DISABLED
validate:
type: bool
base_classes:
type: selectize
label: PLUGIN_MARKDOWN_NOTICES.BASE_CLASSES
size: large
placeholder: PLUGIN_MARKDOWN_NOTICES.BASE_CLASSES_PLACEHOLDER
help: PLUGIN_MARKDOWN_NOTICES.BASE_CLASSES_HELP
classes: fancy
validate:
type: string
level_classes:
type: selectize
label: PLUGIN_MARKDOWN_NOTICES.LEVEL_CLASSES
size: large
placeholder: PLUGIN_MARKDOWN_NOTICES.LEVEL_CLASSES_PLACEHOLDER
help: PLUGIN_MARKDOWN_NOTICES.LEVEL_CLASSES_HELP
classes: fancy
validate:
type: commalist

View File

@ -1,27 +0,0 @@
{
"name": "grav-plugin-markdown-notices",
"type": "grav-plugin",
"description": "Markdown notices plugin for Grav CMS",
"keywords": ["notices"],
"homepage": "https://github.com/getgrav/grav-plugin-markdown-notices/",
"license": "MIT",
"authors": [
{
"name": "Team Grav",
"email": "devs@getgrav.org",
"homepage": "http://getgrav.org",
"role": "Developer"
}
],
"require": {
"php": ">=7.1.3"
},
"autoload": {
"classmap": ["markdown-notices.php"]
},
"config": {
"platform": {
"php": "7.1.3"
}
}
}

View File

@ -1,22 +0,0 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "683006688355ff7a1f71b2726c2629b6",
"packages": [],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=7.1.3"
},
"platform-dev": [],
"platform-overrides": {
"php": "7.1.3"
}
}

View File

@ -1,29 +0,0 @@
en:
PLUGIN_MARKDOWN_NOTICES:
USE_BUILT_IN_CSS: 'Use built-in CSS'
BASE_CLASSES: 'Base classes'
BASE_CLASSES_HELP: 'These classes will be added before the class level'
BASE_CLASSES_PLACEHOLDER: 'e.g. notices'
LEVEL_CLASSES: 'Level classes'
LEVEL_CLASSES_HELP: 'The classes to use for each level of notices depth'
LEVEL_CLASSES_PLACEHOLDER: 'e.g. yellow, red, blue, green'
ru:
PLUGIN_MARKDOWN_NOTICES:
USE_BUILT_IN_CSS: 'Использовать встроенный CSS'
BASE_CLASSES: 'Базовые классы'
BASE_CLASSES_HELP: 'Эти классы будут добавлены до уровня класса'
BASE_CLASSES_PLACEHOLDER: 'например notices'
LEVEL_CLASSES: 'Классы уровней'
LEVEL_CLASSES_HELP: 'Эти классы используются на каждом уровне глубины уведомлений'
LEVEL_CLASSES_PLACEHOLDER: 'например yellow, red, blue, green'
uk:
PLUGIN_MARKDOWN_NOTICES:
USE_BUILT_IN_CSS: 'Використовувати вбудований CSS'
BASE_CLASSES: 'Базові класи'
BASE_CLASSES_HELP: 'Ці класи будуть додані до рівня класу'
BASE_CLASSES_PLACEHOLDER: 'наприклад notices'
LEVEL_CLASSES: 'Класи рівнів'
LEVEL_CLASSES_HELP: 'Ці класи використовуються на кожному рівні глибини повідомлень'
LEVEL_CLASSES_PLACEHOLDER: 'наприклад yellow, red, blue, green'

View File

@ -1,92 +0,0 @@
<?php
namespace Grav\Plugin;
use Composer\Autoload\ClassLoader;
use Grav\Common\Plugin;
use RocketTheme\Toolbox\Event\Event;
class MarkdownNoticesPlugin extends Plugin
{
protected $base_classes;
protected $level_classes;
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
'onPluginsInitialized' => [
['autoload', 100001],
],
'onMarkdownInitialized' => ['onMarkdownInitialized', 0],
'onTwigSiteVariables' => ['onTwigSiteVariables', 0]
];
}
/**
* [onPluginsInitialized:100000] Composer autoload.
*
* @return ClassLoader
*/
public function autoload()
{
return require __DIR__ . '/vendor/autoload.php';
}
public function onMarkdownInitialized(Event $event)
{
$markdown = $event['markdown'];
$markdown->addBlockType('!', 'Notices', true, false);
$markdown->blockNotices = function($Line) {
$this->level_classes = $this->config->get('plugins.markdown-notices.level_classes');
$this->base_classes = $this->config->get('plugins.markdown-notices.base_classes');
if (preg_match('/^(!{1,'.count($this->level_classes).'}) (.*)/', $Line['text'], $matches))
{
$level = strlen($matches[1]) - 1;
$text = $matches[2];
$base_classes = (empty($this->base_classes)) ? '' : str_replace(',', ' ', $this->base_classes) . ' ';
$Block = [
'element' => [
'name' => 'div',
'handler' => 'lines',
'attributes' => [
'class' => $base_classes . $this->level_classes[$level],
],
'text' => (array) $text,
],
];
return $Block;
}
};
$markdown->blockNoticesContinue = function($Line, array $Block) {
if (isset($Block['interrupted']))
{
return;
}
if (preg_match('/^(!{1,'.count($this->level_classes).'}) ?(.*)/', $Line['text'], $matches))
{
$Block['element']['text'] []= $matches[2];
return $Block;
}
};
}
public function onTwigSiteVariables()
{
if ($this->config->get('plugins.markdown-notices.built_in_css')) {
$this->grav['assets']
->add('plugin://markdown-notices/assets/notices.css');
}
}
}

View File

@ -1,4 +0,0 @@
enabled: true
built_in_css: true
base_classes: 'notices'
level_classes: [yellow, red, blue, green]

View File

@ -1,7 +0,0 @@
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer/autoload_real.php';
return ComposerAutoloaderInit83fb2a7c0fd89ecaed52b0401a5f24c0::getLoader();

View File

@ -1,445 +0,0 @@
<?php
/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Composer\Autoload;
/**
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
*
* $loader = new \Composer\Autoload\ClassLoader();
*
* // register classes with namespaces
* $loader->add('Symfony\Component', __DIR__.'/component');
* $loader->add('Symfony', __DIR__.'/framework');
*
* // activate the autoloader
* $loader->register();
*
* // to enable searching the include path (eg. for PEAR packages)
* $loader->setUseIncludePath(true);
*
* In this example, if you try to use a class in the Symfony\Component
* namespace or one of its children (Symfony\Component\Console for instance),
* the autoloader will first look for the class under the component/
* directory, and it will then fallback to the framework/ directory if not
* found before giving up.
*
* This class is loosely based on the Symfony UniversalClassLoader.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jordi Boggiano <j.boggiano@seld.be>
* @see http://www.php-fig.org/psr/psr-0/
* @see http://www.php-fig.org/psr/psr-4/
*/
class ClassLoader
{
// PSR-4
private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
// PSR-0
private $prefixesPsr0 = array();
private $fallbackDirsPsr0 = array();
private $useIncludePath = false;
private $classMap = array();
private $classMapAuthoritative = false;
private $missingClasses = array();
private $apcuPrefix;
public function getPrefixes()
{
if (!empty($this->prefixesPsr0)) {
return call_user_func_array('array_merge', $this->prefixesPsr0);
}
return array();
}
public function getPrefixesPsr4()
{
return $this->prefixDirsPsr4;
}
public function getFallbackDirs()
{
return $this->fallbackDirsPsr0;
}
public function getFallbackDirsPsr4()
{
return $this->fallbackDirsPsr4;
}
public function getClassMap()
{
return $this->classMap;
}
/**
* @param array $classMap Class to filename map
*/
public function addClassMap(array $classMap)
{
if ($this->classMap) {
$this->classMap = array_merge($this->classMap, $classMap);
} else {
$this->classMap = $classMap;
}
}
/**
* Registers a set of PSR-0 directories for a given prefix, either
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*/
public function add($prefix, $paths, $prepend = false)
{
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
);
}
return;
}
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-4 directories for a given namespace, either
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
);
}
}
/**
* Registers a set of PSR-0 directories for a given prefix,
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param array|string $paths The PSR-0 base directories
*/
public function set($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr0 = (array) $paths;
} else {
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
}
}
/**
* Registers a set of PSR-4 directories for a given namespace,
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*/
public function setPsr4($prefix, $paths)
{
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
$length = strlen($prefix);
if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
/**
* Turns on searching the include path for class files.
*
* @param bool $useIncludePath
*/
public function setUseIncludePath($useIncludePath)
{
$this->useIncludePath = $useIncludePath;
}
/**
* Can be used to check if the autoloader uses the include path to check
* for classes.
*
* @return bool
*/
public function getUseIncludePath()
{
return $this->useIncludePath;
}
/**
* Turns off searching the prefix and fallback directories for classes
* that have not been registered with the class map.
*
* @param bool $classMapAuthoritative
*/
public function setClassMapAuthoritative($classMapAuthoritative)
{
$this->classMapAuthoritative = $classMapAuthoritative;
}
/**
* Should class lookup fail if not found in the current class map?
*
* @return bool
*/
public function isClassMapAuthoritative()
{
return $this->classMapAuthoritative;
}
/**
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
*
* @param string|null $apcuPrefix
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
}
/**
* The APCu prefix in use, or null if APCu caching is not enabled.
*
* @return string|null
*/
public function getApcuPrefix()
{
return $this->apcuPrefix;
}
/**
* Registers this instance as an autoloader.
*
* @param bool $prepend Whether to prepend the autoloader or not
*/
public function register($prepend = false)
{
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
}
/**
* Unregisters this instance as an autoloader.
*/
public function unregister()
{
spl_autoload_unregister(array($this, 'loadClass'));
}
/**
* Loads the given class or interface.
*
* @param string $class The name of the class
* @return bool|null True if loaded, null otherwise
*/
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
return true;
}
}
/**
* Finds the path to the file where the class is defined.
*
* @param string $class The name of the class
*
* @return string|false The path if found, false otherwise
*/
public function findFile($class)
{
// class map lookup
if (isset($this->classMap[$class])) {
return $this->classMap[$class];
}
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
return false;
}
if (null !== $this->apcuPrefix) {
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
if ($hit) {
return $file;
}
}
$file = $this->findFileWithExtension($class, '.php');
// Search for Hack files if we are running on HHVM
if (false === $file && defined('HHVM_VERSION')) {
$file = $this->findFileWithExtension($class, '.hh');
}
if (null !== $this->apcuPrefix) {
apcu_add($this->apcuPrefix.$class, $file);
}
if (false === $file) {
// Remember that this class does not exist.
$this->missingClasses[$class] = true;
}
return $file;
}
private function findFileWithExtension($class, $ext)
{
// PSR-4 lookup
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath.'\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
if (file_exists($file = $dir . $pathEnd)) {
return $file;
}
}
}
}
}
// PSR-4 fallback dirs
foreach ($this->fallbackDirsPsr4 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
return $file;
}
}
// PSR-0 lookup
if (false !== $pos = strrpos($class, '\\')) {
// namespaced class name
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
} else {
// PEAR-like class name
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
}
if (isset($this->prefixesPsr0[$first])) {
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
if (0 === strpos($class, $prefix)) {
foreach ($dirs as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
}
}
}
// PSR-0 fallback dirs
foreach ($this->fallbackDirsPsr0 as $dir) {
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
return $file;
}
}
// PSR-0 include paths.
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
return $file;
}
return false;
}
}
/**
* Scope isolated include.
*
* Prevents access to $this/self from included files.
*/
function includeFile($file)
{
include $file;
}

View File

@ -1,21 +0,0 @@
Copyright (c) Nils Adermann, Jordi Boggiano
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,10 +0,0 @@
<?php
// autoload_classmap.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'Grav\\Plugin\\MarkdownNoticesPlugin' => $baseDir . '/markdown-notices.php',
);

View File

@ -1,9 +0,0 @@
<?php
// autoload_namespaces.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

View File

@ -1,9 +0,0 @@
<?php
// autoload_psr4.php @generated by Composer
$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
);

View File

@ -1,52 +0,0 @@
<?php
// autoload_real.php @generated by Composer
class ComposerAutoloaderInit83fb2a7c0fd89ecaed52b0401a5f24c0
{
private static $loader;
public static function loadClassLoader($class)
{
if ('Composer\Autoload\ClassLoader' === $class) {
require __DIR__ . '/ClassLoader.php';
}
}
public static function getLoader()
{
if (null !== self::$loader) {
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInit83fb2a7c0fd89ecaed52b0401a5f24c0', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInit83fb2a7c0fd89ecaed52b0401a5f24c0', 'loadClassLoader'));
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
if ($useStaticLoader) {
require_once __DIR__ . '/autoload_static.php';
call_user_func(\Composer\Autoload\ComposerStaticInit83fb2a7c0fd89ecaed52b0401a5f24c0::getInitializer($loader));
} else {
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
$loader->set($namespace, $path);
}
$map = require __DIR__ . '/autoload_psr4.php';
foreach ($map as $namespace => $path) {
$loader->setPsr4($namespace, $path);
}
$classMap = require __DIR__ . '/autoload_classmap.php';
if ($classMap) {
$loader->addClassMap($classMap);
}
}
$loader->register(true);
return $loader;
}
}

View File

@ -1,20 +0,0 @@
<?php
// autoload_static.php @generated by Composer
namespace Composer\Autoload;
class ComposerStaticInit83fb2a7c0fd89ecaed52b0401a5f24c0
{
public static $classMap = array (
'Grav\\Plugin\\MarkdownNoticesPlugin' => __DIR__ . '/../..' . '/markdown-notices.php',
);
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
$loader->classMap = ComposerStaticInit83fb2a7c0fd89ecaed52b0401a5f24c0::$classMap;
}, null, ClassLoader::class);
}
}

View File

@ -1 +0,0 @@
[]

View File

@ -1,3 +0,0 @@
/.idea
/vendor/.DS_Store
.DS_Store

View File

@ -1,411 +0,0 @@
# v5.1.3
## 06/01/2022
1. [](#improved)
* Added a new `display` CLI command to show all registered shortcodes
# v5.1.2
## 05/10/2022
1. [](#bugfix)
* Upgraded `thunderer/shortcode` to 0.7.5 to address a security issue
# v5.1.1
## 01/11/2022
1. [](#improved)
* Improved Twig 2 support
* Bugfixes to support latest NextGen version (v1.1.8)
# v5.1.0
## 12/09/2021
1. [](#new)
* Notice shortcode now uses a twig template to allow for easy overriding of style
1. [](#improved)
* Updated vendor libraries to latest
# v5.0.7
## 09/28/2021
1. [](#improved)
* Added `processShortcodesRaw()` using raw_handlers [#104](https://github.com/getgrav/grav-plugin-shortcode-core/pull/104)
* Better vertical alignment for inline shortcodes in NextGen Editor
1. [](#bugfix)
* NextGen Editor: Ensure content of children shortcode elements, such as UI Tab content, have a new empty line as prefix and suffix, to ensure Markdown lists are not lost [getgrav/grav-premium-issues#123](https://github.com/getgrav/grav-premium-issues/issues/123)
# v5.0.6
## 04/27/2021
1. [](#improved)
* Added the ability to enable/disable built-in notice CSS
* NextGen Editor: Added support for multiple editor instances
# v5.0.5
## 03/12/2021
1. [](#bugfix)
* `SafeEmailShortcode` fixed to be compatible with PHP 7.4
* Addresses shortcodes getting repeated in modular subpages [#101](https://github.com/getgrav/grav-plugin-shortcode-core/pull/101)
# v5.0.4
## 01/26/2021
1. [](#bugfix)
* NextGen Editor: Fixed regexp regression preventing multiple shortcodes to be parsed in certain circumstances
# v5.0.3
## 01/15/2021
1. [](#improved)
* NextGen Editor: Update to support latest version
# v5.0.2
## 12/18/2020
1. [](#improved)
* NexGen Editor: Added optional `shorthand` to force attributes to full declaration
1. [](#bugfix)
* NextGen Editor: Fixed regexp preventing attributes with `/` in the value from being captured
# v5.0.1
## 12/02/2020
1. [](#improved)
* Content editing in settings popup
# v5.0.0
## 11/04/2020
1. [](#new)
* Added built-in support for **Nextgen Editor** with powerful GUI capabilities for all core shortcodes
* Support for 3rd party shortcode plugins to add their own **Nextgen Editor** integrations.
1. [](#improved)
* Support for comma-listed language tags in `[lang]` shortcode: `[lang=dk,se,no,fi]`
* Support for justified text in align shortcode [#94](https://github.com/getgrav/grav-plugin-shortcode-core/issues/94)
* Support for asset collections and arrays [#85](https://github.com/getgrav/grav-plugin-shortcode-core/issues/85)
* Support of `duotone` FontAwesome icons [#78](https://github.com/getgrav/grav-plugin-shortcode-core/issues/78)
1. [](#bugfix)
* Support HTML in Header shortcode
# v4.2.3
## 04/27/2020
1. [](#improved)
* Configuration option to exclude default shortcodes [#86](https://github.com/getgrav/grav-plugin-shortcode-core/issues/86)
* Add support for `style` attribute in `[span]` shortcode [#88](https://github.com/getgrav/grav-plugin-shortcode-core/issues/88)
* Fix typos [#91](https://github.com/getgrav/grav-plugin-shortcode-core/issues/91)
# v4.2.2
## 03/04/2020
1. [](#improved)
* Added second `$options` parameter to `ShortcodeCore->registerAllShortcodes()`, key `ignore` can be used to ignore class names / files from being loaded
1. [](#bugfix)
* Fix shortcodes which do not override `init()` method, added deprecation notice instead [#82](https://github.com/getgrav/grav-plugin-shortcode-core/issues/82)
* Fixed error message showing up when updating older versions (<4.2.0) of the plugin [#84](https://github.com/getgrav/grav-plugin-shortcode-core/issues/84)
# v4.2.1
## 02/14/2020
1. [](#improved)
* Improved shortcode loading, all shortcodes should now extend `Grav\Plugin\Shortcodes\Shortcode` class
1. [](#bugfix)
* Fixed `Class 'Grav\Plugin\Shortcodes\Shortcode' not found` error when using some plugins
* Fixed fatal error when trying to instantiate bad shortcodes (they will be skipped instead)
# v4.2.0
## 02/11/2020
1. [](#new)
* Pass phpstan level 1 tests
* Added autoload support for registering shortcodes with `$grav['shortcode']->registerShortcode($name)`
* Moved `ShortcodeObject` classes into `Grav\Plugin\ShortcodeCore` namespace with old alias
1. [](#improved)
* Major code cleanup
# v4.1.7
## 12/04/2019
1. [](#new)
* Added a new `[lorem]` shortcode for quickly generating lorem ipsum dummy content
* Updated Core Thunderer Shortcode library to `0.7.3` for PHP 7.4 compatibility
# v4.1.6
## 10/03/2019
1. [](#improved)
* Support markdown in `Figure` shortcode caption attribute
* FlexObjects compatibility: changed references to `Page` class to use `PageInterface`
* Reworked the `shortcode` twig var to use a class/method approach for better compatibility in modular/page formats
1. [](#bugfix)
* Fix issue with `[language]` when `include_default_lang: false` [#76](https://github.com/getgrav/grav-plugin-shortcode-core/issues/76)
# v4.1.5
## 09/05/2019
1. [](#improved)
* Run `onContentProcessed()` event after all other plugins [#75](https://github.com/getgrav/grav-plugin-shortcode-core/issues/75)
# v4.1.4
## 08/11/2019
1. [](#new)
* Added a new `[details][/details]` shortcode [#72](https://github.com/getgrav/grav-plugin-shortcode-core/pull/72)
1. [](#improved)
* Fixed regression issue introduced in v1.4.3 [#73](https://github.com/getgrav/grav-plugin-shortcode-core/issues/73)
# v4.1.3
## 08/09/2019
1. [](#improved)
* Fix for shortcode objects not being available. For example `[section][/section]` not working previously without `process: twig: true`
* `README.md` improvements
# v4.1.2
## 06/22/2019
1. [](#new)
* Added new `h#` tags for `h1` through `h6` supporting `class` and `id` attributes
1. [](#improved)
* Make `ShortcodeManager::setStates()` more flexible to accept any type of object
# v4.1.1
## 04/23/2019
1. [](#improved)
* Updated Core Thunderer Shortcode library to `0.7.2`
# v4.1.0
## 04/14/2019
1. [](#new)
* Support for a `ShortCodeManager::getRawHandlers()` to support shortcodes that need to process **before** Markdown (like upcoming `Prism-Highlighter`)
# v4.0.1
## 03/21/2019
1. [](#new)
* Added a new `[mark][/mark]` shortcode which makes highlighting in code blocks much simpler!
# v4.0.0
## 03/20/2019
1. [](#improved)
* Improved way to handle shortcodeAssets from `Page::contentMeta()` - Fixes numerous issues
* Allow `size` shortcode to handle non-numeric values (e.g. `%`, `x-large`, etc.) [#63](https://github.com/getgrav/grav-plugin-shortcode-core/pull/63)
* Added FontAwesome 5 support [#56](https://github.com/getgrav/grav-plugin-shortcode-core/pull/56)
# v3.1.2
## 03/15/2019
1. [](#improved)
* Added a helper method to allow `getBbCode()` to work with `wordpress` parser
# v3.1.1
## 03/12/2019
1. [](#bugfix)
* Reverted accidental change of default parser. Should be `regular`
# v3.1.0
## 02/28/2019
1. [](#improved)
* Modified priority of `onPluginsInitialized` to fire earlier
1. [](#bugfix)
* New language shortcode, for example `[lang=en]...[/lang]`
# v3.0.1
## 02/03/2019
1. [](#bugfix)
* Fixed issues with `0` param and `regular` parser [#14](https://github.com/getgrav/grav-plugin-shortcode-core/issues/14) [#57](https://github.com/getgrav/grav-plugin-shortcode-core/issues/57) [shortcode-ui#29](https://github.com/getgrav/grav-plugin-shortcode-ui/issues/29) [shortcode-ui#6](https://github.com/getgrav/grav-plugin-shortcode-ui/issues/26)
# v3.0.0
## 12/19/2018
1. [](#new)
* Update to latest Shortcode library `v0.7.0` which has over **10X performance** for default regular parser
* Added an option `admin_pages_only` to only process actual `user/pages/` based pages and not dynamic pages to increase performance
# v2.7.3
## 12/07/2018
1. [](#new)
* Added a new `figure` shortcode [#51](https://github.com/getgrav/grav-plugin-shortcode-core/pull/51)
1. [](#bugfix)
* Fix empty space at the end of a line [#54](https://github.com/getgrav/grav-plugin-shortcode-core/pull/54)
# v2.7.2
## 10/26/2018
1. [](#new)
* Added a new `span` shortcode that supports `class` and `id` attributes
1. [](#improved)
* Switched default parser to `regular`
* Using latest `dev-master` version which has a couple of key fixes
# v2.7.1
## 03/14/2018
1. [](#improved)
* Support shortcodes in theme as well as plugins [#43](https://github.com/getgrav/grav-plugin-shortcode-core/issues/43)
# v2.7.0
## 01/16/2018
1. [](#new)
* Added a new `div` shortcode that supports `class` and `id` attributes
# v2.6.0
## 04/25/2017
1. [](#new)
* Added ability to define a custom shortcode path for you own shortcodes [#36](https://github.com/getgrav/grav-plugin-shortcode-core/issues/36)
* Added a twig filter to allow you to use shortcodes directly in Twig templates [#33](https://github.com/getgrav/grav-plugin-shortcode-core/pull/33)
# v2.5.4
## 02/26/2017
1. [](#bugfix)
* Fixed issue with modular Shortcode meta was not getting processed properly (Assets, Sections, etc.)
# v2.5.3
## 02/21/2017
1. [](#improved)
* Added a reference to current Page in `ShortcodeManager`
# v2.5.2
## 01/26/2017
1. [](#bugfix)
* Fixed Mozilla column css prefix
# v2.5.1
## 01/25/2017
1. [](#improved)
* Added `moz-` prefix in column shortcode
# v2.5.0
## 01/25/2017
1. [](#new)
* Added **new** `columns` shortcode for CSS columns support
# v2.4.0
## 01/17/2017
1. [](#improved)
* Switched to `Regex` parser by default (previous was Regex)
* Update to latest Shortcode library v0.6.5
1. [](#bugfix)
* Removed `getParameterAt(0)` hack in favor of `getBbbCode()` that works with Regex parser
# v2.3.2
## 12/15/2016
1. [](#improved)
* Update to latest Shortcode library v0.6.4 to address a parser bug [#25](https://github.com/getgrav/grav-plugin-shortcode-core/issues/25)
# v2.3.1
## 07/14/2016
1. [](#improved)
* renamed internal `contentMeta` variables to `shortcodeMeta` and `shortcodeAssets`
* Update to latest Shortcode library
# v2.3.0
## 05/20/2016
1. [](#improved)
* Use new conentmeta approach from Grav 1.1
# v2.2.1
## 05/09/2016
1. [](#bugfix)
* Always initialize current page even if collection exists [#3](https://github.com/getgrav/grav-plugin-shortcode-ui/issues/3)
# v2.2.0
## 04/23/2016
1. [](#new)
* Added **new** `fa` FontAwesome shortcode
# v2.1.0
## 04/21/2016
1. [](#new)
* Added **new** `notice` shortcode
1. [](#improved)
* Updated to latest Shortcode library version
# v2.0.2
## 02/17/2016
1. [](#bugfix)
* Initialized states in constructor
# v2.0.1
## 02/16/2016
1. [](#improved)
* Support **modular** pages by populating Twig variables in `onTwigPageVariables()` event #8
1. [](#bugfix)
* Better more flexible regex in the Markdown **block** definition for more reliable markdown in shortcodes. #3
# v2.0.0
## 02/11/2016
1. [](#new)
* Added **new** `section` shortcode
* Use new `contentMeta` mechanism for storing/caching objects and assets per page
* Added new `ShortcodeManager::reset()` methods
1. [](#improved)
* Completely refactored the plugin to use a new extensible mechanism that makes it easier to manage multiple shortcodes
# v1.4.0
## 02/03/2016
1. [](#improved)
* Updated Shortcode to latest `dev-master` that includes Events
1. [](#bugfix)
* Fixed `raw` shortcode to use new `FilterRawEventHandler` so it doesn't process shortcodes at all
# v1.3.0
## 01/29/2016
1. [](#improved)
* Added markdown-shortcode-block support to the plugin
1. [](#bugfix)
* Updated Core Thunderer Shortcode library with some important fixes
# v1.2.0
## 01/25/2016
1. [](#improved)
* Customizable Parser. Choose from `WordPress`, `Regex`, and `Regular`
# v1.1.0
## 01/24/2016
1. [](#improved)
* Updated to latest Shortcode `dev-master` version that contains some important fixes
* Switched to `WordPressParser` for 2x speed improvements
# v1.0.1
## 01/18/2016
1. [](#bugfix)
* Fixed blueprint
* Fixed a default yaml state
# v1.0.0
## 01/18/2016
1. [](#new)
* ChangeLog started...

View File

@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2016 Grav
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,575 +0,0 @@
# Grav Shortcode Core Plugin
## About
The **Shortcode Core** plugin allow for the development of simple yet powerful shortcode plugins that utilize the common format utilized by **WordPress** and **BBCode**. The core plugin loads the libraries required and fires a new event that other plugins can use. It also provides a mechanism for adding CSS/JS assets that are cached so that shortcodes can work effectively even when the processed page content is cached. This ensures that shortcodes are only processed once and will not impact performance by doing unnecessary work on every page.
This plugin uses the [Thunderer Advanced shortcode engine](https://github.com/thunderer/Shortcode). For more information please check out that repo on GitHub.
## Quick Example
```
This is some [u]bb style underline[/u] and not much else
[center]This is centered[/center]
This is [size=30]bigger text[/size] and this is [color=blue]blue text[/color]
```
This example functionality is provided with the **Shortcode Core** plugin to provide some functionality that is not available in traditional markdown but is standard **BBCode** used in many form platforms. You can see how the syntax is just a simple open and close element using square brackets.
This will render:
![](assets/shortcode-core-1.png)
The core plugin required for any other shortcode specific plugin. Provides some basic BBCode style syntax such as underline, color, center, and size.
## Installation
Typically a plugin should be installed via [GPM](http://learn.getgrav.org/advanced/grav-gpm) (Grav Package Manager):
```
$ bin/gpm install shortcode-core
```
Alternatively it can be installed via the [Admin Plugin](http://learn.getgrav.org/admin-panel/plugins)
> NOTE: If you install a shortcode plugin such as [grav-plugin-shortcode-ui](https://github.com/getgrav/grav-plugin-shortcode-ui) it may have this core plugin configured as a dependency and install it automatically.
## Configuration Defaults
The **Shortcode Core** plugin only has a few options to configure. The default values are:
```yaml
enabled: true
active: true
active_admin: true
admin_pages_only: true
parser: regular
include_default_shortcodes: true
css:
notice_enabled: true
custom_shortcodes:
fontawesome:
load: true
url: '//maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css'
v5: false
```
* `enabled: true|false` toggles if the shortcodes plugin is turned on or off
* `active: true|false` toggles if shortcodes will be enabled site-wide or not
* `active_admin: true|false` toggles if shortcodes will be processed in the admin plugin
* `admin_pages_only: true|false` toggles if admin should only process shortcodes for Grav pages
* `parser: wordpress|regex|regular` let's you configure the parser to use
* `include_default_shortcodes: true|false` toggle the inclusion of shortcodes provided by this plugin
* `custom_shortcodes:` the path to a directory where you can put your custom shortcodes (e.g. `/user/custom/shortcodes`)
* `fontawesome.load: true|false` toggles if the fontawesome icon library should be loaded or not
* `fontawesome.url:` the CDN Url to use for fontawesome
* `v5:` Version 5 flag as it requires some additional logic
> NOTE: In previous versions the `wordpress` parser was preferred. However with version `2.4.0`, the `regex` parser is now default. If you have saved configuration, you should manually change this to `regex` or you may receive errors or bad output.
## Configuration Modifications
The best approach to make modifications to the core plugin settings is to copy the `shortcode-core.yaml` file from the plugin into your `user/config/plugins/` folder (create it if it doesn't exist). You can modify the settings there.
> NOTE: If you have the admin plugin installed, you can make modifications to the settings via the **Plugins** page and it will create that overridden file automatically.
## Per-Page Configuration
Sometimes you may want to only enable shortcodes on a _page-by-page_ basis. To accomplish this set your plugin defaults to:
```yaml
enabled: true
active: false
```
This will ensure the plugin is loaded, but not **active**, then on the page you wish to process shortcodes on simply add this to the page header:
```yaml
shortcode-core:
active: true
```
This will ensure the shortcodes are processed on this page only.
You can also change the parser on a particular page with the following:
```yaml
shortcode-core:
parser: regex
```
## Available Shortcodes
The core plugin contains a few simple shortcodes that can be used as basic examples:
#### Underline
Underline a section of text
```
This is some [u]bb style underline[/u] and not much else
```
#### Font Size
Set the size of some text to a specific pixel size
```
This is [size=30]bigger text[/size]
```
#### Left Align
Left align the text between this shortcode
```
[left]This text is left aligned[/left]
```
#### Center Align
Center a selection of text between this shortcode
```
[center]This text is centered[/center]
```
#### Right Align
Right align the text between this shortcode
```
[right]This text is right aligned[/right]
```
#### Div
Allows you to wrap markdown in an HTML `div` tag that supports both `id` and `classes` attributes
```
[div class="text-center"]
This text is **centered** aligned
[/div]
```
or
```
[div class="table table-striped"]
| header 1 | header 2 |
|----------|----------|
| A 1 | B 1 |
| A 2 | B 2 |
| A 3 | B 3 |
[/div]
```
#### Headers
Allows you to add `id` and `class` attributes to HTML `h1` through `h6` tags:
```
[h1 class="major"]This is my title[/h1]
```
#### Span
Allows you to wrap markdown in an HTML `span` tag that supports both `id` and `class` attributes
```
[span class="text-center"]
This text is **centered** aligned
[/span]
```
#### Columns
Take advantage of powerful CSS columns support by using this shortcode
```
[columns]
### Headline
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
[/columns]
```
Defaults to 2 columns. You can also explicitly set the number of `columns`, `width`, `gap`, and `rule` styling for the column divider:
```
[columns count=3 width=200px gap=30px rule="1px dotted #930"]
### Headline
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
[/columns]
```
#### Raw
Do not process the shortcodes between these raw shortcode tags
```
[raw]This is some [u]bb style underline[/u] and not much else[/raw]
```
#### Safe-Email
Encode an email address so that it's not so easily 'scrapable' by nefarious scripts. This one has a couple of options: `autolink` toggle to turn the email into a link, and an `icon` option that lets you pick a font-awesome icon to prefix the email. Both settings are optional.
```
Safe-Email Address: [safe-email autolink="true" icon="envelope-o"]user@domain.com[/safe-email]
```
#### Section
The **section** shortcode is a powerful way to encompass some text in your markdown page with a `[section][/section]` tag and then this is cached by Grav so it can be accessed later. For example you could have a page with a variety of sections described in it that let you create many **chunks** of data. These are then added to Twig as an array of shortcode objects. An example of this would be the following markdown:
```
[section name="author"]
![](author.jpg?cropResize=100,100&classes=left)
### Johnny Appleseed
Johnny Appleseed was an American pioneer nurseryman who introduced apple trees to large parts of Pennsylvania, Ontario, Ohio, Indiana, and Illinois, as well as the northern counties of present-day West Virginia. He became an American legend while still alive, due to his kind, generous ways, his leadership in conservation, and the symbolic importance he attributed to apples.
[/section]
[section name="quote"]
> Some are born great, some achieve greatness, and some have greatness thrust upon them.
Read more at http://www.brainyquote.com/quotes/topics/topic_great.html#tdqt3strtEYBCH43.99
> <cite>William Shakespeare</cite>
Regular **Markdown** content that will be output as `page.content`
[/section]
```
This we be removed from the page content and made available in Twig variables so you could insert these into custom HTML structures, for example:
```
<div id="author">{{ shortcode.section.author }}</div>
<div id="article">
<div class="left">
{{ page.content|raw }}
</div>
<div class="right">
{{ shortcode.section.quote }}
</div>
</div>
```
#### Sections from other pages
You can even retrieve a section from another page utilizing the shortcodes as they are stored in the page's `contentMeta` with this syntax:
```
<div id="author">{{ page.find('/my/custom/page').contentMeta.shortcodeMeta.shortcode.section.author }}</div>
```
#### Notice
A useful shortcode that performs a similar job to the [markdown-notices](https://github.com/getgrav/grav-plugin-markdown-notices) plugins, allows you to easily create simple notice blocks as seen on http://learn.getgrav.org and http://getgrav.org. To use simply use the following syntax:
```
[notice]
Your **Markdown** text that will appear in the notice
[/notice]
```
You can also specifically choose from `note`, `info`, `warning`, `tip` types which provide unique color options:
```
[notice=warning]
Danger Will Robinson! Danger, Will Robinson!
[/notice]
```
#### Figure
Figure elements are the recommended way to add self-contained units of flow content, i.e. images, charts and other visual elements that can be moved away from the main flow of the document without affecting the document's meaning. Figures may include captions through the `caption` attribute. Both `id` and `class` attributes are also available.
```
[figure id="fig1" class="image" caption="**Fig. 1** A beautiful figure."]
![Gorgeous image](image.png)
[/figure]
```
#### Mark
The HTML `<mark></mark>` tag is extremely useful to highlight text in your pages, and serves like a highlighter pen. However, as we know that markdown inside of HTML is not processed, using this HTML is often not convenient as it means markdown inside will not be processed.
Another important usecase is trying to highlight code in a markdown text block, again the HTML tag doesn't work because the result is escaped and treated like any other code and simply displayed.
The solution is simple, just use the shortcode version instead:
```
This is a sample of text [mark]with this bit **highlighted** with _markdown_ syntax[/mark] and the rest just plain.
```
You can also use the `class` option to specificy a specific a CSS class to add to the `<mark>` HTML tag (useful to color the marked output):
```
This is a sample of text [mark class=blue]with this bit **highlighted** with _markdown_ syntax[/mark] and the rest just plain.
```
It also works great in code blocks:
```
<?php
class Pipeline extends PropertyObject
{
use AssetUtilsTrait;
[mark]protected const CSS_ASSET = true;[/mark]
protected const JS_ASSET = false;
...
}
```
You can also pass an option `style` attribute of `block` to get a full lines highlighted:
```
<?php
class Pipeline extends PropertyObject
{
use AssetUtilsTrait;
[mark style=block]
protected const CSS_ASSET = true;
protected const JS_ASSET = false;
[/mark]
...
}
```
#### Language
Hooks into Grav's multi-language capabilities to allow you to show certain blocks of code only for the current active language.
```
[lang=en]
Or kind rest bred with am shed then.
[/lang]
[lang=fr]
Marche diable ombres net non qui.
[/lang]
[lang=de]
Genie dahin einem ein gib geben allen.
[/lang]
```
#### FontAwesome
[FontAwesome](https://fortawesome.github.io/Font-Awesome/) is a powerful library of font-based icons. This shortcode makes it simple to add fontawesome icons to your page content without using HTML.
```
[fa=cog /] Simplest Format
[fa=fa-cog /] Format using `fa-` prefix
[fa icon=fa-camera-retro /] Explicit format
[fa icon=fa-grav extras=fab /] Font Awesome 5 format
[fa icon=fa-camera-retro extras=fa-4x /] Explicit format with extras - [See FontAwesome Examples](https://fortawesome.github.io/Font-Awesome/examples/)
[fa icon=fa-circle-o-notch extras=fa-spin,fa-3x,fa-fw,margin-bottom /] The full monty! - [See FontAwesome Examples](https://fortawesome.github.io/Font-Awesome/examples/)
```
#### Details/Summary
The `<details>` element provides a simple show/hide behaviour without JavaScript, and can optionally contain a `<summary>` element that is always shown. Clicking on the summary text toggles the visibility of the content, and when a summary is not provided, it defaults to "Details". The element can be used to provide extra details, or can be combined into an accordion-like structure.
```
[details]
Lorem ipsum dolor sit amet...
[/details]
[details="Summary text"]
Lorem ipsum dolor sit amet...
[/details]
[details summary="Summary text" class="accordion"]
Lorem ipsum dolor sit amet...
[/details]
```
**Note:** The show/hide behaviour is not supported in IE 11 or Edge 18, and the element will be permanently open. You can check the current status of browser compatibility at [Can I Use](https://caniuse.com/#search=details).
#### Lorem Ipsum
Useful for faking content, you can use a shortcode to quickly generate some random "lorem ipsum" text:
**Paragraphs:**
```
[lorem=5 /]
[lorem p=5 tag=div /]
```
**Sentences:**
```
[lorem s=4 /]
```
**Words:**
```
[lorem w=35 /]
```
## Using Shortcodes in Twig
You can now use shortcodes in Twig templates and process them with the `|shortcodes` filter. For example:
```
{% set twig_text = "This is [size=30]bigger text[/size] and this is [color=green]green text[/color]" %}
{{ twig_text|shortcodes }}
```
## Custom Shortcodes
### Simple Way
First, configure a directory from which custom shortcodes are loaded. Edit `user/config/plugins/shortcode-core.yaml` like follows (create it if it does not exist):
```yaml
custom_shortcodes: '/user/custom/shortcodes'
```
To add a custom shortcode, create a PHP file that defines a new shortcode class. For example, to create a shortcode for ~~strikethrough~~ text, save the following code as `user/custom/shortcodes/StrikeShortcode.php`:
```php
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class StrikeShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('strike', function(ShortcodeInterface $sc) {
return '<del>'.$sc->getContent().'</del>';
});
}
}
```
Note that the class name (`StrikeShortcode`) must match the file name for the shortcode to work.
`[strike]text[/strike]` should now produce strikethrough text.
### As a Custom Plugin
The more flexible approach is to create a custom plugin.
The **Shortcode Core** plugin is developed on the back of the [Thunderer Advanced Shortcode Engine](https://github.com/thunderer/Shortcode) and as such loads the libraries and classes required to build third party shortcode plugins.
We introduced a new event called `onShortcodeHandlers()` that allows a 3rd party plugin to create and add their own custom handlers. These are then all processed by the core plugin in one shot.
```php
public static function getSubscribedEvents()
{
return [
'onShortcodeHandlers' => ['onShortcodeHandlers', 0]
];
}
```
Then you just need to listen to the event:
```php
public function onShortcodeHandlers()
{
$this->grav['shortcode']->registerAllShortcodes(__DIR__.'/shortcodes');
}
```
Lastly create your shortcode in the `user/plugins/my-plugin/shortcodes/` folder, in this example we created a simple `[red][/red]` shortcode as `RedShortcode.php`:
```php
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class RedShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('red', function(ShortcodeInterface $sc) {
return '<span style="color:red;">'.$sc->getContent().'</span>';
});
}
}
```
> If you have not already done so, I suggest reading the [Grav Plugin Tutorial](http://learn.getgrav.org/plugins/plugin-tutorial) first to gain a full understanding of what you need to develop a Grav plugin.
The best way to see how to create a new shortcode-based plugins is to look at the **Shortcode UI** plugin that extends the **Shortcode Core** by adding more shortcodes. It also makes use of Twig to handle processing and has some more advanced shortcode techniques.
* Core Plugin: https://github.com/getgrav/grav-plugin-shortcode-ui/blob/develop/shortcode-ui.php
* Tabs Shortcode Example: https://github.com/getgrav/grav-plugin-shortcode-ui/blob/develop/shortcodes/TabsShortcode.php
* Color Shortcode Example: https://github.com/getgrav/grav-plugin-shortcode-core/blob/develop/shortcodes/ColorShortcode.php
* Section Shortcode Example: https://github.com/getgrav/grav-plugin-shortcode-core/blob/develop/shortcodes/SectionShortcode.php
* Section Prism Highlight Example: https://github.com/trilbymedia/grav-plugin-prism-highlight/blob/develop/shortcodes/PrismShortcode.php
## Processing Shortcodes Before or After Markdown processing
There are basically two ways of processing a shortcode:
1. After markdown is processed
2. Before markdown is processed
These two approaches are important because, for the most part, shortcodes make more sense when they can 'wrap' markdown, so they process **after** markdown.
For example a `[div][/div]` shortcode would be useless if it ran before markdown is processed because it would add the relevant HTML `<div></div>` tags, and then the markdown parser would promptly **skip** all markdown processing between those divs because it won't process markdown **inside** HTML. So this shortcode and most others run after markdown processing has already occurred using this approach:
```php
$this->shortcode->getHandlers()->add('div', function(ShortcodeInterface $sc) { ... }
```
Notice the `getHandlers()` call is the standard way to add a handler.
However, there are situations when you need to process the shortcode **before** the markdown processing to ensure markdown **is skipped**, like in the example of a code block. This is why in the [Prism Highlighter](https://github.com/trilbymedia/grav-plugin-prism-highlight) plugin, we use this approach to defining the shortcode:
```php
$this->shortcode->getRawHandlers()->add('prism', function(ProcessedShortcode $sc) { ... }
```
The difference here is it uses `getRawHandlers()` to ensure the handler is processed to the content in the _raw_ state.
## Display All Shortcodes
You can now display all available shortcodes by using the CLI command:
```shell
bin/plugin shortcode-core display
```

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,127 +0,0 @@
name: Shortcode Core
slug: shortcode-core
type: plugin
version: 5.1.3
description: "This plugin provides the core functionality for shortcode plugins"
icon: code
author:
name: Team Grav
email: devs@getgrav.org
url: http://getgrav.org
homepage: https://github.com/getgrav/grav-plugin-shortcode-core
demo: http://learn.getgrav.org
keywords: gui, plugin, tabs, twig
bugs: https://github.com/getgrav/grav-plugin-shortcode-core/issues
license: MIT
dependencies:
- { name: grav, version: '>=1.6.4' }
form:
validation: strict
fields:
enabled:
type: toggle
label: Plugin Enabled
highlight: 1
default: 1
options:
1: Enabled
0: Disabled
validate:
type: bool
active:
type: toggle
label: Activated
help: Site-Wide activation
highlight: 1
default: 1
options:
1: Enabled
0: Disabled
validate:
type: bool
active_admin:
type: toggle
label: Activated in Admin
highlight: 1
default: 1
options:
1: Enabled
0: Disabled
validate:
type: bool
admin_pages_only:
type: toggle
label: Admin Real-Pages Only
help: When activate, only process real-pages
highlight: 1
default: 1
options:
1: Enabled
0: Disabled
validate:
type: bool
parser:
type: select
size: medium
classes: fancy
label: Processor
help: Which built-in processor to use. WordPress (fastest), Regular (customizable), Regex (solid)
options:
wordpress: WordpressParser
regex: RegexParser
regular: RegularParser
custom_shortcodes:
type: text
label: Custom Shortcodes
help: The path to a location where you store custom shortcodes.
placeholder: '/user/custom/shortcodes'
size: large
css.notice_enabled:
type: toggle
label: Enable Notice Shortcode CSS
help: Enable the default notice CSS by default. Disable if you want to use your own custom CSS.
highlight: 1
default: 1
options:
1: Enabled
0: Disabled
validate:
type: bool
fontawesome.load:
type: toggle
label: Load Fontawesome Library
help: Used by the `safe-email` shortcode if your theme doesn't already load it
highlight: 1
default: 1
options:
1: Enabled
0: Disabled
validate:
type: bool
fontawesome.url:
type: text
label: Fontawesome URL
help: You can change the location of fontawesome by changing this URL
size: large
fontawesome.v5:
type: toggle
label: Use Fontawesome Version 5
help: Allows usage of the 'fab', 'fas' and other new font families of Fontawesome 5.
highlight: 0
default: 0
options:
1: Enabled
0: Disabled
validate:
type: bool

View File

@ -1,7 +0,0 @@
<?php
// This file is for older Grav versions (needed during plugin update).
if (!class_exists(\Grav\Plugin\Shortcodes\Shortcode::class, false)) {
require_once __DIR__ . '/shortcodes/Shortcode.php';
}

View File

@ -1,15 +0,0 @@
<?php
// This file is for older Grav versions (needed during plugin update).
@trigger_error(
'\\Grav\\Plugin\\ShortcodeManager class is deprecated, use \\Grav\\Plugin\\ShortcodeCore\\ShortcodeManager instead',
E_USER_DEPRECATED
);
if (!class_exists(\Grav\Plugin\ShortcodeCore\ShortcodeManager::class, false)) {
require_once __DIR__ . '/plugin/ShortcodeManager.php';
}
// Create alias for the deprecated class.
class_alias(\Grav\Plugin\ShortcodeCore\ShortcodeManager::class, \Grav\Plugin\ShortcodeManager::class);

View File

@ -1,7 +0,0 @@
<?php
// This file is for older Grav versions (needed during plugin update).
if (!class_exists(\Grav\Plugin\ShortcodeCore\ShortcodeObject::class, false)) {
require_once __DIR__ . '/shortcodes/ShortcodeObject.php';
}

View File

@ -1,24 +0,0 @@
<?php
namespace Grav\Plugin\ShortcodeCore;
// Check if the new class has been autoloaded. If not, trigger deprecation error.
if (!class_exists(\Grav\Plugin\Shortcodes\Shortcode::class, false)) {
@trigger_error(
Shortcode::class . ' class is deprecated, use \\Grav\\Plugin\\Shortcodes\\Shortcode instead',
E_USER_DEPRECATED
);
}
// Create alias for the deprecated class.
class_alias(\Grav\Plugin\Shortcodes\Shortcode::class, Shortcode::class);
// Make sure that both IDE and composer knows about the deprecated class.
if (false) {
/**
* @deprecated 4.2.1 This was a bad idea, reverting back to the old class.
*/
abstract class Shortcode extends \Grav\Plugin\Shortcodes\Shortcode
{
}
}

View File

@ -1,383 +0,0 @@
<?php
namespace Grav\Plugin\ShortcodeCore;
use Grav\Common\Config\Config;
use Grav\Common\Data\Data;
use Grav\Common\Grav;
use Grav\Common\Page\Interfaces\PageInterface;
use Thunder\Shortcode\EventContainer\EventContainer;
use Thunder\Shortcode\HandlerContainer\HandlerContainer;
use Thunder\Shortcode\Parser\RegexParser;
use Thunder\Shortcode\Parser\RegularParser;
use Thunder\Shortcode\Parser\WordpressParser;
use Thunder\Shortcode\Processor\Processor;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
use Thunder\Shortcode\Syntax\CommonSyntax;
class ShortcodeManager
{
/** @var Grav $grav */
protected $grav;
/** @var Config */
protected $config;
/** @var PageInterface $page */
protected $page;
/** @var HandlerContainer $handlers */
protected $handlers;
/** @var HandlerContainer $raw_handlers */
protected $raw_handlers;
/** @var EventContainer $events */
protected $events;
/** @var array */
protected $assets;
/** @var array */
protected $states;
/** @var array */
protected $objects;
/**
* initialize some internal instance variables
*/
public function __construct()
{
$this->grav = Grav::instance();
$this->config = $this->grav['config'];
$this->handlers = new HandlerContainer();
$this->raw_handlers = new HandlerContainer();
$this->events = new EventContainer();
$this->states = [];
$this->assets = [];
$this->objects = [];
}
/**
* add CSS and JS assets to the Manager so that they can be saved to cache
* for subsequent cached pages
*
* @param mixed $actionOrAsset the type of asset (JS or CSS) or, if the second parameter is omitted,
* a collection or an array of asset.
* @param string $asset the asset path in question
*/
public function addAssets($actionOrAsset, $asset = null)
{
if ($asset == null) {
if (is_array($actionOrAsset)) {
$this->assets[''] = array_merge($this->assets[''] ?? array(), $actionOrAsset);
} else {
$this->assets[''] [] = $actionOrAsset;
}
} else {
if (isset($this->assets[$actionOrAsset]) && in_array($asset, $this->assets[$actionOrAsset], true)) {
return;
}
$this->assets[$actionOrAsset] [] = $asset;
}
}
/**
* return a multi-dimensional array of all the assets
*
* @return array the assets array
*/
public function getAssets()
{
return $this->assets;
}
/**
* reset the assets
*/
public function resetAssets()
{
$this->assets = [];
}
/**
* adds ad object
* @param string $key The key to look up the object
* @param object $object The object to store
*/
public function addObject($key, $object)
{
$new = [$object->name() => $object];
if (array_key_exists($key, $this->objects)) {
$current = (array)$this->objects[$key];
$this->objects[$key] = $current + $new;
} else {
$this->objects[$key] = $new;
}
}
/**
* sets all the objects
* @param array $objects The objects array
*/
public function setObjects($objects)
{
$this->objects = $objects;
}
/**
* return all the objects
* @return array The objects array
*/
public function getObjects()
{
return $this->objects;
}
/**
* reset the objects
*/
public function resetObjects()
{
$this->objects = [];
}
/**
* returns the current handler container object
*
* @return HandlerContainer
*/
public function getHandlers()
{
return $this->handlers;
}
/**
* returns the current raw handler container object
*
* @return HandlerContainer
*/
public function getRawHandlers()
{
return $this->raw_handlers;
}
/**
* returns the current event container object
*
* @return EventContainer
*/
public function getEvents()
{
return $this->events;
}
/**
* Register an individual shortcode with the manager so it can be operated on by the Shortcode library
*
* @param string $name the name of the shortcode (should match the classname)
* @param string|null $directory directory where the shortcode is located
*/
public function registerShortcode($name, $directory = null)
{
$className = 'Grav\\Plugin\\Shortcodes\\' . basename($name, '.php');
if (!class_exists($className) && $directory) {
$path = rtrim($directory, '/').'/'.$name;
require_once $path;
}
// Make sure the class exists, extends Shortcode and is not abstract.
if (class_exists($className) && is_subclass_of($className, \Grav\Plugin\Shortcodes\Shortcode::class)) {
$reflection = new \ReflectionClass($className);
if (!$reflection->isAbstract()) {
/** @var \Grav\Plugin\Shortcodes\Shortcode $shortcode */
$shortcode = new $className();
$shortcode->init();
}
}
}
/**
* register all files as shortcodes in a particular directory
* @param string $directory directory where the shortcodes are located
* @param array $options Extra options
*/
public function registerAllShortcodes($directory, array $options = [])
{
try {
$ignore = $options['ignore'] ?? [];
foreach (new \DirectoryIterator($directory) as $file) {
if ($file->isDot() || \in_array($file->getBasename('.php'), $ignore, true)) {
continue;
}
$this->registerShortcode($file->getFilename(), $directory);
}
} catch (\UnexpectedValueException $e) {
Grav::instance()['log']->error('ShortcodeCore Plugin: Directory not found => ' . $directory);
}
}
/**
* setup the markdown parser to handle shortcodes properly
*
* @param object $markdown the markdown parser object
*/
public function setupMarkdown($markdown)
{
$markdown->addBlockType('[', 'ShortCodes', true, false);
$markdown->blockShortCodes = function($Line) {
$valid_shortcodes = implode('|', $this->handlers->getNames());
$regex = '/^\[\/?(?:' . $valid_shortcodes . ')[^\]]*\]$/';
if (preg_match($regex, trim($Line['body']), $matches)) {
return [
'markup' => $Line['body'],
];
}
return null;
};
}
/**
* process the content by running over all the known shortcodes with the
* chosen parser
*
* @param PageInterface $page the page to work on
* @param Data $config configuration merged with the page config
* @param null $handlers
* @return string
*/
public function processContent(PageInterface $page, Data $config, $handlers = null)
{
$parser = $this->getParser($config->get('parser'));
if (!$handlers) {
$handlers = $this->handlers;
}
if ($page && $config->get('enabled')) {
$this->page = $page;
$content = $page->getRawContent();
$processor = new Processor(new $parser(new CommonSyntax()), $handlers);
$processor = $processor->withEventContainer($this->events);
return $processor->process($content);
}
return null;
}
public function processRawContent(PageInterface $page, Data $config)
{
return $this->processContent($page, $config, $this->raw_handlers);
}
/**
* Allow the processing of shortcodes directly on a string
* For example when used by Twig directly
*
* @param $str
* @param null $handlers
* @return string
*/
public function processShortcodes($str, $handlers = null)
{
$parser = $this->getParser($this->config->get('parser'));
if (!$handlers) {
$handlers = $this->handlers;
}
$processor = new Processor(new $parser(new CommonSyntax()), $handlers);
return $processor->process($str);
}
public function processShortcodesRaw($str)
{
return $this->processShortcodes($str, $this->raw_handlers);
}
/**
* set a state of a particular item with a hash for retrieval later
*
* @param string $hash a unique hash code
* @param object $item some item to store
*/
public function setStates($hash, $item)
{
$this->states[$hash][] = $item;
}
/**
* returns the shortcode of a specific hash
*
* @param string $hash unique id of state
* @return ShortcodeInterface shortcode stored for this hash
*/
public function getStates($hash)
{
if (array_key_exists($hash, $this->states)) {
return $this->states[$hash];
}
return null;
}
/**
* helper method to create a unique shortcode based on the content
*
* @param ShortcodeInterface $shortcode
* @return string
*/
public function getId(ShortcodeInterface $shortcode)
{
return substr(md5($shortcode->getShortcodeText()), -10);
}
/**
* Sets the current page context
*
* @param PageInterface $page
*/
public function setPage(PageInterface $page)
{
$this->page = $page;
}
/** gets the current page context if set */
public function getPage()
{
return $this->page;
}
/**
* Get the appropriate parser object
*
* @param $parser
* @return string
*/
protected function getParser($parser)
{
switch($parser)
{
case 'regular':
$parser = RegularParser::class;
break;
case 'wordpress':
$parser = WordpressParser::class;
break;
default:
$parser = RegexParser::class;
break;
}
return $parser;
}
}

View File

@ -1,33 +0,0 @@
<?php
namespace Grav\Plugin\ShortcodeCore;
class ShortcodeObject
{
protected $obj_name;
protected $obj_object;
public function __construct($name, $object)
{
$this->obj_name = $name;
$this->obj_object = $object;
}
public function __toString()
{
return $this->obj_object;
}
public function name()
{
return $this->obj_name;
}
public function object()
{
return $this->obj_object;
}
}
// Make sure we also autoload the deprecated class.
class_exists(\Grav\Plugin\Shortcodes\ShortcodeObject::class);

View File

@ -1,27 +0,0 @@
<?php
namespace Grav\Plugin\ShortcodeCore;
use Grav\Common\Grav;
class ShortcodeTwigVar
{
public function __call($name, $args)
{
/** @var ShortcodeManager $shortcode */
$shortcode = Grav::instance()['shortcode'];
$objects = $shortcode->getObjects();
if ($objects) {
return $objects[$name] ?? [];
}
$page_meta = Grav::instance()['page']->getContentMeta('shortcodeMeta');
if (isset($page_meta['shortcode'])) {
$objects = (array) $page_meta['shortcode'];
return $objects[$name] ?? [];
}
return [];
}
}

View File

@ -1,26 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class AlignShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('center', static function(ShortcodeInterface $sc) {
return '<div style="text-align: center;">' . $sc->getContent() . '</div>';
});
$this->shortcode->getHandlers()->add('left', static function(ShortcodeInterface $sc) {
return '<div style="text-align: left;">' . $sc->getContent() . '</div>';
});
$this->shortcode->getHandlers()->add('right', static function(ShortcodeInterface $sc) {
return '<div style="text-align: right;">' . $sc->getContent() . '</div>';
});
$this->shortcode->getHandlers()->add('justify', static function(ShortcodeInterface $sc) {
return '<div style="text-align: justify;">' . $sc->getContent() . '</div>';
});
}
}

View File

@ -1,16 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class ColorShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('color', function(ShortcodeInterface $sc) {
$color = $sc->getParameter('color', $this->getBbCode($sc));
return '<span style="color: ' . $color . ';">' . $sc->getContent() . '</span>';
});
}
}

View File

@ -1,27 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class ColumnsShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('columns', static function(ShortcodeInterface $sc) {
$column_count = (int)$sc->getParameter('count', 2);
$column_width = $sc->getParameter('width', 'auto');
$column_gap = $sc->getParameter('gap', 'normal');
$column_rule = $sc->getParameter('rule', false);
$css_style = 'columns:' . $column_count . ' ' . $column_width . ';-moz-columns:' . $column_count . ' ' . $column_width . ';';
$css_style .= 'column-gap:' . $column_gap . ';-moz-column-gap:' . $column_gap . ';';
if ($column_rule) {
$css_style .= 'column-rule:' . $column_rule . ';-moz-column-rule:' . $column_rule . ';';
}
return '<div class="sc-columns" style="' . $css_style . '">' . $sc->getContent() . '</div>';
});
}
}

View File

@ -1,26 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class DetailsShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('details', function(ShortcodeInterface $sc) {
// Get summary/title
$summary = $sc->getParameter('summary', $this->getBbCode($sc));
$summaryHTML = $summary ? '<summary>' . $summary . '</summary>' : '';
// Get classes for details
$class = $sc->getParameter('class', $this->getBbCode($sc));
$classHTML = (isset($class) and $class !== $summary) ? 'class="' . $class . '"' : '';
// Get content
$content = $sc->getContent();
// Return the details/summary block
return '<details ' . $classHTML . '>' . $summaryHTML . $content . '</details>';
});
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class DivShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('div', static function(ShortcodeInterface $sc) {
$id = $sc->getParameter('id');
$class = $sc->getParameter('class');
$style = $sc->getParameter('style');
$id_output = $id ? ' id="' . $id . '" ': '';
$class_output = $class ? ' class="' . $class . '"' : '';
$style_output = $style ? ' style="' . $style . '"' : '';
return '<div ' . $id_output . $class_output . $style_output . '>' . $sc->getContent() . '</div>';
});
}
}

View File

@ -1,27 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Grav\Common\Utils;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class FigureShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('figure', function(ShortcodeInterface $sc) {
$id = $sc->getParameter('id');
$class = $sc->getParameter('class');
$caption = $sc->getParameter('caption');
$page = $this->grav['page'];
// Process any markdown on caption
$caption = Utils::processMarkdown($caption, false, $page);
$id_output = $id ? 'id="' . $id . '" ': '';
$class_output = $class ? 'class="' . $class . '"' : '';
$caption_output = $caption ? '<figcaption>' . $caption . '</figcaption>' : '';
return '<figure ' . $id_output . ' ' . $class_output . '>'.$sc->getContent(). $caption_output . '</figure>';
});
}
}

View File

@ -1,53 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Grav\Common\Utils;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class FontAwesomeShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('fa', function(ShortcodeInterface $sc) {
// Load assets if required
if ($this->config->get('plugins.shortcode-core.fontawesome.load', false)) {
$this->shortcode->addAssets('css', $this->config->get('plugins.shortcode-core.fontawesome.url'));
}
if ($this->config->get('plugins.shortcode-core.fontawesome.v5', false)) {
$v5classes = ['fab', 'fal', 'fas', 'far', 'fad'];
} else {
$v5classes = [];
}
// Get shortcode content and parameters
$str = $sc->getContent();
$icon = $sc->getParameter('icon', $sc->getParameter('fa', $this->getBbCode($sc)));
if (!Utils::startsWith($icon, 'fa-')) {
$icon = 'fa-'.$icon;
}
if ($icon) {
$fa_class = 'fa';
$extras = explode(',', $sc->getParameter('extras', ''));
foreach($extras as $extra) {
if(!empty($extra)) {
if(in_array($extra, $v5classes, true)) {
$fa_class = $extra;
continue;
}
if(!Utils::startsWith($extra, 'fa-')) {
$extra = 'fa-' . $extra;
}
$icon .= ' ' . $extra;
}
}
return '<i class="' . $fa_class . ' ' . $icon . '">' . $str . '</i>';
}
return '';
});
}
}

View File

@ -1,48 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class HShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('h1', function(ShortcodeInterface $sc) {
return $this->header(1, $sc);
});
$this->shortcode->getHandlers()->add('h2', function(ShortcodeInterface $sc) {
return $this->header(2, $sc);
});
$this->shortcode->getHandlers()->add('h3', function(ShortcodeInterface $sc) {
return $this->header(3, $sc);
});
$this->shortcode->getHandlers()->add('h4', function(ShortcodeInterface $sc) {
return $this->header(4, $sc);
});
$this->shortcode->getHandlers()->add('h5', function(ShortcodeInterface $sc) {
return $this->header(5, $sc);
});
$this->shortcode->getHandlers()->add('h6', function(ShortcodeInterface $sc) {
return $this->header(6, $sc);
});
}
protected function header($level, ShortcodeInterface $sc)
{
$id = $sc->getParameter('id');
$class = $sc->getParameter('class');
$tag = 'h' . $level;
$id_output = $id ? ' id="' . $id . '" ': '';
$class_output = $class ? ' class="' . $class . '"' : '';
return "<{$tag}{$id_output}{$class_output}>{$sc->getContent()}</{$tag}>";
}
}

View File

@ -1,31 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Grav\Common\Language\Language;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class LanguageShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('lang', function(ShortcodeInterface $sc) {
$lang = $this->getBbCode($sc);
if ($lang) {
$list = explode(',', $lang);
array_walk($list, 'trim');
/** @var Language $language */
$language = $this->grav['language'];
$current = $language->getLanguage();
if (in_array($current, $list)) {
return $sc->getContent();
}
}
return '';
});
}
}

View File

@ -1,360 +0,0 @@
<?php
/**
* Based on Lorem Ipsum Generator by Josh Sherman
*
* Licensed under The MIT License.
* Redistribution of these files must retain the above copyright notice.
*
* @author Josh Sherman <hello@joshtronic.com>
* @copyright Copyright 2014, 2015, 2016, 2017, 2018, 2019 Josh Sherman
* @license http://www.opensource.org/licenses/mit-license.html
* @link https://github.com/joshtronic/php-loremipsum
*/
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class LoremShortcode extends Shortcode
{
/**
* First
*
* Whether or not we should be starting the string with "Lorem ipsum..."
*
* @access private
* @var boolean
*/
private $first = true;
/**
* Words
*
* A lorem ipsum vocabulary of sorts. Not a complete list as I'm unsure if
* a complete list exists and if so, where to get it.
*
* @access private
* @var array
*/
public $words = [
// Lorem ipsum...
'lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing', 'elit',
// and the rest of the vocabulary
'a', 'ac', 'accumsan', 'ad', 'aenean', 'aliquam', 'aliquet', 'ante',
'aptent', 'arcu', 'at', 'auctor', 'augue', 'bibendum', 'blandit',
'class', 'commodo', 'condimentum', 'congue', 'consequat', 'conubia',
'convallis', 'cras', 'cubilia', 'curabitur', 'curae', 'cursus',
'dapibus', 'diam', 'dictum', 'dictumst', 'dignissim', 'dis', 'donec',
'dui', 'duis', 'efficitur', 'egestas', 'eget', 'eleifend', 'elementum',
'enim', 'erat', 'eros', 'est', 'et', 'etiam', 'eu', 'euismod', 'ex',
'facilisi', 'facilisis', 'fames', 'faucibus', 'felis', 'fermentum',
'feugiat', 'finibus', 'fringilla', 'fusce', 'gravida', 'habitant',
'habitasse', 'hac', 'hendrerit', 'himenaeos', 'iaculis', 'id',
'imperdiet', 'in', 'inceptos', 'integer', 'interdum', 'justo',
'lacinia', 'lacus', 'laoreet', 'lectus', 'leo', 'libero', 'ligula',
'litora', 'lobortis', 'luctus', 'maecenas', 'magna', 'magnis',
'malesuada', 'massa', 'mattis', 'mauris', 'maximus', 'metus', 'mi',
'molestie', 'mollis', 'montes', 'morbi', 'mus', 'nam', 'nascetur',
'natoque', 'nec', 'neque', 'netus', 'nibh', 'nisi', 'nisl', 'non',
'nostra', 'nulla', 'nullam', 'nunc', 'odio', 'orci', 'ornare',
'parturient', 'pellentesque', 'penatibus', 'per', 'pharetra',
'phasellus', 'placerat', 'platea', 'porta', 'porttitor', 'posuere',
'potenti', 'praesent', 'pretium', 'primis', 'proin', 'pulvinar',
'purus', 'quam', 'quis', 'quisque', 'rhoncus', 'ridiculus', 'risus',
'rutrum', 'sagittis', 'sapien', 'scelerisque', 'sed', 'sem', 'semper',
'senectus', 'sociosqu', 'sodales', 'sollicitudin', 'suscipit',
'suspendisse', 'taciti', 'tellus', 'tempor', 'tempus', 'tincidunt',
'torquent', 'tortor', 'tristique', 'turpis', 'ullamcorper', 'ultrices',
'ultricies', 'urna', 'ut', 'varius', 'vehicula', 'vel', 'velit',
'venenatis', 'vestibulum', 'vitae', 'vivamus', 'viverra', 'volutpat',
'vulputate',
];
public function init()
{
$this->shortcode->getHandlers()->add('lorem', function(ShortcodeInterface $sc) {
$paragraphs = $sc->getParameter('p', $this->getBbCode($sc));
$paragraph_tag = $sc->getParameter('tag', 'p');
$sentences = $sc->getParameter('s');
$words = $sc->getParameter('w');
if ($words) {
return $this->words($words);
}
if ($sentences) {
return $this->sentences($sentences);
}
return $this->paragraphs($paragraphs ?? 1, $paragraph_tag);
});
}
/**
* Word
*
* Generates a single word of lorem ipsum.
*
* @access public
* @param mixed $tags string or array of HTML tags to wrap output with
* @return string generated lorem ipsum word
*/
public function word($tags = false)
{
return $this->words(1, $tags);
}
/**
* Words Array
*
* Generates an array of lorem ipsum words.
*
* @access public
* @param integer $count how many words to generate
* @param mixed $tags string or array of HTML tags to wrap output with
* @return array generated lorem ipsum words
*/
public function wordsArray($count = 1, $tags = false)
{
return $this->words($count, $tags, true);
}
/**
* Words
*
* Generates words of lorem ipsum.
*
* @access public
* @param integer $count how many words to generate
* @param mixed $tags string or array of HTML tags to wrap output with
* @param boolean $array whether an array or a string should be returned
* @return mixed string or array of generated lorem ipsum words
*/
public function words($count = 1, $tags = false, $array = false)
{
$words = [];
$word_count = 0;
// Shuffles and appends the word list to compensate for count
// arguments that exceed the size of our vocabulary list
while ($word_count < $count) {
$shuffle = true;
while ($shuffle) {
$this->shuffle();
// Checks that the last word of the list and the first word of
// the list that's about to be appended are not the same
if (!$word_count || $words[$word_count - 1] != $this->words[0]) {
$words = array_merge($words, $this->words);
$word_count = count($words);
$shuffle = false;
}
}
}
$words = array_slice($words, 0, $count);
return $this->output($words, $tags, $array);
}
/**
* Sentence
*
* Generates a full sentence of lorem ipsum.
*
* @access public
* @param mixed $tags string or array of HTML tags to wrap output with
* @return string generated lorem ipsum sentence
*/
public function sentence($tags = false)
{
return $this->sentences(1, $tags);
}
/**
* Sentences Array
*
* Generates an array of lorem ipsum sentences.
*
* @access public
* @param integer $count how many sentences to generate
* @param mixed $tags string or array of HTML tags to wrap output with
* @return array generated lorem ipsum sentences
*/
public function sentencesArray($count = 1, $tags = false)
{
return $this->sentences($count, $tags, true);
}
/**
* Sentences
*
* Generates sentences of lorem ipsum.
*
* @access public
* @param integer $count how many sentences to generate
* @param mixed $tags string or array of HTML tags to wrap output with
* @param boolean $array whether an array or a string should be returned
* @return mixed string or array of generated lorem ipsum sentences
*/
public function sentences($count = 1, $tags = false, $array = false)
{
$sentences = [];
for ($i = 0; $i < $count; $i++) {
$sentences[] = $this->wordsArray($this->gauss(24.46, 5.08));
}
$this->punctuate($sentences);
return $this->output($sentences, $tags, $array);
}
/**
* Paragraph
*
* Generates a full paragraph of lorem ipsum.
*
* @access public
* @param mixed $tags string or array of HTML tags to wrap output with
* @return string generated lorem ipsum paragraph
*/
public function paragraph($tags = false)
{
return $this->paragraphs(1, $tags);
}
/**
* Paragraph Array
*
* Generates an array of lorem ipsum paragraphs.
*
* @access public
* @param integer $count how many paragraphs to generate
* @param mixed $tags string or array of HTML tags to wrap output with
* @return array generated lorem ipsum paragraphs
*/
public function paragraphsArray($count = 1, $tags = false)
{
return $this->paragraphs($count, $tags, true);
}
/**
* Paragraphss
*
* Generates paragraphs of lorem ipsum.
*
* @access public
* @param integer $count how many paragraphs to generate
* @param mixed $tags string or array of HTML tags to wrap output with
* @param boolean $array whether an array or a string should be returned
* @return mixed string or array of generated lorem ipsum paragraphs
*/
public function paragraphs($count = 1, $tags = false, $array = false)
{
$paragraphs = [];
for ($i = 0; $i < $count; $i++) {
$paragraphs[] = $this->sentences($this->gauss(5.8, 1.93));
}
return $this->output($paragraphs, $tags, $array, "\n\n");
}
/**
* Gaussian Distribution
*
* This is some smart kid stuff. I went ahead and combined the N(0,1) logic
* with the N(m,s) logic into this single function. Used to calculate the
* number of words in a sentence, the number of sentences in a paragraph
* and the distribution of commas in a sentence.
*
* @access private
* @param double $mean average value
* @param double $std_dev stadnard deviation
* @return double calculated distribution
*/
private function gauss($mean, $std_dev)
{
$x = mt_rand() / mt_getrandmax();
$y = mt_rand() / mt_getrandmax();
$z = sqrt(-2 * log($x)) * cos(2 * pi() * $y);
return $z * $std_dev + $mean;
}
/**
* Shuffle
*
* Shuffles the words, forcing "Lorem ipsum..." at the beginning if it is
* the first time we are generating the text.
*
* @access private
*/
private function shuffle()
{
if ($this->first) {
$this->first = array_slice($this->words, 0, 8);
$this->words = array_slice($this->words, 8);
shuffle($this->words);
$this->words = $this->first + $this->words;
$this->first = false;
} else {
shuffle($this->words);
}
}
/**
* Punctuate
*
* Applies punctuation to a sentence. This includes a period at the end,
* the injection of commas as well as capitalizing the first letter of the
* first word of the sentence.
*
* @access private
* @param array $sentences the sentences we would like to punctuate
*/
private function punctuate(&$sentences)
{
foreach ($sentences as $key => $sentence) {
$words = count($sentence);
// Only worry about commas on sentences longer than 4 words
if ($words > 4) {
$mean = log($words, 6);
$std_dev = $mean / 6;
$commas = round($this->gauss($mean, $std_dev));
for ($i = 1; $i <= $commas; $i++) {
$word = round($i * $words / ($commas + 1));
if ($word < ($words - 1) && $word > 0) {
$sentence[$word] .= ',';
}
}
}
$sentences[$key] = ucfirst(implode(' ', $sentence) . '.');
}
}
/**
* Output
*
* Does the rest of the processing of the strings. This includes wrapping
* the strings in HTML tags, handling transformations with the ability of
* back referencing and determining if the passed array should be converted
* into a string or not.
*
* @access private
* @param string|string[] $strings an array of generated strings
* @param mixed $tags string or array of HTML tags to wrap output with
* @param boolean $array whether an array or a string should be returned
* @param string $delimiter the string to use when calling implode()
* @return string|string[] string or array of generated lorem ipsum text
*/
private function output($strings, $tags, $array, $delimiter = ' ')
{
if ($tags) {
if (!is_array($tags)) {
$tags = [$tags];
} else {
// Flips the array so we can work from the inside out
$tags = array_reverse($tags);
}
foreach ($strings as $key => $string) {
foreach ($tags as $tag) {
// Detects / applies back reference
if ($tag[0] === '<') {
$string = str_replace('$1', $string, $tag);
} else {
$string = sprintf('<%1$s>%2$s</%1$s>', $tag, $string);
}
$strings[$key] = $string;
}
}
}
if (!$array) {
$strings = implode($delimiter, $strings);
}
return $strings;
}
}

View File

@ -1,27 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class MarkShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('mark', function(ShortcodeInterface $sc) {
$style = $sc->getParameter('style', $this->getBbCode($sc));
$class = $sc->getParameter('class', 'default');
$css_class = 'class="mark-class-' . $class . '"';
if ($style === 'block') {
$css_style = 'style="display:block;"';
$content = trim($sc->getContent(), "\n");
} else {
$css_style = '';
$content = $sc->getContent();
}
return "<mark {$css_class} {$css_style}>{$content}</mark>";
});
}
}

View File

@ -1,24 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class NoticeShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('notice', function(ShortcodeInterface $sc) {
$css_enabled = $this->grav['config']->get('plugins.shortcode-core.css.notice_enabled', true);
if ($css_enabled) {
$this->shortcode->addAssets('css', 'plugin://shortcode-core/css/shortcode-notice.css');
}
$output = $this->twig->processTemplate('shortcodes/notice.html.twig', [
'type' => $sc->getParameter('notice', $this->getBbCode($sc)) ?: 'info',
'content' => $sc->getContent(),
]);
return $output;
});
}
}

View File

@ -1,18 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\EventHandler\FilterRawEventHandler;
use Thunder\Shortcode\Events;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class RawShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('raw', static function(ShortcodeInterface $sc) {
return trim($sc->getContent());
});
$this->shortcode->getEvents()->addListener(Events::FILTER_SHORTCODES, new FilterRawEventHandler(['raw']));
}
}

View File

@ -1,51 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class SafeEmailShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('safe-email', function(ShortcodeInterface $sc) {
// Load assets if required
if ($this->config->get('plugins.shortcode-core.fontawesome.load', false)) {
$this->shortcode->addAssets('css', $this->config->get('plugins.shortcode-core.fontawesome.url'));
}
// Get shortcode content and parameters
$str = $sc->getContent();
$icon = $sc->getParameter('icon', false);
$icon_base = "fa fa-";
$autolink = $sc->getParameter('autolink', false);
// Encode email
$email = '';
$str_len = strlen($str);
for ($i = 0; $i < $str_len; $i++) {
$email .= '&#' . ord($str[$i]). ';';
}
// Handle autolinking
if ($autolink) {
$output = '<a href="mailto:' . $email . '">' . $email . '</a>';
} else {
$output = $email;
}
// Handle icon option
if ($icon) {
if ($this->config->get('plugins.shortcode-core.fontawesome.v5', false)) {
if (preg_match("/^(?P<weight>fa[srlbd]) fa-(?<icon>.+)/", $icon, $icon_parts)) {
$icon_base = $icon_parts["weight"] . " fa-";
$icon = $icon_parts["icon"];
}
}
$output = '<i class="'. $icon_base . $icon . '"></i> ' . $output;
}
return $output;
});
}
}

View File

@ -1,17 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class SectionShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('section', function(ShortcodeInterface $sc) {
$name = $sc->getParameter('name');
$object = new \Grav\Plugin\ShortcodeCore\ShortcodeObject($name, $sc->getContent());
$this->shortcode->addObject($sc->getName(), $object);
});
}
}

View File

@ -1,91 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Grav\Common\Config\Config;
use Grav\Common\Grav;
use Grav\Common\Twig\Twig;
use Grav\Plugin\ShortcodeCore\ShortcodeManager;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
abstract class Shortcode
{
/** @var ShortcodeManager */
protected $shortcode;
/** @var Grav */
protected $grav;
/** @var Config */
protected $config;
/** @var Twig */
protected $twig;
/**
* Shortcode constructor.
*/
public function __construct()
{
$this->grav = Grav::instance();
$this->shortcode = $this->grav['shortcode'];
$this->config = $this->grav['config'];
$this->twig = $this->grav['twig'];
}
/**
* Initialize shortcode handler
*/
public function init()
{
user_error(__METHOD__ . '() method will be abstract in the future, please override it!', E_USER_DEPRECATED);
// FIXME: This code had to be put back because of some plugins do not properly initialize themselves.
$this->shortcode->getHandlers()->add('u', static function(ShortcodeInterface $shortcode) {
return $shortcode->getContent();
});
}
/**
* Returns the name of the class if required
*
* @return string the name of the class
*/
public function getName()
{
return get_class($this);
}
/**
* @return string
*/
public function getParser()
{
return $this->config->get('plugins.shortcode-core.parser');
}
/**
* @param ShortcodeInterface $sc
* @param string|null $default
* @return string|null
*/
public function getBbCode(ShortcodeInterface $sc, $default = null)
{
$code = $default;
if ($this->getParser() === 'wordpress') {
$params = $sc->getParameters();
if (is_array($params)) {
$keys = array_keys($params);
$code = trim(array_shift($keys), '=');
}
} else {
$code = $sc->getBbCode();
}
return $code;
}
}
// Make sure we also autoload the deprecated class.
class_exists(\Grav\Plugin\ShortcodeCore\Shortcode::class);

View File

@ -1,24 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
// Check if the new class has been autoloaded. If not, trigger deprecation error.
if (!class_exists(\Grav\Plugin\ShortcodeCore\ShortcodeObject::class, false)) {
@trigger_error(
ShortcodeObject::class . ' class is deprecated, use \\Grav\\Plugin\\ShortcodeCore\\ShortcodeObject instead',
E_USER_DEPRECATED
);
}
// Create alias for the deprecated class.
class_alias(\Grav\Plugin\ShortcodeCore\ShortcodeObject::class, ShortcodeObject::class);
// Make sure that both IDE and composer knows about the deprecated class.
if (false) {
/**
* @deprecated 4.2.0 Use \Grav\Plugin\ShortcodeCore\ShortcodeObject instead
*/
class ShortcodeObject extends \Grav\Plugin\ShortcodeCore\ShortcodeObject
{
}
}

View File

@ -1,19 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class SizeShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('size', function(ShortcodeInterface $sc) {
$size = $sc->getParameter('size', $this->getBbCode($sc));
if (is_numeric($size)) {
$size .= 'px';
}
return '<span style="font-size: ' . $size . ';">' . $sc->getContent() . '</span>';
});
}
}

View File

@ -1,22 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class SpanShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('span', static function(ShortcodeInterface $sc) {
$id = $sc->getParameter('id');
$class = $sc->getParameter('class');
$style = $sc->getParameter('style');
$id_output = $id ? 'id="' . $id . '" ': '';
$class_output = $class ? 'class="' . $class . '"' : '';
$style_output = $style ? 'style="' . $style . '"' : '';
return '<span ' . $id_output . ' ' . $class_output . ' ' . $style_output . '>' . $sc->getContent() . '</span>';
});
}
}

View File

@ -1,14 +0,0 @@
<?php
namespace Grav\Plugin\Shortcodes;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
class UnderlineShortcode extends Shortcode
{
public function init()
{
$this->shortcode->getHandlers()->add('u', static function(ShortcodeInterface $sc) {
return '<span style="text-decoration: underline;">' . $sc->getContent() . '</span>';
});
}
}

View File

@ -1,55 +0,0 @@
<?php
namespace Grav\Plugin\Console;
use Grav\Common\Grav;
use Grav\Common\Twig\Twig;
use Grav\Console\ConsoleCommand;
use Grav\Plugin\CloudflarePlugin;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Style\SymfonyStyle;
/**
* Class CloudflareIPsCommand
*
* @package Grav\Plugin\Console
*/
class ShortcodesCommand extends ConsoleCommand
{
/**
*
*/
protected function configure()
{
$this
->setName('display')
->setDescription('Display a list the available shortcodes that are registered');
}
/**
* @return int|null|void
*/
protected function serve()
{
$io = new SymfonyStyle($this->input, $this->output);
$this->initializePlugins();
$this->initializeThemes();
$shortcodes = Grav::instance()['shortcode'];
$io->title('Available Shortcodes');
$io->section('Regular Handlers:');
foreach ($shortcodes->getHandlers()->getNames() as $name) {
$io->writeln($name);
}
$io->section('Raw Handlers:');
foreach ($shortcodes->getRawHandlers()->getNames() as $name) {
$io->writeln($name);
}
$io->newLine();
}
}

View File

@ -1,32 +0,0 @@
{
"name": "getgrav/shortcode-core",
"type": "grav-plugin",
"description": "Shortcode Core plugin for Grav CMS",
"keywords": ["shortcode"],
"homepage": "https://github.com/getgrav/grav-plugin-shortcode-core/",
"license": "MIT",
"authors": [
{
"name": "Team Grav",
"email": "devs@getgrav.org",
"homepage": "http://getgrav.org",
"role": "Developer"
}
],
"require": {
"php": ">=7.1.3",
"thunderer/shortcode": "~0.7"
},
"autoload": {
"psr-4": {
"Grav\\Plugin\\ShortcodeCore\\": "classes/plugin",
"Grav\\Plugin\\Shortcodes\\": "classes/shortcodes"
},
"classmap": ["shortcode-core.php"]
},
"config": {
"platform": {
"php": "7.1.3"
}
}
}

View File

@ -1,80 +0,0 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "95ac1934b2d5e35cff7d71f6744b2666",
"packages": [
{
"name": "thunderer/shortcode",
"version": "v0.7.5",
"source": {
"type": "git",
"url": "https://github.com/thunderer/Shortcode.git",
"reference": "a4fee30613bd46efb421f8305aff0466a3268a99"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thunderer/Shortcode/zipball/a4fee30613bd46efb421f8305aff0466a3268a99",
"reference": "a4fee30613bd46efb421f8305aff0466a3268a99",
"shasum": ""
},
"require": {
"php": ">=5.3"
},
"require-dev": {
"phpunit/phpunit": ">=4.1",
"symfony/yaml": ">=2.0"
},
"suggest": {
"ext-dom": "if you want to use XML serializer",
"ext-json": "if you want to use JSON serializer",
"symfony/yaml": "if you want to use YAML serializer"
},
"type": "library",
"autoload": {
"psr-4": {
"Thunder\\Shortcode\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Tomasz Kowalczyk",
"email": "tomasz@kowalczyk.cc"
}
],
"description": "Advanced shortcode (BBCode) parser and engine for PHP",
"keywords": [
"bbcode",
"engine",
"library",
"parser",
"shortcode"
],
"support": {
"issues": "https://github.com/thunderer/Shortcode/issues",
"source": "https://github.com/thunderer/Shortcode/tree/v0.7.5"
},
"time": "2022-01-13T18:53:33+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=7.1.3"
},
"platform-dev": [],
"platform-overrides": {
"php": "7.1.3"
},
"plugin-api-version": "2.3.0"
}

View File

@ -1,64 +0,0 @@
.sc-notice {
margin: 30px 0;
position: relative;
}
.sc-notice > div {
padding: 5px 20px;
display: block;
margin-top: 0rem;
margin-bottom: 0rem;
color: #666;
}
.sc-notice > div:before {
position: absolute;
top: 2px;
color: #fff;
font-family: FontAwesome;
content: '';
left: 10px;
}
.sc-notice > div:first-child:after {
position: absolute;
top: 2px;
color: #fff;
left: 30px;
}
.sc-notice.info > div:first-child {
border-top: 30px solid #F0B37E;
background: #FFF2DB;
}
.sc-notice.info > div:first-child:after {
content: 'Info';
}
.sc-notice.warning > div:first-child {
border-top: 30px solid #DF6F6C;
background: #FAE2E2;
}
.sc-notice.warning > div:first-child:after {
content: 'Warning';
}
.sc-notice.note > div:first-child {
border-top: 30px solid #6AB0DE;
background: #E7F2FA;
}
.sc-notice.note > div:first-child:after {
content: 'Note';
}
.sc-notice.tip > div:first-child {
border-top: 30px solid #77C577;
background: #E6F9E6;
}
.sc-notice.tip > div:first-child:after {
content: 'Tip';
}

View File

@ -1,2 +0,0 @@
> 1%
last 2 versions

View File

@ -1,7 +0,0 @@
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 100

View File

@ -1,2 +0,0 @@
DEV_HOST=localhost
DEV_PORT=2001

View File

@ -1,27 +0,0 @@
module.exports = {
root: true,
env: {
node: true,
},
extends: [
'plugin:vue/recommended',
'@vue/airbnb',
],
parserOptions: {
parser: 'babel-eslint',
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'import/extensions': 'off',
'import/no-unresolved': 'off',
'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
'no-restricted-syntax': ['off', 'ForOfStatement'],
'no-param-reassign': ['error', { props: false }],
'class-methods-use-this': 'off',
'object-curly-newline': 'off',
'no-nested-ternary': 'off',
'no-await-in-loop': 'off',
'max-len': 'off',
},
};

View File

@ -1,20 +0,0 @@
.DS_Store
node_modules
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@ -1,24 +0,0 @@
# app
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn serve
```
### Compiles and minifies for production
```
yarn build
```
### Lints and fixes files
```
yarn lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@ -1,5 +0,0 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset',
],
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,24 +0,0 @@
{
"name": "nextgen-editor",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "vue-cli-service serve",
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.13",
"@vue/cli-plugin-eslint": "~4.5.13",
"@vue/cli-service": "~4.5.13",
"@vue/eslint-config-airbnb": "^5.3.0",
"babel-eslint": "^10.1.0",
"directory-named-webpack-plugin": "^4.0.1",
"eslint": "^7.32.0",
"eslint-plugin-import": "^2.24.2",
"eslint-plugin-vue": "^7.18.0",
"node-sass": "^6.0.1",
"sass-loader": "^12.1.0"
}
}

View File

@ -1,55 +0,0 @@
window.nextgenEditor.addHook('hookInit', () => {
window.nextgenEditor.addButtonGroup('shortcode-core-align', {
icon: '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M2.75 1h-.01c-.56 0-1 .44-1 1v20c0 .55.44.99 1 .99.55-.01.99-.45.99-1.01v-20c0-.56-.45-1-1-1z"/><rect style="width:11px;height:6px;" x="5.25" rx="1.5" y="5"/><rect style="width:17px;height:6px;" x="5.25" rx="1.5" y="13"/></svg>',
label: 'SC Align',
});
});
window.nextgenEditor.addShortcode('left', {
type: 'block',
plugin: 'shortcode-core',
title: 'Align Left',
button: {
group: 'shortcode-core-align',
label: 'Align Left',
},
content() {
return '<div style="text-align:left">{{content_editable}}</div>';
},
});
window.nextgenEditor.addShortcode('center', {
type: 'block',
title: 'Align Center',
button: {
group: 'shortcode-core-align',
label: 'Align Center',
},
content() {
return '<div style="text-align:center">{{content_editable}}</div>';
},
});
window.nextgenEditor.addShortcode('right', {
type: 'block',
title: 'Align Right',
button: {
group: 'shortcode-core-align',
label: 'Align Right',
},
content() {
return '<div style="text-align:right">{{content_editable}}</div>';
},
});
window.nextgenEditor.addShortcode('justify', {
type: 'block',
title: 'Justify',
button: {
group: 'shortcode-core-align',
label: 'Justify',
},
content() {
return '<div style="text-align:justify">{{content_editable}}</div>';
},
});

View File

@ -1,22 +0,0 @@
window.nextgenEditor.addShortcode('color', {
type: 'inline',
plugin: 'shortcode-core',
title: 'Color',
button: {
group: 'shortcode-core',
label: 'Color',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.3 24a1 1 0 00.756-.345L22.523 9.277a2 2 0 00-.212-2.822l-2.45-2.105a1 1 0 00-1.3 1.517l2.072 1.775a.5.5 0 01.052.707l-7.8 9a.25.25 0 01-.423-.251l4.671-12.614a2 2 0 00-1.181-2.57L12.609.675a1 1 0 10-.7 1.875l2.876 1.065a.5.5 0 01.295.643l-4.602 12.419a.25.25 0 01-.485-.087V1.5a1.5 1.5 0 00-1.5-1.5h-6a1.5 1.5 0 00-1.5 1.5v21a1.5 1.5 0 001.5 1.5zM3.493 9.75a.5.5 0 01.5-.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5h-3a.5.5 0 01-.5-.5zm0-3.75V3a.5.5 0 01.5-.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5h-3a.5.5 0 01-.5-.5zm0 10.5a.5.5 0 01.5-.5h3a.5.5 0 01.5.5v3a.5.5 0 01-.5.5h-3a.5.5 0 01-.5-.5z"/></svg>',
},
attributes: {
color: {
type: String,
title: 'Color',
bbcode: true,
widget: 'input-text',
default: '',
},
},
content({ attributes }) {
return `<span style="color:${attributes.color}">{{content_editable}}</span>`;
},
});

View File

@ -1,58 +0,0 @@
window.nextgenEditor.addShortcode('columns', {
type: 'block',
plugin: 'shortcode-core',
title: 'Columns',
button: {
group: 'shortcode-core',
label: 'Columns',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M22 0H2a2 2 0 00-2 2v20a2 2 0 002 2h20a2 2 0 002-2V2a2 2 0 00-2-2zm-7 2.5v19a.5.5 0 01-.5.5h-5a.5.5 0 01-.5-.5v-19a.5.5 0 01.5-.5h5a.5.5 0 01.5.5zM2.5 2h4a.5.5 0 01.5.5v19a.5.5 0 01-.5.5h-4a.5.5 0 01-.5-.5v-19a.5.5 0 01.5-.5zm19 20h-4a.5.5 0 01-.5-.5v-19a.5.5 0 01.5-.5h4a.5.5 0 01.5.5v19a.5.5 0 01-.5.5z"/></svg>',
},
attributes: {
count: {
type: Number,
title: 'Count',
widget: {
type: 'input-number',
min: 1,
max: 12,
},
default: 2,
},
width: {
type: String,
title: 'Width',
widget: 'input-text',
default: 'auto',
},
gap: {
type: String,
title: 'Gap',
widget: 'input-text',
default: 'normal',
},
rule: {
type: String,
title: 'Rule',
widget: 'input-text',
default: '',
},
},
titlebar({ attributes }) {
return `columns: <strong>${attributes.count}</strong>`;
},
content({ attributes }) {
const styles = []
.concat([
`columns:${attributes.count} ${attributes.width}`,
`-moz-columns:${attributes.count} ${attributes.width}`,
`column-gap:${attributes.gap}`,
`-moz-column-gap:${attributes.gap}`,
attributes.rule ? `column-rule:${attributes.rule}` : null,
attributes.rule ? `-moz-column-rule:${attributes.rule}` : null,
])
.filter((item) => !!item)
.join(';');
return `<div style="${styles}">{{content_editable}}</div>`;
},
});

View File

@ -1,8 +0,0 @@
shortcode-block[name="details"] summary {
margin: 8px 8px;
}
shortcode-block[name="details"] summary > p {
display: inline;
margin: 0;
}

View File

@ -1,50 +0,0 @@
window.nextgenEditor.addShortcode('details', {
type: 'block',
plugin: 'shortcode-core',
title: 'Details',
button: {
group: 'shortcode-core',
label: 'Details',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M2.2 8.348a1 1 0 001.4.2l3.465-2.6a1.5 1.5 0 000-2.4L3.6.948a1 1 0 00-1.2 1.6l2.666 2a.25.25 0 010 .4l-2.666 2a1 1 0 00-.2 1.4zM23 21.248H1a1 1 0 000 2h22a1 1 0 000-2zM23 16.248H1a1 1 0 000 2h22a1 1 0 000-2zM23 11.248H1a1 1 0 000 2h22a1 1 0 000-2zM24 7.248a1 1 0 00-1-1H12a1 1 0 000 2h11a1 1 0 001-1zM12 3.248h11a1 1 0 000-2H12a1 1 0 000 2z"/></svg>',
},
attributes: {
summary: {
type: String,
title: 'Summary',
bbcode: true,
widget: 'input-text',
default: '',
},
class: {
type: String,
title: 'Class',
widget: 'input-text',
default: '',
},
},
titlebar({ attributes }) {
return attributes.class
? `class: <strong>${attributes.class}</strong>`
: '';
},
content({ attributes }) {
let output = '';
output += `<details class="${attributes.class || ''}" open>`;
if (attributes.summary) {
output += `<summary>${attributes.summary}</summary>`;
}
output += '{{content_editable}}';
output += '</details>';
return output;
},
preserve: {
block: [
'details',
'summary',
],
},
});

View File

@ -1,47 +0,0 @@
window.nextgenEditor.addShortcode('div', {
type: 'block',
plugin: 'shortcode-core',
title: 'Div',
button: {
group: 'shortcode-core',
label: 'Div',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M24 4.5a3 3 0 00-3-3H3a3 3 0 00-3 3v15a3 3 0 003 3h18a3 3 0 003-3zM3 5a1 1 0 111 1 1 1 0 01-1-1zm3 0a1 1 0 111 1 1 1 0 01-1-1zm3 0a1 1 0 111 1 1 1 0 01-1-1zm13 14.5a1 1 0 01-1 1H3a1 1 0 01-1-1V9a.5.5 0 01.5-.5h19a.5.5 0 01.5.5z"/><path d="M7.75 12a.75.75 0 00.75.75.25.25 0 01.25.25v4a.75.75 0 001.5 0v-4a.25.25 0 01.25-.25.75.75 0 000-1.5h-2a.75.75 0 00-.75.75zM4 17.75a.75.75 0 00.75-.75v-1a.25.25 0 01.5 0v1a.75.75 0 001.5 0v-5a.75.75 0 00-1.5 0v2a.25.25 0 01-.5 0v-2a.75.75 0 00-1.5 0v5a.75.75 0 00.75.75zM17.75 16a1.752 1.752 0 001.75 1.75h1a.75.75 0 000-1.5h-1a.25.25 0 01-.25-.25v-4a.75.75 0 00-1.5 0zM13 17.75a.75.75 0 00.75-.75v-2.085a.057.057 0 01.106-.029.781.781 0 001.288 0 .057.057 0 01.106.029V17a.75.75 0 001.5 0v-5a.751.751 0 00-1.394-.386l-.642 1.071a.25.25 0 01-.428 0l-.642-1.071A.751.751 0 0012.25 12v5a.75.75 0 00.75.75z"/></svg>',
},
attributes: {
id: {
type: String,
title: 'ID',
widget: 'input-text',
default: '',
},
class: {
type: String,
title: 'Class',
widget: 'input-text',
default: '',
},
style: {
type: String,
title: 'Style',
widget: 'input-text',
default: '',
},
},
titlebar({ attributes }) {
return []
.concat([
attributes.id ? `id: <strong>${attributes.id}</strong>` : null,
attributes.class ? `class: <strong>${attributes.class}</strong>` : null,
attributes.style ? `style: <strong>${attributes.style}</strong>` : null,
])
.filter((item) => !!item)
.join(', ');
},
content({ attributes }) {
const id = attributes.id || '';
const cclass = attributes.class || '';
const style = attributes.style || '';
return `<div id="${id}" class="${cclass}" style="${style}">{{content_editable}}</div>`;
},
});

View File

@ -1,46 +0,0 @@
window.nextgenEditor.addShortcode('figure', {
type: 'block',
plugin: 'shortcode-core',
title: 'Figure',
button: {
group: 'shortcode-core',
label: 'Figure',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M24 3a3 3 0 00-3-3H3a3 3 0 00-3 3v18a3 3 0 003 3h18a3 3 0 003-3zm-2 18a1 1 0 01-1 1H3a1 1 0 01-1-1V3a1 1 0 011-1h18a1 1 0 011 1z"/><circle cx="14" cy="9.5" r="3"/><path d="M14 5.25a.75.75 0 00.75-.75V4a.75.75 0 00-1.5 0v.5a.75.75 0 00.75.75zM9.935 6.494A.75.75 0 1011 5.434l-.353-.354a.75.75 0 00-1.066 1.061zM8.5 10.25H9a.75.75 0 000-1.5h-.5a.75.75 0 000 1.5zM18.065 12.506a.75.75 0 00-1.06 1.06l.353.354a.75.75 0 001.061-1.061zM18.25 9.5a.75.75 0 00.75.75h.5a.75.75 0 000-1.5H19a.75.75 0 00-.75.75zM17.535 6.715a.743.743 0 00.53-.221l.354-.353a.75.75 0 00-1.061-1.061l-.353.354a.751.751 0 00.53 1.281zM15.8 16.086a4.573 4.573 0 00-1.449.234.249.249 0 00-.12.388 7.827 7.827 0 011.518 3.654.161.161 0 00.159.138h3.154a1.536 1.536 0 001.264-.663 4.607 4.607 0 00-4.526-3.751zM7.914 14.551a6.875 6.875 0 00-4.32 1.518.25.25 0 00-.094.2v2.7A1.535 1.535 0 005.035 20.5h9.427a.251.251 0 00.193-.09.249.249 0 00.053-.205 6.909 6.909 0 00-6.794-5.654z"/></svg>',
},
attributes: {
id: {
type: String,
title: 'ID',
widget: 'input-text',
default: '',
},
class: {
type: String,
title: 'Class',
widget: 'input-text',
default: '',
},
caption: {
type: String,
title: 'Caption',
widget: 'input-text',
default: '',
},
},
titlebar({attributes }) {
return []
.concat([
attributes.id ? `id: <strong>${attributes.id}</strong>` : null,
attributes.class ? `class: <strong>${attributes.class}</strong>` : null,
])
.filter((item) => !!item)
.join(', ');
},
content({ attributes }) {
const id = attributes.id || '';
const cclass = attributes.class || '';
const caption = attributes.caption || '';
return `<div id="${id}" class="${cclass}">{{content_editable}}<div style="margin:0 8px;">${caption}</div></div>`;
},
});

View File

@ -1,50 +0,0 @@
window.nextgenEditor.addShortcode('fa', {
type: 'inline',
plugin: 'shortcode-core',
title: 'Font Awesome',
wrapOnInsert: false,
button: {
group: 'shortcode-core',
label: 'Font Awesome',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.093 18.527a1.5 1.5 0 01-.65.382.25.25 0 00-.181.212l-.227 1.941a1.03 1.03 0 001.752.849l2.671-2.671a7.688 7.688 0 001.622-2.446 12.4 12.4 0 00.366-3.007.25.25 0 00-.427-.186zM5.484 12.92l4.952-4.964a.251.251 0 00-.184-.427 12.988 12.988 0 00-3.087.349A7.687 7.687 0 004.75 9.531l-2.662 2.662a1.031 1.031 0 00.727 1.759c.035 0 1.572-.185 2.091-.248a.251.251 0 00.209-.174 1.5 1.5 0 01.369-.61zM6.038 16.536c-.845-.847-2.125-.7-3.183.353-.749.75-1.519 3.166-2.033 5.062a1 1 0 001.23 1.226c1.889-.52 4.3-1.3 5.046-2.045 1.057-1.057 1.2-2.337.354-3.182zM22.62.8c-1.248.252-3.756.838-4.534 1.616-.648.643-9.961 9.984-11.364 11.384a.25.25 0 000 .353l3.134 3.137a.25.25 0 00.353 0L21.587 5.913c.779-.779 1.365-3.287 1.616-4.534A.495.495 0 0022.62.8z"/></svg>',
},
attributes: {
icon: {
type: String,
title: 'Icon',
bbcode: true,
widget: 'input-text',
default: 'grav',
},
extras: {
type: String,
title: 'Extras',
widget: 'input-text',
default: '',
},
},
content({ attributes }) {
let faclass = 'fa';
let icon = attributes.icon && !attributes.icon.startsWith('fa-')
? `fa-${attributes.icon}`
: attributes.icon;
if (attributes.extras) {
attributes.extras.split(',').forEach((extra) => {
if (extra) {
if (['fab', 'fal', 'fas', 'far', 'fad'].includes(extra)) {
faclass = extra;
return;
}
icon += !extra.startsWith('fa-')
? ` fa-${extra}`
: ` ${extra}`;
}
});
}
return `<span class="${faclass} ${icon}" style="margin:4px"></span>`;
},
});

View File

@ -1,32 +0,0 @@
shortcode-block[name="h1"] .sc-content,
shortcode-block[name="h2"] .sc-content,
shortcode-block[name="h3"] .sc-content,
shortcode-block[name="h4"] .sc-content,
shortcode-block[name="h5"] .sc-content,
shortcode-block[name="h6"] .sc-content {
font-weight: 700;
}
shortcode-block[name="h1"] .sc-content {
font-size: 30px;
}
shortcode-block[name="h2"] .sc-content {
font-size: 24px;
}
shortcode-block[name="h3"] .sc-content {
font-size: 20px;
}
shortcode-block[name="h4"] .sc-content {
font-size: 18px;
}
shortcode-block[name="h5"] .sc-content {
font-size: 16px;
}
shortcode-block[name="h6"] .sc-content {
font-size: 14px;
}

View File

@ -1,47 +0,0 @@
window.nextgenEditor.addHook('hookInit', () => {
window.nextgenEditor.addButtonGroup('shortcode-core-headers', {
icon: '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M17.567 20.509h-.61a.274.274 0 01-.24-.17L10.62 2.5l-.01-.01c-.21-.6-.76-1-1.39-1H9.2c-.63 0-1.19.39-1.39.99L1.74 20.29v-.01c-.04.09-.13.16-.24.16H.9a.976.976 0 10-.08 1.95h3l-.01-.001c.54 0 .97-.44.98-.98v-.02a.96.96 0 00-.82-.96l-.01-.001c-.07-.02-.14-.06-.17-.12a.245.245 0 01-.03-.2l1.5-4.413h-.01c.03-.1.12-.17.23-.17h7.23l-.01-.001c.1 0 .19.06.23.16l1.5 4.41c.04.12-.03.26-.16.31h-.04c-.47.07-.8.48-.8.95v-.01c-.01.54.43.97.97.98h2.94c.54.01.99-.41 1.01-.95.01-.55-.41-1-.95-1.02-.03-.01-.05-.01-.07-.01zM6.47 13.669v-.001c-.14 0-.25-.11-.25-.25-.01-.03 0-.06.01-.08L9 5.178h-.01c.04-.13.18-.2.31-.16.07.02.12.08.15.15l2.78 8.153c.02.07.01.15-.04.22h-.01c-.05.06-.13.1-.2.09z"/><path d="M23.02 20.509h-.22l-.01-.001a.274.274 0 01-.24-.17L18.29 7.87a1.53 1.53 0 00-1.94-.97c-.46.15-.81.5-.97.96l-1.15 3.38h-.01c-.18.51.09 1.06.61 1.24.51.17 1.06-.1 1.24-.62l.51-1.513v-.01c.04-.13.18-.2.31-.16.07.02.12.08.15.15l1.46 4.3c.04.12-.03.26-.16.31-.03 0-.06.01-.09.01h-1.37v-.01c-.55.01-.97.46-.95 1.01.01.51.43.93.94.94h2.2l-.01-.001c.1 0 .19.06.23.16l1.1 3.21a.25.25 0 01-.12.3v-.01c-.32.16-.52.49-.52.84v-.01c-.01.54.43.97.97.98h2.17c.54.01.99-.41 1.01-.95.01-.55-.41-1-.95-1.02-.03-.01-.05-.01-.07-.01z"/></svg>',
label: 'SC Headers',
});
});
for (let i = 1; i <= 6; i += 1) {
window.nextgenEditor.addShortcode(`h${i}`, {
type: 'block',
plugin: 'shortcode-core',
title: `H${i}`,
button: {
group: 'shortcode-core-headers',
label: `H${i}`,
},
attributes: {
id: {
type: String,
title: 'ID',
widget: 'input-text',
default: '',
},
class: {
type: String,
title: 'Class',
widget: 'input-text',
default: '',
},
},
titlebar({ attributes }) {
return []
.concat([
attributes.id ? `id: <strong>${attributes.id}</strong>` : null,
attributes.class ? `class: <strong>${attributes.class}</strong>` : null,
])
.filter((item) => !!item)
.join(', ');
},
content({ attributes }) {
const id = attributes.id || '';
const cclass = attributes.class || '';
return `<div id="${id}" class="${cclass}">{{content_editable}}</div>`;
},
});
}

View File

@ -1,25 +0,0 @@
window.nextgenEditor.addShortcode('lang', {
type: 'block',
plugin: 'shortcode-core',
title: 'Language',
button: {
group: 'shortcode-core',
label: 'Language',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M22.917 11H15.5a.5.5 0 00-.5.5v.417A3.083 3.083 0 0111.917 15H11.5a.5.5 0 00-.5.5v7.417A1.083 1.083 0 0012.083 24h10.834A1.083 1.083 0 0024 22.915V12.081A1.083 1.083 0 0022.917 11zm-2.153 11.2a.741.741 0 01-.264.048.749.749 0 01-.7-.486l-.507-1.352a.251.251 0 00-.234-.162h-3.116a.251.251 0 00-.234.162l-.509 1.352a.75.75 0 01-1.4-.528l2.532-6.751a1.25 1.25 0 012.34 0l1.758 4.687a.889.889 0 01.038.1l.736 1.963a.75.75 0 01-.44.967z"/><path d="M16.459 18.41a.25.25 0 00.234.338h1.614a.25.25 0 00.234-.338l-.807-2.151a.25.25 0 00-.468 0zM7.779 5.607a.251.251 0 00-.226-.359H5.447a.251.251 0 00-.226.359 7.962 7.962 0 001.088 1.667.249.249 0 00.382 0 7.962 7.962 0 001.088-1.667z"/><path d="M11.917 13A1.083 1.083 0 0013 11.915V1.081A1.083 1.083 0 0011.917 0H1.083A1.083 1.083 0 000 1.081v10.834A1.083 1.083 0 001.083 13zm-1.193-2.3a.751.751 0 01-.724.554.782.782 0 01-.2-.026A9.212 9.212 0 016.651 9.67a.249.249 0 00-.3 0A9.212 9.212 0 013.2 11.222a.782.782 0 01-.2.026.749.749 0 01-.2-1.473 7.707 7.707 0 002.365-1.1.253.253 0 00.11-.175.248.248 0 00-.058-.2A9.508 9.508 0 013.53 5.412a.249.249 0 00-.23-.164h-.769a.75.75 0 010-1.5H5.5a.25.25 0 00.25-.25v-1a.75.75 0 111.5 0v1a.25.25 0 00.25.25h3a.75.75 0 010 1.5h-.795a.249.249 0 00-.235.164A9.508 9.508 0 017.783 8.3a.25.25 0 00.048.368 7.707 7.707 0 002.365 1.1.749.749 0 01.528.926zM17.646 5.352A.5.5 0 0018.5 5v-.31a.25.25 0 01.367-.221A4 4 0 0121 8a1 1 0 102 0 6 6 0 00-4.32-5.753.25.25 0 01-.18-.24V1a.5.5 0 00-.309-.462.506.506 0 00-.545.109l-2 2a.5.5 0 000 .707zM2 14a1 1 0 00-1 .992V15a6 6 0 004.32 5.753.25.25 0 01.18.24V22a.5.5 0 00.854.354l2-2a.5.5 0 000-.707l-2-2A.5.5 0 005.5 18v.31a.252.252 0 01-.121.215.248.248 0 01-.246.006A4 4 0 013 15a1 1 0 00-1-1z"/></svg>',
},
attributes: {
lang: {
type: String,
title: 'Language',
bbcode: true,
widget: 'input-text',
default: 'en',
},
},
titlebar({ attributes }) {
return `language: <strong>${attributes.lang}</strong>`;
},
content() {
return '{{content_editable}}';
},
});

View File

@ -1,80 +0,0 @@
const sentence = 'Lorem ipsum dolor sit amet consectetur adipiscing elit, molestie tortor cubilia eu facilisi ex varius, convallis pretium dapibus fusce porta ligula.';
const words = [].concat(...Array(1000).fill(sentence.toLowerCase().replace(/[.|,]/g, '').split(' ')));
const paragraph = Array(2).fill(sentence).join(' ');
window.nextgenEditor.addShortcode('lorem', {
type: 'block',
plugin: 'shortcode-core',
title: 'Lorem',
wrapOnInsert: false,
button: {
group: 'shortcode-core',
label: 'Lorem',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7.54 9a.48.48 0 00.172-.031A14.327 14.327 0 0112 8a14.327 14.327 0 014.288.969.507.507 0 00.172.031H19a.454.454 0 00.394-.678 8.553 8.553 0 00-4.206-3.685.5.5 0 00-.688.463v.4a.5.5 0 01-1 0v-4a1.5 1.5 0 00-3 0v4a.5.5 0 01-1 0v-.4a.5.5 0 00-.688-.463 8.555 8.555 0 00-4.206 3.684A.454.454 0 005 9zM20.5 12a1.5 1.5 0 00-1.5-1.5h-2.813a.493.493 0 01-.178-.033A14 14 0 0012 9.5a14 14 0 00-4.009.967.493.493 0 01-.178.033H5A1.5 1.5 0 003.5 12v6.639a3.5 3.5 0 001.2 2.633l2.87 2.512A.866.866 0 009 23.136V17a1.5 1.5 0 00-1.5-1.5H6.25a.75.75 0 010-1.5H9a1.5 1.5 0 011.5 1.5v2.793a.993.993 0 00.293.707l.5.5a1 1 0 001.414 0l.5-.5a.993.993 0 00.293-.707V15.5A1.5 1.5 0 0115 14h2.75a.75.75 0 010 1.5H16.5A1.5 1.5 0 0015 17v6.137a.864.864 0 001.432.649l2.873-2.514a3.5 3.5 0 001.2-2.633z"/></svg>',
},
attributes: {
p: {
type: Number,
title: 'Paragraphs',
bbcode: true,
widget: {
type: 'input-number',
min: 0,
max: 10,
},
default: 2,
},
tag: {
type: String,
title: 'Tag',
widget: 'input-text',
default: 'p',
},
s: {
type: Number,
title: 'Sentences',
widget: 'input-number',
default: 0,
},
w: {
type: Number,
title: 'Words',
widget: 'input-number',
default: 0,
},
},
titlebar({ attributes }) {
if (attributes.w) {
return `words: <strong>${attributes.w}</strong>`;
}
if (attributes.s) {
return `sentences: <strong>${attributes.s}</strong>`;
}
if (attributes.p) {
return `paragraphs: <strong>${attributes.p}</strong>`;
}
return '';
},
content({ attributes }) {
let output = '';
output += '<div style="margin:16px 16px">';
if (attributes.w) {
output += words.slice(0, attributes.w).join(' ');
} else if (attributes.s) {
output += Array(attributes.s).fill(sentence).join(' ');
} else if (attributes.p) {
[...Array(attributes.p)].forEach(() => {
output += `<p>${paragraph}</p>`;
});
}
output += '</div>';
return output;
},
});

View File

@ -1,7 +0,0 @@
shortcode-inline[name="mark"] > .sc-content > span {
background: #ffe9b3;
border-bottom: .05rem solid #ffd367;
border-radius: .1rem;
color: #50596c;
padding: .05rem .1rem 0;
}

View File

@ -1,49 +0,0 @@
window.nextgenEditor.addShortcode('mark', {
type: 'inline',
plugin: 'shortcode-core',
title: 'Mark',
button: {
group: 'shortcode-core',
label: 'Mark',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3.448 18a.253.253 0 00-.184-.073.25.25 0 00-.179.083L.192 21.247A.75.75 0 00.751 22.5H4a.752.752 0 00.507-.2L6 20.929a.244.244 0 00.081-.178.25.25 0 00-.073-.183zM7.27 20.035a1.256 1.256 0 001.7.068c.611-.524 1.8-1.278 2.894-.447a1.269 1.269 0 001.7-.171l.182-.227a.25.25 0 00-.018-.333l-8.673-8.667a.249.249 0 00-.341-.011l-.273.238a1.257 1.257 0 00-.111 1.641c.832 1.094.078 2.282-.444 2.894a1.254 1.254 0 00.065 1.7zM14.312 18.1a.249.249 0 00.372-.021L23.1 7.6a1.884 1.884 0 00-.133-2.486L18.379.523A1.841 1.841 0 0015.9.443L5.844 9.256a.25.25 0 00-.012.365zM24 23a1 1 0 00-1-1H9a1 1 0 000 2h14a1 1 0 001-1z"/></svg>',
},
attributes: {
style: {
type: String,
title: 'Style',
bbcode: true,
widget: {
type: 'radios',
values: [
{ value: 'inline', label: 'Inline' },
{ value: 'block', label: 'Block' },
],
},
default: 'inline',
},
class: {
type: String,
title: 'Class',
widget: 'input-text',
default: '',
},
},
titlebar({ attributes }) {
return []
.concat([
attributes.style ? `style: <strong>${attributes.style}</strong>` : null,
attributes.class ? `class: <strong>${attributes.class}</strong>` : null,
])
.filter((item) => !!item)
.join(', ');
},
content({ attributes }) {
const style = attributes.style === 'block'
? 'display:block'
: '';
const cclass = `mark-class-${attributes.class}`;
return `<span class="${cclass}" style="${style}">{{content_editable}}</span>`;
},
});

View File

@ -1,63 +0,0 @@
shortcode-block[name="notice"] .sc-notice {
color: #666;
font-size: 16px;
line-height: 24px;
margin: 8px 8px;
position: relative;
}
shortcode-block[name="notice"] .sc-notice .sc-notice-wrapper {
padding: 4px 12px;
}
shortcode-block[name="notice"] .sc-notice .sc-notice-wrapper:before {
color: rgb(255, 255, 255);
content: "";
font-family: FontAwesome;
left: 10px;
position: absolute;
top: 2px;
}
shortcode-block[name="notice"] .sc-notice .sc-notice-wrapper:after {
color: #fff;
left: 30px;
position: absolute;
top: 3px;
}
shortcode-block[name="notice"] .sc-notice-info .sc-notice-wrapper {
border-top: 30px solid #F0B37E;
background: #FFF2DB;
}
shortcode-block[name="notice"] .sc-notice-warning .sc-notice-wrapper {
border-top: 30px solid #DF6F6C;
background: #FAE2E2;
}
shortcode-block[name="notice"] .sc-notice-note .sc-notice-wrapper {
border-top: 30px solid #6AB0DE;
background: #E7F2FA;
}
shortcode-block[name="notice"] .sc-notice-tip .sc-notice-wrapper {
border-top: 30px solid #77C577;
background: #E6F9E6;
}
shortcode-block[name="notice"] .sc-notice-info .sc-notice-wrapper:after {
content: 'Info';
}
shortcode-block[name="notice"] .sc-notice-warning .sc-notice-wrapper:after {
content: 'Warning';
}
shortcode-block[name="notice"] .sc-notice-note .sc-notice-wrapper:after {
content: 'Note';
}
shortcode-block[name="notice"] .sc-notice-tip .sc-notice-wrapper:after {
content: 'Tip';
}

View File

@ -1,41 +0,0 @@
window.nextgenEditor.addShortcode('notice', {
type: 'block',
plugin: 'shortcode-core',
title: 'Notice',
button: {
group: 'shortcode-core',
label: 'Notice',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.5 14a1 1 0 00-.665.252L5 16.773V15a1 1 0 00-1-1H2.25a.251.251 0 01-.25-.253V2.25A.249.249 0 012.251 2h18a.25.25 0 01.25.25v10.007a.248.248 0 00.028.116l1.316 2.509a.25.25 0 00.445 0A1.939 1.939 0 0022.5 14V2a2 2 0 00-2-2H2a2 2 0 00-2 2v12.053A1.953 1.953 0 002 16h1v3a1 1 0 001.664.748L8.881 16h3.537a.251.251 0 00.221-.134l.787-1.5a.249.249 0 00-.007-.245.252.252 0 00-.214-.121z"/><path d="M18.782 12.271a1.45 1.45 0 00-2.562 0l-5.055 9.634a1.433 1.433 0 00.048 1.409 1.457 1.457 0 001.232.686h10.111a1.459 1.459 0 001.234-.687 1.434 1.434 0 00.047-1.408zM17.5 15.25a.75.75 0 01.75.75v3a.75.75 0 01-1.5 0v-3a.75.75 0 01.75-.75zm0 7a1 1 0 111-1 1 1 0 01-1 1z"/></svg>',
},
attributes: {
notice: {
type: String,
title: 'Type',
bbcode: true,
widget: {
type: 'radios',
values: [
{ value: 'info', label: 'Info' },
{ value: 'warning', label: 'Warning' },
{ value: 'note', label: 'Note' },
{ value: 'tip', label: 'Tip' },
],
},
default: 'info',
},
},
titlebar({ attributes }) {
const notice = attributes.notice
? this.attributes.notice.widget.values.find((item) => item.value === attributes.notice)
: '';
const type = notice
? notice.label
: '';
return `type: <strong>${type}</strong>`;
},
content({ attributes }) {
return `<div class="sc-notice sc-notice-${attributes.notice}"><div class="sc-notice-wrapper">{{content_editable}}</div></div>`;
},
});

View File

@ -1,13 +0,0 @@
window.nextgenEditor.addShortcode('raw', {
type: 'block',
plugin: 'shortcode-core',
title: 'Raw',
button: {
group: 'shortcode-core',
label: 'Raw',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 15.034 9"><path d="M5.726 0a.5.5 0 00-.5.5h-2.25a2.744 2.744 0 00-1.807 4.813A1.998 1.998 0 00.226 7c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2 0-.488-.186-.93-.48-1.277l2.177.963a.75.75 0 10.606-1.372l-1.81-.802 1.63-.272a.75.75 0 10-.246-1.48l-2.13.355C11.484 1.952 10.264.784 8.226.55V.5a.5.5 0 00-.5-.5h-2zm.5 1h1v7h-1V1zm3.5 4c.259 0 .464.197.49.45l.076-.134a.5.5 0 11.866.5l-.258.448a.986.986 0 01.326.736c0 .563-.437 1-1 1h-2V6h1v-.5c0-.277.223-.5.5-.5zm-7.06.07a.498.498 0 01.494.246l.2.348a.493.493 0 01.366-.164c.277 0 .5.223.5.5h1v2h-3c-.563 0-1-.437-1-1s.437-1 1-1H2.4l-.106-.184a.497.497 0 01.371-.746z"/></svg>',
},
content() {
return '{{content_editable}}';
},
});

View File

@ -1,48 +0,0 @@
window.nextgenEditor.addShortcode('safe-email', {
type: 'inline',
plugin: 'shortcode-core',
title: 'Safe Email',
button: {
group: 'shortcode-core',
label: 'Safe Email',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 9.25a4.924 4.924 0 011.666.291.25.25 0 00.334-.236V1.75a.158.158 0 00-.1-.147.16.16 0 00-.173.034L12.2 10.164a2.407 2.407 0 01-3.4 0L.271 1.637A.159.159 0 000 1.75v10.5A1.749 1.749 0 001.75 14h12.043a.25.25 0 00.249-.226A4.992 4.992 0 0119 9.25z"/><path d="M9.726 9.236a1.094 1.094 0 001.547 0L19.748.761A.437.437 0 0019.5.019 1.62 1.62 0 0019.249 0h-17.5A1.62 1.62 0 001.5.019a.437.437 0 00-.352.3.441.441 0 00.102.442zM22.5 15.5v-1.25a3.5 3.5 0 00-7 0v1.25A1.5 1.5 0 0014 17v5.5a1.5 1.5 0 001.5 1.5h7a1.5 1.5 0 001.5-1.5V17a1.5 1.5 0 00-1.5-1.5zM19 12.75a1.5 1.5 0 011.5 1.5v1.25h-3v-1.25a1.5 1.5 0 011.5-1.5zm1 7.5a1 1 0 11-1-1 1 1 0 011 1z"/></svg>',
},
attributes: {
icon: {
type: String,
title: 'Icon',
bbcode: true,
widget: 'input-text',
default: 'grav',
},
autolink: {
type: String,
title: 'Autolink',
widget: {
type: 'checkbox',
valueType: String,
label: 'Yes',
},
default: 'false',
},
},
content({ attributes }) {
let output = '';
if (attributes.autolink === 'true') {
output += '<span style="color:#1c90fb">';
}
if (attributes.icon) {
output += `<span class="fa fa-${attributes.icon}" style="margin-left:4px"></span>`;
}
output += '{{content_editable}}';
if (attributes.autolink === 'true') {
output += '</span>';
}
return output;
},
});

View File

@ -1,26 +0,0 @@
window.nextgenEditor.addShortcode('section', {
type: 'block',
plugin: 'shortcode-core',
title: 'Section',
button: {
group: 'shortcode-core',
label: 'Section',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20.242 18.827a6.523 6.523 0 10-1.414 1.414l3.465 3.465a1.014 1.014 0 001.414 0 1 1 0 000-1.414zM15 10.5a4.5 4.5 0 11-4.5 4.5 4.505 4.505 0 014.5-4.5z"/><path d="M13 15.749h1.25V17a.75.75 0 001.5 0v-1.25H17a.75.75 0 000-1.5h-1.25V13a.75.75 0 00-1.5 0v1.25H13a.75.75 0 000 1.5zM3.933 0H1.957A1.959 1.959 0 000 1.956v1.977a1 1 0 002 0L1.957 2h1.976a1 1 0 000-2zM3.933 22L2 22.042v-1.976a1 1 0 00-2 0v1.976A1.959 1.959 0 001.957 24h1.976a1 1 0 000-2zM1 11.533a1 1 0 001-1V7.6a1 1 0 00-2 0v2.934a1 1 0 001 .999zM1 17.4a1 1 0 001-1v-2.934a1 1 0 00-2 0V16.4a1 1 0 001 1zM23 6.6a1 1 0 00-1 1v2.934a1 1 0 102 0V7.6a1 1 0 00-1-1zM7.6 2H10a1 1 0 000-2H7.6a1 1 0 000 2zM14 2h2.4a1 1 0 000-2H14a1 1 0 000 2zM20.067 2L22 1.956v1.977a1 1 0 002 0V1.956A1.959 1.959 0 0022.043 0h-1.976a1 1 0 000 2zM10.533 22H7.6a1 1 0 100 2h2.933a1 1 0 000-2z"/></svg>',
},
attributes: {
name: {
type: String,
title: 'Name',
widget: 'input-text',
default: '',
},
},
titlebar({ attributes }) {
return attributes.name
? `name: <strong>${attributes.name}</strong>`
: '';
},
content() {
return '{{content_editable}}';
},
});

View File

@ -1,10 +0,0 @@
window.nextgenEditor.addHook('hookInit', () => {
window.nextgenEditor.addShortcodePlugin('shortcode-core', {
title: 'Shortcode Core',
});
window.nextgenEditor.addButtonGroup('shortcode-core', {
icon: '<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M22 0H1.99c-1.11 0-2 .89-2 2v7-.01c-.01 1.1.89 2 1.99 2h20l-.01-.001c1.1 0 2-.9 2-2v-7a2 2 0 00-2-2zm-7.25 8.5c0 .27-.23.5-.5.5H2.49a.51.51 0 01-.5-.51V2.479c0-.28.22-.5.5-.5h11.75-.01c.27-.01.5.22.5.49zM21 6.85h-.01c-.01.4-.33.72-.73.72a.824.824 0 01-.46-.16l-1.75-1.4-.01-.01a.733.733 0 01-.12-1.03c.03-.05.07-.09.11-.12l1.74-1.4h-.01c.31-.26.77-.21 1.02.11.1.13.16.29.15.46z"/><path d="M4 4.75h7.5l-.01-.001a.749.749 0 100-1.5H3.98c-.42 0-.75.33-.75.75 0 .41.33.75.75.75zM4 7.75h4.5l-.01-.001a.749.749 0 100-1.5H3.98c-.42 0-.75.33-.75.75 0 .41.33.75.75.75zM22 13H1.99c-1.11 0-2 .89-2 2v7-.01c-.01 1.1.89 2 1.99 2h20l-.01-.001c1.1 0 2-.9 2-2v-7a2 2 0 00-2-2zm-7.25 8.5c0 .27-.23.5-.5.5H2.49a.51.51 0 01-.5-.51v-6c-.01-.28.22-.51.49-.51h11.75-.01c.27-.01.5.22.5.49zM21 19.85h-.01c-.01.4-.33.72-.73.72a.824.824 0 01-.46-.16l-1.75-1.4-.01-.01a.733.733 0 01-.12-1.03c.03-.05.07-.09.11-.12l1.74-1.4h-.01c.31-.26.77-.21 1.02.11.1.13.16.29.15.46z"/><path d="M4 17.75h7.5-.01a.749.749 0 100-1.5H3.98c-.42 0-.75.33-.75.75 0 .41.33.75.75.75zM4 20.75h4.5-.01a.749.749 0 100-1.5H3.98c-.42 0-.75.33-.75.75 0 .41.33.75.75.75z"/></svg>',
label: 'Shortcode Core',
});
});

View File

@ -1,26 +0,0 @@
window.nextgenEditor.addShortcode('size', {
type: 'inline',
plugin: 'shortcode-core',
title: 'Font Size',
button: {
group: 'shortcode-core',
label: 'Font Size',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 3.993H2a2 2 0 00-2 2v2a1 1 0 002 0v-1.75a.249.249 0 01.25-.25h4a.249.249 0 01.25.25v12.5a.25.25 0 01-.25.25H4.5a1 1 0 000 2h6a1 1 0 000-2H8.75a.25.25 0 01-.25-.25v-12.5a.249.249 0 01.25-.25h4a.249.249 0 01.25.25v1.75a1 1 0 102 0v-2a2 2 0 00-2-2zM23.5 18.493h-1.75a.25.25 0 01-.25-.25v-12.5a.249.249 0 01.25-.25h1.75a.5.5 0 00.4-.8l-3-4a.518.518 0 00-.8 0l-3 4a.5.5 0 00.4.8h1.75a.249.249 0 01.25.25v12.5a.25.25 0 01-.25.25H17.5a.5.5 0 00-.4.8l3 4a.5.5 0 00.8 0l3-4a.5.5 0 00-.4-.8z"/></svg>',
},
attributes: {
size: {
type: String,
title: 'Size',
bbcode: true,
widget: 'input-text',
default: '14',
},
},
content({ attributes }) {
const size = !Number.isNaN(+attributes.size)
? `${attributes.size}px`
: attributes.size;
return `<span style="font-size:${size}">{{content_editable}}</span>`;
},
});

View File

@ -1,37 +0,0 @@
window.nextgenEditor.addShortcode('span', {
type: 'inline',
plugin: 'shortcode-core',
title: 'Span',
button: {
group: 'shortcode-core',
label: 'Span',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M24 4.5a3 3 0 00-3-3H3a3 3 0 00-3 3v15a3 3 0 003 3h18a3 3 0 003-3zM3 5a1 1 0 111 1 1 1 0 01-1-1zm3 0a1 1 0 111 1 1 1 0 01-1-1zm3 0a1 1 0 111 1 1 1 0 01-1-1zm13 14.5a1 1 0 01-1 1H3a1 1 0 01-1-1V9a.5.5 0 01.5-.5h19a.5.5 0 01.5.5z"/><path d="M7.75 12a.75.75 0 00.75.75.25.25 0 01.25.25v4a.75.75 0 001.5 0v-4a.25.25 0 01.25-.25.75.75 0 000-1.5h-2a.75.75 0 00-.75.75zM4 17.75a.75.75 0 00.75-.75v-1a.25.25 0 01.5 0v1a.75.75 0 001.5 0v-5a.75.75 0 00-1.5 0v2a.25.25 0 01-.5 0v-2a.75.75 0 00-1.5 0v5a.75.75 0 00.75.75zM17.75 16a1.752 1.752 0 001.75 1.75h1a.75.75 0 000-1.5h-1a.25.25 0 01-.25-.25v-4a.75.75 0 00-1.5 0zM13 17.75a.75.75 0 00.75-.75v-2.085a.057.057 0 01.106-.029.781.781 0 001.288 0 .057.057 0 01.106.029V17a.75.75 0 001.5 0v-5a.751.751 0 00-1.394-.386l-.642 1.071a.25.25 0 01-.428 0l-.642-1.071A.751.751 0 0012.25 12v5a.75.75 0 00.75.75z"/></svg>',
},
attributes: {
id: {
type: String,
title: 'ID',
widget: 'input-text',
default: '',
},
class: {
type: String,
title: 'Class',
widget: 'input-text',
default: '',
},
style: {
type: String,
title: 'Style',
widget: 'input-text',
default: '',
},
},
content({ attributes }) {
const id = attributes.id || '';
const cclass = attributes.class || '';
const style = attributes.style || '';
return `<span id="${id}" class="${cclass}" style="${style}">{{content_editable}}</span>`;
},
});

View File

@ -1,13 +0,0 @@
window.nextgenEditor.addShortcode('u', {
type: 'inline',
plugin: 'shortcode-core',
title: 'Underline',
button: {
group: 'shortcode-core',
label: 'Underline',
icon: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M22.5 21.248h-21a1.25 1.25 0 000 2.5h21a1.25 1.25 0 000-2.5zM1.978 2.748h1.363a.25.25 0 01.25.25v8.523a8.409 8.409 0 0016.818 0V3a.25.25 0 01.25-.25h1.363a1.25 1.25 0 000-2.5H16.3a1.25 1.25 0 000 2.5h1.363a.25.25 0 01.25.25v8.523a5.909 5.909 0 01-11.818 0V3a.25.25 0 01.25-.25H7.7a1.25 1.25 0 100-2.5H1.978a1.25 1.25 0 000 2.5z"/></svg>',
},
content() {
return '<span style="text-decoration:underline">{{content_editable}}</span>';
},
});

View File

@ -1,30 +0,0 @@
export default function collapse(input) {
let output = input;
output = output.replace(/<figure class="image">((((?!(<\/figure>)).)|\n)*)<\/figure>/gm, '$1');
const domOutput = new DOMParser().parseFromString(output, 'text/html');
[...domOutput.querySelectorAll('shortcode-block, shortcode-inline')].forEach((domShortcode) => {
domShortcode.setAttribute('sc-rendered', false);
});
let domShortcode = domOutput.querySelector('shortcode-block[sc-rendered], shortcode-inline[sc-rendered]');
while (domShortcode) {
const name = domShortcode.getAttribute('name');
const shortcode = window.nextgenEditor.shortcodes[name];
domShortcode.removeAttribute('class');
domShortcode.removeAttribute('sc-rendered');
const domInnerContent = domShortcode.querySelector(`shortcode-${shortcode.type}-editable, shortcode-${shortcode.type}-readonly`);
domShortcode.innerHTML = (domInnerContent && domInnerContent.innerHTML) || '';
domShortcode = domOutput.querySelector('shortcode-block[sc-rendered], shortcode-inline[sc-rendered]');
}
output = domOutput.body.innerHTML;
return output;
}

View File

@ -1,153 +0,0 @@
import collapse from './collapse';
import uncollapse from './uncollapse';
const Command = window.nextgenEditor.classes.core.command.class;
window.nextgenEditor.addPlugin('GravShortcodeCoreCommand', {
init() {
Object.values(window.nextgenEditor.shortcodes).forEach((shortcode) => {
const commandName = `shortcode_${shortcode.name}`;
class GravShortcodeCoreCommand extends Command {
execute(args) {
this.editor.model.change((modelWriter) => {
let dataShortcode = '';
const argsForUncollapse = {};
const wrapOnInsert = !shortcode.child && !shortcode.parent
? shortcode.wrapOnInsert !== undefined
? shortcode.wrapOnInsert
: true
: false;
const selectedBlocks = [...this.editor.model.document.selection.getSelectedBlocks()];
const selectedItems = [...this.editor.model.document.selection.getFirstRange().getItems({ shallow: true })];
const firstSelectedBlock = selectedBlocks[0];
const firstBlockSelectedItems = selectedItems.filter((item) => item.parent === firstSelectedBlock);
const attributes = Object.keys(shortcode.attributes).reduce((acc, attrName) => {
acc[attrName] = shortcode.attributes[attrName].default.value;
return acc;
}, {});
dataShortcode += `<shortcode-${shortcode.type} name="${shortcode.name}" attributes="${encodeURIComponent(JSON.stringify(attributes))}">`;
if (wrapOnInsert) {
if (shortcode.type === 'block') {
const modelSelectedBlocks = modelWriter.createDocumentFragment();
selectedBlocks.forEach((block) => modelWriter.append(modelWriter.cloneElement(block), modelSelectedBlocks));
const viewSelectedBlocks = this.editor.data.toView(modelSelectedBlocks);
const dataSelectedBlocks = this.editor.data.processor.toData(viewSelectedBlocks);
dataShortcode += collapse(dataSelectedBlocks);
}
if (shortcode.type === 'inline') {
const modelSelectedBlocks = modelWriter.createDocumentFragment();
firstBlockSelectedItems.forEach((item) => {
const block = item.textNode
? modelWriter.createText(item.data)
: modelWriter.cloneElement(item);
modelWriter.append(block, modelSelectedBlocks);
});
const viewSelectedBlocks = this.editor.data.toView(modelSelectedBlocks);
const dataSelectedBlocks = this.editor.data.processor.toData(viewSelectedBlocks);
dataShortcode += collapse(dataSelectedBlocks);
}
}
if (shortcode.parent) {
dataShortcode += '<p>&nbsp;</p>';
}
dataShortcode += `</shortcode-${shortcode.type}>`;
if (shortcode.parent) {
if (args && args.modelParentShortcode) {
argsForUncollapse.parentAttributes = JSON.parse(decodeURIComponent(args.modelParentShortcode.getAttribute('attributes')));
}
}
dataShortcode = uncollapse(dataShortcode, argsForUncollapse);
const convertContext = shortcode.type === 'inline'
? '$block'
: '$root';
const viewShortcode = this.editor.data.processor.toView(dataShortcode).getChild(0);
const modelShortcode = this.editor.data.toModel(viewShortcode, convertContext).getChild(0);
let insertPosition = modelWriter.createPositionAt(this.editor.model.document.getRoot(), 0);
if (!args || !args.insertPosition) {
if (shortcode.type === 'block') {
const firstBlock = selectedBlocks[0];
const lastBlock = selectedBlocks[selectedBlocks.length - 1];
if (wrapOnInsert) {
insertPosition = modelWriter.createPositionBefore(firstBlock);
modelWriter.remove(
modelWriter.createRange(
modelWriter.createPositionBefore(firstBlock),
modelWriter.createPositionAfter(lastBlock),
),
);
} else {
insertPosition = modelWriter.createPositionAfter(lastBlock);
if (lastBlock && lastBlock.name === 'paragraph' && lastBlock.childCount === 0) {
insertPosition = modelWriter.createPositionBefore(lastBlock);
modelWriter.remove(lastBlock);
}
}
}
if (shortcode.type === 'inline') {
const firstItem = firstBlockSelectedItems.length
? firstBlockSelectedItems[0]
: null;
const lastItem = firstBlockSelectedItems.length
? firstBlockSelectedItems[firstBlockSelectedItems.length - 1]
: null;
if (wrapOnInsert) {
insertPosition = firstItem
? modelWriter.createPositionBefore(firstItem)
: this.editor.model.document.selection.getFirstPosition();
if (firstItem) {
modelWriter.remove(
modelWriter.createRange(
modelWriter.createPositionBefore(firstItem),
modelWriter.createPositionAfter(lastItem),
),
);
}
} else {
insertPosition = lastItem
? modelWriter.createPositionAfter(lastItem)
: this.editor.model.document.selection.getFirstPosition();
}
}
} else {
insertPosition = args.insertPosition;
}
modelWriter.insert(modelShortcode, insertPosition);
modelWriter.setSelection(modelShortcode, 'on');
});
}
}
this.editor.commands.add(commandName, new GravShortcodeCoreCommand(this.editor));
});
},
});

View File

@ -1,150 +0,0 @@
const Widget = window.nextgenEditor.classes.widget.class;
const { toWidget, toWidgetEditable } = window.nextgenEditor.classes.widget.utils;
window.nextgenEditor.addPlugin('GravShortcodeCoreConvertersBlock', {
requires: [Widget],
init() {
this.editor.model.schema.register('shortcode-block', {
isBlock: true,
isObject: true,
allowWhere: '$block',
allowContentOf: '$root',
allowAttributes: [
'name',
'attributes',
'class',
],
});
this.editor.conversion.for('upcast').elementToElement({
view: 'shortcode-block',
model(viewElement, { writer }) {
return writer.createElement('shortcode-block', viewElement.getAttributes());
},
});
this.editor.conversion.for('dataDowncast').elementToElement({
model: 'shortcode-block',
view(modelElement, { writer }) {
return writer.createContainerElement('shortcode-block', modelElement.getAttributes());
},
});
this.editor.conversion.for('editingDowncast').elementToElement({
model: 'shortcode-block',
view(modelElement, { writer }) {
const container = writer.createContainerElement('shortcode-block', modelElement.getAttributes());
return toWidget(container, writer);
},
});
this.editor.model.schema.register('shortcode-block-editable', {
isLimit: true,
allowWhere: '$block',
allowContentOf: '$root',
});
this.editor.conversion.for('upcast').elementToElement({
view: 'shortcode-block-editable',
model: 'shortcode-block-editable',
});
this.editor.conversion.for('dataDowncast').elementToElement({
model: 'shortcode-block-editable',
view: 'shortcode-block-editable',
});
this.editor.conversion.for('editingDowncast').elementToElement({
model: 'shortcode-block-editable',
view(modelElement, { writer }) {
const container = writer.createEditableElement('shortcode-block-editable', modelElement.getAttributes());
return toWidgetEditable(container, writer);
},
});
this.editor.model.schema.register('shortcode-block-readonly', {
isLimit: true,
allowWhere: '$block',
allowContentOf: '$root',
});
this.editor.conversion.elementToElement({
view: 'shortcode-block-readonly',
model: 'shortcode-block-readonly',
});
},
});
window.nextgenEditor.addPlugin('GravShortcodeCoreConvertersInline', {
requires: [Widget],
init() {
this.editor.model.schema.register('shortcode-inline', {
isObject: true,
isInline: true,
allowWhere: '$text',
allowContentOf: '$block',
allowAttributes: [
'name',
'attributes',
'class',
],
});
this.editor.conversion.for('upcast').elementToElement({
view: 'shortcode-inline',
model(viewElement, { writer }) {
return writer.createElement('shortcode-inline', viewElement.getAttributes());
},
});
this.editor.conversion.for('dataDowncast').elementToElement({
model: 'shortcode-inline',
view(modelElement, { writer }) {
return writer.createContainerElement('shortcode-inline', modelElement.getAttributes());
},
});
this.editor.conversion.for('editingDowncast').elementToElement({
model: 'shortcode-inline',
view(modelElement, { writer }) {
const container = writer.createContainerElement('shortcode-inline', modelElement.getAttributes());
return toWidget(container, writer);
},
});
this.editor.model.schema.register('shortcode-inline-editable', {
isLimit: true,
allowWhere: '$text',
allowContentOf: '$block',
});
this.editor.conversion.for('upcast').elementToElement({
view: 'shortcode-inline-editable',
model: 'shortcode-inline-editable',
});
this.editor.conversion.for('dataDowncast').elementToElement({
model: 'shortcode-inline-editable',
view: 'shortcode-inline-editable',
});
this.editor.conversion.for('editingDowncast').elementToElement({
model: 'shortcode-inline-editable',
view(modelElement, { writer }) {
const container = writer.createEditableElement('shortcode-inline-editable', modelElement.getAttributes());
return toWidgetEditable(container, writer);
},
});
this.editor.model.schema.register('shortcode-inline-readonly', {
isLimit: true,
allowWhere: '$text',
allowContentOf: '$block',
});
this.editor.conversion.elementToElement({
view: 'shortcode-inline-readonly',
model: 'shortcode-inline-readonly',
});
},
});

View File

@ -1,86 +0,0 @@
import displaySettings from './settings';
window.scDisplaySettings = function scDisplaySettings() {
const domShortcode = this.closest('shortcode-block, shortcode-inline');
if (domShortcode) {
displaySettings(domShortcode);
}
};
window.scBlockAddChildFromParent = function scBlockAddChildFromParent() {
const { editors } = window.nextgenEditor;
const domShortcode = this.parentNode;
const editor = (editors.filter((instance) => instance.ui.view.element.contains(domShortcode)) || []).shift();
const name = domShortcode.getAttribute('name');
const shortcode = window.nextgenEditor.shortcodes[name];
if (editor) {
const viewShortcode = editor.editing.view.domConverter.mapDomToView(domShortcode);
const modelShortcode = editor.editing.mapper.toModelElement(viewShortcode);
const domShortcodeBlockReadOnly = domShortcode.querySelector('shortcode-block-readonly');
const viewShortcodeBlockReadOnly = editor.editing.view.domConverter.mapDomToView(domShortcodeBlockReadOnly);
const modelShortcodeBlockReadOnly = editor.editing.mapper.toModelElement(viewShortcodeBlockReadOnly);
editor.model.change((modelWriter) => {
const insertPosition = modelWriter.createPositionAt(modelShortcodeBlockReadOnly, 0);
editor.execute(`shortcode_${shortcode.child.name}`, { insertPosition, modelParentShortcode: modelShortcode });
domShortcode.querySelector('.sc-add-child').classList.remove('sc-visible');
});
}
};
window.scBlockAddChild = function scBlockAddChild(event, where) {
const { editors } = window.nextgenEditor;
const domShortcode = this.parentNode;
const editor = (editors.filter((instance) => instance.ui.view.element.contains(domShortcode)) || []).shift();
const name = domShortcode.getAttribute('name');
const shortcode = window.nextgenEditor.shortcodes[name];
if (editor) {
const viewShortcode = editor.editing.view.domConverter.mapDomToView(domShortcode);
const modelShortcode = editor.editing.mapper.toModelElement(viewShortcode);
editor.model.change((modelWriter) => {
let modelParentShortcode = modelShortcode.parent;
const insertPosition = modelWriter.createPositionAt(modelShortcode, where);
while (modelParentShortcode && modelParentShortcode.name !== 'shortcode-block') {
modelParentShortcode = modelParentShortcode.parent;
}
if (modelParentShortcode) {
editor.execute(`shortcode_${shortcode.name}`, { insertPosition, modelParentShortcode });
}
});
}
};
window.scBlockMoveChild = function scBlockMove(event, where) {
const { editors } = window.nextgenEditor;
const domShortcode = this.parentNode;
const editor = (editors.filter((instance) => instance.ui.view.element.contains(domShortcode)) || []).shift();
if (editor) {
const viewShortcode = editor.editing.view.domConverter.mapDomToView(domShortcode);
const modelShortcode = editor.editing.mapper.toModelElement(viewShortcode);
const domSiblingShortcode = where === 'up'
? domShortcode.previousSibling
: domShortcode.nextSibling;
const viewSiblingShortcode = editor.editing.view.domConverter.mapDomToView(domSiblingShortcode);
const modelSiblingShortcode = editor.editing.mapper.toModelElement(viewSiblingShortcode);
editor.model.change((modelWriter) => {
modelWriter.move(modelWriter.createRangeOn(modelShortcode), modelSiblingShortcode, where === 'up' ? 'before' : 'after');
});
}
};

View File

@ -1,45 +0,0 @@
window.nextgenEditor.addHook('hookInit', () => {
Object.values(window.nextgenEditor.shortcodes).forEach((shortcode) => {
shortcode.attributes = shortcode.attributes || {};
if (!shortcode.button) {
shortcode.button = { label: shortcode.title };
}
Object.values(shortcode.attributes).forEach((attribute) => {
if (attribute.default === undefined) {
attribute.default = '';
}
if (typeof attribute.default !== 'object') {
attribute.default = { value: attribute.default };
}
if (attribute.shorthand === undefined) {
attribute.shorthand = true;
}
});
if (shortcode.type === 'block' && !shortcode.titlebar) {
shortcode.titlebar = () => '';
}
if (!shortcode.content) {
shortcode.content = () => '';
}
if (shortcode.preserve) {
if (shortcode.preserve.block) {
window.nextgenEditor.addVariable('preserveBlockTags', shortcode.preserve.block);
}
if (shortcode.preserve.inline) {
window.nextgenEditor.addVariable('preserveInlineTags', shortcode.preserve.inline);
}
}
if (!shortcode.parent) {
window.nextgenEditor.addButton(`shortcode_${shortcode.name}`, {
command: `shortcode_${shortcode.name}`,
...shortcode.button,
});
}
});
});

View File

@ -1,278 +0,0 @@
shortcode-block {
background: #fff;
border: 1px solid #ccc;
display: block;
margin: 16px 0;
}
#admin-main .ck.ck-editor__editable_inline > :first-child {
margin-top: 16px;
}
#admin-main .ck.ck-editor__editable_inline > :last-child {
margin-bottom: 16px;
}
#admin-main .ck-editor shortcode-block.ck-shortcode-child:hover {
outline-color: #1f89e5;
}
#admin-main .ck-editor shortcode-block > .sc-header > .sc-title > p,
#admin-main .ck-editor shortcode-block > .sc-header > .sc-titlebar > p,
#admin-main .ck-editor shortcode-block > .sc-header > .sc-settings > p,
#admin-main .ck-editor shortcode-block > .sc-add > p,
#admin-main .ck-editor shortcode-block > .sc-move > p {
margin: 0;
}
shortcode-block > .sc-header {
align-items: center;
border-bottom: 1px solid #ccc;
display: flex;
font-size: 14px;
line-height: 1.5;
padding: 8px 8px;
}
shortcode-block > .sc-header > .sc-title > p > .sc-value {
font-weight: 700;
}
shortcode-block > .sc-header > .sc-titlebar {
margin-left: 24px;
}
shortcode-block > .sc-header > .sc-settings {
color: #ffc83d;
cursor: pointer;
font-size: 0;
line-height: 0;
margin-left: auto;
opacity: 0;
transition: opacity .2s ease, color .2s ease;
}
shortcode-block > .sc-header > .sc-settings:hover,
shortcode-block.ck-shortcode-child > .sc-header > .sc-settings,
shortcode-block.ck-widget_selected > .sc-header > .sc-settings {
color: #1f89e5;
}
shortcode-block.ck-widget_selected > .sc-header > .sc-settings:hover,
shortcode-block.ck-shortcode-child > .sc-header > .sc-settings:hover {
opacity: .5
}
shortcode-block:hover > .sc-header > .sc-settings,
shortcode-block.ck-widget_selected > .sc-header > .sc-settings {
opacity: 1;
}
shortcode-block > .sc-header > .sc-settings > p > svg {
height: 24px;
width: 24px;
}
shortcode-block-editable,
shortcode-block-readonly {
display: block;
padding: 0 8px;
}
shortcode-block-readonly > [data-cke-filler] {
display: none;
}
#admin-main .ck-editor shortcode-block-editable > :first-child {
margin-top: 14px;
}
#admin-main .ck-editor shortcode-block.ck-shortcode-child .ck-widget__type-around__button_after,
#admin-main .ck-editor shortcode-block.ck-shortcode-child .ck-widget__type-around__button_before {
display: none;
}
shortcode-block > .sc-add-child {
align-items: center;
display: none;
justify-content: center;
margin: 16px 0;
opacity: 0;
transition: opacity .2s ease;
}
shortcode-block > .sc-add-child.sc-visible {
display: flex;
}
shortcode-block:hover > .sc-add-child,
shortcode-block.ck-widget_selected > .sc-add-child {
opacity: 1;
z-index: 1;
}
shortcode-block > .sc-add-child > p {
align-items: center;
background: #ffc83d;
border-radius: 50%;
cursor: pointer;
display: flex;
height: 24px;
justify-content: center;
margin: 0!important;
transition: opacity .2s ease, background .2s ease;
width: 24px;
}
shortcode-block > .sc-add-child > p:hover,
shortcode-block.ck-widget_selected > .sc-add-child > p {
background: #1f89e5;
}
shortcode-block.ck-widget_selected > .sc-add-child > p:hover {
opacity: .5;
}
shortcode-block > .sc-add-child > p > svg {
color: #fff;
height: 20px;
transition: opacity .2s ease;
width: 20px;
}
shortcode-block > .sc-add {
left: 30px;
opacity: 0;
position: absolute;
transition: opacity .2s ease;
top: -12px;
}
shortcode-block > .sc-add-after {
bottom: -11px;
left: auto;
right: 30px;
top: auto;
}
shortcode-block:hover > .sc-add {
opacity: 1;
z-index: 1;
}
shortcode-block > .sc-add > p {
align-items: center;
background: #1f89e5;
border-radius: 50%;
cursor: pointer;
display: flex;
height: 20px;
justify-content: center;
width: 20px;
}
shortcode-block > .sc-add > p > svg {
color: #fff;
height: 16px;
transition: opacity .2s ease;
width: 16px;
}
shortcode-block > .sc-add:hover > p > svg {
opacity: .5;
}
shortcode-block > .sc-move {
background: #1f89e5;
border-radius: 50%;
cursor: pointer;
height: 20px;
opacity: 0;
position: absolute;
right: -12px;
transition: opacity .2s ease;
width: 20px;
top: 46px;
}
shortcode-block > .sc-move-up {
transform: rotate(180deg);
}
shortcode-block:first-child > .sc-move-up,
shortcode-block:last-child > .sc-move-down {
display: none;
}
shortcode-block > .sc-move-down {
bottom: 4px;
left: auto;
top: auto;
}
shortcode-block:hover > .sc-move {
opacity: 1;
z-index: 1;
}
shortcode-block > .sc-move > p > svg {
color: #fff;
height: 20px;
left: 1.5px;
position: absolute;
top: 2px;
transition: opacity .2s ease;
width: 20px;
}
shortcode-block > .sc-move:hover > p > svg {
opacity: .5;
}
shortcode-inline {
background: #fff;
border: 1px solid #ccc;
display: inline-flex;
margin-left: 2px;
margin-right: 1px;
vertical-align: middle;
}
shortcode-inline-editable,
shortcode-inline-readonly {
display: inline;
padding: 1px 4px 2px;
}
shortcode-inline > .sc-content {
display: inline-flex;
align-items: center;
}
shortcode-inline > .sc-settings {
align-items: center;
border-left: 1px solid #ccc;
cursor: pointer;
display: inline-flex;
font-size: 0;
line-height: 0;
padding: 0 2px;
transition: opacity .2s ease, color .2s ease;
}
shortcode-inline:hover > .sc-settings {
color: #ffc83d;
}
shortcode-inline > .sc-settings:hover,
shortcode-inline.ck-widget_selected > .sc-settings {
color: #1f89e5;
}
shortcode-inline.ck-widget_selected > .sc-settings:hover {
opacity: .5;
}
shortcode-inline > .sc-settings > svg {
height: 16px;
width: 16px;
}

View File

@ -1,10 +0,0 @@
import './command';
import './converters';
import './events';
import './init';
import './prerender';
import './postsave';
import './remove';
import './render';
import './save';
import './main.css';

View File

@ -1,95 +0,0 @@
window.nextgenEditor.addHook('hookHTMLtoMarkdown', {
weight: 50,
handler(options, editor, input) {
let output = input;
const realNames = Object.values(window.nextgenEditor.shortcodes).map((shortcode) => shortcode.realName)
.filter((value, index, self) => self.indexOf(value) === index);
const openingRegexp = realNames
.map((name) => `(\\[${name}[^\\]]*\\])`).join('|');
const hashMap = {};
let shortcodeCounter = 1;
while (shortcodeCounter > 0) {
shortcodeCounter = 0;
// eslint-disable-next-line no-loop-func
Object.values(window.nextgenEditor.shortcodes).forEach((shortcode) => {
const regexp = `(?<opening>\\[${shortcode.realName}[^\\]]*\\])(?<content>(((?!(${openingRegexp}|(\\[\\/${shortcode.realName}\\]))).)|\\n)*)(?<closing>\\[\\/${shortcode.realName}\\])`;
output = output.replace(new RegExp(regexp, 'g'), (...matches) => {
shortcodeCounter += 1;
const hash = Math.random().toString(36).slice(2);
hashMap[hash] = { shortcode, matches };
if (shortcode.child) {
const childName = shortcode.child.realName;
Object.keys(hashMap).forEach((childHash) => {
const childShortcode = hashMap[childHash].shortcode;
if (childShortcode === shortcode.child && childShortcode.name !== `${shortcode.realName}_${childName}` && matches[0].includes(childHash)) {
hashMap[childHash].shortcode = window.nextgenEditor.shortcodes[`${shortcode.realName}_${childName}`];
}
});
}
return hash;
});
});
}
shortcodeCounter = 1;
while (shortcodeCounter > 0) {
shortcodeCounter = 0;
// eslint-disable-next-line no-loop-func
Object.keys(hashMap).forEach((hash) => {
if (!output.includes(hash)) {
return;
}
shortcodeCounter += 1;
const { shortcode, matches } = hashMap[hash];
const groups = matches.pop();
if (shortcode.type === 'block') {
let content = groups.content.replace(/^\n/, '').replace(/\n$/, '');
if (shortcode.child) {
content = content.trim().split('\n').filter((line) => !!line).join('\n');
content = `\n${content}\n`;
}
if (shortcode.parent) {
content = `\n${content}\n`;
}
output = output.replace(hash, `${groups.opening}${content}${groups.closing}`);
}
if (shortcode.type === 'inline') {
output = output.replace(hash, matches[0]);
}
});
}
/*
Object.values(window.nextgenEditor.shortcodes).forEach((shortcode) => {
const regexp = `(?<opening>\\[${shortcode.realName}[^\\]]*\\])\n(?<content>(((?!(${openingRegexp}|(\\[\\/${shortcode.realName}\\]))).))*)\n(?<closing>\\[\\/${shortcode.realName}\\])`;
output = output.replace(new RegExp(regexp, 'g'), (...matches) => {
const groups = matches.pop();
return `${groups.opening}${groups.content}${groups.closing}`;
});
});
*/
return output;
},
});

View File

@ -1,100 +0,0 @@
window.nextgenEditor.addHook('hookMarkdowntoHTML', {
weight: -50,
handler(options, input) {
let output = input;
const realNames = Object.values(window.nextgenEditor.shortcodes).map((shortcode) => shortcode.realName)
.filter((value, index, self) => self.indexOf(value) === index);
const openingRegexp = realNames
.map((name) => `(\\[${name}[^\\]]*\\])`).join('|');
realNames.forEach((name) => {
const regexp = `\\[${name}(?<attributes>(=| +).+?(?=/]))?\\/\\]`;
output = output.replace(new RegExp(regexp, 'g'), (...matches) => {
const groups = matches.pop();
const attributes = groups.attributes.trim()
? `${groups.attributes}`
: '';
return `[${name}${attributes}][/${name}]`;
});
});
const hashMap = {};
let shortcodeCounter = 1;
while (shortcodeCounter > 0) {
shortcodeCounter = 0;
// eslint-disable-next-line no-loop-func
Object.values(window.nextgenEditor.shortcodes).forEach((shortcode) => {
const regexp = `(?<spaces_before> *)\\[${shortcode.realName}(?<attributes>(=| +)[^\\]]*)?\\](?<content>(((?!(${openingRegexp}|(\\[\\/${shortcode.realName}\\]))).)|\\n)*)\\[\\/${shortcode.realName}\\](?<spaces_after> *)`;
output = output.replace(new RegExp(regexp, 'g'), (...matches) => {
shortcodeCounter += 1;
const hash = Math.random().toString(36).slice(2);
hashMap[hash] = { shortcode, matches };
if (shortcode.child) {
const childName = shortcode.child.realName;
Object.keys(hashMap).forEach((childHash) => {
const childShortcode = hashMap[childHash].shortcode;
if (childShortcode === shortcode.child && childShortcode.name !== `${shortcode.realName}_${childName}` && matches[0].includes(childHash)) {
hashMap[childHash].shortcode = window.nextgenEditor.shortcodes[`${shortcode.realName}_${childName}`];
}
});
}
return hash;
});
});
}
shortcodeCounter = 1;
while (shortcodeCounter > 0) {
shortcodeCounter = 0;
// eslint-disable-next-line no-loop-func
Object.keys(hashMap).forEach((hash) => {
if (!output.includes(hash)) {
return;
}
shortcodeCounter += 1;
const { shortcode, matches } = hashMap[hash];
const groups = matches.pop();
const spacesBefore = groups.spaces_before.replace(/ /g, '&nbsp;');
const spacesAfter = groups.spaces_after.replace(/ /g, '&nbsp;');
if (shortcode.type === 'block') {
let content = groups.content.trim();
if (groups.spaces_before.length) {
content = content.replace(new RegExp(`^( ){${groups.spaces_before.length}}`, 'gm'), '');
}
const replacement = `\n\n[${shortcode.name}${groups.attributes || ''}]\n\n${content}\n\n[/${shortcode.name}]\n\n`;
output = output.replace(new RegExp(`(\\n)?(\\n)?${hash}(\\n)?(\\n)?`), replacement);
}
if (shortcode.type === 'inline') {
output = output.replace(hash, `${spacesBefore}[${shortcode.name}${groups.attributes || ''}]${groups.content}[/${shortcode.name}]${spacesAfter}`);
}
});
}
output = output.replace(/^\n\n/, '').replace(/\n\n$/, '');
return output;
},
});

Some files were not shown because too many files have changed in this diff Show More