From eb853da92aef802deee84ea46476b14318ce3b12 Mon Sep 17 00:00:00 2001 From: Daniel Rudolf Date: Thu, 13 Oct 2016 19:25:30 +0200 Subject: [PATCH 01/10] Revert "Prevent breaking remaining previously compliant CommonMarkWeak tests" This reverts commit 6973302ca8f6f8613cd76488ad3f87067458e215. --- Parsedown.php | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Parsedown.php b/Parsedown.php index e6a4799..f774b88 100644 --- a/Parsedown.php +++ b/Parsedown.php @@ -165,7 +165,7 @@ class Parsedown if (isset($CurrentBlock['continuable'])) { - $Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock, $parentType); + $Block = $this->{'block'.$CurrentBlock['type'].'Continue'}($Line, $CurrentBlock); if (isset($Block)) { @@ -449,7 +449,7 @@ class Parsedown } } - protected function blockFencedCodeContinue($Line, $Block, $parentType) + protected function blockFencedCodeContinue($Line, $Block) { if (isset($Block['complete'])) { @@ -472,11 +472,6 @@ class Parsedown return $Block; } - if ($parentType === 'List') - { - $Line['body'] = preg_replace('/^[ ]{0,'.min(4, $Line['indent']).'}/', '', $Line['body']); - } - $Block['element']['text']['text'] .= "\n".$Line['body'];; return $Block; From e691034861679341341d9cde4fcbf0a8cabb75d3 Mon Sep 17 00:00:00 2001 From: Daniel Rudolf Date: Thu, 13 Oct 2016 19:25:37 +0200 Subject: [PATCH 02/10] Revert "Prevent failure with data set 77 in CommonMarkWeak" This reverts commit 0a43799da4f6b10d9fc3bdbb6482e2e1713fb79f. --- Parsedown.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/Parsedown.php b/Parsedown.php index f774b88..2ee8417 100644 --- a/Parsedown.php +++ b/Parsedown.php @@ -115,7 +115,7 @@ class Parsedown # Blocks # - protected function lines(array $lines, $parentType = null) + protected function lines(array $lines) { $CurrentBlock = null; @@ -216,12 +216,6 @@ class Parsedown $blockTypes = array_merge($highPriority, $blockTypes); - if ( $parentType === 'List' and ($a = array_search('List', $blockTypes)) !== false and ($b = array_search('Code', $blockTypes)) !== false and $a > $b and ($placeholder = $this->blockList($Line))) - { - unset($blockTypes[$b]); - array_splice($blockTypes, $a + 1, 0, 'Code'); - } - # # ~ @@ -1508,7 +1502,7 @@ class Parsedown protected function li($lines) { - $markup = $this->lines($lines, 'List'); + $markup = $this->lines($lines); $trimmedMarkup = trim($markup); From 81025cd468f4f51eebedd2c159be893bfa414602 Mon Sep 17 00:00:00 2001 From: Daniel Rudolf Date: Thu, 13 Oct 2016 19:25:43 +0200 Subject: [PATCH 03/10] Revert "Break less previously passed CommonMarkWeak tests" This reverts commit 2db31995104f9ad31b9b1a10f8cf2be9d7a32441. --- Parsedown.php | 31 +++++-------------------------- 1 file changed, 5 insertions(+), 26 deletions(-) diff --git a/Parsedown.php b/Parsedown.php index 2ee8417..bb2bd11 100644 --- a/Parsedown.php +++ b/Parsedown.php @@ -188,34 +188,16 @@ class Parsedown # ~ - $highPriority = array(); - $blockTypes = $this->unmarkedBlockTypes; if (isset($this->BlockTypes[$marker])) { foreach ($this->BlockTypes[$marker] as $blockType) { - if - ( - isset($CurrentBlock['type']) - and $CurrentBlock['type'] === $blockType - and ! isset($CurrentBlock['interrupted']) - and isset($CurrentBlock['continuable']) - and ! isset($CurrentBlock['complete']) - ) - { - $highPriority[] = $CurrentBlock['type']; - } - else - { - $blockTypes []= $blockType; - } + $blockTypes []= $blockType; } } - $blockTypes = array_merge($highPriority, $blockTypes); - # # ~ @@ -607,6 +589,8 @@ class Parsedown return null; } + unset($placeholder); + if ($Line['text'][0] === '[' and $this->blockReference($Line)) { return $Block; @@ -614,7 +598,7 @@ class Parsedown if ( ! isset($Block['interrupted'])) { - $text = preg_replace('/^[ ]{0,'.min(4, $Block['indent']).'}/', '', $Line['body']); + $text = preg_replace('/^[ ]{0,'.min(4, $Block['indent'] + 1).'}/', '', $Line['body']); $Block['li']['text'] []= $text; @@ -625,12 +609,7 @@ class Parsedown { $Block['li']['text'] []= ''; - $text = preg_replace('/^[ ]{0,4}/', '', $Line['body']); - - if ($placeholder = $this->blockList($Line)) - { - $text = preg_replace('/^[ ]{0,'.min(4, $Block['indent']).'}/', '', $Line['body']); - } + $text = preg_replace('/^[ ]{0,'.min(4, $Block['indent'] + 1).'}/', '', $Line['body']); $Block['li']['text'] []= $text; From bdf537e9d57035a12160ab4344e9a7361e327bbf Mon Sep 17 00:00:00 2001 From: Daniel Rudolf Date: Thu, 13 Oct 2016 19:30:50 +0200 Subject: [PATCH 04/10] Fix ordered list start argument See CommonMark spec examples [#226](http://spec.commonmark.org/0.26/#example-226) to #229 --- Parsedown.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Parsedown.php b/Parsedown.php index bb2bd11..ac83e50 100644 --- a/Parsedown.php +++ b/Parsedown.php @@ -502,7 +502,7 @@ class Parsedown 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)) { @@ -521,7 +521,7 @@ class Parsedown if($name === 'ol') { - $listStart = stristr($matches[1], $Block['data']['marker'], true); + $listStart = ltrim(strstr($matches[1], $Block['data']['marker'], true), '0') ?: '0'; if($listStart !== '1') { From 30ff5c6e7564aa3d0e30dd9476335c0a444f8dcd Mon Sep 17 00:00:00 2001 From: Daniel Rudolf Date: Thu, 13 Oct 2016 19:31:35 +0200 Subject: [PATCH 05/10] Remove unused $placeholder variable --- Parsedown.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Parsedown.php b/Parsedown.php index ac83e50..5003775 100644 --- a/Parsedown.php +++ b/Parsedown.php @@ -584,13 +584,11 @@ class Parsedown return $Block; } - elseif ($Block['indent'] === $Line['indent'] and $placeholder = $this->blockList($Line)) + elseif ($Block['indent'] === $Line['indent'] and $this->blockList($Line)) { return null; } - unset($placeholder); - if ($Line['text'][0] === '[' and $this->blockReference($Line)) { return $Block; From 4b3b7df710e7a8ccd0a6fe66f84a03cddeb988e4 Mon Sep 17 00:00:00 2001 From: Daniel Rudolf Date: Thu, 13 Oct 2016 19:46:29 +0200 Subject: [PATCH 06/10] Support list items starting with a blank line According to the CommonMark specs ([list items](http://spec.commonmark.org/0.26/#list-items), rule 3), list items starting with a blank line basically behave like as if the \n doesn't exist. Also see example [#241](http://spec.commonmark.org/0.26/#example-241). --- Parsedown.php | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/Parsedown.php b/Parsedown.php index 5003775..df79c99 100644 --- a/Parsedown.php +++ b/Parsedown.php @@ -504,8 +504,12 @@ class Parsedown { 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)) { + if ($matches[2] === '') { + $matches[1] .= ' '; + } + $Block = array( 'indent' => $Line['indent'], 'pattern' => $pattern, @@ -532,9 +536,7 @@ class Parsedown $Block['li'] = array( 'name' => 'li', 'handler' => 'li', - 'text' => array( - $matches[2], - ), + 'text' => !empty($matches[3]) ? array($matches[3]) : array(), ); $Block['element']['text'] []= & $Block['li']; @@ -545,6 +547,10 @@ class Parsedown protected function blockListContinue($Line, array $Block) { + if (isset($Block['interrupted']) and empty($Block['li']['text'])) { + return null; + } + if ( $Block['indent'] === $Line['indent'] and From 1d61f90bf94a5a27736208275dae6d93c79107b8 Mon Sep 17 00:00:00 2001 From: Daniel Rudolf Date: Thu, 13 Oct 2016 19:47:06 +0200 Subject: [PATCH 07/10] Support list items starting with indented code --- Parsedown.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Parsedown.php b/Parsedown.php index df79c99..2f81b84 100644 --- a/Parsedown.php +++ b/Parsedown.php @@ -506,7 +506,12 @@ class Parsedown if (preg_match('/^('.$pattern.'([ ]+|$))(.*)/', $Line['text'], $matches)) { - if ($matches[2] === '') { + $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] .= ' '; } From 7b1529fff036b9c4c2c301bc4939a8c7f6e7d245 Mon Sep 17 00:00:00 2001 From: Daniel Rudolf Date: Thu, 13 Oct 2016 19:51:32 +0200 Subject: [PATCH 08/10] Use the list marker width to determine whether a list item is continued This basically represents [list item parsing](http://spec.commonmark.org/0.26/#list-items), rule 1 of the CommonMark specs. --- Parsedown.php | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/Parsedown.php b/Parsedown.php index 2f81b84..f6e1bec 100644 --- a/Parsedown.php +++ b/Parsedown.php @@ -520,7 +520,8 @@ class Parsedown 'pattern' => $pattern, 'data' => array( 'type' => $name, - 'marker' => ($name === 'ul' ? stristr($matches[1], ' ', true) : substr(stristr($matches[1], ' ', true), -1)), + 'marker' => $matches[1], + 'markerType' => ($name === 'ul' ? strstr($matches[1], ' ', true) : substr(strstr($matches[1], ' ', true), -1)), ), 'element' => array( 'name' => $name, @@ -530,7 +531,7 @@ class Parsedown if($name === 'ol') { - $listStart = ltrim(strstr($matches[1], $Block['data']['marker'], true), '0') ?: '0'; + $listStart = ltrim(strstr($matches[1], $Block['data']['markerType'], true), '0') ?: '0'; if($listStart !== '1') { @@ -562,12 +563,12 @@ class Parsedown ( ( $Block['data']['type'] === 'ol' - and preg_match('/^[0-9]+'.preg_quote($Block['data']['marker']).'(?:[ ]+(.*)|$)/', $Line['text'], $matches) + 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']['marker']).'(?:[ ]+(.*)|$)/', $Line['text'], $matches) + and preg_match('/^'.preg_quote($Block['data']['markerType']).'(?:[ ]+(.*)|$)/', $Line['text'], $matches) ) ) ) @@ -605,25 +606,31 @@ class Parsedown return $Block; } - if ( ! isset($Block['interrupted'])) + $requiredIndent = ($Block['indent'] + strlen($Block['data']['marker'])); + + if ($Line['indent'] >= $requiredIndent) { - $text = preg_replace('/^[ ]{0,'.min(4, $Block['indent'] + 1).'}/', '', $Line['body']); + if (isset($Block['interrupted'])) + { + $Block['li']['text'] []= ''; + + unset($Block['interrupted']); + } + + $text = substr($Line['body'], $requiredIndent); $Block['li']['text'] []= $text; return $Block; } - if ($Line['indent'] > 0) + if ( ! isset($Block['interrupted'])) { - $Block['li']['text'] []= ''; - - $text = preg_replace('/^[ ]{0,'.min(4, $Block['indent'] + 1).'}/', '', $Line['body']); + // TODO: force multi-line paragraph, this must not parse any new block + $text = preg_replace('/^[ ]{0,'.$requiredIndent.'}/', '', $Line['body']); $Block['li']['text'] []= $text; - unset($Block['interrupted']); - return $Block; } } From a9e1163c85bb23564458af84e8852650e209fbe9 Mon Sep 17 00:00:00 2001 From: Daniel Rudolf Date: Thu, 13 Oct 2016 19:52:38 +0200 Subject: [PATCH 09/10] Fix code formatting --- Parsedown.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Parsedown.php b/Parsedown.php index f6e1bec..ececf78 100644 --- a/Parsedown.php +++ b/Parsedown.php @@ -507,11 +507,15 @@ class Parsedown if (preg_match('/^('.$pattern.'([ ]+|$))(.*)/', $Line['text'], $matches)) { $contentIndent = strlen($matches[2]); - if ($contentIndent >= 5) { + + if ($contentIndent >= 5) + { $contentIndent -= 1; $matches[1] = substr($matches[1], 0, -$contentIndent); $matches[3] = str_repeat(' ', $contentIndent) . $matches[3]; - } elseif ($contentIndent === 0) { + } + elseif ($contentIndent === 0) + { $matches[1] .= ' '; } @@ -553,7 +557,8 @@ class Parsedown protected function blockListContinue($Line, array $Block) { - if (isset($Block['interrupted']) and empty($Block['li']['text'])) { + if (isset($Block['interrupted']) and empty($Block['li']['text'])) + { return null; } From a3836b185368b92dad899e7a9567731eeed8297d Mon Sep 17 00:00:00 2001 From: Daniel Rudolf Date: Thu, 13 Oct 2016 20:44:02 +0200 Subject: [PATCH 10/10] Handle subsequent list items which aren't indented sufficiently Subsequent list items which aren't indented sufficiently are treated as part of the original list, see CommonMark spec example [#256](http://spec.commonmark.org/0.26/#example-256). --- Parsedown.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Parsedown.php b/Parsedown.php index ececf78..de80f3f 100644 --- a/Parsedown.php +++ b/Parsedown.php @@ -562,8 +562,10 @@ class Parsedown return null; } + $requiredIndent = ($Block['indent'] + strlen($Block['data']['marker'])); + if ( - $Block['indent'] === $Line['indent'] + $Line['indent'] < $requiredIndent and ( ( @@ -589,6 +591,8 @@ class Parsedown $text = isset($matches[1]) ? $matches[1] : ''; + $Block['indent'] = $Line['indent']; + $Block['li'] = array( 'name' => 'li', 'handler' => 'li', @@ -601,7 +605,7 @@ class Parsedown return $Block; } - elseif ($Block['indent'] === $Line['indent'] and $this->blockList($Line)) + elseif ($Line['indent'] < $requiredIndent and $this->blockList($Line)) { return null; } @@ -611,8 +615,6 @@ class Parsedown return $Block; } - $requiredIndent = ($Block['indent'] + strlen($Block['data']['marker'])); - if ($Line['indent'] >= $requiredIndent) { if (isset($Block['interrupted'])) @@ -631,7 +633,6 @@ class Parsedown if ( ! isset($Block['interrupted'])) { - // TODO: force multi-line paragraph, this must not parse any new block $text = preg_replace('/^[ ]{0,'.$requiredIndent.'}/', '', $Line['body']); $Block['li']['text'] []= $text;