From 3aa3a0421a48b97d915a75d9a22e914f5923b429 Mon Sep 17 00:00:00 2001
From: Taufik Nurrohman
Date: Sat, 20 Jun 2020 08:15:48 +0700
Subject: [PATCH] Revert Parsedown Extra to Version 0.8.0
Related: https://github.com/erusev/parsedown-extra/issues/152
---
README.md | 2 +-
.../engine/kernel/parsedown-extra.php | 268 ++++++++++++++----
2 files changed, 209 insertions(+), 61 deletions(-)
diff --git a/README.md b/README.md
index 971760d9..7ab36dee 100644
--- a/README.md
+++ b/README.md
@@ -75,7 +75,7 @@ Release Notes
### master
- - Updated [Parsedown Extra](https://github.com/erusev/parsedown-extra) to version 0.8.1.
+ - Updated [Parsedown Extra](https://github.com/erusev/parsedown-extra) to version 0.8.0.
### 2.3.1
diff --git a/lot/x/markdown/engine/kernel/parsedown-extra.php b/lot/x/markdown/engine/kernel/parsedown-extra.php
index e4b8b466..8782d358 100644
--- a/lot/x/markdown/engine/kernel/parsedown-extra.php
+++ b/lot/x/markdown/engine/kernel/parsedown-extra.php
@@ -17,13 +17,13 @@ class ParsedownExtra extends Parsedown
{
# ~
- const version = '0.8.1';
+ const version = '0.8.0';
# ~
function __construct()
{
- if (version_compare(parent::version, '1.7.4') < 0)
+ if (version_compare(parent::version, '1.7.1') < 0)
{
throw new Exception('ParsedownExtra requires a later version of Parsedown');
}
@@ -43,7 +43,13 @@ function __construct()
function text($text)
{
- $markup = parent::text($text);
+ $Elements = $this->textElements($text);
+
+ # convert to markup
+ $markup = $this->elements($Elements);
+
+ # trim line breaks
+ $markup = trim($markup, "\n");
# merge consecutive dl elements
@@ -139,25 +145,27 @@ protected function blockFootnoteComplete($Block)
protected function blockDefinitionList($Line, $Block)
{
- if ( ! isset($Block) or isset($Block['type']))
+ if ( ! isset($Block) or $Block['type'] !== 'Paragraph')
{
return;
}
$Element = array(
'name' => 'dl',
- 'handler' => 'elements',
- 'text' => array(),
+ 'elements' => array(),
);
- $terms = explode("\n", $Block['element']['text']);
+ $terms = explode("\n", $Block['element']['handler']['argument']);
foreach ($terms as $term)
{
- $Element['text'] []= array(
+ $Element['elements'] []= array(
'name' => 'dt',
- 'handler' => 'line',
- 'text' => $term,
+ 'handler' => array(
+ 'function' => 'lineElements',
+ 'argument' => $term,
+ 'destination' => 'elements'
+ ),
);
}
@@ -185,15 +193,17 @@ protected function blockDefinitionListContinue($Line, array $Block)
if (isset($Block['interrupted']))
{
- $Block['dd']['handler'] = 'text';
- $Block['dd']['text'] .= "\n\n";
+ $Block['dd']['handler']['function'] = 'textElements';
+ $Block['dd']['handler']['argument'] .= "\n\n";
+
+ $Block['dd']['handler']['destination'] = 'elements';
unset($Block['interrupted']);
}
$text = substr($Line['body'], min($Line['indent'], 4));
- $Block['dd']['text'] .= "\n" . $text;
+ $Block['dd']['handler']['argument'] .= "\n" . $text;
return $Block;
}
@@ -206,17 +216,13 @@ 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))
+ if ($Block !== null && preg_match('/[ #]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['handler']['argument'], $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]);
+ $Block['element']['handler']['argument'] = substr($Block['element']['handler']['argument'], 0, $matches[0][1]);
}
return $Block;
@@ -225,11 +231,98 @@ protected function blockHeader($Line)
#
# Markup
+ protected function blockMarkup($Line)
+ {
+ if ($this->markupEscaped or $this->safeMode)
+ {
+ return;
+ }
+
+ if (preg_match('/^<(\w[\w-]*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches))
+ {
+ $element = strtolower($matches[1]);
+
+ if (in_array($element, $this->textLevelElements))
+ {
+ return;
+ }
+
+ $Block = array(
+ 'name' => $matches[1],
+ 'depth' => 0,
+ 'element' => array(
+ 'rawHtml' => $Line['text'],
+ 'autobreak' => true,
+ ),
+ );
+
+ $length = strlen($matches[0]);
+ $remainder = substr($Line['text'], $length);
+
+ if (trim($remainder) === '')
+ {
+ if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
+ {
+ $Block['closed'] = true;
+ $Block['void'] = true;
+ }
+ }
+ else
+ {
+ if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
+ {
+ return;
+ }
+ if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder))
+ {
+ $Block['closed'] = true;
+ }
+ }
+
+ return $Block;
+ }
+ }
+
+ protected function blockMarkupContinue($Line, array $Block)
+ {
+ if (isset($Block['closed']))
+ {
+ return;
+ }
+
+ if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open
+ {
+ $Block['depth'] ++;
+ }
+
+ if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close
+ {
+ if ($Block['depth'] > 0)
+ {
+ $Block['depth'] --;
+ }
+ else
+ {
+ $Block['closed'] = true;
+ }
+ }
+
+ if (isset($Block['interrupted']))
+ {
+ $Block['element']['rawHtml'] .= "\n";
+ unset($Block['interrupted']);
+ }
+
+ $Block['element']['rawHtml'] .= "\n".$Line['body'];
+
+ return $Block;
+ }
+
protected function blockMarkupComplete($Block)
{
if ( ! isset($Block['void']))
{
- $Block['markup'] = $this->processTag($Block['markup']);
+ $Block['element']['rawHtml'] = $this->processTag($Block['element']['rawHtml']);
}
return $Block;
@@ -242,17 +335,13 @@ 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))
+ if ($Block !== null && preg_match('/[ ]*{('.$this->regexAttribute.'+)}[ ]*$/', $Block['element']['handler']['argument'], $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]);
+ $Block['element']['handler']['argument'] = substr($Block['element']['handler']['argument'], 0, $matches[0][1]);
}
return $Block;
@@ -286,8 +375,7 @@ protected function inlineFootnoteMarker($Excerpt)
$Element = array(
'name' => 'sup',
'attributes' => array('id' => 'fnref'.$this->DefinitionData['Footnote'][$name]['count'].':'.$name),
- 'handler' => 'element',
- 'text' => array(
+ 'element' => array(
'name' => 'a',
'attributes' => array('href' => '#fn:'.$name, 'class' => 'footnote-ref'),
'text' => $this->DefinitionData['Footnote'][$name]['number'],
@@ -310,11 +398,7 @@ protected function inlineLink($Excerpt)
{
$Link = parent::inlineLink($Excerpt);
- if (! isset($Link)) {
- return null;
- }
-
- $remainder = substr($Excerpt['text'], $Link['extent']);
+ $remainder = $Link !== null ? substr($Excerpt['text'], $Link['extent']) : '';
if (preg_match('/^[ ]*{('.$this->regexAttribute.'+)}/', $remainder, $matches))
{
@@ -330,21 +414,52 @@ protected function inlineLink($Excerpt)
# ~
#
- protected function unmarkedText($text)
+ private $currentAbreviation;
+ private $currentMeaning;
+
+ protected function insertAbreviation(array $Element)
{
- $text = parent::unmarkedText($text);
+ if (isset($Element['text']))
+ {
+ $Element['elements'] = self::pregReplaceElements(
+ '/\b'.preg_quote($this->currentAbreviation, '/').'\b/',
+ array(
+ array(
+ 'name' => 'abbr',
+ 'attributes' => array(
+ 'title' => $this->currentMeaning,
+ ),
+ 'text' => $this->currentAbreviation,
+ )
+ ),
+ $Element['text']
+ );
+
+ unset($Element['text']);
+ }
+
+ return $Element;
+ }
+
+ protected function inlineText($text)
+ {
+ $Inline = parent::inlineText($text);
if (isset($this->DefinitionData['Abbreviation']))
{
foreach ($this->DefinitionData['Abbreviation'] as $abbreviation => $meaning)
{
- $pattern = '/\b'.preg_quote($abbreviation, '/').'\b/';
+ $this->currentAbreviation = $abbreviation;
+ $this->currentMeaning = $meaning;
- $text = preg_replace($pattern, ''.$abbreviation.'', $text);
+ $Inline['element'] = $this->elementApplyRecursiveDepthFirst(
+ array($this, 'insertAbreviation'),
+ $Inline['element']
+ );
}
}
- return $text;
+ return $Inline;
}
#
@@ -360,18 +475,21 @@ protected function addDdElement(array $Line, array $Block)
$Block['dd'] = array(
'name' => 'dd',
- 'handler' => 'line',
- 'text' => $text,
+ 'handler' => array(
+ 'function' => 'lineElements',
+ 'argument' => $text,
+ 'destination' => 'elements'
+ ),
);
if (isset($Block['interrupted']))
{
- $Block['dd']['handler'] = 'text';
+ $Block['dd']['handler']['function'] = 'textElements';
unset($Block['interrupted']);
}
- $Block['element']['text'] []= & $Block['dd'];
+ $Block['element']['elements'] []= & $Block['dd'];
return $Block;
}
@@ -381,15 +499,11 @@ protected function buildFootnoteElement()
$Element = array(
'name' => 'div',
'attributes' => array('class' => 'footnotes'),
- 'handler' => 'elements',
- 'text' => array(
- array(
- 'name' => 'hr',
- ),
+ 'elements' => array(
+ array('name' => 'hr'),
array(
'name' => 'ol',
- 'handler' => 'elements',
- 'text' => array(),
+ 'elements' => array(),
),
),
);
@@ -405,34 +519,68 @@ protected function buildFootnoteElement()
$text = $DefinitionData['text'];
- $text = parent::text($text);
+ $textElements = parent::textElements($text);
$numbers = range(1, $DefinitionData['count']);
- $backLinksMarkup = '';
+ $backLinkElements = array();
foreach ($numbers as $number)
{
- $backLinksMarkup .= ' ';
+ $backLinkElements[] = array('text' => ' ');
+ $backLinkElements[] = array(
+ 'name' => 'a',
+ 'attributes' => array(
+ 'href' => "#fnref$number:$definitionId",
+ 'rev' => 'footnote',
+ 'class' => 'footnote-backref',
+ ),
+ 'rawHtml' => '↩',
+ 'allowRawHtmlInSafeMode' => true,
+ 'autobreak' => false,
+ );
}
- $backLinksMarkup = substr($backLinksMarkup, 1);
+ unset($backLinkElements[0]);
- if (substr($text, - 4) === '
')
- {
- $backLinksMarkup = ' '.$backLinksMarkup;
+ $n = count($textElements) -1;
- $text = substr_replace($text, $backLinksMarkup.'', - 4);
+ if ($textElements[$n]['name'] === 'p')
+ {
+ $backLinkElements = array_merge(
+ array(
+ array(
+ 'rawHtml' => ' ',
+ 'allowRawHtmlInSafeMode' => true,
+ ),
+ ),
+ $backLinkElements
+ );
+
+ unset($textElements[$n]['name']);
+
+ $textElements[$n] = array(
+ 'name' => 'p',
+ 'elements' => array_merge(
+ array($textElements[$n]),
+ $backLinkElements
+ ),
+ );
}
else
{
- $text .= "\n".''.$backLinksMarkup.'
';
+ $textElements[] = array(
+ 'name' => 'p',
+ 'elements' => $backLinkElements
+ );
}
- $Element['text'][1]['text'] []= array(
+ $Element['elements'][1]['elements'] []= array(
'name' => 'li',
'attributes' => array('id' => 'fn:'.$definitionId),
- 'rawHtml' => "\n".$text."\n",
+ 'elements' => array_merge(
+ $textElements
+ ),
);
}