no need to know the structure of markup blocks

This commit is contained in:
Emanuil Rusev 2015-01-11 02:14:45 +02:00
parent 4aca208f96
commit 15a32fcd0e

View File

@ -673,78 +673,48 @@ class Parsedown
return; return;
} }
$attrName = '[a-zA-Z_:][\w:.-]*'; if (preg_match('/^<(\w*)(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*(\/)?>/', $Line['text'], $matches))
$attrValue = '(?:[^"\'=<>`\s]+|".*?"|\'.*?\')'; {
if (in_array($matches[1], $this->textLevelElements))
preg_match('/^<(\w[\d\w]*)((?:\s'.$attrName.'(?:\s*=\s*'.$attrValue.')?)*)\s*(\/?)>/', $Line['text'], $matches);
if ( ! $matches or in_array($matches[1], $this->textLevelElements))
{ {
return; return;
} }
$Block = array( $Block = array(
'name' => $matches[1],
'depth' => 0, 'depth' => 0,
'element' => array( 'element' => array(
'name' => $matches[1], 'text' => $Line['text'],
'text' => null,
), ),
); );
$remainder = substr($Line['text'], strlen($matches[0])); $length = strlen($matches[0]);
$remainder = substr($Line['text'], $length);
if (trim($remainder) === '') if (trim($remainder) === '')
{ {
if ($matches[3] or in_array($matches[1], $this->voidElements)) if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
{ {
$Block['closed'] = true; $Block['closed'] = true;
} }
} }
else else
{ {
if ($matches[3] or in_array($matches[1], $this->voidElements)) if (isset($matches[2]) or in_array($matches[1], $this->voidElements))
{ {
return; return;
} }
preg_match('/(.*)<\/'.$matches[1].'>\s*$/i', $remainder, $nestedMatches); if (preg_match('/<\/'.$matches[1].'>[ ]*$/i', $remainder))
if ($nestedMatches)
{ {
$Block['closed'] = true; $Block['closed'] = true;
$Block['element']['text'] = $nestedMatches[1];
}
else
{
$Block['element']['text'] = $remainder;
}
}
if ( ! $matches[2])
{
return $Block;
}
preg_match_all('/\s('.$attrName.')(?:\s*=\s*('.$attrValue.'))?/', $matches[2], $nestedMatches, PREG_SET_ORDER);
foreach ($nestedMatches as $nestedMatch)
{
if ( ! isset($nestedMatch[2]))
{
$Block['element']['attributes'][$nestedMatch[1]] = '';
}
elseif ($nestedMatch[2][0] === '"' or $nestedMatch[2][0] === '\'')
{
$Block['element']['attributes'][$nestedMatch[1]] = substr($nestedMatch[2], 1, - 1);
}
else
{
$Block['element']['attributes'][$nestedMatch[1]] = $nestedMatch[2];
} }
} }
return $Block; return $Block;
} }
}
protected function blockMarkupContinue($Line, array $Block) protected function blockMarkupContinue($Line, array $Block)
{ {
@ -753,12 +723,12 @@ class Parsedown
return; return;
} }
if (preg_match('/^<'.$Block['element']['name'].'(?:\s.*[\'"])?\s*>/i', $Line['text'])) # open if (preg_match('/^<'.$Block['name'].'(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*>/i', $Line['text'])) # open
{ {
$Block['depth'] ++; $Block['depth'] ++;
} }
if (preg_match('/(.*?)<\/'.$Block['element']['name'].'>\s*$/i', $Line['text'], $matches)) # close if (preg_match('/(.*?)<\/'.$Block['name'].'>[ ]*$/i', $Line['text'], $matches)) # close
{ {
if ($Block['depth'] > 0) if ($Block['depth'] > 0)
{ {
@ -766,8 +736,6 @@ class Parsedown
} }
else else
{ {
$Block['element']['text'] .= "\n";
$Block['closed'] = true; $Block['closed'] = true;
} }
@ -781,10 +749,7 @@ class Parsedown
unset($Block['interrupted']); unset($Block['interrupted']);
} }
if ( ! isset($Block['closed']))
{
$Block['element']['text'] .= "\n".$Line['body']; $Block['element']['text'] .= "\n".$Line['body'];
}
return $Block; return $Block;
} }
@ -1569,6 +1534,8 @@ class Parsedown
'_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us', '_' => '/^_((?:\\\\_|[^_]|__[^_]*__)+?)_(?!_)\b/us',
); );
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',
); );