mirror of
https://github.com/Neetpone/ponepaste.git
synced 2025-03-11 14:10:06 +01:00
fix: make Pastedown great again (some code by Aftercase)
This commit is contained in:
parent
7bcabf7ba0
commit
83f3fdb5e6
30 changed files with 1081 additions and 8 deletions
|
@ -19,7 +19,8 @@
|
|||
"scrivo/highlight.php": "^9.18",
|
||||
"erusev/parsedown": "^1.7",
|
||||
"illuminate/database": "^9.4",
|
||||
"ext-redis": "*"
|
||||
"ext-redis": "*",
|
||||
"erusev/parsedown-extra": "^0.8.1"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
|
53
composer.lock
generated
53
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "e4f29c3440a94cc63c1b5d37ca4f76e8",
|
||||
"content-hash": "84a10eea0cdac506e1b208869ec7879e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
|
@ -202,6 +202,57 @@
|
|||
},
|
||||
"time": "2019-12-30T22:54:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "erusev/parsedown-extra",
|
||||
"version": "0.8.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/erusev/parsedown-extra.git",
|
||||
"reference": "91ac3ff98f0cea243bdccc688df43810f044dcef"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/erusev/parsedown-extra/zipball/91ac3ff98f0cea243bdccc688df43810f044dcef",
|
||||
"reference": "91ac3ff98f0cea243bdccc688df43810f044dcef",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"erusev/parsedown": "^1.7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"ParsedownExtra": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Emanuil Rusev",
|
||||
"email": "hello@erusev.com",
|
||||
"homepage": "http://erusev.com"
|
||||
}
|
||||
],
|
||||
"description": "An extension of Parsedown that adds support for Markdown Extra.",
|
||||
"homepage": "https://github.com/erusev/parsedown-extra",
|
||||
"keywords": [
|
||||
"markdown",
|
||||
"markdown extra",
|
||||
"parsedown",
|
||||
"parser"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/erusev/parsedown-extra/issues",
|
||||
"source": "https://github.com/erusev/parsedown-extra/tree/0.8.x"
|
||||
},
|
||||
"time": "2019-12-30T23:20:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/collections",
|
||||
"version": "v9.52.4",
|
||||
|
|
|
@ -48,13 +48,17 @@ class Paste extends Model {
|
|||
|
||||
public function expiryDisplay() {
|
||||
$expiry = $this->expiry;
|
||||
if (!$expiry) {
|
||||
if (!$expiry || $expiry === 'NULL') { // TODO: Investigate why this is a string
|
||||
return 'Never';
|
||||
}
|
||||
|
||||
if ($expiry == 'SELF') {
|
||||
return '<b>View Once</b>';
|
||||
}
|
||||
$dateTime = new DateTime();
|
||||
|
||||
var_dump($expiry);
|
||||
|
||||
$dateTime = new DateTime($expiry);
|
||||
$dateTime->setTimestamp($expiry);
|
||||
$ret = $dateTime->format('Y-m-d H:i:s');
|
||||
if ($dateTime->diff(new DateTime())->days < 1) {
|
||||
|
|
70
includes/Pastedown.php
Normal file
70
includes/Pastedown.php
Normal file
|
@ -0,0 +1,70 @@
|
|||
<?php
|
||||
namespace PonePaste;
|
||||
|
||||
use ParsedownExtra;
|
||||
|
||||
class Pastedown extends ParsedownExtra {
|
||||
public function __construct() {
|
||||
$this->BlockTypes['>'] = ['Greentext'];
|
||||
$this->BlockTypes['<'] []= ['Redtext'];
|
||||
$this->BlockTypes['@'] = ['Purpletext'];
|
||||
}
|
||||
|
||||
|
||||
protected function blockGreentext($Line)
|
||||
{
|
||||
if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
|
||||
{
|
||||
$Block = array(
|
||||
'element' => array(
|
||||
'name' => 'span',
|
||||
'attributes' => [
|
||||
'class' => 'greentext'
|
||||
],
|
||||
'handler' => 'line',
|
||||
'text' => $matches[0],
|
||||
),
|
||||
);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
protected function blockRedtext($Line)
|
||||
{
|
||||
if (preg_match('/^<[ ]?(.*)/', $Line['text'], $matches))
|
||||
{
|
||||
$Block = array(
|
||||
'element' => array(
|
||||
'name' => 'span',
|
||||
'handler' => 'line',
|
||||
'attributes' => [
|
||||
'class' => 'redtext'
|
||||
],
|
||||
'text' => $matches[0],
|
||||
),
|
||||
);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
protected function blockPurpletext($Line)
|
||||
{
|
||||
if (preg_match('/^@[ ]?(.*)/', $Line['text'], $matches))
|
||||
{
|
||||
$Block = array(
|
||||
'element' => array(
|
||||
'name' => 'span',
|
||||
'handler' => 'line',
|
||||
'attributes' => [
|
||||
'class' => 'purpletext'
|
||||
],
|
||||
'text' => $matches[0],
|
||||
),
|
||||
);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ require_once(__DIR__ . '/../includes/common.php');
|
|||
use Highlight\Highlighter;
|
||||
use PonePaste\Models\Paste;
|
||||
use PonePaste\Models\User;
|
||||
use PonePaste\Pastedown;
|
||||
|
||||
function isRequesterLikelyBot() : bool {
|
||||
return str_contains(strtolower($_SERVER['HTTP_USER_AGENT']), 'bot');
|
||||
|
@ -212,7 +213,7 @@ $p_content = rtrim($p_content);
|
|||
$p_content = htmlspecialchars_decode($p_content);
|
||||
|
||||
if ($paste_code === "pastedown" || $paste_code === 'pastedown_old') {
|
||||
$parsedown = new Parsedown();
|
||||
$parsedown = new Pastedown();
|
||||
$parsedown->setSafeMode(true);
|
||||
$p_content = $parsedown->text($p_content);
|
||||
} else {
|
||||
|
|
|
@ -260,4 +260,17 @@ button.button--no-style {
|
|||
code {
|
||||
overflow-wrap: anywhere;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
||||
.content .greentext {
|
||||
color: #789922;
|
||||
content: ">";
|
||||
}
|
||||
|
||||
.content .redtext {
|
||||
color: #d12222;
|
||||
}
|
||||
|
||||
.content .purpletext {
|
||||
color: #9f14ae;
|
||||
}
|
||||
|
|
1
vendor/composer/autoload_namespaces.php
vendored
1
vendor/composer/autoload_namespaces.php
vendored
|
@ -6,6 +6,7 @@ $vendorDir = dirname(__DIR__);
|
|||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'ParsedownExtra' => array($vendorDir . '/erusev/parsedown-extra'),
|
||||
'Parsedown' => array($vendorDir . '/erusev/parsedown'),
|
||||
'Highlight\\' => array($vendorDir . '/scrivo/highlight.php'),
|
||||
'HighlightUtilities\\' => array($vendorDir . '/scrivo/highlight.php'),
|
||||
|
|
4
vendor/composer/autoload_static.php
vendored
4
vendor/composer/autoload_static.php
vendored
|
@ -158,6 +158,10 @@ class ComposerStaticInit5bf95489f4eff2c10ec062bf7ba377da
|
|||
public static $prefixesPsr0 = array (
|
||||
'P' =>
|
||||
array (
|
||||
'ParsedownExtra' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/erusev/parsedown-extra',
|
||||
),
|
||||
'Parsedown' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/erusev/parsedown',
|
||||
|
|
54
vendor/composer/installed.json
vendored
54
vendor/composer/installed.json
vendored
|
@ -205,6 +205,60 @@
|
|||
},
|
||||
"install-path": "../erusev/parsedown"
|
||||
},
|
||||
{
|
||||
"name": "erusev/parsedown-extra",
|
||||
"version": "0.8.1",
|
||||
"version_normalized": "0.8.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/erusev/parsedown-extra.git",
|
||||
"reference": "91ac3ff98f0cea243bdccc688df43810f044dcef"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/erusev/parsedown-extra/zipball/91ac3ff98f0cea243bdccc688df43810f044dcef",
|
||||
"reference": "91ac3ff98f0cea243bdccc688df43810f044dcef",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"erusev/parsedown": "^1.7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35"
|
||||
},
|
||||
"time": "2019-12-30T23:20:37+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"ParsedownExtra": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Emanuil Rusev",
|
||||
"email": "hello@erusev.com",
|
||||
"homepage": "http://erusev.com"
|
||||
}
|
||||
],
|
||||
"description": "An extension of Parsedown that adds support for Markdown Extra.",
|
||||
"homepage": "https://github.com/erusev/parsedown-extra",
|
||||
"keywords": [
|
||||
"markdown",
|
||||
"markdown extra",
|
||||
"parsedown",
|
||||
"parser"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/erusev/parsedown-extra/issues",
|
||||
"source": "https://github.com/erusev/parsedown-extra/tree/0.8.x"
|
||||
},
|
||||
"install-path": "../erusev/parsedown-extra"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/collections",
|
||||
"version": "v9.52.4",
|
||||
|
|
13
vendor/composer/installed.php
vendored
13
vendor/composer/installed.php
vendored
|
@ -3,7 +3,7 @@
|
|||
'name' => 'aftercase/ponepaste',
|
||||
'pretty_version' => 'dev-main',
|
||||
'version' => 'dev-main',
|
||||
'reference' => '9bd921ee714769fcddbcbbd0d7c49a64336794f9',
|
||||
'reference' => 'ca52ccebb87c68aa9a6e0cf2cd58e9278736033a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
@ -13,7 +13,7 @@
|
|||
'aftercase/ponepaste' => array(
|
||||
'pretty_version' => 'dev-main',
|
||||
'version' => 'dev-main',
|
||||
'reference' => '9bd921ee714769fcddbcbbd0d7c49a64336794f9',
|
||||
'reference' => 'ca52ccebb87c68aa9a6e0cf2cd58e9278736033a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
@ -46,6 +46,15 @@
|
|||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'erusev/parsedown-extra' => array(
|
||||
'pretty_version' => '0.8.1',
|
||||
'version' => '0.8.1.0',
|
||||
'reference' => '91ac3ff98f0cea243bdccc688df43810f044dcef',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../erusev/parsedown-extra',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'illuminate/collections' => array(
|
||||
'pretty_version' => 'v9.52.4',
|
||||
'version' => '9.52.4.0',
|
||||
|
|
30
vendor/erusev/parsedown-extra/.travis.yml
vendored
Normal file
30
vendor/erusev/parsedown-extra/.travis.yml
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
language: php
|
||||
|
||||
dist: trusty
|
||||
sudo: false
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- php: 5.3
|
||||
dist: precise
|
||||
- php: 5.4
|
||||
- php: 5.5
|
||||
- php: 5.6
|
||||
- php: 7.0
|
||||
- php: 7.1
|
||||
- php: 7.2
|
||||
- php: 7.3
|
||||
- php: 7.4
|
||||
- php: nightly
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
- php: nightly
|
||||
- php: hhvm-nightly
|
||||
|
||||
install:
|
||||
- composer install --prefer-source
|
||||
|
||||
script:
|
||||
- vendor/bin/phpunit
|
||||
- vendor/bin/phpunit vendor/erusev/parsedown/test/CommonMarkTestWeak.php || true
|
||||
- '[ -z "$TRAVIS_TAG" ] || [ "$TRAVIS_TAG" == "$(php -r "require(\"ParsedownExtra.php\"); echo ParsedownExtra::version;")" ]'
|
20
vendor/erusev/parsedown-extra/LICENSE.txt
vendored
Normal file
20
vendor/erusev/parsedown-extra/LICENSE.txt
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Emanuil Rusev, erusev.com
|
||||
|
||||
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.
|
538
vendor/erusev/parsedown-extra/ParsedownExtra.php
vendored
Normal file
538
vendor/erusev/parsedown-extra/ParsedownExtra.php
vendored
Normal file
|
@ -0,0 +1,538 @@
|
|||
<?php
|
||||
|
||||
#
|
||||
#
|
||||
# Parsedown Extra
|
||||
# https://github.com/erusev/parsedown-extra
|
||||
#
|
||||
# (c) Emanuil Rusev
|
||||
# http://erusev.com
|
||||
#
|
||||
# For the full license information, view the LICENSE file that was distributed
|
||||
# with this source code.
|
||||
#
|
||||
#
|
||||
|
||||
class ParsedownExtra extends Parsedown
|
||||
{
|
||||
# ~
|
||||
|
||||
const version = '0.8.1';
|
||||
|
||||
# ~
|
||||
|
||||
function __construct()
|
||||
{
|
||||
if (version_compare(parent::version, '1.7.4') < 0)
|
||||
{
|
||||
throw new Exception('ParsedownExtra requires a later version of Parsedown');
|
||||
}
|
||||
|
||||
$this->BlockTypes[':'] []= 'DefinitionList';
|
||||
$this->BlockTypes['*'] []= 'Abbreviation';
|
||||
|
||||
# identify footnote definitions before reference definitions
|
||||
array_unshift($this->BlockTypes['['], 'Footnote');
|
||||
|
||||
# identify footnote markers before before links
|
||||
array_unshift($this->InlineTypes['['], 'FootnoteMarker');
|
||||
}
|
||||
|
||||
#
|
||||
# ~
|
||||
|
||||
function text($text)
|
||||
{
|
||||
$markup = parent::text($text);
|
||||
|
||||
# merge consecutive dl elements
|
||||
|
||||
$markup = preg_replace('/<\/dl>\s+<dl>\s+/', '', $markup);
|
||||
|
||||
# add footnotes
|
||||
|
||||
if (isset($this->DefinitionData['Footnote']))
|
||||
{
|
||||
$Element = $this->buildFootnoteElement();
|
||||
|
||||
$markup .= "\n" . $this->element($Element);
|
||||
}
|
||||
|
||||
return $markup;
|
||||
}
|
||||
|
||||
#
|
||||
# Blocks
|
||||
#
|
||||
|
||||
#
|
||||
# Abbreviation
|
||||
|
||||
protected function blockAbbreviation($Line)
|
||||
{
|
||||
if (preg_match('/^\*\[(.+?)\]:[ ]*(.+?)[ ]*$/', $Line['text'], $matches))
|
||||
{
|
||||
$this->DefinitionData['Abbreviation'][$matches[1]] = $matches[2];
|
||||
|
||||
$Block = array(
|
||||
'hidden' => true,
|
||||
);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Footnote
|
||||
|
||||
protected function blockFootnote($Line)
|
||||
{
|
||||
if (preg_match('/^\[\^(.+?)\]:[ ]?(.*)$/', $Line['text'], $matches))
|
||||
{
|
||||
$Block = array(
|
||||
'label' => $matches[1],
|
||||
'text' => $matches[2],
|
||||
'hidden' => true,
|
||||
);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
protected function blockFootnoteContinue($Line, $Block)
|
||||
{
|
||||
if ($Line['text'][0] === '[' and preg_match('/^\[\^(.+?)\]:/', $Line['text']))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($Block['interrupted']))
|
||||
{
|
||||
if ($Line['indent'] >= 4)
|
||||
{
|
||||
$Block['text'] .= "\n\n" . $Line['text'];
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$Block['text'] .= "\n" . $Line['text'];
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
protected function blockFootnoteComplete($Block)
|
||||
{
|
||||
$this->DefinitionData['Footnote'][$Block['label']] = array(
|
||||
'text' => $Block['text'],
|
||||
'count' => null,
|
||||
'number' => null,
|
||||
);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
|
||||
#
|
||||
# Definition List
|
||||
|
||||
protected function blockDefinitionList($Line, $Block)
|
||||
{
|
||||
if ( ! isset($Block) or isset($Block['type']))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$Element = array(
|
||||
'name' => 'dl',
|
||||
'handler' => 'elements',
|
||||
'text' => array(),
|
||||
);
|
||||
|
||||
$terms = explode("\n", $Block['element']['text']);
|
||||
|
||||
foreach ($terms as $term)
|
||||
{
|
||||
$Element['text'] []= array(
|
||||
'name' => 'dt',
|
||||
'handler' => 'line',
|
||||
'text' => $term,
|
||||
);
|
||||
}
|
||||
|
||||
$Block['element'] = $Element;
|
||||
|
||||
$Block = $this->addDdElement($Line, $Block);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
|
||||
protected function blockDefinitionListContinue($Line, array $Block)
|
||||
{
|
||||
if ($Line['text'][0] === ':')
|
||||
{
|
||||
$Block = $this->addDdElement($Line, $Block);
|
||||
|
||||
return $Block;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($Block['interrupted']) and $Line['indent'] === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($Block['interrupted']))
|
||||
{
|
||||
$Block['dd']['handler'] = 'text';
|
||||
$Block['dd']['text'] .= "\n\n";
|
||||
|
||||
unset($Block['interrupted']);
|
||||
}
|
||||
|
||||
$text = substr($Line['body'], min($Line['indent'], 4));
|
||||
|
||||
$Block['dd']['text'] .= "\n" . $text;
|
||||
|
||||
return $Block;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Header
|
||||
|
||||
protected function blockHeader($Line)
|
||||
{
|
||||
$Block = parent::blockHeader($Line);
|
||||
|
||||
if (! isset($Block)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (preg_match('/[ #]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE))
|
||||
{
|
||||
$attributeString = $matches[1][0];
|
||||
|
||||
$Block['element']['attributes'] = $this->parseAttributeData($attributeString);
|
||||
|
||||
$Block['element']['text'] = substr($Block['element']['text'], 0, $matches[0][1]);
|
||||
}
|
||||
|
||||
return $Block;
|
||||
}
|
||||
|
||||
#
|
||||
# Markup
|
||||
|
||||
protected function blockMarkupComplete($Block)
|
||||
{
|
||||
if ( ! isset($Block['void']))
|
||||
{
|
||||
$Block['markup'] = $this->processTag($Block['markup']);
|
||||
}
|
||||
|
||||
return $Block;
|
||||
}
|
||||
|
||||
#
|
||||
# Setext
|
||||
|
||||
protected function blockSetextHeader($Line, array $Block = null)
|
||||
{
|
||||
$Block = parent::blockSetextHeader($Line, $Block);
|
||||
|
||||
if (! isset($Block)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (preg_match('/[ ]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['text'], $matches, PREG_OFFSET_CAPTURE))
|
||||
{
|
||||
$attributeString = $matches[1][0];
|
||||
|
||||
$Block['element']['attributes'] = $this->parseAttributeData($attributeString);
|
||||
|
||||
$Block['element']['text'] = substr($Block['element']['text'], 0, $matches[0][1]);
|
||||
}
|
||||
|
||||
return $Block;
|
||||
}
|
||||
|
||||
#
|
||||
# Inline Elements
|
||||
#
|
||||
|
||||
#
|
||||
# Footnote Marker
|
||||
|
||||
protected function inlineFootnoteMarker($Excerpt)
|
||||
{
|
||||
if (preg_match('/^\[\^(.+?)\]/', $Excerpt['text'], $matches))
|
||||
{
|
||||
$name = $matches[1];
|
||||
|
||||
if ( ! isset($this->DefinitionData['Footnote'][$name]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->DefinitionData['Footnote'][$name]['count'] ++;
|
||||
|
||||
if ( ! isset($this->DefinitionData['Footnote'][$name]['number']))
|
||||
{
|
||||
$this->DefinitionData['Footnote'][$name]['number'] = ++ $this->footnoteCount; # » &
|
||||
}
|
||||
|
||||
$Element = array(
|
||||
'name' => 'sup',
|
||||
'attributes' => array('id' => 'fnref'.$this->DefinitionData['Footnote'][$name]['count'].':'.$name),
|
||||
'handler' => 'element',
|
||||
'text' => array(
|
||||
'name' => 'a',
|
||||
'attributes' => array('href' => '#fn:'.$name, 'class' => 'footnote-ref'),
|
||||
'text' => $this->DefinitionData['Footnote'][$name]['number'],
|
||||
),
|
||||
);
|
||||
|
||||
return array(
|
||||
'extent' => strlen($matches[0]),
|
||||
'element' => $Element,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private $footnoteCount = 0;
|
||||
|
||||
#
|
||||
# Link
|
||||
|
||||
protected function inlineLink($Excerpt)
|
||||
{
|
||||
$Link = parent::inlineLink($Excerpt);
|
||||
|
||||
if (! isset($Link)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$remainder = substr($Excerpt['text'], $Link['extent']);
|
||||
|
||||
if (preg_match('/^[ ]*{('.$this->regexAttribute.'+)}/', $remainder, $matches))
|
||||
{
|
||||
$Link['element']['attributes'] += $this->parseAttributeData($matches[1]);
|
||||
|
||||
$Link['extent'] += strlen($matches[0]);
|
||||
}
|
||||
|
||||
return $Link;
|
||||
}
|
||||
|
||||
#
|
||||
# ~
|
||||
#
|
||||
|
||||
protected function unmarkedText($text)
|
||||
{
|
||||
$text = parent::unmarkedText($text);
|
||||
|
||||
if (isset($this->DefinitionData['Abbreviation']))
|
||||
{
|
||||
foreach ($this->DefinitionData['Abbreviation'] as $abbreviation => $meaning)
|
||||
{
|
||||
$pattern = '/\b'.preg_quote($abbreviation, '/').'\b/';
|
||||
|
||||
$text = preg_replace($pattern, '<abbr title="'.$meaning.'">'.$abbreviation.'</abbr>', $text);
|
||||
}
|
||||
}
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
#
|
||||
# Util Methods
|
||||
#
|
||||
|
||||
protected function addDdElement(array $Line, array $Block)
|
||||
{
|
||||
$text = substr($Line['text'], 1);
|
||||
$text = trim($text);
|
||||
|
||||
unset($Block['dd']);
|
||||
|
||||
$Block['dd'] = array(
|
||||
'name' => 'dd',
|
||||
'handler' => 'line',
|
||||
'text' => $text,
|
||||
);
|
||||
|
||||
if (isset($Block['interrupted']))
|
||||
{
|
||||
$Block['dd']['handler'] = 'text';
|
||||
|
||||
unset($Block['interrupted']);
|
||||
}
|
||||
|
||||
$Block['element']['text'] []= & $Block['dd'];
|
||||
|
||||
return $Block;
|
||||
}
|
||||
|
||||
protected function buildFootnoteElement()
|
||||
{
|
||||
$Element = array(
|
||||
'name' => 'div',
|
||||
'attributes' => array('class' => 'footnotes'),
|
||||
'handler' => 'elements',
|
||||
'text' => array(
|
||||
array(
|
||||
'name' => 'hr',
|
||||
),
|
||||
array(
|
||||
'name' => 'ol',
|
||||
'handler' => 'elements',
|
||||
'text' => array(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
uasort($this->DefinitionData['Footnote'], 'self::sortFootnotes');
|
||||
|
||||
foreach ($this->DefinitionData['Footnote'] as $definitionId => $DefinitionData)
|
||||
{
|
||||
if ( ! isset($DefinitionData['number']))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$text = $DefinitionData['text'];
|
||||
|
||||
$text = parent::text($text);
|
||||
|
||||
$numbers = range(1, $DefinitionData['count']);
|
||||
|
||||
$backLinksMarkup = '';
|
||||
|
||||
foreach ($numbers as $number)
|
||||
{
|
||||
$backLinksMarkup .= ' <a href="#fnref'.$number.':'.$definitionId.'" rev="footnote" class="footnote-backref">↩</a>';
|
||||
}
|
||||
|
||||
$backLinksMarkup = substr($backLinksMarkup, 1);
|
||||
|
||||
if (substr($text, - 4) === '</p>')
|
||||
{
|
||||
$backLinksMarkup = ' '.$backLinksMarkup;
|
||||
|
||||
$text = substr_replace($text, $backLinksMarkup.'</p>', - 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
$text .= "\n".'<p>'.$backLinksMarkup.'</p>';
|
||||
}
|
||||
|
||||
$Element['text'][1]['text'] []= array(
|
||||
'name' => 'li',
|
||||
'attributes' => array('id' => 'fn:'.$definitionId),
|
||||
'rawHtml' => "\n".$text."\n",
|
||||
);
|
||||
}
|
||||
|
||||
return $Element;
|
||||
}
|
||||
|
||||
# ~
|
||||
|
||||
protected function parseAttributeData($attributeString)
|
||||
{
|
||||
$Data = array();
|
||||
|
||||
$attributes = preg_split('/[ ]+/', $attributeString, - 1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
foreach ($attributes as $attribute)
|
||||
{
|
||||
if ($attribute[0] === '#')
|
||||
{
|
||||
$Data['id'] = substr($attribute, 1);
|
||||
}
|
||||
else # "."
|
||||
{
|
||||
$classes []= substr($attribute, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($classes))
|
||||
{
|
||||
$Data['class'] = implode(' ', $classes);
|
||||
}
|
||||
|
||||
return $Data;
|
||||
}
|
||||
|
||||
# ~
|
||||
|
||||
protected function processTag($elementMarkup) # recursive
|
||||
{
|
||||
# http://stackoverflow.com/q/1148928/200145
|
||||
libxml_use_internal_errors(true);
|
||||
|
||||
$DOMDocument = new DOMDocument;
|
||||
|
||||
# http://stackoverflow.com/q/11309194/200145
|
||||
$elementMarkup = mb_convert_encoding($elementMarkup, 'HTML-ENTITIES', 'UTF-8');
|
||||
|
||||
# http://stackoverflow.com/q/4879946/200145
|
||||
$DOMDocument->loadHTML($elementMarkup);
|
||||
$DOMDocument->removeChild($DOMDocument->doctype);
|
||||
$DOMDocument->replaceChild($DOMDocument->firstChild->firstChild->firstChild, $DOMDocument->firstChild);
|
||||
|
||||
$elementText = '';
|
||||
|
||||
if ($DOMDocument->documentElement->getAttribute('markdown') === '1')
|
||||
{
|
||||
foreach ($DOMDocument->documentElement->childNodes as $Node)
|
||||
{
|
||||
$elementText .= $DOMDocument->saveHTML($Node);
|
||||
}
|
||||
|
||||
$DOMDocument->documentElement->removeAttribute('markdown');
|
||||
|
||||
$elementText = "\n".$this->text($elementText)."\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($DOMDocument->documentElement->childNodes as $Node)
|
||||
{
|
||||
$nodeMarkup = $DOMDocument->saveHTML($Node);
|
||||
|
||||
if ($Node instanceof DOMElement and ! in_array($Node->nodeName, $this->textLevelElements))
|
||||
{
|
||||
$elementText .= $this->processTag($nodeMarkup);
|
||||
}
|
||||
else
|
||||
{
|
||||
$elementText .= $nodeMarkup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# because we don't want for markup to get encoded
|
||||
$DOMDocument->documentElement->nodeValue = 'placeholder\x1A';
|
||||
|
||||
$markup = $DOMDocument->saveHTML($DOMDocument->documentElement);
|
||||
$markup = str_replace('placeholder\x1A', $elementText, $markup);
|
||||
|
||||
return $markup;
|
||||
}
|
||||
|
||||
# ~
|
||||
|
||||
protected function sortFootnotes($A, $B) # callback
|
||||
{
|
||||
return $A['number'] - $B['number'];
|
||||
}
|
||||
|
||||
#
|
||||
# Fields
|
||||
#
|
||||
|
||||
protected $regexAttribute = '(?:[#.][-\w]+[ ]*)';
|
||||
}
|
31
vendor/erusev/parsedown-extra/README.md
vendored
Normal file
31
vendor/erusev/parsedown-extra/README.md
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
> You might also like [Caret](http://caret.io?ref=parsedown) - our Markdown editor for the Desktop.
|
||||
|
||||
## Parsedown Extra
|
||||
|
||||
[](https://travis-ci.org/erusev/parsedown-extra)
|
||||
|
||||
An extension of [Parsedown](http://parsedown.org) that adds support for [Markdown Extra](https://michelf.ca/projects/php-markdown/extra/).
|
||||
|
||||
[See Demo](http://parsedown.org/extra/)
|
||||
|
||||
### Installation
|
||||
|
||||
Include both `Parsedown.php` and `ParsedownExtra.php` or install [the composer package](https://packagist.org/packages/erusev/parsedown-extra).
|
||||
|
||||
### Example
|
||||
|
||||
``` php
|
||||
$Extra = new ParsedownExtra();
|
||||
|
||||
echo $Extra->text('# Header {.sth}'); # prints: <h1 class="sth">Header</h1>
|
||||
```
|
||||
|
||||
### Questions
|
||||
|
||||
**Who uses Parsedown Extra?**
|
||||
|
||||
[October CMS](http://octobercms.com/), [Bolt CMS](http://bolt.cm/), [Kirby CMS](http://getkirby.com/), [Grav CMS](http://getgrav.org/), [Statamic CMS](http://www.statamic.com/) and [more](https://www.versioneye.com/php/erusev:parsedown-extra/references).
|
||||
|
||||
**How can I help?**
|
||||
|
||||
Use it, star it, share it and in case you feel generous, [donate some money](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).
|
33
vendor/erusev/parsedown-extra/composer.json
vendored
Normal file
33
vendor/erusev/parsedown-extra/composer.json
vendored
Normal file
|
@ -0,0 +1,33 @@
|
|||
{
|
||||
"name": "erusev/parsedown-extra",
|
||||
"description": "An extension of Parsedown that adds support for Markdown Extra.",
|
||||
"keywords": ["markdown", "markdown extra", "parser", "parsedown"],
|
||||
"homepage": "https://github.com/erusev/parsedown-extra",
|
||||
"type": "library",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Emanuil Rusev",
|
||||
"email": "hello@erusev.com",
|
||||
"homepage": "http://erusev.com"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"erusev/parsedown": "^1.7.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": {"ParsedownExtra": ""}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-0": {
|
||||
"TestParsedown": "test/",
|
||||
"ParsedownExtraTest": "test/",
|
||||
"ParsedownTest": "vendor/erusev/parsedown/test/",
|
||||
"CommonMarkTest": "vendor/erusev/parsedown/test/",
|
||||
"CommonMarkTestWeak": "vendor/erusev/parsedown/test/"
|
||||
}
|
||||
}
|
||||
}
|
8
vendor/erusev/parsedown-extra/phpunit.xml.dist
vendored
Normal file
8
vendor/erusev/parsedown-extra/phpunit.xml.dist
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit bootstrap="vendor/autoload.php" colors="true">
|
||||
<testsuites>
|
||||
<testsuite>
|
||||
<file>test/ParsedownExtraTest.php</file>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
11
vendor/erusev/parsedown-extra/test/ParsedownExtraTest.php
vendored
Normal file
11
vendor/erusev/parsedown-extra/test/ParsedownExtraTest.php
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
class ParsedownExtraTest extends ParsedownTest
|
||||
{
|
||||
protected function initDirs()
|
||||
{
|
||||
$dirs = parent::initDirs();
|
||||
$dirs[] = __DIR__ . '/data/';
|
||||
return $dirs;
|
||||
}
|
||||
}
|
9
vendor/erusev/parsedown-extra/test/TestParsedown.php
vendored
Normal file
9
vendor/erusev/parsedown-extra/test/TestParsedown.php
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
class TestParsedown extends ParsedownExtra
|
||||
{
|
||||
public function getTextLevelElements()
|
||||
{
|
||||
return $this->textLevelElements;
|
||||
}
|
||||
}
|
3
vendor/erusev/parsedown-extra/test/data/abbreviation.html
vendored
Normal file
3
vendor/erusev/parsedown-extra/test/data/abbreviation.html
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
<p>The <abbr title="Hyper Text Markup Language">HTML</abbr> specification
|
||||
is maintained by the <abbr title="World Wide Web Consortium">W3C</abbr>.
|
||||
The abbreviation <abbr title="Markup Language">ML</abbr> is contained in the abbreviation <abbr title="Hyper Text Markup Language">HTML</abbr>.</p>
|
7
vendor/erusev/parsedown-extra/test/data/abbreviation.md
vendored
Normal file
7
vendor/erusev/parsedown-extra/test/data/abbreviation.md
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
The HTML specification
|
||||
is maintained by the W3C.
|
||||
The abbreviation ML is contained in the abbreviation HTML.
|
||||
|
||||
*[HTML]: Hyper Text Markup Language
|
||||
*[W3C]: World Wide Web Consortium
|
||||
*[ML]: Markup Language
|
18
vendor/erusev/parsedown-extra/test/data/compound_footnote.html
vendored
Normal file
18
vendor/erusev/parsedown-extra/test/data/compound_footnote.html
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
<p>footnote <sup id="fnref1:1"><a href="#fn:1" class="footnote-ref">1</a></sup> and another one <sup id="fnref1:2"><a href="#fn:2" class="footnote-ref">2</a></sup></p>
|
||||
<div class="footnotes">
|
||||
<hr />
|
||||
<ol>
|
||||
<li id="fn:1">
|
||||
<p>line 1
|
||||
line 2</p>
|
||||
<blockquote>
|
||||
<p>quote</p>
|
||||
</blockquote>
|
||||
<p>another paragraph <a href="#fnref1:1" rev="footnote" class="footnote-backref">↩</a></p>
|
||||
</li>
|
||||
<li id="fn:2">
|
||||
<p>paragraph</p>
|
||||
<p>another paragraph <a href="#fnref1:2" rev="footnote" class="footnote-backref">↩</a></p>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
14
vendor/erusev/parsedown-extra/test/data/compound_footnote.md
vendored
Normal file
14
vendor/erusev/parsedown-extra/test/data/compound_footnote.md
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
footnote [^1] and another one [^2]
|
||||
|
||||
[^1]: line 1
|
||||
line 2
|
||||
|
||||
> quote
|
||||
|
||||
another paragraph
|
||||
|
||||
[^2]:
|
||||
paragraph
|
||||
|
||||
another paragraph
|
||||
|
17
vendor/erusev/parsedown-extra/test/data/definition_list.html
vendored
Normal file
17
vendor/erusev/parsedown-extra/test/data/definition_list.html
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
<dl>
|
||||
<dt>Term 1</dt>
|
||||
<dd>one</dd>
|
||||
<dd>two
|
||||
extra line</dd>
|
||||
<dt>Term 2</dt>
|
||||
<dd><p>lazy
|
||||
line</p></dd>
|
||||
<dd><p>multiple</p>
|
||||
<p>paragraphs</p></dd>
|
||||
<dd><p>nested</p>
|
||||
<pre><code>code block</code></pre>
|
||||
<blockquote>
|
||||
<p>quote
|
||||
block</p>
|
||||
</blockquote></dd>
|
||||
</dl>
|
20
vendor/erusev/parsedown-extra/test/data/definition_list.md
vendored
Normal file
20
vendor/erusev/parsedown-extra/test/data/definition_list.md
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
Term 1
|
||||
: one
|
||||
: two
|
||||
extra line
|
||||
|
||||
Term 2
|
||||
|
||||
: lazy
|
||||
line
|
||||
|
||||
: multiple
|
||||
|
||||
paragraphs
|
||||
|
||||
: nested
|
||||
|
||||
code block
|
||||
|
||||
> quote
|
||||
> block
|
20
vendor/erusev/parsedown-extra/test/data/footnote.html
vendored
Normal file
20
vendor/erusev/parsedown-extra/test/data/footnote.html
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
<p>first <sup id="fnref1:1"><a href="#fn:1" class="footnote-ref">1</a></sup> second <sup id="fnref1:2"><a href="#fn:2" class="footnote-ref">2</a></sup>.</p>
|
||||
<p>first <sup id="fnref1:a"><a href="#fn:a" class="footnote-ref">3</a></sup> second <sup id="fnref1:b"><a href="#fn:b" class="footnote-ref">4</a></sup>.</p>
|
||||
<p>second time <sup id="fnref2:1"><a href="#fn:1" class="footnote-ref">1</a></sup></p>
|
||||
<div class="footnotes">
|
||||
<hr />
|
||||
<ol>
|
||||
<li id="fn:1">
|
||||
<p>one <a href="#fnref1:1" rev="footnote" class="footnote-backref">↩</a> <a href="#fnref2:1" rev="footnote" class="footnote-backref">↩</a></p>
|
||||
</li>
|
||||
<li id="fn:2">
|
||||
<p>two <a href="#fnref1:2" rev="footnote" class="footnote-backref">↩</a></p>
|
||||
</li>
|
||||
<li id="fn:a">
|
||||
<p>one <a href="#fnref1:a" rev="footnote" class="footnote-backref">↩</a></p>
|
||||
</li>
|
||||
<li id="fn:b">
|
||||
<p>two <a href="#fnref1:b" rev="footnote" class="footnote-backref">↩</a></p>
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
11
vendor/erusev/parsedown-extra/test/data/footnote.md
vendored
Normal file
11
vendor/erusev/parsedown-extra/test/data/footnote.md
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
first [^1] second [^2].
|
||||
|
||||
[^1]: one
|
||||
[^2]: two
|
||||
|
||||
first [^a] second [^b].
|
||||
|
||||
[^a]: one
|
||||
[^b]: two
|
||||
|
||||
second time [^1]
|
25
vendor/erusev/parsedown-extra/test/data/markdown_inside_markup.html
vendored
Normal file
25
vendor/erusev/parsedown-extra/test/data/markdown_inside_markup.html
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
<div class="example">
|
||||
<p><em>markdown</em></p>
|
||||
<p>This is another paragraph. It contains <em>inline markup</em>.</p>
|
||||
<div>
|
||||
_no markdown_
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
<p><em>markdown</em></p>
|
||||
<div>
|
||||
<p><em>markdown</em></p>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div>
|
||||
_no markdown_
|
||||
<div>
|
||||
<p><em>markdown</em></p>
|
||||
</div>
|
||||
</div>
|
||||
<hr />
|
||||
<div markdown="0">
|
||||
_no markdown_
|
||||
</div>
|
32
vendor/erusev/parsedown-extra/test/data/markdown_inside_markup.md
vendored
Normal file
32
vendor/erusev/parsedown-extra/test/data/markdown_inside_markup.md
vendored
Normal file
|
@ -0,0 +1,32 @@
|
|||
<div class="example" markdown="1">
|
||||
_markdown_
|
||||
|
||||
This is another paragraph. It contains <em>inline markup</em>.
|
||||
<div>
|
||||
_no markdown_
|
||||
</div>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
<div markdown="1">
|
||||
_markdown_
|
||||
<div markdown="1">
|
||||
_markdown_
|
||||
</div>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
<div>
|
||||
_no markdown_
|
||||
<div markdown="1">
|
||||
_markdown_
|
||||
</div>
|
||||
</div>
|
||||
|
||||
---
|
||||
|
||||
<div markdown="0">
|
||||
_no markdown_
|
||||
</div>
|
6
vendor/erusev/parsedown-extra/test/data/special_attributes.html
vendored
Normal file
6
vendor/erusev/parsedown-extra/test/data/special_attributes.html
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
<h1 id="header1">Header 1</h1>
|
||||
<h2 id="header2">Header 2</h2>
|
||||
<h2 class="main">The Site</h2>
|
||||
<h2 id="the-site" class="main shine">The Site</h2>
|
||||
<p><a href="http://parsedown.org" id="link" class="primary upper-case">link</a></p>
|
||||
<p><img src="/md.png" alt="logo" id="logo" class="big" /></p>
|
12
vendor/erusev/parsedown-extra/test/data/special_attributes.md
vendored
Normal file
12
vendor/erusev/parsedown-extra/test/data/special_attributes.md
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
Header 1 {#header1}
|
||||
========
|
||||
|
||||
## Header 2 ## {#header2}
|
||||
|
||||
## The Site ## {.main}
|
||||
|
||||
## The Site ## {.main .shine #the-site}
|
||||
|
||||
[link](http://parsedown.org) {.primary #link .upper-case}
|
||||
|
||||
 {#logo .big}
|
Loading…
Add table
Reference in a new issue