Merge pull request #439 from aidantwoods/patch-4

Improve CommonMark mixed-marker list compliance
This commit is contained in:
Aidan Woods 2018-03-27 11:31:34 +01:00 committed by GitHub
commit 2f291e0b2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 132 additions and 20 deletions

View File

@ -524,13 +524,31 @@ class Parsedown
protected function blockList($Line) protected function blockList($Line)
{ {
list($name, $pattern) = $Line['text'][0] <= '-' ? array('ul', '[*+-]') : array('ol', '[0-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]);
if ($contentIndent >= 5)
{
$contentIndent -= 1;
$matches[1] = substr($matches[1], 0, -$contentIndent);
$matches[3] = str_repeat(' ', $contentIndent) . $matches[3];
}
elseif ($contentIndent === 0)
{
$matches[1] .= ' ';
}
$Block = array( $Block = array(
'indent' => $Line['indent'], 'indent' => $Line['indent'],
'pattern' => $pattern, 'pattern' => $pattern,
'data' => array(
'type' => $name,
'marker' => $matches[1],
'markerType' => ($name === 'ul' ? strstr($matches[1], ' ', true) : substr(strstr($matches[1], ' ', true), -1)),
),
'element' => array( 'element' => array(
'name' => $name, 'name' => $name,
'handler' => 'elements', 'handler' => 'elements',
@ -539,7 +557,7 @@ class Parsedown
if($name === 'ol') if($name === 'ol')
{ {
$listStart = stristr($matches[0], '.', true); $listStart = ltrim(strstr($matches[1], $Block['data']['markerType'], true), '0') ?: '0';
if($listStart !== '1') if($listStart !== '1')
{ {
@ -550,9 +568,7 @@ class Parsedown
$Block['li'] = array( $Block['li'] = array(
'name' => 'li', 'name' => 'li',
'handler' => 'li', 'handler' => 'li',
'text' => array( 'text' => !empty($matches[3]) ? array($matches[3]) : array(),
$matches[2],
),
); );
$Block['element']['text'] []= & $Block['li']; $Block['element']['text'] []= & $Block['li'];
@ -563,7 +579,28 @@ class Parsedown
protected function blockListContinue($Line, array $Block) protected function blockListContinue($Line, array $Block)
{ {
if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches)) if (isset($Block['interrupted']) and empty($Block['li']['text']))
{
return null;
}
$requiredIndent = ($Block['indent'] + strlen($Block['data']['marker']));
if (
$Line['indent'] < $requiredIndent
and
(
(
$Block['data']['type'] === 'ol'
and preg_match('/^[0-9]+'.preg_quote($Block['data']['markerType']).'(?:[ ]+(.*)|$)/', $Line['text'], $matches)
)
or
(
$Block['data']['type'] === 'ul'
and preg_match('/^'.preg_quote($Block['data']['markerType']).'(?:[ ]+(.*)|$)/', $Line['text'], $matches)
)
)
)
{ {
if (isset($Block['interrupted'])) if (isset($Block['interrupted']))
{ {
@ -578,6 +615,8 @@ class Parsedown
$text = isset($matches[1]) ? $matches[1] : ''; $text = isset($matches[1]) ? $matches[1] : '';
$Block['indent'] = $Line['indent'];
$Block['li'] = array( $Block['li'] = array(
'name' => 'li', 'name' => 'li',
'handler' => 'li', 'handler' => 'li',
@ -590,31 +629,38 @@ class Parsedown
return $Block; return $Block;
} }
elseif ($Line['indent'] < $requiredIndent and $this->blockList($Line))
{
return null;
}
if ($Line['text'][0] === '[' and $this->blockReference($Line)) if ($Line['text'][0] === '[' and $this->blockReference($Line))
{ {
return $Block; return $Block;
} }
if ( ! isset($Block['interrupted'])) if ($Line['indent'] >= $requiredIndent)
{ {
$text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); if (isset($Block['interrupted']))
{
$Block['li']['text'] []= '';
unset($Block['interrupted']);
}
$text = substr($Line['body'], $requiredIndent);
$Block['li']['text'] []= $text; $Block['li']['text'] []= $text;
return $Block; return $Block;
} }
if ($Line['indent'] > 0) if ( ! isset($Block['interrupted']))
{ {
$Block['li']['text'] []= ''; $text = preg_replace('/^[ ]{0,'.$requiredIndent.'}/', '', $Line['body']);
$text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
$Block['li']['text'] []= $text; $Block['li']['text'] []= $text;
unset($Block['interrupted']);
return $Block; return $Block;
} }
} }

View File

@ -9,4 +9,32 @@
<li>li</li> <li>li</li>
</ul></li> </ul></li>
<li>li</li> <li>li</li>
</ul>
<hr />
<ul>
<li>level 1
<ul>
<li>level 2
<ul>
<li>level 3
<ul>
<li>level 4
<ul>
<li>level 5</li>
</ul></li>
</ul></li>
</ul></li>
</ul></li>
</ul>
<hr />
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
<li>f</li>
<li>g</li>
<li>h</li>
<li>i</li>
</ul> </ul>

View File

@ -3,4 +3,24 @@
- li - li
- li - li
- li - li
- li - li
---
- level 1
- level 2
- level 3
- level 4
- level 5
---
- a
- b
- c
- d
- e
- f
- g
- h
- i

View File

@ -2,9 +2,21 @@
<li>li</li> <li>li</li>
<li>li</li> <li>li</li>
</ul> </ul>
<p>mixed markers:</p> <p>mixed unordered markers:</p>
<ul> <ul>
<li>li</li> <li>li</li>
</ul>
<ul>
<li>li</li> <li>li</li>
</ul>
<ul>
<li>li</li> <li>li</li>
</ul> </ul>
<p>mixed ordered markers:</p>
<ol>
<li>starting at 1, list one</li>
<li>number 2, list one</li>
</ol>
<ol start="3">
<li>starting at 3, list two</li>
</ol>

View File

@ -1,8 +1,14 @@
- li - li
- li - li
mixed markers: mixed unordered markers:
* li * li
+ li + li
- li - li
mixed ordered markers:
1. starting at 1, list one
2. number 2, list one
3) starting at 3, list two