1
0
mirror of https://github.com/erusev/parsedown.git synced 2023-08-10 21:13:06 +03:00

Track whitespace left on blank lines to match CommonMark

Test changes copy pasted to match CommonMark reference parser
This commit is contained in:
Aidan Woods 2019-01-28 19:13:57 +00:00
parent 49dd8b113d
commit f47ba7aa34
No known key found for this signature in database
GPG Key ID: 9A6A8EFAA512BBB9
17 changed files with 106 additions and 59 deletions

View File

@ -85,19 +85,15 @@ final class FencedCode implements ContinuableBlock
$newCode = $this->code; $newCode = $this->code;
if ($Context->previousEmptyLines() > 0) { $newCode .= $Context->previousEmptyLinesText();
$newCode .= \str_repeat("\n", $Context->previousEmptyLines());
}
if (($len = \strspn($Context->line()->text(), $this->marker)) >= $this->openerLength if (($len = \strspn($Context->line()->text(), $this->marker)) >= $this->openerLength
&& \chop(\substr($Context->line()->text(), $len), ' ') === '' && \chop(\substr($Context->line()->text(), $len), ' ') === ''
) { ) {
$newCode = \substr($newCode, 1);
return new self($newCode, $this->infostring, $this->marker, $this->openerLength, true); return new self($newCode, $this->infostring, $this->marker, $this->openerLength, true);
} }
$newCode .= "\n" . $Context->line()->rawLine(); $newCode .= $Context->line()->rawLine() . "\n";
return new self($newCode, $this->infostring, $this->marker, $this->openerLength, false); return new self($newCode, $this->infostring, $this->marker, $this->openerLength, false);
} }

View File

@ -8,6 +8,7 @@ use Erusev\Parsedown\Components\ContinuableBlock;
use Erusev\Parsedown\Html\Renderables\Element; use Erusev\Parsedown\Html\Renderables\Element;
use Erusev\Parsedown\Html\Renderables\Text; use Erusev\Parsedown\Html\Renderables\Text;
use Erusev\Parsedown\Parsing\Context; use Erusev\Parsedown\Parsing\Context;
use Erusev\Parsedown\Parsing\Line;
use Erusev\Parsedown\State; use Erusev\Parsedown\State;
final class IndentedCode implements ContinuableBlock final class IndentedCode implements ContinuableBlock
@ -44,7 +45,7 @@ final class IndentedCode implements ContinuableBlock
return null; return null;
} }
return new self($Context->line()->ltrimBodyUpto(4)); return new self($Context->line()->ltrimBodyUpto(4) . "\n");
} }
/** /**
@ -59,11 +60,19 @@ final class IndentedCode implements ContinuableBlock
$newCode = $this->code; $newCode = $this->code;
$offset = $Context->line()->indentOffset();
if ($Context->previousEmptyLines() > 0) { if ($Context->previousEmptyLines() > 0) {
$newCode .= \str_repeat("\n", $Context->previousEmptyLines()); foreach (\explode("\n", $Context->previousEmptyLinesText()) as $line) {
$newCode .= (new Line($line, $offset))->ltrimBodyUpto(4) . "\n";
}
$newCode = \substr($newCode, 0, -1);
} }
return new self($newCode . "\n" . $Context->line()->ltrimBodyUpto(4)); $newCode .= $Context->line()->ltrimBodyUpto(4) . "\n";
return new self($newCode);
} }
/** /**

View File

@ -4,24 +4,24 @@ namespace Erusev\Parsedown\Parsing;
final class Context final class Context
{ {
/** /** @var Line */
* @var Line
*/
private $Line; private $Line;
/** /** @var int */
* @var int
*/
private $previousEmptyLines; private $previousEmptyLines;
/** @var string */
private $previousEmptyLinesText;
/** /**
* @param Line $Line * @param Line $Line
* @param int $previousEmptyLines * @param string $previousEmptyLinesText
*/ */
public function __construct($Line, $previousEmptyLines) public function __construct($Line, $previousEmptyLinesText)
{ {
$this->Line = $Line; $this->Line = $Line;
$this->previousEmptyLines = \max($previousEmptyLines, 0); $this->previousEmptyLinesText = $previousEmptyLinesText;
$this->previousEmptyLines = \substr_count($previousEmptyLinesText, "\n");
} }
/** @return Line */ /** @return Line */
@ -35,4 +35,10 @@ final class Context
{ {
return $this->previousEmptyLines; return $this->previousEmptyLines;
} }
/** @return string */
public function previousEmptyLinesText()
{
return $this->previousEmptyLinesText;
}
} }

View File

@ -10,20 +10,24 @@ final class Lines
/** @var bool */ /** @var bool */
private $containsBlankLines; private $containsBlankLines;
/** @var string */
private $trailingBlankLinesText;
/** @var int */ /** @var int */
private $trailingBlankLines; private $trailingBlankLines;
/** /**
* @param Context[] $Contexts * @param Context[] $Contexts
* @param int $trailingBlankLines * @param string $trailingBlankLinesText
*/ */
private function __construct($Contexts, $trailingBlankLines) private function __construct($Contexts, $trailingBlankLinesText)
{ {
$this->Contexts = $Contexts; $this->Contexts = $Contexts;
$this->trailingBlankLines = $trailingBlankLines; $this->trailingBlankLinesText = $trailingBlankLinesText;
$this->trailingBlankLines = \substr_count($trailingBlankLinesText, "\n");
$this->containsBlankLines = ( $this->containsBlankLines = (
($trailingBlankLines > 0) ($this->trailingBlankLines > 0)
|| \array_reduce( || \array_reduce(
$Contexts, $Contexts,
/** /**
@ -42,7 +46,7 @@ final class Lines
/** @return self */ /** @return self */
public static function none() public static function none()
{ {
return new self([], 0); return new self([], '');
} }
/** /**
@ -56,23 +60,23 @@ final class Lines
$text = \str_replace(["\r\n", "\r"], "\n", $text); $text = \str_replace(["\r\n", "\r"], "\n", $text);
$Contexts = []; $Contexts = [];
$sequentialBreaks = 0; $sequentialLines = '';
foreach (\explode("\n", $text) as $line) { foreach (\explode("\n", $text) as $line) {
if (\chop($line) === '') { if (\chop($line) === '') {
$sequentialBreaks += 1; $sequentialLines .= $line . "\n";
continue; continue;
} }
$Contexts[] = new Context( $Contexts[] = new Context(
new Line($line, $indentOffset), new Line($line, $indentOffset),
$sequentialBreaks $sequentialLines
); );
$sequentialBreaks = 0; $sequentialLines = '';
} }
return new self($Contexts, $sequentialBreaks); return new self($Contexts, $sequentialLines);
} }
/** @return bool */ /** @return bool */
@ -116,6 +120,7 @@ final class Lines
} }
$Lines = clone($this); $Lines = clone($this);
$Lines->trailingBlankLinesText .= \str_repeat("\n", $count);
$Lines->trailingBlankLines += $count; $Lines->trailingBlankLines += $count;
$Lines->containsBlankLines = $Lines->containsBlankLines || ($count > 0); $Lines->containsBlankLines = $Lines->containsBlankLines || ($count > 0);
@ -135,6 +140,7 @@ final class Lines
if (\count($NextLines->Contexts) === 0) { if (\count($NextLines->Contexts) === 0) {
$Lines->trailingBlankLines += $NextLines->trailingBlankLines; $Lines->trailingBlankLines += $NextLines->trailingBlankLines;
$Lines->trailingBlankLinesText .= $NextLines->trailingBlankLinesText;
$Lines->containsBlankLines = $Lines->containsBlankLines $Lines->containsBlankLines = $Lines->containsBlankLines
|| ($Lines->trailingBlankLines > 0) || ($Lines->trailingBlankLines > 0)
@ -145,12 +151,13 @@ final class Lines
$NextLines->Contexts[0] = new Context( $NextLines->Contexts[0] = new Context(
$NextLines->Contexts[0]->line(), $NextLines->Contexts[0]->line(),
$NextLines->Contexts[0]->previousEmptyLines() + $Lines->trailingBlankLines $NextLines->Contexts[0]->previousEmptyLinesText() . $Lines->trailingBlankLinesText
); );
$Lines->Contexts = \array_merge($Lines->Contexts, $NextLines->Contexts); $Lines->Contexts = \array_merge($Lines->Contexts, $NextLines->Contexts);
$Lines->trailingBlankLines = $NextLines->trailingBlankLines; $Lines->trailingBlankLines = $NextLines->trailingBlankLines;
$Lines->trailingBlankLinesText = $NextLines->trailingBlankLinesText;
$Lines->containsBlankLines = $Lines->containsBlankLines $Lines->containsBlankLines = $Lines->containsBlankLines
|| $NextLines->containsBlankLines || $NextLines->containsBlankLines
@ -166,7 +173,7 @@ final class Lines
$Context = new Context( $Context = new Context(
$Context->line(), $Context->line(),
$Context->previousEmptyLines() + $Lines->trailingBlankLines $Context->previousEmptyLinesText() . $Lines->trailingBlankLinesText
); );
if ($Context->previousEmptyLines() > 0) { if ($Context->previousEmptyLines() > 0) {
@ -174,6 +181,7 @@ final class Lines
} }
$Lines->trailingBlankLines = 0; $Lines->trailingBlankLines = 0;
$Lines->trailingBlankLinesText = '';
$Lines->Contexts[] = $Context; $Lines->Contexts[] = $Context;

View File

@ -1,4 +1,3 @@
<p>foo</p> <pre><code>aaa
<pre><code>bar ~~~ ~~
</code></pre> </code></pre>
<p>baz</p>

View File

@ -1,5 +1,3 @@
foo ~~~~~~
``` aaa
bar ~~~ ~~
```
baz

View File

@ -0,0 +1,4 @@
<pre><code>chunk1
chunk2
</code></pre>

View File

@ -0,0 +1,3 @@
chunk1
chunk2

View File

@ -0,0 +1,4 @@
<pre><code>
```
aaa
</code></pre>

View File

@ -0,0 +1,4 @@
`````
```
aaa

View File

@ -1,3 +1,5 @@
<pre><code> <blockquote>
<pre><code>aaa
</code></pre> </code></pre>
</blockquote>
<p>bbb</p>

View File

@ -1,4 +1,4 @@
``` > ```
> aaa
bbb
```

View File

@ -1,20 +1,24 @@
<pre><code>&lt;?php <pre><code>&lt;?php
$message = 'Hello World!'; $message = 'Hello World!';
echo $message;</code></pre> echo $message;
</code></pre>
<hr /> <hr />
<pre><code>&gt; not a quote <pre><code>&gt; not a quote
- not a list item - not a list item
[not a reference]: http://foo.com</code></pre> [not a reference]: http://foo.com
</code></pre>
<hr /> <hr />
<pre><code>foo <pre><code>foo
bar</code></pre> bar
</code></pre>
<hr /> <hr />
<ul> <ul>
<li> <li>
<p>foo</p> <p>foo</p>
<pre><code> bar</code></pre> <pre><code> bar
</code></pre>
</li> </li>
</ul> </ul>

View File

@ -1,6 +1,7 @@
<p>escaped *emphasis*.</p> <p>escaped *emphasis*.</p>
<p><code>escaped \*emphasis\* in a code span</code></p> <p><code>escaped \*emphasis\* in a code span</code></p>
<pre><code>escaped \*emphasis\* in a code block</code></pre> <pre><code>escaped \*emphasis\* in a code block
</code></pre>
<p>\ ` * _ { } [ ] ( ) &gt; # + - . !</p> <p>\ ` * _ { } [ ] ( ) &gt; # + - . !</p>
<p><em>one_two</em> <strong>one_two</strong></p> <p><em>one_two</em> <strong>one_two</strong></p>
<p><em>one*two</em> <strong>one*two</strong></p> <p><em>one*two</em> <strong>one*two</strong></p>

View File

@ -1,18 +1,25 @@
<pre><code>&lt;?php <pre><code>&lt;?php
$message = 'fenced code block'; $message = 'fenced code block';
echo $message;</code></pre> echo $message;
<pre><code>tilde</code></pre> </code></pre>
<pre><code class="language-php">echo 'language identifier';</code></pre> <pre><code>tilde
<pre><code class="language-c#">echo 'language identifier with non words';</code></pre> </code></pre>
<pre><code class="language-php">echo 'language identifier';
</code></pre>
<pre><code class="language-c#">echo 'language identifier with non words';
</code></pre>
<pre><code class="language-html+php">&lt;?php <pre><code class="language-html+php">&lt;?php
echo &quot;Hello World&quot;; echo &quot;Hello World&quot;;
?&gt; ?&gt;
&lt;a href=&quot;http://auraphp.com&quot; &gt;Aura Project&lt;/a&gt;</code></pre> &lt;a href=&quot;http://auraphp.com&quot; &gt;Aura Project&lt;/a&gt;
</code></pre>
<pre><code>the following isn't quite enough to close <pre><code>the following isn't quite enough to close
``` ```
still a fenced code block</code></pre> still a fenced code block
</code></pre>
<pre><code>foo <pre><code>foo
bar</code></pre> bar
</code></pre>

View File

@ -3,4 +3,5 @@
$message = 'Hello World!'; $message = 'Hello World!';
echo $message; echo $message;
echo &quot;following a blank line&quot;;</code></pre> echo &quot;following a blank line&quot;;
</code></pre>

View File

@ -1 +1,2 @@
<pre><code>code</code></pre> <pre><code>code
</code></pre>