├── boot.php ├── uninstall.php ├── update.php ├── plugins ├── email_url │ ├── README.md │ ├── lang │ │ └── de_de.lang │ ├── install.php │ ├── pages │ │ └── index.php │ ├── package.yml │ └── boot.php ├── min │ ├── README.md │ ├── lang │ │ └── de_de.lang │ ├── install.php │ ├── package.yml │ ├── pages │ │ └── index.php │ └── boot.php ├── border │ ├── README.md │ ├── install.php │ ├── package.yml │ ├── boot.php │ └── pages │ │ └── index.php ├── login_image │ ├── README.md │ ├── lang │ │ └── de_de.lang │ ├── assets │ │ └── out5_login_image.jpg │ ├── install.php │ ├── package.yml │ ├── boot.php │ └── pages │ │ └── index.php ├── structure_separators │ ├── README.md │ ├── install.php │ ├── package.yml │ ├── boot.php │ └── pages │ │ └── index.php └── wartungsarbeiten │ ├── lang │ └── de_de.lang │ ├── README.md │ ├── install.php │ ├── boot.php │ ├── package.yml │ └── pages │ └── index.php ├── help.php ├── lang └── de_de.lang ├── pages ├── index.php ├── info.php └── uebersicht.php ├── package.yml ├── README.md ├── CHANGELOG.md ├── LICENSE.md └── lib └── class.parsedown.inc.php /boot.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /uninstall.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /update.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/email_url/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /plugins/min/README.md: -------------------------------------------------------------------------------- 1 | Readme 2 | -------------------------------------------------------------------------------- /plugins/border/README.md: -------------------------------------------------------------------------------- 1 | Readme 2 | -------------------------------------------------------------------------------- /plugins/login_image/README.md: -------------------------------------------------------------------------------- 1 | Readme 2 | -------------------------------------------------------------------------------- /plugins/structure_separators/README.md: -------------------------------------------------------------------------------- 1 | Readme 2 | -------------------------------------------------------------------------------- /help.php: -------------------------------------------------------------------------------- 1 |

"out5" - Outpufilter für Redaxo 5

2 | -------------------------------------------------------------------------------- /lang/de_de.lang: -------------------------------------------------------------------------------- 1 | out5_title = Outputfilter 2 | 3 | perm_general_out55[] = Rechte für das Out5 Addon 4 | 5 | -------------------------------------------------------------------------------- /plugins/min/lang/de_de.lang: -------------------------------------------------------------------------------- 1 | perm_general_be5_login_image[] = Rechte für das BE5 Addon Plugin: Login Image 2 | 3 | 4 | -------------------------------------------------------------------------------- /plugins/email_url/lang/de_de.lang: -------------------------------------------------------------------------------- 1 | perm_general_out5_wartungsarbeiten[] = Rechte für das out5 Addon Plugin: Wartungsarbeiten 2 | -------------------------------------------------------------------------------- /plugins/login_image/lang/de_de.lang: -------------------------------------------------------------------------------- 1 | perm_general_be5_login_image[] = Rechte für das BE5 Addon Plugin: Login Image 2 | 3 | 4 | -------------------------------------------------------------------------------- /plugins/wartungsarbeiten/lang/de_de.lang: -------------------------------------------------------------------------------- 1 | perm_general_out5_wartungsarbeiten[] = Rechte für das out5 Addon Plugin: Wartungsarbeiten 2 | -------------------------------------------------------------------------------- /pages/index.php: -------------------------------------------------------------------------------- 1 | i18n('title')); 4 | include rex_be_controller::getCurrentPageObject()->getSubPath(); 5 | -------------------------------------------------------------------------------- /plugins/login_image/assets/out5_login_image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FriendsOfREDAXO/out5/HEAD/plugins/login_image/assets/out5_login_image.jpg -------------------------------------------------------------------------------- /plugins/wartungsarbeiten/README.md: -------------------------------------------------------------------------------- 1 | Leitet nicht im Backend angemeldete Benutzer auf google.de 2 | ========================================================== 3 | -------------------------------------------------------------------------------- /plugins/min/install.php: -------------------------------------------------------------------------------- 1 | hasConfig()) { 6 | $plugin->setConfig('status', 'deaktiviert'); 7 | } 8 | -------------------------------------------------------------------------------- /plugins/email_url/install.php: -------------------------------------------------------------------------------- 1 | hasConfig()) { 5 | $plugin->setConfig('status', 'deaktiviert'); 6 | } 7 | -------------------------------------------------------------------------------- /plugins/login_image/install.php: -------------------------------------------------------------------------------- 1 | hasConfig()) { 6 | $plugin->setConfig('bild', 'out5_login_image.jpg'); 7 | $plugin->setConfig('status', 'deaktiviert'); 8 | } 9 | -------------------------------------------------------------------------------- /plugins/wartungsarbeiten/install.php: -------------------------------------------------------------------------------- 1 | hasConfig()) { 5 | $plugin->setConfig('url', 'http://www.redaxo.org'); 6 | $plugin->setConfig('status', 'deaktiviert'); 7 | } 8 | -------------------------------------------------------------------------------- /plugins/border/install.php: -------------------------------------------------------------------------------- 1 | hasConfig()) { 5 | $plugin->setConfig('text', 'ACHTUNG: Dies ist die Entwicklungsversion'); 6 | $plugin->setConfig('farbe', '#B02F15'); 7 | $plugin->setConfig('status', 'deaktiviert'); 8 | } 9 | 10 | -------------------------------------------------------------------------------- /plugins/wartungsarbeiten/boot.php: -------------------------------------------------------------------------------- 1 | getConfig('status') != 'deaktiviert') { 4 | $session = rex_backend_login::hasSession(); 5 | if (!$session or $this->getConfig('ip')!=$_SERVER['REMOTE_ADDR']) { 6 | header('Location: ' . $this->getConfig('url')); 7 | exit; 8 | } 9 | } 10 | } 11 | 12 | -------------------------------------------------------------------------------- /plugins/structure_separators/install.php: -------------------------------------------------------------------------------- 1 | hasConfig()) { 5 | $plugin->setConfig('sepp', 'sepp: '); 6 | $plugin->setConfig('cssColor', '#283542'); 7 | $plugin->setConfig('cssBackground', '#dfe3e9'); 8 | $plugin->setConfig('status', 'deaktiviert'); 9 | } 10 | -------------------------------------------------------------------------------- /plugins/email_url/pages/index.php: -------------------------------------------------------------------------------- 1 | setVar('class', 'edit'); 9 | $fragment->setVar('title', 'E-Mail / externe Links'); 10 | $fragment->setVar('body', $content, false); 11 | echo $fragment->parse('core/page/section.php'); 12 | -------------------------------------------------------------------------------- /package.yml: -------------------------------------------------------------------------------- 1 | # Alle hier gesetzten Werte können über $addon->getProperty($key) abgefragt werden 2 | 3 | package: out5 4 | version: '1.1.0' 5 | author: Friends Of REDAXO 6 | supportpage: https://github.com/FriendsOfREDAXO/out5 7 | 8 | page: 9 | title: 'out5' 10 | perm: out5[] 11 | icon: rex-icon fa-gears 12 | subpages: 13 | uebersicht: { title: 'Übersicht' } 14 | info: { title: 'Info' } 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | *ACHTUNG*: Dieses AddOn wird nicht mehr weiterentwicklet, da es für alle Funktionen inzwichen bessere Alternativen gibt. 3 | 4 | Outpufilter für REDAXO 5 5 | ======================== 6 | 7 | Das AddOn stellt ein paar kleine Helfer zur Verfügung, die über die Plugins installiert werrden können. 8 | 9 | 10 | -------------------------------------------------------------------------------- /plugins/border/package.yml: -------------------------------------------------------------------------------- 1 | # Alle hier gesetzten Werte können über $addon->getProperty($key) abgefragt werden 2 | 3 | package: out5/border 4 | version: '0.1' 5 | author: Friends Of REDAXO 6 | supportpage: https://github.com/FriendsOfREDAXO/out5 7 | title: 'Border' 8 | nav_icon: fa-minus 9 | kurzbeschreibung: 'Darstellung einer Hinweisleiste am Anfang der Seite.' 10 | umgebung: Backend 11 | 12 | page: 13 | title: 'Border' 14 | hidden: true 15 | -------------------------------------------------------------------------------- /plugins/login_image/package.yml: -------------------------------------------------------------------------------- 1 | # Alle hier gesetzten Werte können über $addon->getProperty($key) abgefragt werden 2 | 3 | package: out5/login_image 4 | version: '0.1' 5 | author: Friends Of REDAXO 6 | supportpage: https://github.com/FriendsOfREDAXO/out5 7 | title: 'Login Image' 8 | nav_icon: fa-image 9 | kurzbeschreibung: 'Darstellung eines Bildes auf der Loginseite' 10 | umgebung: Backend 11 | 12 | page: 13 | title: 'Login Image' 14 | hidden: true 15 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ##### ToDo siehe [ISSUES](https://github.com/FriendsOfREDAXO/out5/issues) ##### 2 | 3 | --- 4 | 5 | ### Changelog ### 6 | 7 | ### 27.08.2017 Version 1.1.0 ### 8 | 9 | - In den Wartungsarbeiten kann nun eine IP hinterlegt werden, die immer Zugriff auf das Frontend erhält 10 | 11 | 12 | ### 25.02.2017 Version 1.0.1 ### 13 | 14 | - Update en_gb.lang - Danke an @ynamite! 15 | 16 | 17 | ### 03.06.2016 Version 1.0 ### 18 | 19 | - FOR Version 1.0 20 | -------------------------------------------------------------------------------- /plugins/min/package.yml: -------------------------------------------------------------------------------- 1 | # Alle hier gesetzten Werte können über $addon->getProperty($key) abgefragt werden 2 | 3 | package: out5/min 4 | version: '0.1' 5 | author: Friends Of REDAXO 6 | supportpage: https://github.com/FriendsOfREDAXO/out5 7 | title: 'min' 8 | nav_icon: fa-file 9 | kurzbeschreibung: 'Komprimiert den augegebenen HTML Code und bietet die Möglichkeit CSS bzw. JS Dateien zusammenzufassen und zu minifizieren.' 10 | umgebung: Frontend 11 | 12 | page: 13 | title: 'min' 14 | hidden: true 15 | -------------------------------------------------------------------------------- /plugins/email_url/package.yml: -------------------------------------------------------------------------------- 1 | # Alle hier gesetzten Werte können über $addon->getProperty($key) abgefragt werden 2 | 3 | package: out5/email_url 4 | version: '0.1' 5 | author: Friends Of REDAXO 6 | supportpage: https://github.com/FriendsOfREDAXO/out5 7 | title: 'E-Mail / Links' 8 | nav_icon: fa-envelope-o 9 | kurzbeschreibung: 'E-Mail-Adressen mit Klasse "email" versehen und verschlüsseln.
Externe URLs mit der Klasse "extern" versehen.' 10 | umgebung: Frontend 11 | 12 | page: 13 | title: 'E-Mail / externe Links' 14 | hidden: true 15 | -------------------------------------------------------------------------------- /plugins/structure_separators/package.yml: -------------------------------------------------------------------------------- 1 | # Alle hier gesetzten Werte können über $addon->getProperty($key) abgefragt werden 2 | 3 | package: out5/structure_separators 4 | version: '0.1' 5 | author: Friends Of REDAXO 6 | supportpage: https://github.com/FriendsOfREDAXO/out5 7 | 8 | supportpage: www.redaxo.org/de/forum 9 | title: 'Structur Separartors' 10 | nav_icon: fa-minus 11 | kurzbeschreibung: 'Ermöglicht es Trenner in der Struktur zu definieren.' 12 | umgebung: Backend 13 | 14 | page: 15 | title: 'Structure Separators' 16 | hidden: true 17 | -------------------------------------------------------------------------------- /plugins/wartungsarbeiten/package.yml: -------------------------------------------------------------------------------- 1 | # Alle hier gesetzten Werte können über $addon->getProperty($key) abgefragt werden 2 | 3 | package: out5/wartungsarbeiten 4 | version: '1.0.0' 5 | author: Friends Of REDAXO 6 | supportpage: https://github.com/FriendsOfREDAXO/out5 7 | title: 'Wartungsarbeiten' 8 | nav_icon: fa-share 9 | kurzbeschreibung: 'Umleitung der Frontendseite auf eine beliebige URL wenn der Besucher nicht im Backend angemeldet ist oder nicht der hintelegten IP entspricht' 10 | umgebung: Frontend 11 | 12 | page: 13 | title: 'Wartungsarbeiten' 14 | hidden: true 15 | -------------------------------------------------------------------------------- /plugins/border/boot.php: -------------------------------------------------------------------------------- 1 | getConfig('status') != 'deaktiviert') { 4 | rex_extension::register('OUTPUT_FILTER',function(rex_extension_point $ep){ 5 | $suchmuster = '
'; 6 | $ersetzen = '
'.$this->getConfig('text').'
'; 7 | $ep->setSubject(str_replace($suchmuster, $ersetzen, $ep->getSubject())); 8 | }); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /plugins/login_image/boot.php: -------------------------------------------------------------------------------- 1 | getConfig('status') != 'deaktiviert') { 4 | rex_extension::register('OUTPUT_FILTER',function(rex_extension_point $ep){ 5 | $filepath = ''; 6 | $bild = $this->getConfig('bild'); 7 | 8 | 9 | 10 | if ($bild != 'out5_login_image.jpg') { 11 | $filepath = 'Bitte anmelden'; 12 | } else { 13 | $filepath = 'Bitte anmelden'; 14 | } 15 | 16 | $suchmuster = '
Bitte anmelden.
'; 17 | $ersetzen = '
'.$filepath.'
'; 18 | $ep->setSubject(str_replace($suchmuster, $ersetzen, $ep->getSubject())); 19 | }); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /pages/info.php: -------------------------------------------------------------------------------- 1 | text($file); 6 | 7 | $fragment = new rex_fragment(); 8 | $fragment->setVar('title', 'Hilfe'); 9 | $fragment->setVar('body', $content, false); 10 | echo $fragment->parse('core/page/section.php'); 11 | 12 | 13 | 14 | $file = rex_file::get(rex_path::addon('out5','CHANGELOG.md')); 15 | $Parsedown = new Parsedown(); 16 | $content = $Parsedown->text($file); 17 | 18 | $fragment = new rex_fragment(); 19 | $fragment->setVar('title', 'Changelog'); 20 | $fragment->setVar('body', $content, false); 21 | echo $fragment->parse('core/page/section.php'); 22 | 23 | 24 | $file = rex_file::get(rex_path::addon('out5','LICENSE.md')); 25 | $Parsedown = new Parsedown(); 26 | $content = $Parsedown->text($file); 27 | 28 | $fragment = new rex_fragment(); 29 | $fragment->setVar('title', 'Lizenz'); 30 | $fragment->setVar('body', $content, false); 31 | echo $fragment->parse('core/page/section.php'); 32 | -------------------------------------------------------------------------------- /plugins/min/pages/index.php: -------------------------------------------------------------------------------- 1 | combinied.min.css im Frontend einbinden

6 |
 7 | $ str = file_get_contents('main.css');
 8 | $ str = $ str.file_get_contents('navigation.css');
 9 | $ str = $ str.file_get_contents('content.css');
10 | $ str = $ str.file_get_contents('media/default.css');
11 | 
12 | 
13 | file_put_contents('./media/combinied.min.css', minify_css($ str));
14 | 
15 | 16 |
17 |

combinied.min.js im Frontend einbinden

18 | 19 |
20 | // if (!file_exists('./assets/js/combinied.js')) {
21 | 
22 | $ str = file_get_contents('./assets/vendor/jquery/domscript.js');
23 | $ str = $ str.file_get_contents('./assets/vendor/jquery/jquery.cookiebar.js');
24 | file_put_contents('./assets/js/domscript.js', minify_js($ str));
25 | 
26 | // }
27 | 
28 | ($ str ohne Leerzeichen) 29 | "; 30 | 31 | 32 | $fragment = new rex_fragment(); 33 | $fragment->setVar('class', 'edit'); 34 | $fragment->setVar('title', 'min'); 35 | $fragment->setVar('body', $content, false); 36 | echo $fragment->parse('core/page/section.php'); 37 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Friends Of REDAXO 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /plugins/border/pages/index.php: -------------------------------------------------------------------------------- 1 | setConfig(rex_post('config', [ 8 | ['text', 'string'], 9 | ['farbe', 'string'], 10 | ])); 11 | 12 | $content .= rex_view::info('Änderung gespeichert'); 13 | } 14 | 15 | $content .= ' 16 |
17 |
18 |
'; 19 | 20 | $formElements = []; 21 | 22 | $n = []; 23 | $n['label'] = ''; 24 | $n['field'] = ''; 25 | $formElements[] = $n; 26 | 27 | $n['label'] = ''; 28 | $n['field'] = ''; 29 | $formElements[] = $n; 30 | 31 | $fragment = new rex_fragment(); 32 | $fragment->setVar('elements', $formElements, false); 33 | $content .= $fragment->parse('core/form/form.php'); 34 | 35 | $content .= ' 36 |
37 | 38 |
'; 39 | 40 | $formElements = []; 41 | 42 | $n = []; 43 | $n['field'] = '
'; 44 | $formElements[] = $n; 45 | 46 | $fragment = new rex_fragment(); 47 | $fragment->setVar('elements', $formElements, false); 48 | $content .= $fragment->parse('core/form/submit.php'); 49 | 50 | $content .= ' 51 |
52 | 53 |
54 |
'; 55 | 56 | $fragment = new rex_fragment(); 57 | $fragment->setVar('class', 'edit'); 58 | $fragment->setVar('title', 'Border - Einstellungen'); 59 | $fragment->setVar('body', $content, false); 60 | echo $fragment->parse('core/page/section.php'); 61 | -------------------------------------------------------------------------------- /plugins/structure_separators/boot.php: -------------------------------------------------------------------------------- 1 | getConfig('status') != 'deaktiviert') { 6 | 7 | if (rex_be_controller::getCurrentPage() == 'structure') { 8 | rex_extension::register('OUTPUT_FILTER', function(rex_extension_point $ep) { 9 | 10 | // settings 11 | // - - - - - - - - - - - - - - - - - - 12 | // separator 13 | $sepp = $this->getConfig('sepp'); 14 | // color 15 | $cssColor = $this->getConfig('cssColor'); 16 | // background 17 | $cssBackground = $this->getConfig('cssBackground'); 18 | // - - - - - - - - - - - - - - - - - - 19 | // settings end 20 | 21 | 22 | $seppClass = preg_replace('/\W+/', '', $sepp); 23 | $html = $ep->getSubject(); 24 | $put = ' 25 | 37 | 52 | '; 53 | $html = str_replace('', $put . '', $html); 54 | $ep->setSubject($html); 55 | 56 | }); 57 | } 58 | 59 | 60 | } 61 | } 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /plugins/wartungsarbeiten/pages/index.php: -------------------------------------------------------------------------------- 1 | setConfig(rex_post('config', [ 8 | ['url', 'string'], 9 | ])); 10 | $plugin->setConfig(rex_post('config', [ 11 | ['ip', 'string'], 12 | ])); 13 | 14 | $content .= rex_view::info('Änderung gespeichert'); 15 | } 16 | 17 | $content .= ' 18 |
19 |
20 |
'; 21 | 22 | $formElements = []; 23 | 24 | $n = []; 25 | $n['label'] = ''; 26 | $n['field'] = ''; 27 | $formElements[] = $n; 28 | 29 | $n1['label'] = ''; 30 | $n1['field'] = 'IP:'.$_SERVER['REMOTE_ADDR'].''; 31 | $formElements[] = $n1; 32 | 33 | 34 | $fragment = new rex_fragment(); 35 | $fragment->setVar('elements', $formElements, false); 36 | $content .= $fragment->parse('core/form/form.php'); 37 | 38 | $content .= ' 39 |
40 | 41 |
'; 42 | 43 | $formElements = []; 44 | 45 | $n = []; 46 | $n['field'] = '
'; 47 | $formElements[] = $n; 48 | 49 | $fragment = new rex_fragment(); 50 | $fragment->setVar('elements', $formElements, false); 51 | $content .= $fragment->parse('core/form/submit.php'); 52 | 53 | $content .= ' 54 |
55 | 56 |
57 |
'; 58 | 59 | $fragment = new rex_fragment(); 60 | $fragment->setVar('class', 'edit'); 61 | $fragment->setVar('title', 'Wartungsarbeiten - Einstellungen'); 62 | $fragment->setVar('body', $content, false); 63 | echo $fragment->parse('core/page/section.php'); 64 | 65 | -------------------------------------------------------------------------------- /plugins/structure_separators/pages/index.php: -------------------------------------------------------------------------------- 1 | setConfig(rex_post('config', [ 8 | ['sepp', 'string'], 9 | ['cssColor', 'string'], 10 | ['cssBackground', 'string'], 11 | ])); 12 | 13 | $content .= rex_view::info('Änderung gespeichert'); 14 | } 15 | 16 | $content .= ' 17 |
18 |
19 |
'; 20 | 21 | $formElements = []; 22 | 23 | $n = []; 24 | $n['label'] = ''; 25 | $n['field'] = ''; 26 | $formElements[] = $n; 27 | 28 | $n['label'] = ''; 29 | $n['field'] = ''; 30 | $formElements[] = $n; 31 | 32 | $n['label'] = ''; 33 | $n['field'] = ''; 34 | $formElements[] = $n; 35 | 36 | 37 | $fragment = new rex_fragment(); 38 | $fragment->setVar('elements', $formElements, false); 39 | $content .= $fragment->parse('core/form/form.php'); 40 | 41 | $content .= ' 42 |
43 | 44 |
'; 45 | 46 | $formElements = []; 47 | 48 | $n = []; 49 | $n['field'] = '
'; 50 | $formElements[] = $n; 51 | 52 | $fragment = new rex_fragment(); 53 | $fragment->setVar('elements', $formElements, false); 54 | $content .= $fragment->parse('core/form/submit.php'); 55 | 56 | $content .= ' 57 |
58 | 59 |
60 |
'; 61 | 62 | $fragment = new rex_fragment(); 63 | $fragment->setVar('class', 'edit'); 64 | $fragment->setVar('title', 'Structure Separator - Einstellungen'); 65 | $fragment->setVar('body', $content, false); 66 | echo $fragment->parse('core/page/section.php'); 67 | -------------------------------------------------------------------------------- /plugins/login_image/pages/index.php: -------------------------------------------------------------------------------- 1 | Hier kann ein anderes Bild als das default Bild angegeben werden.
6 |

Einfach eine .jpg Datei mit den Abmessungen von 340px x 90px aus dem Medienpool auswählen.



'; 7 | 8 | if (rex_post('config-submit', 'boolean')) { 9 | $plugin->setConfig(rex_post('config', [ 10 | ['bild', 'string'], 11 | ])); 12 | 13 | $content .= rex_view::info('Änderung gespeichert'); 14 | } 15 | 16 | $content .= ' 17 |
18 |
19 |
'; 20 | 21 | $formElements = []; 22 | 23 | $n = []; 24 | $n['label'] = ''; 25 | 26 | $n['field'] = ' 27 |
28 |
29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 |
39 | '; 40 | 41 | $formElements[] = $n; 42 | 43 | $fragment = new rex_fragment(); 44 | $fragment->setVar('elements', $formElements, false); 45 | $content .= $fragment->parse('core/form/form.php'); 46 | 47 | $content .= ' 48 |
49 | 50 |
'; 51 | 52 | $formElements = []; 53 | 54 | $n = []; 55 | $n['field'] = ' 56 |
'; 57 | $formElements[] = $n; 58 | 59 | $fragment = new rex_fragment(); 60 | $fragment->setVar('elements', $formElements, false); 61 | $content .= $fragment->parse('core/form/submit.php'); 62 | 63 | $content .= ' 64 |
65 | 66 |
67 |
'; 68 | 69 | $fragment = new rex_fragment(); 70 | $fragment->setVar('class', 'edit'); 71 | $fragment->setVar('title', 'Login Image - Einstellungen'); 72 | $fragment->setVar('body', $content, false); 73 | echo $fragment->parse('core/page/section.php'); 74 | -------------------------------------------------------------------------------- /plugins/email_url/boot.php: -------------------------------------------------------------------------------- 1 | getConfig('status') != 'deaktiviert') { 4 | rex_extension::register('OUTPUT_FILTER',function(rex_extension_point $ep){ 5 | preg_match_all("/]*(href\s*=\s*(\"|')(mailto)(?=:).*?(\"|'))[^>]*>(.*?)<\/a>/ims", $ep->getSubject(), $matches); 6 | // hier jetzt alle gefundenen durchgehen und um klasse erweitern 7 | if ( isset ($matches[0][0]) and $matches[0][0] != '') { 8 | for ($m = 0; $m < count ($matches[0]); $m++) { 9 | $msearch = $matches[0][$m]; 10 | if (strstr($matches[0][$m], 'class=')) { 11 | $mreplace = $matches[0][$m]; 12 | } else { 13 | $mreplace = str_replace('href=', 'class="email" href=', $matches[0][$m]); 14 | } 15 | $ep->setSubject(str_replace($msearch, $mreplace, $ep->getSubject())); 16 | } 17 | } 18 | 19 | // hier jetzt alle gefundenen durchgehen und crypt 20 | if ( isset ($matches[1][0]) and $matches[1][0] != '') { 21 | for ($m = 0; $m < count ($matches[1]); $m++) { 22 | $va = explode('mailto:', $matches[1][$m]); 23 | $originalemail = str_replace('"', '', $va[1]); 24 | 25 | $encryptedemail = ''; 26 | for ($i=0; $i < strlen($originalemail); $i++) { 27 | $encryptedemail .= '&#'.ord(substr($originalemail, $i, 1)).';'; 28 | } 29 | 30 | $msearch = 'mailto:'.$originalemail; 31 | $mreplace = 'mailto:'.str_replace('@', '%40', $encryptedemail); 32 | $ep->getSubject(str_replace($msearch, $mreplace, $ep->getSubject())); 33 | 34 | $msearch = $originalemail; 35 | $mreplace = $encryptedemail; 36 | $ep->setSubject(str_replace($msearch, $mreplace, $ep->getSubject())); 37 | } 38 | } 39 | 40 | /** 41 | * Kennzeichnung externe Links mit Ausnahme 42 | */ 43 | 44 | $excl = array(); 45 | // Von der Ersetzung ausgeschlossen: 46 | // $excl[] = 'href="' . $REX['SERVER']; 47 | // $excl[] = 'href="http://' . $_SERVER['HTTP_HOST']; 48 | // $excl[] = 'href="https://' . $_SERVER['HTTP_HOST']; 49 | // $excl[] = '#top'; 50 | // $excl[] = '#nav'; 51 | // $excl[] = '#mainnav'; 52 | // $excl[] = '#content'; 53 | // $excl[] = 'href="http://www.facebook.com'; 54 | // $excl[] = 'href="http://twitter.com'; 55 | 56 | // hier via regEx alle absoluten, externen Linkadressen heraussuchen 57 | preg_match_all("/]*(href\s*=\s*(\"|')(http(s)?|ftp(s)?|telnet|irc)(?=:\/\/).*?(\"|'))[^>]*>(.*?)<\/a>/ims", $ep->getSubject(), $matches); 58 | 59 | if ( isset ($matches[0][0]) and $matches[0][0] != '') { 60 | $srch = $repl = array(); 61 | for ($m = 0; $m < count ($matches[0]); $m++) { 62 | $msearch = $matches[0][$m]; 63 | if (strstr($matches[0][$m], 'class=')) { 64 | $mreplace = $matches[0][$m]; 65 | } else { 66 | $mreplace = str_replace('href=', 'class="extern" href=', $matches[0][$m]); 67 | } 68 | for ($x = 0; $x < count($excl); $x++) { 69 | if (strstr($matches[1][$m], $excl[$x])) { 70 | $mreplace = $matches[0][$m]; 71 | } 72 | } 73 | $srch[] = $msearch; 74 | $repl[] = $mreplace; 75 | } 76 | $ep->setSubject(str_replace($srch, $repl, $ep->getSubject())); 77 | } 78 | }); 79 | } 80 | } 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /pages/uebersicht.php: -------------------------------------------------------------------------------- 1 | setConfig('status', 'aktiviert'); 12 | } else { 13 | $plugin_temp->setConfig('status', 'deaktiviert'); 14 | } 15 | 16 | 17 | 18 | 19 | $func = ''; 20 | $status = ''; 21 | $plugin = ''; 22 | } 23 | 24 | 25 | if ($func == '') { 26 | $content = ' 27 |
28 |
29 |
Liste der verfügbaren Filter
30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | '; 44 | 45 | $AvailablePlugins = $this->getAvailablePlugins(); 46 | $i=0; 47 | if(!empty($AvailablePlugins)) { 48 | $Page = $this->getProperty('page'); 49 | foreach($AvailablePlugins as $key => $plugin) { 50 | 51 | $i++; 52 | 53 | $icon = $plugin->getProperty('nav_icon'); 54 | if (!$icon) { 55 | $icon = 'fa-cubes'; 56 | } 57 | $title = $plugin->getProperty('title'); 58 | if (!$title) { 59 | $title = $key; 60 | } 61 | $kurzbeschreibung = $plugin->getProperty('kurzbeschreibung'); 62 | if (!$kurzbeschreibung) { 63 | $kurzbeschreibung = $key; 64 | } 65 | $umgebung = $plugin->getProperty('umgebung'); 66 | if (!$umgebung) { 67 | $umgebung = $key; 68 | } 69 | $status = $plugin->getConfig('status'); 70 | if (!$status) { 71 | $status = 'kein Status vergeben'; 72 | } 73 | 74 | rex_perm::register('out5['.$key.']'); // with perms? 75 | $Page['subpages']['main']['subpages'][$key] = [ 76 | 'title' => $title, 77 | 'perm' => 'out5['.$key.']', // with perms? 78 | 'icon' => 'rex-icon '.$icon.'' 79 | ]; 80 | 81 | $content .= ' 82 | 83 | 84 | 87 | 88 | 89 | '; 90 | 91 | if ($status == 'deaktiviert') { 92 | $content .= ' 93 | '; 94 | } else { 95 | $content .= ' 96 | '; 97 | } 98 | 99 | $content .=' 100 | 101 | 102 | '; 103 | 104 | } 105 | $this->setProperty('page',$Page); 106 | } 107 | 108 | $content .= ' 109 | 110 |
NameKurzbeschreibungUmgebungStatus
85 | '.$title.' 86 | '.$kurzbeschreibung.''.$umgebung.''.$status.''.$status.' editieren
111 |
112 |
113 |
114 | '; 115 | 116 | echo $content; 117 | } 118 | -------------------------------------------------------------------------------- /plugins/min/boot.php: -------------------------------------------------------------------------------- 1 | !]+)(?:\s+([^<>]*?)\s*|\s*)(\/?)>#s', function($matches) { 14 | return '<' . $matches[1] . preg_replace('#([^\s=]+)(\=([\'"]?)(.*?)\3)?(\s+|$)#s', ' $1$2', $matches[2]) . $matches[3] . '>'; 15 | }, str_replace("\r", "", $input)); 16 | // Minify inline CSS declaration(s) 17 | if(strpos($input, ' style=') !== false) { 18 | $input = preg_replace_callback('#<([^<]+?)\s+style=([\'"])(.*?)\2(?=[\/\s>])#s', function($matches) { 19 | return '<' . $matches[1] . ' style=' . $matches[2] . minify_css($matches[3]) . $matches[2]; 20 | }, $input); 21 | } 22 | return preg_replace( 23 | array( 24 | // t = text 25 | // o = tag open 26 | // c = tag close 27 | // Keep important white-space(s) after self-closing HTML tag(s) 28 | '#<(img|input)(>| .*?>)#s', 29 | // Remove a line break and two or more white-space(s) between tag(s) 30 | '#()|(>)(?:\n*|\s{2,})(<)|^\s*|\s*$#s', 31 | '#()|(?)\s+(<\/.*?>)|(<[^\/]*?>)\s+(?!\<)#s', // t+c || o+t 32 | '#()|(<[^\/]*?>)\s+(<[^\/]*?>)|(<\/.*?>)\s+(<\/.*?>)#s', // o+o || c+c 33 | '#()|(<\/.*?>)\s+(\s)(?!\<)|(?)\s+(\s)(<[^\/]*?\/?>)|(<[^\/]*?\/?>)\s+(\s)(?!\<)#s', // c+t || t+o || o+t -- separated by long white-space(s) 34 | '#()|(<[^\/]*?>)\s+(<\/.*?>)#s', // empty tag 35 | '#<(img|input)(>| .*?>)<\/\1>#s', // reset previous fix 36 | '#( ) (?![<\s])#', // clean up ... 37 | '#(?<=\>)( )(?=\<)#', // --ibid 38 | // Remove HTML comment(s) except IE comment(s) 39 | '#\s*\s*|(?)\n+(?=\<[^!])#s' 40 | ), 41 | array( 42 | '<$1$2', 43 | '$1$2$3', 44 | '$1$2$3', 45 | '$1$2$3$4$5', 46 | '$1$2$3$4$5$6$7', 47 | '$1$2$3', 48 | '<$1$2', 49 | '$1 ', 50 | '$1', 51 | "" 52 | ), 53 | $input); 54 | } 55 | // CSS Minifier => http://ideone.com/Q5USEF + improvement(s) 56 | function minify_css($input) { 57 | if(trim($input) === "") return $input; 58 | return preg_replace( 59 | array( 60 | // Remove comment(s) 61 | '#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')|\/\*(?!\!)(?>.*?\*\/)|^\s*|\s*$#s', 62 | // Remove unused white-space(s) 63 | '#("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\'|\/\*(?>.*?\*\/))|\s*+;\s*+(})\s*+|\s*+([*$~^|]?+=|[{};,>~+]|\s*+-(?![0-9\.])|!important\b)\s*+|([[(:])\s++|\s++([])])|\s++(:)\s*+(?!(?>[^{}"\']++|"(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')*+{)|^\s++|\s++\z|(\s)\s+#si', 64 | // Replace `0(cm|em|ex|in|mm|pc|pt|px|vh|vw|%)` with `0` 65 | '#(?<=[\s:])(0)(cm|em|ex|in|mm|pc|pt|px|vh|vw|%)#si', 66 | // Replace `:0 0 0 0` with `:0` 67 | '#:(0\s+0|0\s+0\s+0\s+0)(?=[;\}]|\!important)#i', 68 | // Replace `background-position:0` with `background-position:0 0` 69 | '#(background-position):0(?=[;\}])#si', 70 | // Replace `0.6` with `.6`, but only when preceded by `:`, `,`, `-` or a white-space 71 | '#(?<=[\s:,\-])0+\.(\d+)#s', 72 | // Minify string value 73 | '#(\/\*(?>.*?\*\/))|(?.*?\*\/))|(\burl\()([\'"])([^\s]+?)\3(\))#si', 75 | // Minify HEX color code 76 | '#(?<=[\s:,\-]\#)([a-f0-6]+)\1([a-f0-6]+)\2([a-f0-6]+)\3#i', 77 | // Replace `(border|outline):none` with `(border|outline):0` 78 | '#(?<=[\{;])(border|outline):none(?=[;\}\!])#', 79 | // Remove empty selector(s) 80 | '#(\/\*(?>.*?\*\/))|(^|[\{\}])(?:[^\s\{\}]+)\{\}#s' 81 | ), 82 | array( 83 | '$1', 84 | '$1$2$3$4$5$6$7', 85 | '$1', 86 | ':0', 87 | '$1:0 0', 88 | '.$1', 89 | '$1$3', 90 | '$1$2$4$5', 91 | '$1$2$3', 92 | '$1:0', 93 | '$1$2' 94 | ), 95 | $input); 96 | } 97 | // JavaScript Minifier 98 | function minify_js($input) { 99 | if(trim($input) === "") return $input; 100 | return preg_replace( 101 | array( 102 | // Remove comment(s) 103 | '#\s*("(?:[^"\\\]++|\\\.)*+"|\'(?:[^\'\\\\]++|\\\.)*+\')\s*|\s*\/\*(?!\!|@cc_on)(?>[\s\S]*?\*\/)\s*|\s*(?.*?\*\/)|\/(?!\/)[^\n\r]*?\/(?=[\s.,;]|[gimuy]|$))|\s*([!%&*\(\)\-=+\[\]\{\}|;:,.<>?\/])\s*#s', 106 | // Remove the last semicolon 107 | '#;+\}#', 108 | // Minify object attribute(s) except JSON attribute(s). From `{'foo':'bar'}` to `{foo:'bar'}` 109 | '#([\{,])([\'])(\d+|[a-z_][a-z0-9_]*)\2(?=\:)#i', 110 | // --ibid. From `foo['bar']` to `foo.bar` 111 | '#([a-z0-9_\)\]])\[([\'"])([a-z_][a-z0-9_]*)\2\]#i' 112 | ), 113 | array( 114 | '$1', 115 | '$1$2', 116 | '}', 117 | '$1$3', 118 | '$1.$3' 119 | ), 120 | $input); 121 | } 122 | 123 | if ($this->getConfig('status') != 'deaktiviert') { 124 | rex_extension::register('OUTPUT_FILTER',function(rex_extension_point $ep){ 125 | $ep->setSubject(minify_html($ep->getSubject())); 126 | }); 127 | } 128 | 129 | 130 | } 131 | -------------------------------------------------------------------------------- /lib/class.parsedown.inc.php: -------------------------------------------------------------------------------- 1 | DefinitionData = array(); 28 | 29 | # standardize line breaks 30 | $text = str_replace(array("\r\n", "\r"), "\n", $text); 31 | 32 | # remove surrounding line breaks 33 | $text = trim($text, "\n"); 34 | 35 | # split text into lines 36 | $lines = explode("\n", $text); 37 | 38 | # iterate through lines to identify blocks 39 | $markup = $this->lines($lines); 40 | 41 | # trim line breaks 42 | $markup = trim($markup, "\n"); 43 | 44 | return $markup; 45 | } 46 | 47 | # 48 | # Setters 49 | # 50 | 51 | function setBreaksEnabled($breaksEnabled) 52 | { 53 | $this->breaksEnabled = $breaksEnabled; 54 | 55 | return $this; 56 | } 57 | 58 | protected $breaksEnabled; 59 | 60 | function setMarkupEscaped($markupEscaped) 61 | { 62 | $this->markupEscaped = $markupEscaped; 63 | 64 | return $this; 65 | } 66 | 67 | protected $markupEscaped; 68 | 69 | function setUrlsLinked($urlsLinked) 70 | { 71 | $this->urlsLinked = $urlsLinked; 72 | 73 | return $this; 74 | } 75 | 76 | protected $urlsLinked = true; 77 | 78 | # 79 | # Lines 80 | # 81 | 82 | protected $BlockTypes = array( 83 | '#' => array('Header'), 84 | '*' => array('Rule', 'List'), 85 | '+' => array('List'), 86 | '-' => array('SetextHeader', 'Table', 'Rule', 'List'), 87 | '0' => array('List'), 88 | '1' => array('List'), 89 | '2' => array('List'), 90 | '3' => array('List'), 91 | '4' => array('List'), 92 | '5' => array('List'), 93 | '6' => array('List'), 94 | '7' => array('List'), 95 | '8' => array('List'), 96 | '9' => array('List'), 97 | ':' => array('Table'), 98 | '<' => array('Comment', 'Markup'), 99 | '=' => array('SetextHeader'), 100 | '>' => array('Quote'), 101 | '[' => array('Reference'), 102 | '_' => array('Rule'), 103 | '`' => array('FencedCode'), 104 | '|' => array('Table'), 105 | '~' => array('FencedCode'), 106 | ); 107 | 108 | # ~ 109 | 110 | protected $unmarkedBlockTypes = array( 111 | 'Code', 112 | ); 113 | 114 | # 115 | # Blocks 116 | # 117 | 118 | protected function lines(array $lines) 119 | { 120 | $CurrentBlock = null; 121 | 122 | foreach ($lines as $line) 123 | { 124 | if (chop($line) === '') 125 | { 126 | if (isset($CurrentBlock)) 127 | { 128 | $CurrentBlock['interrupted'] = true; 129 | } 130 | 131 | continue; 132 | } 133 | 134 | if (strpos($line, "\t") !== false) 135 | { 136 | $parts = explode("\t", $line); 137 | 138 | $line = $parts[0]; 139 | 140 | unset($parts[0]); 141 | 142 | foreach ($parts as $part) 143 | { 144 | $shortage = 4 - mb_strlen($line, 'utf-8') % 4; 145 | 146 | $line .= str_repeat(' ', $shortage); 147 | $line .= $part; 148 | } 149 | } 150 | 151 | $indent = 0; 152 | 153 | while (isset($line[$indent]) and $line[$indent] === ' ') 154 | { 155 | $indent ++; 156 | } 157 | 158 | $text = $indent > 0 ? substr($line, $indent) : $line; 159 | 160 | # ~ 161 | 162 | $Line = array('body' => $line, 'indent' => $indent, 'text' => $text); 163 | 164 | # ~ 165 | 166 | if (isset($CurrentBlock['continuable'])) 167 | { 168 | $Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock); 169 | 170 | if (isset($Block)) 171 | { 172 | $CurrentBlock = $Block; 173 | 174 | continue; 175 | } 176 | else 177 | { 178 | if ($this->isBlockCompletable($CurrentBlock['type'])) 179 | { 180 | $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock); 181 | } 182 | } 183 | } 184 | 185 | # ~ 186 | 187 | $marker = $text[0]; 188 | 189 | # ~ 190 | 191 | $blockTypes = $this->unmarkedBlockTypes; 192 | 193 | if (isset($this->BlockTypes[$marker])) 194 | { 195 | foreach ($this->BlockTypes[$marker] as $blockType) 196 | { 197 | $blockTypes []= $blockType; 198 | } 199 | } 200 | 201 | # 202 | # ~ 203 | 204 | foreach ($blockTypes as $blockType) 205 | { 206 | $Block = $this->{'block'.$blockType}($Line, $CurrentBlock); 207 | 208 | if (isset($Block)) 209 | { 210 | $Block['type'] = $blockType; 211 | 212 | if ( ! isset($Block['identified'])) 213 | { 214 | $Blocks []= $CurrentBlock; 215 | 216 | $Block['identified'] = true; 217 | } 218 | 219 | if ($this->isBlockContinuable($blockType)) 220 | { 221 | $Block['continuable'] = true; 222 | } 223 | 224 | $CurrentBlock = $Block; 225 | 226 | continue 2; 227 | } 228 | } 229 | 230 | # ~ 231 | 232 | if (isset($CurrentBlock) and ! isset($CurrentBlock['type']) and ! isset($CurrentBlock['interrupted'])) 233 | { 234 | $CurrentBlock['element']['text'] .= "\n".$text; 235 | } 236 | else 237 | { 238 | $Blocks []= $CurrentBlock; 239 | 240 | $CurrentBlock = $this->paragraph($Line); 241 | 242 | $CurrentBlock['identified'] = true; 243 | } 244 | } 245 | 246 | # ~ 247 | 248 | if (isset($CurrentBlock['continuable']) and $this->isBlockCompletable($CurrentBlock['type'])) 249 | { 250 | $CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock); 251 | } 252 | 253 | # ~ 254 | 255 | $Blocks []= $CurrentBlock; 256 | 257 | unset($Blocks[0]); 258 | 259 | # ~ 260 | 261 | $markup = ''; 262 | 263 | foreach ($Blocks as $Block) 264 | { 265 | if (isset($Block['hidden'])) 266 | { 267 | continue; 268 | } 269 | 270 | $markup .= "\n"; 271 | $markup .= isset($Block['markup']) ? $Block['markup'] : $this->element($Block['element']); 272 | } 273 | 274 | $markup .= "\n"; 275 | 276 | # ~ 277 | 278 | return $markup; 279 | } 280 | 281 | # 282 | # Allow for plugin extensibility 283 | # 284 | protected function isBlockContinuable($Type) 285 | { 286 | return method_exists($this, 'block'.$Type.'Continue'); 287 | } 288 | 289 | protected function isBlockCompletable($Type) 290 | { 291 | return method_exists($this, 'block'.$Type.'Complete'); 292 | } 293 | 294 | # 295 | # Code 296 | 297 | protected function blockCode($Line, $Block = null) 298 | { 299 | if (isset($Block) and ! isset($Block['type']) and ! isset($Block['interrupted'])) 300 | { 301 | return; 302 | } 303 | 304 | if ($Line['indent'] >= 4) 305 | { 306 | $text = substr($Line['body'], 4); 307 | 308 | $Block = array( 309 | 'element' => array( 310 | 'name' => 'pre', 311 | 'handler' => 'element', 312 | 'text' => array( 313 | 'name' => 'code', 314 | 'text' => $text, 315 | ), 316 | ), 317 | ); 318 | 319 | return $Block; 320 | } 321 | } 322 | 323 | protected function blockCodeContinue($Line, $Block) 324 | { 325 | if ($Line['indent'] >= 4) 326 | { 327 | if (isset($Block['interrupted'])) 328 | { 329 | $Block['element']['text']['text'] .= "\n"; 330 | 331 | unset($Block['interrupted']); 332 | } 333 | 334 | $Block['element']['text']['text'] .= "\n"; 335 | 336 | $text = substr($Line['body'], 4); 337 | 338 | $Block['element']['text']['text'] .= $text; 339 | 340 | return $Block; 341 | } 342 | } 343 | 344 | protected function blockCodeComplete($Block) 345 | { 346 | $text = $Block['element']['text']['text']; 347 | 348 | $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8'); 349 | 350 | $Block['element']['text']['text'] = $text; 351 | 352 | return $Block; 353 | } 354 | 355 | # 356 | # Comment 357 | 358 | protected function blockComment($Line) 359 | { 360 | if ($this->markupEscaped) 361 | { 362 | return; 363 | } 364 | 365 | if (isset($Line['text'][3]) and $Line['text'][3] === '-' and $Line['text'][2] === '-' and $Line['text'][1] === '!') 366 | { 367 | $Block = array( 368 | 'markup' => $Line['body'], 369 | ); 370 | 371 | if (preg_match('/-->$/', $Line['text'])) 372 | { 373 | $Block['closed'] = true; 374 | } 375 | 376 | return $Block; 377 | } 378 | } 379 | 380 | protected function blockCommentContinue($Line, array $Block) 381 | { 382 | if (isset($Block['closed'])) 383 | { 384 | return; 385 | } 386 | 387 | $Block['markup'] .= "\n" . $Line['body']; 388 | 389 | if (preg_match('/-->$/', $Line['text'])) 390 | { 391 | $Block['closed'] = true; 392 | } 393 | 394 | return $Block; 395 | } 396 | 397 | # 398 | # Fenced Code 399 | 400 | protected function blockFencedCode($Line) 401 | { 402 | if (preg_match('/^['.$Line['text'][0].']{3,}[ ]*([\w-]+)?[ ]*$/', $Line['text'], $matches)) 403 | { 404 | $Element = array( 405 | 'name' => 'code', 406 | 'text' => '', 407 | ); 408 | 409 | if (isset($matches[1])) 410 | { 411 | $class = 'language-'.$matches[1]; 412 | 413 | $Element['attributes'] = array( 414 | 'class' => $class, 415 | ); 416 | } 417 | 418 | $Block = array( 419 | 'char' => $Line['text'][0], 420 | 'element' => array( 421 | 'name' => 'pre', 422 | 'handler' => 'element', 423 | 'text' => $Element, 424 | ), 425 | ); 426 | 427 | return $Block; 428 | } 429 | } 430 | 431 | protected function blockFencedCodeContinue($Line, $Block) 432 | { 433 | if (isset($Block['complete'])) 434 | { 435 | return; 436 | } 437 | 438 | if (isset($Block['interrupted'])) 439 | { 440 | $Block['element']['text']['text'] .= "\n"; 441 | 442 | unset($Block['interrupted']); 443 | } 444 | 445 | if (preg_match('/^'.$Block['char'].'{3,}[ ]*$/', $Line['text'])) 446 | { 447 | $Block['element']['text']['text'] = substr($Block['element']['text']['text'], 1); 448 | 449 | $Block['complete'] = true; 450 | 451 | return $Block; 452 | } 453 | 454 | $Block['element']['text']['text'] .= "\n".$Line['body'];; 455 | 456 | return $Block; 457 | } 458 | 459 | protected function blockFencedCodeComplete($Block) 460 | { 461 | $text = $Block['element']['text']['text']; 462 | 463 | $text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8'); 464 | 465 | $Block['element']['text']['text'] = $text; 466 | 467 | return $Block; 468 | } 469 | 470 | # 471 | # Header 472 | 473 | protected function blockHeader($Line) 474 | { 475 | if (isset($Line['text'][1])) 476 | { 477 | $level = 1; 478 | 479 | while (isset($Line['text'][$level]) and $Line['text'][$level] === '#') 480 | { 481 | $level ++; 482 | } 483 | 484 | if ($level > 6) 485 | { 486 | return; 487 | } 488 | 489 | $text = trim($Line['text'], '# '); 490 | 491 | $Block = array( 492 | 'element' => array( 493 | 'name' => 'h' . min(6, $level), 494 | 'text' => $text, 495 | 'handler' => 'line', 496 | ), 497 | ); 498 | 499 | return $Block; 500 | } 501 | } 502 | 503 | # 504 | # List 505 | 506 | protected function blockList($Line) 507 | { 508 | list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]+[.]'); 509 | 510 | if (preg_match('/^('.$pattern.'[ ]+)(.*)/', $Line['text'], $matches)) 511 | { 512 | $Block = array( 513 | 'indent' => $Line['indent'], 514 | 'pattern' => $pattern, 515 | 'element' => array( 516 | 'name' => $name, 517 | 'handler' => 'elements', 518 | ), 519 | ); 520 | 521 | $Block['li'] = array( 522 | 'name' => 'li', 523 | 'handler' => 'li', 524 | 'text' => array( 525 | $matches[2], 526 | ), 527 | ); 528 | 529 | $Block['element']['text'] []= & $Block['li']; 530 | 531 | return $Block; 532 | } 533 | } 534 | 535 | protected function blockListContinue($Line, array $Block) 536 | { 537 | if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches)) 538 | { 539 | if (isset($Block['interrupted'])) 540 | { 541 | $Block['li']['text'] []= ''; 542 | 543 | unset($Block['interrupted']); 544 | } 545 | 546 | unset($Block['li']); 547 | 548 | $text = isset($matches[1]) ? $matches[1] : ''; 549 | 550 | $Block['li'] = array( 551 | 'name' => 'li', 552 | 'handler' => 'li', 553 | 'text' => array( 554 | $text, 555 | ), 556 | ); 557 | 558 | $Block['element']['text'] []= & $Block['li']; 559 | 560 | return $Block; 561 | } 562 | 563 | if ($Line['text'][0] === '[' and $this->blockReference($Line)) 564 | { 565 | return $Block; 566 | } 567 | 568 | if ( ! isset($Block['interrupted'])) 569 | { 570 | $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); 571 | 572 | $Block['li']['text'] []= $text; 573 | 574 | return $Block; 575 | } 576 | 577 | if ($Line['indent'] > 0) 578 | { 579 | $Block['li']['text'] []= ''; 580 | 581 | $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); 582 | 583 | $Block['li']['text'] []= $text; 584 | 585 | unset($Block['interrupted']); 586 | 587 | return $Block; 588 | } 589 | } 590 | 591 | # 592 | # Quote 593 | 594 | protected function blockQuote($Line) 595 | { 596 | if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches)) 597 | { 598 | $Block = array( 599 | 'element' => array( 600 | 'name' => 'blockquote', 601 | 'handler' => 'lines', 602 | 'text' => (array) $matches[1], 603 | ), 604 | ); 605 | 606 | return $Block; 607 | } 608 | } 609 | 610 | protected function blockQuoteContinue($Line, array $Block) 611 | { 612 | if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches)) 613 | { 614 | if (isset($Block['interrupted'])) 615 | { 616 | $Block['element']['text'] []= ''; 617 | 618 | unset($Block['interrupted']); 619 | } 620 | 621 | $Block['element']['text'] []= $matches[1]; 622 | 623 | return $Block; 624 | } 625 | 626 | if ( ! isset($Block['interrupted'])) 627 | { 628 | $Block['element']['text'] []= $Line['text']; 629 | 630 | return $Block; 631 | } 632 | } 633 | 634 | # 635 | # Rule 636 | 637 | protected function blockRule($Line) 638 | { 639 | if (preg_match('/^(['.$Line['text'][0].'])([ ]*\1){2,}[ ]*$/', $Line['text'])) 640 | { 641 | $Block = array( 642 | 'element' => array( 643 | 'name' => 'hr' 644 | ), 645 | ); 646 | 647 | return $Block; 648 | } 649 | } 650 | 651 | # 652 | # Setext 653 | 654 | protected function blockSetextHeader($Line, array $Block = null) 655 | { 656 | if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted'])) 657 | { 658 | return; 659 | } 660 | 661 | if (chop($Line['text'], $Line['text'][0]) === '') 662 | { 663 | $Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2'; 664 | 665 | return $Block; 666 | } 667 | } 668 | 669 | # 670 | # Markup 671 | 672 | protected function blockMarkup($Line) 673 | { 674 | if ($this->markupEscaped) 675 | { 676 | return; 677 | } 678 | 679 | if (preg_match('/^<(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches)) 680 | { 681 | $element = strtolower($matches[1]); 682 | 683 | if (in_array($element, $this->textLevelElements)) 684 | { 685 | return; 686 | } 687 | 688 | $Block = array( 689 | 'name' => $matches[1], 690 | 'depth' => 0, 691 | 'markup' => $Line['text'], 692 | ); 693 | 694 | $length = strlen($matches[0]); 695 | 696 | $remainder = substr($Line['text'], $length); 697 | 698 | if (trim($remainder) === '') 699 | { 700 | if (isset($matches[2]) or in_array($matches[1], $this->voidElements)) 701 | { 702 | $Block['closed'] = true; 703 | 704 | $Block['void'] = true; 705 | } 706 | } 707 | else 708 | { 709 | if (isset($matches[2]) or in_array($matches[1], $this->voidElements)) 710 | { 711 | return; 712 | } 713 | 714 | if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder)) 715 | { 716 | $Block['closed'] = true; 717 | } 718 | } 719 | 720 | return $Block; 721 | } 722 | } 723 | 724 | protected function blockMarkupContinue($Line, array $Block) 725 | { 726 | if (isset($Block['closed'])) 727 | { 728 | return; 729 | } 730 | 731 | if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open 732 | { 733 | $Block['depth'] ++; 734 | } 735 | 736 | if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close 737 | { 738 | if ($Block['depth'] > 0) 739 | { 740 | $Block['depth'] --; 741 | } 742 | else 743 | { 744 | $Block['closed'] = true; 745 | } 746 | } 747 | 748 | if (isset($Block['interrupted'])) 749 | { 750 | $Block['markup'] .= "\n"; 751 | 752 | unset($Block['interrupted']); 753 | } 754 | 755 | $Block['markup'] .= "\n".$Line['body']; 756 | 757 | return $Block; 758 | } 759 | 760 | # 761 | # Reference 762 | 763 | protected function blockReference($Line) 764 | { 765 | if (preg_match('/^\[(.+?)\]:[ ]*?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches)) 766 | { 767 | $id = strtolower($matches[1]); 768 | 769 | $Data = array( 770 | 'url' => $matches[2], 771 | 'title' => null, 772 | ); 773 | 774 | if (isset($matches[3])) 775 | { 776 | $Data['title'] = $matches[3]; 777 | } 778 | 779 | $this->DefinitionData['Reference'][$id] = $Data; 780 | 781 | $Block = array( 782 | 'hidden' => true, 783 | ); 784 | 785 | return $Block; 786 | } 787 | } 788 | 789 | # 790 | # Table 791 | 792 | protected function blockTable($Line, array $Block = null) 793 | { 794 | if ( ! isset($Block) or isset($Block['type']) or isset($Block['interrupted'])) 795 | { 796 | return; 797 | } 798 | 799 | if (strpos($Block['element']['text'], '|') !== false and chop($Line['text'], ' -:|') === '') 800 | { 801 | $alignments = array(); 802 | 803 | $divider = $Line['text']; 804 | 805 | $divider = trim($divider); 806 | $divider = trim($divider, '|'); 807 | 808 | $dividerCells = explode('|', $divider); 809 | 810 | foreach ($dividerCells as $dividerCell) 811 | { 812 | $dividerCell = trim($dividerCell); 813 | 814 | if ($dividerCell === '') 815 | { 816 | continue; 817 | } 818 | 819 | $alignment = null; 820 | 821 | if ($dividerCell[0] === ':') 822 | { 823 | $alignment = 'left'; 824 | } 825 | 826 | if (substr($dividerCell, - 1) === ':') 827 | { 828 | $alignment = $alignment === 'left' ? 'center' : 'right'; 829 | } 830 | 831 | $alignments []= $alignment; 832 | } 833 | 834 | # ~ 835 | 836 | $HeaderElements = array(); 837 | 838 | $header = $Block['element']['text']; 839 | 840 | $header = trim($header); 841 | $header = trim($header, '|'); 842 | 843 | $headerCells = explode('|', $header); 844 | 845 | foreach ($headerCells as $index => $headerCell) 846 | { 847 | $headerCell = trim($headerCell); 848 | 849 | $HeaderElement = array( 850 | 'name' => 'th', 851 | 'text' => $headerCell, 852 | 'handler' => 'line', 853 | ); 854 | 855 | if (isset($alignments[$index])) 856 | { 857 | $alignment = $alignments[$index]; 858 | 859 | $HeaderElement['attributes'] = array( 860 | 'style' => 'text-align: '.$alignment.';', 861 | ); 862 | } 863 | 864 | $HeaderElements []= $HeaderElement; 865 | } 866 | 867 | # ~ 868 | 869 | $Block = array( 870 | 'alignments' => $alignments, 871 | 'identified' => true, 872 | 'element' => array( 873 | 'name' => 'table', 874 | 'handler' => 'elements', 875 | ), 876 | ); 877 | 878 | $Block['element']['text'] []= array( 879 | 'name' => 'thead', 880 | 'handler' => 'elements', 881 | ); 882 | 883 | $Block['element']['text'] []= array( 884 | 'name' => 'tbody', 885 | 'handler' => 'elements', 886 | 'text' => array(), 887 | ); 888 | 889 | $Block['element']['text'][0]['text'] []= array( 890 | 'name' => 'tr', 891 | 'handler' => 'elements', 892 | 'text' => $HeaderElements, 893 | ); 894 | 895 | return $Block; 896 | } 897 | } 898 | 899 | protected function blockTableContinue($Line, array $Block) 900 | { 901 | if (isset($Block['interrupted'])) 902 | { 903 | return; 904 | } 905 | 906 | if ($Line['text'][0] === '|' or strpos($Line['text'], '|')) 907 | { 908 | $Elements = array(); 909 | 910 | $row = $Line['text']; 911 | 912 | $row = trim($row); 913 | $row = trim($row, '|'); 914 | 915 | preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches); 916 | 917 | foreach ($matches[0] as $index => $cell) 918 | { 919 | $cell = trim($cell); 920 | 921 | $Element = array( 922 | 'name' => 'td', 923 | 'handler' => 'line', 924 | 'text' => $cell, 925 | ); 926 | 927 | if (isset($Block['alignments'][$index])) 928 | { 929 | $Element['attributes'] = array( 930 | 'style' => 'text-align: '.$Block['alignments'][$index].';', 931 | ); 932 | } 933 | 934 | $Elements []= $Element; 935 | } 936 | 937 | $Element = array( 938 | 'name' => 'tr', 939 | 'handler' => 'elements', 940 | 'text' => $Elements, 941 | ); 942 | 943 | $Block['element']['text'][1]['text'] []= $Element; 944 | 945 | return $Block; 946 | } 947 | } 948 | 949 | # 950 | # ~ 951 | # 952 | 953 | protected function paragraph($Line) 954 | { 955 | $Block = array( 956 | 'element' => array( 957 | 'name' => 'p', 958 | 'text' => $Line['text'], 959 | 'handler' => 'line', 960 | ), 961 | ); 962 | 963 | return $Block; 964 | } 965 | 966 | # 967 | # Inline Elements 968 | # 969 | 970 | protected $InlineTypes = array( 971 | '"' => array('SpecialCharacter'), 972 | '!' => array('Image'), 973 | '&' => array('SpecialCharacter'), 974 | '*' => array('Emphasis'), 975 | ':' => array('Url'), 976 | '<' => array('UrlTag', 'EmailTag', 'Markup', 'SpecialCharacter'), 977 | '>' => array('SpecialCharacter'), 978 | '[' => array('Link'), 979 | '_' => array('Emphasis'), 980 | '`' => array('Code'), 981 | '~' => array('Strikethrough'), 982 | '\\' => array('EscapeSequence'), 983 | ); 984 | 985 | # ~ 986 | 987 | protected $inlineMarkerList = '!"*_&[:<>`~\\'; 988 | 989 | # 990 | # ~ 991 | # 992 | 993 | public function line($text) 994 | { 995 | $markup = ''; 996 | 997 | # $excerpt is based on the first occurrence of a marker 998 | 999 | while ($excerpt = strpbrk($text, $this->inlineMarkerList)) 1000 | { 1001 | $marker = $excerpt[0]; 1002 | 1003 | $markerPosition = strpos($text, $marker); 1004 | 1005 | $Excerpt = array('text' => $excerpt, 'context' => $text); 1006 | 1007 | foreach ($this->InlineTypes[$marker] as $inlineType) 1008 | { 1009 | $Inline = $this->{'inline'.$inlineType}($Excerpt); 1010 | 1011 | if ( ! isset($Inline)) 1012 | { 1013 | continue; 1014 | } 1015 | 1016 | # makes sure that the inline belongs to "our" marker 1017 | 1018 | if (isset($Inline['position']) and $Inline['position'] > $markerPosition) 1019 | { 1020 | continue; 1021 | } 1022 | 1023 | # sets a default inline position 1024 | 1025 | if ( ! isset($Inline['position'])) 1026 | { 1027 | $Inline['position'] = $markerPosition; 1028 | } 1029 | 1030 | # the text that comes before the inline 1031 | $unmarkedText = substr($text, 0, $Inline['position']); 1032 | 1033 | # compile the unmarked text 1034 | $markup .= $this->unmarkedText($unmarkedText); 1035 | 1036 | # compile the inline 1037 | $markup .= isset($Inline['markup']) ? $Inline['markup'] : $this->element($Inline['element']); 1038 | 1039 | # remove the examined text 1040 | $text = substr($text, $Inline['position'] + $Inline['extent']); 1041 | 1042 | continue 2; 1043 | } 1044 | 1045 | # the marker does not belong to an inline 1046 | 1047 | $unmarkedText = substr($text, 0, $markerPosition + 1); 1048 | 1049 | $markup .= $this->unmarkedText($unmarkedText); 1050 | 1051 | $text = substr($text, $markerPosition + 1); 1052 | } 1053 | 1054 | $markup .= $this->unmarkedText($text); 1055 | 1056 | return $markup; 1057 | } 1058 | 1059 | # 1060 | # ~ 1061 | # 1062 | 1063 | protected function inlineCode($Excerpt) 1064 | { 1065 | $marker = $Excerpt['text'][0]; 1066 | 1067 | if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(? strlen($matches[0]), 1075 | 'element' => array( 1076 | 'name' => 'code', 1077 | 'text' => $text, 1078 | ), 1079 | ); 1080 | } 1081 | } 1082 | 1083 | protected function inlineEmailTag($Excerpt) 1084 | { 1085 | if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $Excerpt['text'], $matches)) 1086 | { 1087 | $url = $matches[1]; 1088 | 1089 | if ( ! isset($matches[2])) 1090 | { 1091 | $url = 'mailto:' . $url; 1092 | } 1093 | 1094 | return array( 1095 | 'extent' => strlen($matches[0]), 1096 | 'element' => array( 1097 | 'name' => 'a', 1098 | 'text' => $matches[1], 1099 | 'attributes' => array( 1100 | 'href' => $url, 1101 | ), 1102 | ), 1103 | ); 1104 | } 1105 | } 1106 | 1107 | protected function inlineEmphasis($Excerpt) 1108 | { 1109 | if ( ! isset($Excerpt['text'][1])) 1110 | { 1111 | return; 1112 | } 1113 | 1114 | $marker = $Excerpt['text'][0]; 1115 | 1116 | if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches)) 1117 | { 1118 | $emphasis = 'strong'; 1119 | } 1120 | elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches)) 1121 | { 1122 | $emphasis = 'em'; 1123 | } 1124 | else 1125 | { 1126 | return; 1127 | } 1128 | 1129 | return array( 1130 | 'extent' => strlen($matches[0]), 1131 | 'element' => array( 1132 | 'name' => $emphasis, 1133 | 'handler' => 'line', 1134 | 'text' => $matches[1], 1135 | ), 1136 | ); 1137 | } 1138 | 1139 | protected function inlineEscapeSequence($Excerpt) 1140 | { 1141 | if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters)) 1142 | { 1143 | return array( 1144 | 'markup' => $Excerpt['text'][1], 1145 | 'extent' => 2, 1146 | ); 1147 | } 1148 | } 1149 | 1150 | protected function inlineImage($Excerpt) 1151 | { 1152 | if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[') 1153 | { 1154 | return; 1155 | } 1156 | 1157 | $Excerpt['text']= substr($Excerpt['text'], 1); 1158 | 1159 | $Link = $this->inlineLink($Excerpt); 1160 | 1161 | if ($Link === null) 1162 | { 1163 | return; 1164 | } 1165 | 1166 | $Inline = array( 1167 | 'extent' => $Link['extent'] + 1, 1168 | 'element' => array( 1169 | 'name' => 'img', 1170 | 'attributes' => array( 1171 | 'src' => $Link['element']['attributes']['href'], 1172 | 'alt' => $Link['element']['text'], 1173 | ), 1174 | ), 1175 | ); 1176 | 1177 | $Inline['element']['attributes'] += $Link['element']['attributes']; 1178 | 1179 | unset($Inline['element']['attributes']['href']); 1180 | 1181 | return $Inline; 1182 | } 1183 | 1184 | protected function inlineLink($Excerpt) 1185 | { 1186 | $Element = array( 1187 | 'name' => 'a', 1188 | 'handler' => 'line', 1189 | 'text' => null, 1190 | 'attributes' => array( 1191 | 'href' => null, 1192 | 'title' => null, 1193 | ), 1194 | ); 1195 | 1196 | $extent = 0; 1197 | 1198 | $remainder = $Excerpt['text']; 1199 | 1200 | if (preg_match('/\[((?:[^][]|(?R))*)\]/', $remainder, $matches)) 1201 | { 1202 | $Element['text'] = $matches[1]; 1203 | 1204 | $extent += strlen($matches[0]); 1205 | 1206 | $remainder = substr($remainder, $extent); 1207 | } 1208 | else 1209 | { 1210 | return; 1211 | } 1212 | 1213 | if (preg_match('/^[(]((?:[^ ()]|[(][^ )]+[)])+)(?:[ ]+("[^"]*"|\'[^\']*\'))?[)]/', $remainder, $matches)) 1214 | { 1215 | $Element['attributes']['href'] = $matches[1]; 1216 | 1217 | if (isset($matches[2])) 1218 | { 1219 | $Element['attributes']['title'] = substr($matches[2], 1, - 1); 1220 | } 1221 | 1222 | $extent += strlen($matches[0]); 1223 | } 1224 | else 1225 | { 1226 | if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches)) 1227 | { 1228 | $definition = strlen($matches[1]) ? $matches[1] : $Element['text']; 1229 | $definition = strtolower($definition); 1230 | 1231 | $extent += strlen($matches[0]); 1232 | } 1233 | else 1234 | { 1235 | $definition = strtolower($Element['text']); 1236 | } 1237 | 1238 | if ( ! isset($this->DefinitionData['Reference'][$definition])) 1239 | { 1240 | return; 1241 | } 1242 | 1243 | $Definition = $this->DefinitionData['Reference'][$definition]; 1244 | 1245 | $Element['attributes']['href'] = $Definition['url']; 1246 | $Element['attributes']['title'] = $Definition['title']; 1247 | } 1248 | 1249 | $Element['attributes']['href'] = str_replace(array('&', '<'), array('&', '<'), $Element['attributes']['href']); 1250 | 1251 | return array( 1252 | 'extent' => $extent, 1253 | 'element' => $Element, 1254 | ); 1255 | } 1256 | 1257 | protected function inlineMarkup($Excerpt) 1258 | { 1259 | if ($this->markupEscaped or strpos($Excerpt['text'], '>') === false) 1260 | { 1261 | return; 1262 | } 1263 | 1264 | if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w*[ ]*>/s', $Excerpt['text'], $matches)) 1265 | { 1266 | return array( 1267 | 'markup' => $matches[0], 1268 | 'extent' => strlen($matches[0]), 1269 | ); 1270 | } 1271 | 1272 | if ($Excerpt['text'][1] === '!' and preg_match('/^/s', $Excerpt['text'], $matches)) 1273 | { 1274 | return array( 1275 | 'markup' => $matches[0], 1276 | 'extent' => strlen($matches[0]), 1277 | ); 1278 | } 1279 | 1280 | if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches)) 1281 | { 1282 | return array( 1283 | 'markup' => $matches[0], 1284 | 'extent' => strlen($matches[0]), 1285 | ); 1286 | } 1287 | } 1288 | 1289 | protected function inlineSpecialCharacter($Excerpt) 1290 | { 1291 | if ($Excerpt['text'][0] === '&' and ! preg_match('/^&#?\w+;/', $Excerpt['text'])) 1292 | { 1293 | return array( 1294 | 'markup' => '&', 1295 | 'extent' => 1, 1296 | ); 1297 | } 1298 | 1299 | $SpecialCharacter = array('>' => 'gt', '<' => 'lt', '"' => 'quot'); 1300 | 1301 | if (isset($SpecialCharacter[$Excerpt['text'][0]])) 1302 | { 1303 | return array( 1304 | 'markup' => '&'.$SpecialCharacter[$Excerpt['text'][0]].';', 1305 | 'extent' => 1, 1306 | ); 1307 | } 1308 | } 1309 | 1310 | protected function inlineStrikethrough($Excerpt) 1311 | { 1312 | if ( ! isset($Excerpt['text'][1])) 1313 | { 1314 | return; 1315 | } 1316 | 1317 | if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches)) 1318 | { 1319 | return array( 1320 | 'extent' => strlen($matches[0]), 1321 | 'element' => array( 1322 | 'name' => 'del', 1323 | 'text' => $matches[1], 1324 | 'handler' => 'line', 1325 | ), 1326 | ); 1327 | } 1328 | } 1329 | 1330 | protected function inlineUrl($Excerpt) 1331 | { 1332 | if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/') 1333 | { 1334 | return; 1335 | } 1336 | 1337 | if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) 1338 | { 1339 | $Inline = array( 1340 | 'extent' => strlen($matches[0][0]), 1341 | 'position' => $matches[0][1], 1342 | 'element' => array( 1343 | 'name' => 'a', 1344 | 'text' => $matches[0][0], 1345 | 'attributes' => array( 1346 | 'href' => $matches[0][0], 1347 | ), 1348 | ), 1349 | ); 1350 | 1351 | return $Inline; 1352 | } 1353 | } 1354 | 1355 | protected function inlineUrlTag($Excerpt) 1356 | { 1357 | if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches)) 1358 | { 1359 | $url = str_replace(array('&', '<'), array('&', '<'), $matches[1]); 1360 | 1361 | return array( 1362 | 'extent' => strlen($matches[0]), 1363 | 'element' => array( 1364 | 'name' => 'a', 1365 | 'text' => $url, 1366 | 'attributes' => array( 1367 | 'href' => $url, 1368 | ), 1369 | ), 1370 | ); 1371 | } 1372 | } 1373 | 1374 | # ~ 1375 | 1376 | protected function unmarkedText($text) 1377 | { 1378 | if ($this->breaksEnabled) 1379 | { 1380 | $text = preg_replace('/[ ]*\n/', "
\n", $text); 1381 | } 1382 | else 1383 | { 1384 | $text = preg_replace('/(?:[ ][ ]+|[ ]*\\\\)\n/', "
\n", $text); 1385 | $text = str_replace(" \n", "\n", $text); 1386 | } 1387 | 1388 | return $text; 1389 | } 1390 | 1391 | # 1392 | # Handlers 1393 | # 1394 | 1395 | protected function element(array $Element) 1396 | { 1397 | $markup = '<'.$Element['name']; 1398 | 1399 | if (isset($Element['attributes'])) 1400 | { 1401 | foreach ($Element['attributes'] as $name => $value) 1402 | { 1403 | if ($value === null) 1404 | { 1405 | continue; 1406 | } 1407 | 1408 | $markup .= ' '.$name.'="'.$value.'"'; 1409 | } 1410 | } 1411 | 1412 | if (isset($Element['text'])) 1413 | { 1414 | $markup .= '>'; 1415 | 1416 | if (isset($Element['handler'])) 1417 | { 1418 | $markup .= $this->{$Element['handler']}($Element['text']); 1419 | } 1420 | else 1421 | { 1422 | $markup .= $Element['text']; 1423 | } 1424 | 1425 | $markup .= ''; 1426 | } 1427 | else 1428 | { 1429 | $markup .= ' />'; 1430 | } 1431 | 1432 | return $markup; 1433 | } 1434 | 1435 | protected function elements(array $Elements) 1436 | { 1437 | $markup = ''; 1438 | 1439 | foreach ($Elements as $Element) 1440 | { 1441 | $markup .= "\n" . $this->element($Element); 1442 | } 1443 | 1444 | $markup .= "\n"; 1445 | 1446 | return $markup; 1447 | } 1448 | 1449 | # ~ 1450 | 1451 | protected function li($lines) 1452 | { 1453 | $markup = $this->lines($lines); 1454 | 1455 | $trimmedMarkup = trim($markup); 1456 | 1457 | if ( ! in_array('', $lines) and substr($trimmedMarkup, 0, 3) === '

') 1458 | { 1459 | $markup = $trimmedMarkup; 1460 | $markup = substr($markup, 3); 1461 | 1462 | $position = strpos($markup, "

"); 1463 | 1464 | $markup = substr_replace($markup, '', $position, 4); 1465 | } 1466 | 1467 | return $markup; 1468 | } 1469 | 1470 | # 1471 | # Deprecated Methods 1472 | # 1473 | 1474 | function parse($text) 1475 | { 1476 | $markup = $this->text($text); 1477 | 1478 | return $markup; 1479 | } 1480 | 1481 | # 1482 | # Static Methods 1483 | # 1484 | 1485 | static function instance($name = 'default') 1486 | { 1487 | if (isset(self::$instances[$name])) 1488 | { 1489 | return self::$instances[$name]; 1490 | } 1491 | 1492 | $instance = new static(); 1493 | 1494 | self::$instances[$name] = $instance; 1495 | 1496 | return $instance; 1497 | } 1498 | 1499 | private static $instances = array(); 1500 | 1501 | # 1502 | # Fields 1503 | # 1504 | 1505 | protected $DefinitionData; 1506 | 1507 | # 1508 | # Read-Only 1509 | 1510 | protected $specialCharacters = array( 1511 | '\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', '|', 1512 | ); 1513 | 1514 | protected $StrongRegex = array( 1515 | '*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s', 1516 | '_' => '/^__((?:\\\\_|[^_]|_[^_]*_)+?)__(?!_)/us', 1517 | ); 1518 | 1519 | protected $EmRegex = array( 1520 | '*' => '/^[*]((?:\\\\\*|[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s', 1521 | '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us', 1522 | ); 1523 | 1524 | protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*(?:\s*=\s*(?:[^"\'=<>`\s]+|"[^"]*"|\'[^\']*\'))?'; 1525 | 1526 | protected $voidElements = array( 1527 | 'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 1528 | ); 1529 | 1530 | protected $textLevelElements = array( 1531 | 'a', 'br', 'bdo', 'abbr', 'blink', 'nextid', 'acronym', 'basefont', 1532 | 'b', 'em', 'big', 'cite', 'small', 'spacer', 'listing', 1533 | 'i', 'rp', 'del', 'code', 'strike', 'marquee', 1534 | 'q', 'rt', 'ins', 'font', 'strong', 1535 | 's', 'tt', 'sub', 'mark', 1536 | 'u', 'xm', 'sup', 'nobr', 1537 | 'var', 'ruby', 1538 | 'wbr', 'span', 1539 | 'time', 1540 | ); 1541 | } 1542 | --------------------------------------------------------------------------------