mirror of
https://github.com/erusev/parsedown.git
synced 2023-08-10 21:13:06 +03:00
Merge pull request #614 from aidantwoods/enhancement/performance-tweaks
General and performance tweaks
This commit is contained in:
commit
8d172a2994
295
Parsedown.php
295
Parsedown.php
@ -182,29 +182,17 @@ class Parsedown
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strpos($line, "\t") !== false)
|
while (($beforeTab = strstr($line, "\t", true)) !== false)
|
||||||
{
|
{
|
||||||
$parts = explode("\t", $line);
|
$shortage = 4 - mb_strlen($beforeTab, 'utf-8') % 4;
|
||||||
|
|
||||||
$line = $parts[0];
|
$line = $beforeTab
|
||||||
|
. str_repeat(' ', $shortage)
|
||||||
unset($parts[0]);
|
. substr($line, strlen($beforeTab) + 1)
|
||||||
|
;
|
||||||
foreach ($parts as $part)
|
|
||||||
{
|
|
||||||
$shortage = 4 - mb_strlen($line, 'utf-8') % 4;
|
|
||||||
|
|
||||||
$line .= str_repeat(' ', $shortage);
|
|
||||||
$line .= $part;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$indent = 0;
|
$indent = strspn($line, ' ');
|
||||||
|
|
||||||
while (isset($line[$indent]) and $line[$indent] === ' ')
|
|
||||||
{
|
|
||||||
$indent ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
$text = $indent > 0 ? substr($line, $indent) : $line;
|
$text = $indent > 0 ? substr($line, $indent) : $line;
|
||||||
|
|
||||||
@ -216,7 +204,8 @@ class Parsedown
|
|||||||
|
|
||||||
if (isset($CurrentBlock['continuable']))
|
if (isset($CurrentBlock['continuable']))
|
||||||
{
|
{
|
||||||
$Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock);
|
$methodName = 'block' . $CurrentBlock['type'] . 'Continue';
|
||||||
|
$Block = $this->$methodName($Line, $CurrentBlock);
|
||||||
|
|
||||||
if (isset($Block))
|
if (isset($Block))
|
||||||
{
|
{
|
||||||
@ -228,7 +217,8 @@ class Parsedown
|
|||||||
{
|
{
|
||||||
if ($this->isBlockCompletable($CurrentBlock['type']))
|
if ($this->isBlockCompletable($CurrentBlock['type']))
|
||||||
{
|
{
|
||||||
$CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
|
$methodName = 'block' . $CurrentBlock['type'] . 'Complete';
|
||||||
|
$CurrentBlock = $this->$methodName($CurrentBlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,7 +244,7 @@ class Parsedown
|
|||||||
|
|
||||||
foreach ($blockTypes as $blockType)
|
foreach ($blockTypes as $blockType)
|
||||||
{
|
{
|
||||||
$Block = $this->{'block'.$blockType}($Line, $CurrentBlock);
|
$Block = $this->{"block$blockType"}($Line, $CurrentBlock);
|
||||||
|
|
||||||
if (isset($Block))
|
if (isset($Block))
|
||||||
{
|
{
|
||||||
@ -309,7 +299,8 @@ class Parsedown
|
|||||||
|
|
||||||
if (isset($CurrentBlock['continuable']) and $this->isBlockCompletable($CurrentBlock['type']))
|
if (isset($CurrentBlock['continuable']) and $this->isBlockCompletable($CurrentBlock['type']))
|
||||||
{
|
{
|
||||||
$CurrentBlock = $this->{'block'.$CurrentBlock['type'].'Complete'}($CurrentBlock);
|
$methodName = 'block' . $CurrentBlock['type'] . 'Complete';
|
||||||
|
$CurrentBlock = $this->$methodName($CurrentBlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
# ~
|
# ~
|
||||||
@ -336,12 +327,12 @@ class Parsedown
|
|||||||
|
|
||||||
protected function isBlockContinuable($Type)
|
protected function isBlockContinuable($Type)
|
||||||
{
|
{
|
||||||
return method_exists($this, 'block'.$Type.'Continue');
|
return method_exists($this, 'block' . $Type . 'Continue');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function isBlockCompletable($Type)
|
protected function isBlockCompletable($Type)
|
||||||
{
|
{
|
||||||
return method_exists($this, 'block'.$Type.'Complete');
|
return method_exists($this, 'block' . $Type . 'Complete');
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -393,15 +384,6 @@ class Parsedown
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function blockCodeComplete($Block)
|
|
||||||
{
|
|
||||||
$text = $Block['element']['element']['text'];
|
|
||||||
|
|
||||||
$Block['element']['element']['text'] = $text;
|
|
||||||
|
|
||||||
return $Block;
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Comment
|
# Comment
|
||||||
|
|
||||||
@ -452,33 +434,42 @@ class Parsedown
|
|||||||
|
|
||||||
protected function blockFencedCode($Line)
|
protected function blockFencedCode($Line)
|
||||||
{
|
{
|
||||||
if (preg_match('/^(['.$Line['text'][0].']{3,})[ ]*([^`]+)?[ ]*$/', $Line['text'], $matches))
|
$marker = $Line['text'][0];
|
||||||
|
|
||||||
|
$openerLength = strspn($Line['text'], $marker);
|
||||||
|
|
||||||
|
if ($openerLength < 3)
|
||||||
{
|
{
|
||||||
$Element = array(
|
return;
|
||||||
'name' => 'code',
|
|
||||||
'text' => '',
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isset($matches[2]))
|
|
||||||
{
|
|
||||||
$class = 'language-'.$matches[2];
|
|
||||||
|
|
||||||
$Element['attributes'] = array(
|
|
||||||
'class' => $class,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
$Block = array(
|
|
||||||
'char' => $Line['text'][0],
|
|
||||||
'openerLength' => mb_strlen($matches[1]),
|
|
||||||
'element' => array(
|
|
||||||
'name' => 'pre',
|
|
||||||
'element' => $Element,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
return $Block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$infostring = trim(substr($Line['text'], $openerLength), "\t ");
|
||||||
|
|
||||||
|
if (strpos($infostring, '`') !== false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$Element = array(
|
||||||
|
'name' => 'code',
|
||||||
|
'text' => '',
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($infostring !== '')
|
||||||
|
{
|
||||||
|
$Element['attributes'] = array('class' => "language-$infostring");
|
||||||
|
}
|
||||||
|
|
||||||
|
$Block = array(
|
||||||
|
'char' => $marker,
|
||||||
|
'openerLength' => $openerLength,
|
||||||
|
'element' => array(
|
||||||
|
'name' => 'pre',
|
||||||
|
'element' => $Element,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $Block;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function blockFencedCodeContinue($Line, $Block)
|
protected function blockFencedCodeContinue($Line, $Block)
|
||||||
@ -495,9 +486,8 @@ class Parsedown
|
|||||||
unset($Block['interrupted']);
|
unset($Block['interrupted']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (($len = strspn($Line['text'], $Block['char'])) >= $Block['openerLength']
|
||||||
preg_match('/^(['.preg_quote($Block['char']).']{3,})[ ]*$/', $Line['text'], $matches)
|
and chop(substr($Line['text'], $len), ' ') === ''
|
||||||
and mb_strlen($matches[1]) >= $Block['openerLength']
|
|
||||||
) {
|
) {
|
||||||
$Block['element']['element']['text'] = substr($Block['element']['element']['text'], 1);
|
$Block['element']['element']['text'] = substr($Block['element']['element']['text'], 1);
|
||||||
|
|
||||||
@ -506,16 +496,7 @@ class Parsedown
|
|||||||
return $Block;
|
return $Block;
|
||||||
}
|
}
|
||||||
|
|
||||||
$Block['element']['element']['text'] .= "\n".$Line['body'];
|
$Block['element']['element']['text'] .= "\n" . $Line['body'];
|
||||||
|
|
||||||
return $Block;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function blockFencedCodeComplete($Block)
|
|
||||||
{
|
|
||||||
$text = $Block['element']['element']['text'];
|
|
||||||
|
|
||||||
$Block['element']['element']['text'] = $text;
|
|
||||||
|
|
||||||
return $Block;
|
return $Block;
|
||||||
}
|
}
|
||||||
@ -525,12 +506,7 @@ class Parsedown
|
|||||||
|
|
||||||
protected function blockHeader($Line)
|
protected function blockHeader($Line)
|
||||||
{
|
{
|
||||||
$level = 1;
|
$level = strspn($Line['text'], '#');
|
||||||
|
|
||||||
while (isset($Line['text'][$level]) and $Line['text'][$level] === '#')
|
|
||||||
{
|
|
||||||
$level ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($level > 6)
|
if ($level > 6)
|
||||||
{
|
{
|
||||||
@ -565,9 +541,9 @@ class Parsedown
|
|||||||
|
|
||||||
protected function blockList($Line, array $CurrentBlock = null)
|
protected function blockList($Line, array $CurrentBlock = null)
|
||||||
{
|
{
|
||||||
list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]{1,9}[.\)]');
|
list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-9]{1,9}+[.\)]');
|
||||||
|
|
||||||
if (preg_match('/^('.$pattern.'([ ]+|$))(.*)/', $Line['text'], $matches))
|
if (preg_match('/^('.$pattern.'([ ]++|$))(.*+)/', $Line['text'], $matches))
|
||||||
{
|
{
|
||||||
$contentIndent = strlen($matches[2]);
|
$contentIndent = strlen($matches[2]);
|
||||||
|
|
||||||
@ -582,19 +558,22 @@ class Parsedown
|
|||||||
$matches[1] .= ' ';
|
$matches[1] .= ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$markerWithoutWhitespace = strstr($matches[1], ' ', true);
|
||||||
|
|
||||||
$Block = array(
|
$Block = array(
|
||||||
'indent' => $Line['indent'],
|
'indent' => $Line['indent'],
|
||||||
'pattern' => $pattern,
|
'pattern' => $pattern,
|
||||||
'data' => array(
|
'data' => array(
|
||||||
'type' => $name,
|
'type' => $name,
|
||||||
'marker' => $matches[1],
|
'marker' => $matches[1],
|
||||||
'markerType' => ($name === 'ul' ? strstr($matches[1], ' ', true) : substr(strstr($matches[1], ' ', true), -1)),
|
'markerType' => ($name === 'ul' ? $markerWithoutWhitespace : substr($markerWithoutWhitespace, -1)),
|
||||||
),
|
),
|
||||||
'element' => array(
|
'element' => array(
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'elements' => array(),
|
'elements' => array(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
$Block['data']['markerTypeRegex'] = preg_quote($Block['data']['markerType'], '/');
|
||||||
|
|
||||||
if ($name === 'ol')
|
if ($name === 'ol')
|
||||||
{
|
{
|
||||||
@ -642,10 +621,10 @@ class Parsedown
|
|||||||
and (
|
and (
|
||||||
(
|
(
|
||||||
$Block['data']['type'] === 'ol'
|
$Block['data']['type'] === 'ol'
|
||||||
and preg_match('/^[0-9]+'.preg_quote($Block['data']['markerType']).'(?:[ ]+(.*)|$)/', $Line['text'], $matches)
|
and preg_match('/^[0-9]++'.$Block['data']['markerTypeRegex'].'(?:[ ]++(.*)|$)/', $Line['text'], $matches)
|
||||||
) or (
|
) or (
|
||||||
$Block['data']['type'] === 'ul'
|
$Block['data']['type'] === 'ul'
|
||||||
and preg_match('/^'.preg_quote($Block['data']['markerType']).'(?:[ ]+(.*)|$)/', $Line['text'], $matches)
|
and preg_match('/^'.$Block['data']['markerTypeRegex'].'(?:[ ]++(.*)|$)/', $Line['text'], $matches)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
@ -707,7 +686,7 @@ class Parsedown
|
|||||||
|
|
||||||
if ( ! isset($Block['interrupted']))
|
if ( ! isset($Block['interrupted']))
|
||||||
{
|
{
|
||||||
$text = preg_replace('/^[ ]{0,'.$requiredIndent.'}/', '', $Line['body']);
|
$text = preg_replace('/^[ ]{0,'.$requiredIndent.'}+/', '', $Line['body']);
|
||||||
|
|
||||||
$Block['li']['handler']['argument'] []= $text;
|
$Block['li']['handler']['argument'] []= $text;
|
||||||
|
|
||||||
@ -736,7 +715,7 @@ class Parsedown
|
|||||||
|
|
||||||
protected function blockQuote($Line)
|
protected function blockQuote($Line)
|
||||||
{
|
{
|
||||||
if (preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
|
if (preg_match('/^>[ ]?+(.*+)/', $Line['text'], $matches))
|
||||||
{
|
{
|
||||||
$Block = array(
|
$Block = array(
|
||||||
'element' => array(
|
'element' => array(
|
||||||
@ -760,7 +739,7 @@ class Parsedown
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($Line['text'][0] === '>' and preg_match('/^>[ ]?(.*)/', $Line['text'], $matches))
|
if ($Line['text'][0] === '>' and preg_match('/^>[ ]?+(.*+)/', $Line['text'], $matches))
|
||||||
{
|
{
|
||||||
$Block['element']['handler']['argument'] []= $matches[1];
|
$Block['element']['handler']['argument'] []= $matches[1];
|
||||||
|
|
||||||
@ -780,7 +759,9 @@ class Parsedown
|
|||||||
|
|
||||||
protected function blockRule($Line)
|
protected function blockRule($Line)
|
||||||
{
|
{
|
||||||
if (preg_match('/^(['.$Line['text'][0].'])([ ]*\1){2,}[ ]*$/', $Line['text']))
|
$marker = $Line['text'][0];
|
||||||
|
|
||||||
|
if (substr_count($Line['text'], $marker) >= 3 and chop($Line['text'], " $marker") === '')
|
||||||
{
|
{
|
||||||
$Block = array(
|
$Block = array(
|
||||||
'element' => array(
|
'element' => array(
|
||||||
@ -802,10 +783,8 @@ class Parsedown
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if ($Line['indent'] < 4 and chop(chop($Line['text'], ' '), $Line['text'][0]) === '')
|
||||||
chop(chop($Line['text'], ' '), $Line['text'][0]) === ''
|
{
|
||||||
and $Line['indent'] < 4
|
|
||||||
) {
|
|
||||||
$Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2';
|
$Block['element']['name'] = $Line['text'][0] === '=' ? 'h1' : 'h2';
|
||||||
|
|
||||||
return $Block;
|
return $Block;
|
||||||
@ -822,7 +801,7 @@ class Parsedown
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preg_match('/^<[\/]?+(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches))
|
if (preg_match('/^<[\/]?+(\w*)(?:[ ]*+'.$this->regexHtmlAttribute.')*+[ ]*+(\/)?>/', $Line['text'], $matches))
|
||||||
{
|
{
|
||||||
$element = strtolower($matches[1]);
|
$element = strtolower($matches[1]);
|
||||||
|
|
||||||
@ -850,7 +829,7 @@ class Parsedown
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$Block['element']['rawHtml'] .= "\n".$Line['body'];
|
$Block['element']['rawHtml'] .= "\n" . $Line['body'];
|
||||||
|
|
||||||
return $Block;
|
return $Block;
|
||||||
}
|
}
|
||||||
@ -860,8 +839,9 @@ class Parsedown
|
|||||||
|
|
||||||
protected function blockReference($Line)
|
protected function blockReference($Line)
|
||||||
{
|
{
|
||||||
if (preg_match('/^\[(.+?)\]:[ ]*<?(\S+?)>?(?:[ ]+["\'(](.+)["\')])?[ ]*$/', $Line['text'], $matches))
|
if (strpos($Line['text'], ']') !== false
|
||||||
{
|
and preg_match('/^\[(.+?)\]:[ ]*+<?(\S+?)>?(?:[ ]+["\'(](.+)["\')])?[ ]*+$/', $Line['text'], $matches)
|
||||||
|
) {
|
||||||
$id = strtolower($matches[1]);
|
$id = strtolower($matches[1]);
|
||||||
|
|
||||||
$Data = array(
|
$Data = array(
|
||||||
@ -970,7 +950,7 @@ class Parsedown
|
|||||||
$alignment = $alignments[$index];
|
$alignment = $alignments[$index];
|
||||||
|
|
||||||
$HeaderElement['attributes'] = array(
|
$HeaderElement['attributes'] = array(
|
||||||
'style' => 'text-align: '.$alignment.';',
|
'style' => "text-align: $alignment;",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1021,7 +1001,7 @@ class Parsedown
|
|||||||
$row = trim($row);
|
$row = trim($row);
|
||||||
$row = trim($row, '|');
|
$row = trim($row, '|');
|
||||||
|
|
||||||
preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches);
|
preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]++`|`)++/', $row, $matches);
|
||||||
|
|
||||||
$cells = array_slice($matches[0], 0, count($Block['alignments']));
|
$cells = array_slice($matches[0], 0, count($Block['alignments']));
|
||||||
|
|
||||||
@ -1041,7 +1021,7 @@ class Parsedown
|
|||||||
if (isset($Block['alignments'][$index]))
|
if (isset($Block['alignments'][$index]))
|
||||||
{
|
{
|
||||||
$Element['attributes'] = array(
|
$Element['attributes'] = array(
|
||||||
'style' => 'text-align: '.$Block['alignments'][$index].';',
|
'style' => 'text-align: ' . $Block['alignments'][$index] . ';',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1115,7 +1095,7 @@ class Parsedown
|
|||||||
# ~
|
# ~
|
||||||
#
|
#
|
||||||
|
|
||||||
public function line($text, $nonNestables=array())
|
public function line($text, $nonNestables = array())
|
||||||
{
|
{
|
||||||
return $this->elements($this->lineElements($text, $nonNestables));
|
return $this->elements($this->lineElements($text, $nonNestables));
|
||||||
}
|
}
|
||||||
@ -1124,13 +1104,18 @@ class Parsedown
|
|||||||
{
|
{
|
||||||
$Elements = array();
|
$Elements = array();
|
||||||
|
|
||||||
|
$nonNestables = (empty($nonNestables)
|
||||||
|
? array()
|
||||||
|
: array_combine($nonNestables, $nonNestables)
|
||||||
|
);
|
||||||
|
|
||||||
# $excerpt is based on the first occurrence of a marker
|
# $excerpt is based on the first occurrence of a marker
|
||||||
|
|
||||||
while ($excerpt = strpbrk($text, $this->inlineMarkerList))
|
while ($excerpt = strpbrk($text, $this->inlineMarkerList))
|
||||||
{
|
{
|
||||||
$marker = $excerpt[0];
|
$marker = $excerpt[0];
|
||||||
|
|
||||||
$markerPosition = strpos($text, $marker);
|
$markerPosition = strlen($text) - strlen($excerpt);
|
||||||
|
|
||||||
$Excerpt = array('text' => $excerpt, 'context' => $text);
|
$Excerpt = array('text' => $excerpt, 'context' => $text);
|
||||||
|
|
||||||
@ -1138,12 +1123,12 @@ class Parsedown
|
|||||||
{
|
{
|
||||||
# check to see if the current inline type is nestable in the current context
|
# check to see if the current inline type is nestable in the current context
|
||||||
|
|
||||||
if ( ! empty($nonNestables) and in_array($inlineType, $nonNestables))
|
if (isset($nonNestables[$inlineType]))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$Inline = $this->{'inline'.$inlineType}($Excerpt);
|
$Inline = $this->{"inline$inlineType"}($Excerpt);
|
||||||
|
|
||||||
if ( ! isset($Inline))
|
if ( ! isset($Inline))
|
||||||
{
|
{
|
||||||
@ -1166,10 +1151,11 @@ class Parsedown
|
|||||||
|
|
||||||
# cause the new element to 'inherit' our non nestables
|
# cause the new element to 'inherit' our non nestables
|
||||||
|
|
||||||
foreach ($nonNestables as $non_nestable)
|
|
||||||
{
|
$Inline['element']['nonNestables'] = isset($Inline['element']['nonNestables'])
|
||||||
$Inline['element']['nonNestables'][] = $non_nestable;
|
? array_merge($Inline['element']['nonNestables'], $nonNestables)
|
||||||
}
|
: $nonNestables
|
||||||
|
;
|
||||||
|
|
||||||
# the text that comes before the inline
|
# the text that comes before the inline
|
||||||
$unmarkedText = substr($text, 0, $Inline['position']);
|
$unmarkedText = substr($text, 0, $Inline['position']);
|
||||||
@ -1200,14 +1186,13 @@ class Parsedown
|
|||||||
$InlineText = $this->inlineText($text);
|
$InlineText = $this->inlineText($text);
|
||||||
$Elements[] = $InlineText['element'];
|
$Elements[] = $InlineText['element'];
|
||||||
|
|
||||||
$Elements = array_map(
|
foreach ($Elements as &$Element)
|
||||||
function ($Element) {
|
{
|
||||||
$Element['autobreak'] = isset($Element['autobreak'])
|
if ( ! isset($Element['autobreak']))
|
||||||
? $Element['autobreak'] : false;
|
{
|
||||||
return $Element;
|
$Element['autobreak'] = false;
|
||||||
},
|
}
|
||||||
$Elements
|
}
|
||||||
);
|
|
||||||
|
|
||||||
return $Elements;
|
return $Elements;
|
||||||
}
|
}
|
||||||
@ -1220,33 +1205,17 @@ class Parsedown
|
|||||||
{
|
{
|
||||||
$Inline = array(
|
$Inline = array(
|
||||||
'extent' => strlen($text),
|
'extent' => strlen($text),
|
||||||
'element' => array(
|
'element' => array(),
|
||||||
'elements' => array(),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if ($this->breaksEnabled)
|
$safeText = self::escape($text, true);
|
||||||
{
|
|
||||||
$Inline['element']['elements'] = self::pregReplaceElements(
|
$Inline['element']['rawHtml'] = preg_replace(
|
||||||
'/[ ]*\n/',
|
$this->breaksEnabled ? '/[ ]*+\n/' : '/(?:[ ]*+\\\\|[ ]{2,}+)\n/',
|
||||||
array(
|
"<br />\n",
|
||||||
array('name' => 'br'),
|
$safeText
|
||||||
array('text' => "\n"),
|
);
|
||||||
),
|
$Inline['element']['allowRawHtmlInSafeMode'] = true;
|
||||||
$text
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$Inline['element']['elements'] = self::pregReplaceElements(
|
|
||||||
'/(?:[ ][ ]+|[ ]*\\\\)\n/',
|
|
||||||
array(
|
|
||||||
array('name' => 'br'),
|
|
||||||
array('text' => "\n"),
|
|
||||||
),
|
|
||||||
$text
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $Inline;
|
return $Inline;
|
||||||
}
|
}
|
||||||
@ -1255,10 +1224,10 @@ class Parsedown
|
|||||||
{
|
{
|
||||||
$marker = $Excerpt['text'][0];
|
$marker = $Excerpt['text'][0];
|
||||||
|
|
||||||
if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(?<!'.$marker.')\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
|
if (preg_match('/^(['.$marker.']++)[ ]*+(.+?)[ ]*+(?<!['.$marker.'])\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
|
||||||
{
|
{
|
||||||
$text = $matches[2];
|
$text = $matches[2];
|
||||||
$text = preg_replace("/[ ]*\n/", ' ', $text);
|
$text = preg_replace('/[ ]*+\n/', ' ', $text);
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'extent' => strlen($matches[0]),
|
'extent' => strlen($matches[0]),
|
||||||
@ -1284,7 +1253,7 @@ class Parsedown
|
|||||||
|
|
||||||
if ( ! isset($matches[2]))
|
if ( ! isset($matches[2]))
|
||||||
{
|
{
|
||||||
$url = 'mailto:' . $url;
|
$url = "mailto:$url";
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
@ -1414,7 +1383,7 @@ class Parsedown
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*"|\'[^\']*\'))?\s*[)]/', $remainder, $matches))
|
if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*+"|\'[^\']*+\'))?\s*+[)]/', $remainder, $matches))
|
||||||
{
|
{
|
||||||
$Element['attributes']['href'] = $matches[1];
|
$Element['attributes']['href'] = $matches[1];
|
||||||
|
|
||||||
@ -1463,7 +1432,7 @@ class Parsedown
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w[\w-]*[ ]*>/s', $Excerpt['text'], $matches))
|
if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w[\w-]*+[ ]*+>/s', $Excerpt['text'], $matches))
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'element' => array('rawHtml' => $matches[0]),
|
'element' => array('rawHtml' => $matches[0]),
|
||||||
@ -1471,7 +1440,7 @@ class Parsedown
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($Excerpt['text'][1] === '!' and preg_match('/^<!---?[^>-](?:-?[^-])*-->/s', $Excerpt['text'], $matches))
|
if ($Excerpt['text'][1] === '!' and preg_match('/^<!---?[^>-](?:-?+[^-])*-->/s', $Excerpt['text'], $matches))
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'element' => array('rawHtml' => $matches[0]),
|
'element' => array('rawHtml' => $matches[0]),
|
||||||
@ -1479,7 +1448,7 @@ class Parsedown
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w[\w-]*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches))
|
if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w[\w-]*+(?:[ ]*+'.$this->regexHtmlAttribute.')*+[ ]*+\/?>/s', $Excerpt['text'], $matches))
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'element' => array('rawHtml' => $matches[0]),
|
'element' => array('rawHtml' => $matches[0]),
|
||||||
@ -1490,10 +1459,11 @@ class Parsedown
|
|||||||
|
|
||||||
protected function inlineSpecialCharacter($Excerpt)
|
protected function inlineSpecialCharacter($Excerpt)
|
||||||
{
|
{
|
||||||
if (preg_match('/^&(#?+[0-9a-zA-Z]++);/', $Excerpt['text'], $matches))
|
if ($Excerpt['text'][1] !== ' ' and strpos($Excerpt['text'], ';') !== false
|
||||||
{
|
and preg_match('/^&(#?+[0-9a-zA-Z]++);/', $Excerpt['text'], $matches)
|
||||||
|
) {
|
||||||
return array(
|
return array(
|
||||||
'element' => array('rawHtml' => '&'.$matches[1].';'),
|
'element' => array('rawHtml' => '&' . $matches[1] . ';'),
|
||||||
'extent' => strlen($matches[0]),
|
'extent' => strlen($matches[0]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1531,8 +1501,9 @@ class Parsedown
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE))
|
if (strpos($Excerpt['context'], 'http') !== false
|
||||||
{
|
and preg_match('/\bhttps?+:[\/]{2}[^\s<]+\b\/*+/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)
|
||||||
|
) {
|
||||||
$url = $matches[0][0];
|
$url = $matches[0][0];
|
||||||
|
|
||||||
$Inline = array(
|
$Inline = array(
|
||||||
@ -1553,7 +1524,7 @@ class Parsedown
|
|||||||
|
|
||||||
protected function inlineUrlTag($Excerpt)
|
protected function inlineUrlTag($Excerpt)
|
||||||
{
|
{
|
||||||
if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches))
|
if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w++:\/{2}[^ >]++)>/i', $Excerpt['text'], $matches))
|
||||||
{
|
{
|
||||||
$url = $matches[1];
|
$url = $matches[1];
|
||||||
|
|
||||||
@ -1611,9 +1582,9 @@ class Parsedown
|
|||||||
{
|
{
|
||||||
$Element = $this->handle($Element);
|
$Element = $this->handle($Element);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unset($Element['handler']);
|
unset($Element['handler']);
|
||||||
|
}
|
||||||
|
|
||||||
return $Element;
|
return $Element;
|
||||||
}
|
}
|
||||||
@ -1696,7 +1667,7 @@ class Parsedown
|
|||||||
|
|
||||||
if ($hasName)
|
if ($hasName)
|
||||||
{
|
{
|
||||||
$markup .= '<'.$Element['name'];
|
$markup .= '<' . $Element['name'];
|
||||||
|
|
||||||
if (isset($Element['attributes']))
|
if (isset($Element['attributes']))
|
||||||
{
|
{
|
||||||
@ -1707,7 +1678,7 @@ class Parsedown
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$markup .= ' '.$name.'="'.self::escape($value).'"';
|
$markup .= " $name=\"".self::escape($value).'"';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1754,7 +1725,7 @@ class Parsedown
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$markup .= $hasName ? '</'.$Element['name'].'>' : '';
|
$markup .= $hasName ? '</' . $Element['name'] . '>' : '';
|
||||||
}
|
}
|
||||||
elseif ($hasName)
|
elseif ($hasName)
|
||||||
{
|
{
|
||||||
@ -1777,8 +1748,8 @@ class Parsedown
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$autoBreakNext = (isset($Element['autobreak']) && $Element['autobreak']
|
$autoBreakNext = (isset($Element['autobreak'])
|
||||||
|| ! isset($Element['autobreak']) && isset($Element['name'])
|
? $Element['autobreak'] : isset($Element['name'])
|
||||||
);
|
);
|
||||||
// (autobreak === false) covers both sides of an element
|
// (autobreak === false) covers both sides of an element
|
||||||
$autoBreak = !$autoBreak ? $autoBreak : $autoBreakNext;
|
$autoBreak = !$autoBreak ? $autoBreak : $autoBreakNext;
|
||||||
@ -1959,8 +1930,8 @@ class Parsedown
|
|||||||
);
|
);
|
||||||
|
|
||||||
protected $StrongRegex = array(
|
protected $StrongRegex = array(
|
||||||
'*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s',
|
'*' => '/^[*]{2}((?:\\\\\*|[^*]|[*][^*]*+[*])+?)[*]{2}(?![*])/s',
|
||||||
'_' => '/^__((?:\\\\_|[^_]|_[^_]*_)+?)__(?!_)/us',
|
'_' => '/^__((?:\\\\_|[^_]|_[^_]*+_)+?)__(?!_)/us',
|
||||||
);
|
);
|
||||||
|
|
||||||
protected $EmRegex = array(
|
protected $EmRegex = array(
|
||||||
@ -1968,7 +1939,7 @@ class Parsedown
|
|||||||
'_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us',
|
'_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us',
|
||||||
);
|
);
|
||||||
|
|
||||||
protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*(?:\s*=\s*(?:[^"\'=<>`\s]+|"[^"]*"|\'[^\']*\'))?';
|
protected $regexHtmlAttribute = '[a-zA-Z_:][\w:.-]*+(?:\s*+=\s*+(?:[^"\'=<>`\s]+|"[^"]*+"|\'[^\']*+\'))?+';
|
||||||
|
|
||||||
protected $voidElements = array(
|
protected $voidElements = array(
|
||||||
'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source',
|
'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source',
|
||||||
|
Loading…
Reference in New Issue
Block a user