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:
parent
49dd8b113d
commit
f47ba7aa34
@ -85,19 +85,15 @@ final class FencedCode implements ContinuableBlock
|
||||
|
||||
$newCode = $this->code;
|
||||
|
||||
if ($Context->previousEmptyLines() > 0) {
|
||||
$newCode .= \str_repeat("\n", $Context->previousEmptyLines());
|
||||
}
|
||||
$newCode .= $Context->previousEmptyLinesText();
|
||||
|
||||
if (($len = \strspn($Context->line()->text(), $this->marker)) >= $this->openerLength
|
||||
&& \chop(\substr($Context->line()->text(), $len), ' ') === ''
|
||||
) {
|
||||
$newCode = \substr($newCode, 1);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ use Erusev\Parsedown\Components\ContinuableBlock;
|
||||
use Erusev\Parsedown\Html\Renderables\Element;
|
||||
use Erusev\Parsedown\Html\Renderables\Text;
|
||||
use Erusev\Parsedown\Parsing\Context;
|
||||
use Erusev\Parsedown\Parsing\Line;
|
||||
use Erusev\Parsedown\State;
|
||||
|
||||
final class IndentedCode implements ContinuableBlock
|
||||
@ -44,7 +45,7 @@ final class IndentedCode implements ContinuableBlock
|
||||
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;
|
||||
|
||||
$offset = $Context->line()->indentOffset();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4,24 +4,24 @@ namespace Erusev\Parsedown\Parsing;
|
||||
|
||||
final class Context
|
||||
{
|
||||
/**
|
||||
* @var Line
|
||||
*/
|
||||
/** @var Line */
|
||||
private $Line;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
/** @var int */
|
||||
private $previousEmptyLines;
|
||||
|
||||
/** @var string */
|
||||
private $previousEmptyLinesText;
|
||||
|
||||
/**
|
||||
* @param Line $Line
|
||||
* @param int $previousEmptyLines
|
||||
* @param string $previousEmptyLinesText
|
||||
*/
|
||||
public function __construct($Line, $previousEmptyLines)
|
||||
public function __construct($Line, $previousEmptyLinesText)
|
||||
{
|
||||
$this->Line = $Line;
|
||||
$this->previousEmptyLines = \max($previousEmptyLines, 0);
|
||||
$this->previousEmptyLinesText = $previousEmptyLinesText;
|
||||
$this->previousEmptyLines = \substr_count($previousEmptyLinesText, "\n");
|
||||
}
|
||||
|
||||
/** @return Line */
|
||||
@ -35,4 +35,10 @@ final class Context
|
||||
{
|
||||
return $this->previousEmptyLines;
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
public function previousEmptyLinesText()
|
||||
{
|
||||
return $this->previousEmptyLinesText;
|
||||
}
|
||||
}
|
||||
|
@ -10,20 +10,24 @@ final class Lines
|
||||
/** @var bool */
|
||||
private $containsBlankLines;
|
||||
|
||||
/** @var string */
|
||||
private $trailingBlankLinesText;
|
||||
|
||||
/** @var int */
|
||||
private $trailingBlankLines;
|
||||
|
||||
/**
|
||||
* @param Context[] $Contexts
|
||||
* @param int $trailingBlankLines
|
||||
* @param string $trailingBlankLinesText
|
||||
*/
|
||||
private function __construct($Contexts, $trailingBlankLines)
|
||||
private function __construct($Contexts, $trailingBlankLinesText)
|
||||
{
|
||||
$this->Contexts = $Contexts;
|
||||
$this->trailingBlankLines = $trailingBlankLines;
|
||||
$this->trailingBlankLinesText = $trailingBlankLinesText;
|
||||
$this->trailingBlankLines = \substr_count($trailingBlankLinesText, "\n");
|
||||
|
||||
$this->containsBlankLines = (
|
||||
($trailingBlankLines > 0)
|
||||
($this->trailingBlankLines > 0)
|
||||
|| \array_reduce(
|
||||
$Contexts,
|
||||
/**
|
||||
@ -42,7 +46,7 @@ final class Lines
|
||||
/** @return self */
|
||||
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);
|
||||
|
||||
$Contexts = [];
|
||||
$sequentialBreaks = 0;
|
||||
$sequentialLines = '';
|
||||
|
||||
foreach (\explode("\n", $text) as $line) {
|
||||
if (\chop($line) === '') {
|
||||
$sequentialBreaks += 1;
|
||||
$sequentialLines .= $line . "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
$Contexts[] = new Context(
|
||||
new Line($line, $indentOffset),
|
||||
$sequentialBreaks
|
||||
$sequentialLines
|
||||
);
|
||||
|
||||
$sequentialBreaks = 0;
|
||||
$sequentialLines = '';
|
||||
}
|
||||
|
||||
return new self($Contexts, $sequentialBreaks);
|
||||
return new self($Contexts, $sequentialLines);
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
@ -116,6 +120,7 @@ final class Lines
|
||||
}
|
||||
|
||||
$Lines = clone($this);
|
||||
$Lines->trailingBlankLinesText .= \str_repeat("\n", $count);
|
||||
$Lines->trailingBlankLines += $count;
|
||||
$Lines->containsBlankLines = $Lines->containsBlankLines || ($count > 0);
|
||||
|
||||
@ -135,6 +140,7 @@ final class Lines
|
||||
|
||||
if (\count($NextLines->Contexts) === 0) {
|
||||
$Lines->trailingBlankLines += $NextLines->trailingBlankLines;
|
||||
$Lines->trailingBlankLinesText .= $NextLines->trailingBlankLinesText;
|
||||
|
||||
$Lines->containsBlankLines = $Lines->containsBlankLines
|
||||
|| ($Lines->trailingBlankLines > 0)
|
||||
@ -145,12 +151,13 @@ final class Lines
|
||||
|
||||
$NextLines->Contexts[0] = new Context(
|
||||
$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->trailingBlankLines = $NextLines->trailingBlankLines;
|
||||
$Lines->trailingBlankLinesText = $NextLines->trailingBlankLinesText;
|
||||
|
||||
$Lines->containsBlankLines = $Lines->containsBlankLines
|
||||
|| $NextLines->containsBlankLines
|
||||
@ -166,7 +173,7 @@ final class Lines
|
||||
|
||||
$Context = new Context(
|
||||
$Context->line(),
|
||||
$Context->previousEmptyLines() + $Lines->trailingBlankLines
|
||||
$Context->previousEmptyLinesText() . $Lines->trailingBlankLinesText
|
||||
);
|
||||
|
||||
if ($Context->previousEmptyLines() > 0) {
|
||||
@ -174,6 +181,7 @@ final class Lines
|
||||
}
|
||||
|
||||
$Lines->trailingBlankLines = 0;
|
||||
$Lines->trailingBlankLinesText = '';
|
||||
|
||||
$Lines->Contexts[] = $Context;
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
<p>foo</p>
|
||||
<pre><code>bar
|
||||
</code></pre>
|
||||
<p>baz</p>
|
||||
<pre><code>aaa
|
||||
~~~ ~~
|
||||
</code></pre>
|
@ -1,5 +1,3 @@
|
||||
foo
|
||||
```
|
||||
bar
|
||||
```
|
||||
baz
|
||||
~~~~~~
|
||||
aaa
|
||||
~~~ ~~
|
4
tests/commonmark/81-Indented_code_blocks.html
Normal file
4
tests/commonmark/81-Indented_code_blocks.html
Normal file
@ -0,0 +1,4 @@
|
||||
<pre><code>chunk1
|
||||
|
||||
chunk2
|
||||
</code></pre>
|
3
tests/commonmark/81-Indented_code_blocks.md
Normal file
3
tests/commonmark/81-Indented_code_blocks.md
Normal file
@ -0,0 +1,3 @@
|
||||
chunk1
|
||||
|
||||
chunk2
|
4
tests/commonmark/96-Fenced_code_blocks.html
Normal file
4
tests/commonmark/96-Fenced_code_blocks.html
Normal file
@ -0,0 +1,4 @@
|
||||
<pre><code>
|
||||
```
|
||||
aaa
|
||||
</code></pre>
|
4
tests/commonmark/96-Fenced_code_blocks.md
Normal file
4
tests/commonmark/96-Fenced_code_blocks.md
Normal file
@ -0,0 +1,4 @@
|
||||
`````
|
||||
|
||||
```
|
||||
aaa
|
@ -1,3 +1,5 @@
|
||||
<pre><code>
|
||||
|
||||
</code></pre>
|
||||
<blockquote>
|
||||
<pre><code>aaa
|
||||
</code></pre>
|
||||
</blockquote>
|
||||
<p>bbb</p>
|
@ -1,4 +1,4 @@
|
||||
```
|
||||
> ```
|
||||
> aaa
|
||||
|
||||
|
||||
```
|
||||
bbb
|
@ -1,20 +1,24 @@
|
||||
<pre><code><?php
|
||||
|
||||
$message = 'Hello World!';
|
||||
echo $message;</code></pre>
|
||||
echo $message;
|
||||
</code></pre>
|
||||
<hr />
|
||||
<pre><code>> not a quote
|
||||
- not a list item
|
||||
[not a reference]: http://foo.com</code></pre>
|
||||
[not a reference]: http://foo.com
|
||||
</code></pre>
|
||||
<hr />
|
||||
<pre><code>foo
|
||||
|
||||
|
||||
bar</code></pre>
|
||||
bar
|
||||
</code></pre>
|
||||
<hr />
|
||||
<ul>
|
||||
<li>
|
||||
<p>foo</p>
|
||||
<pre><code> bar</code></pre>
|
||||
<pre><code> bar
|
||||
</code></pre>
|
||||
</li>
|
||||
</ul>
|
@ -1,6 +1,7 @@
|
||||
<p>escaped *emphasis*.</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>\ ` * _ { } [ ] ( ) > # + - . !</p>
|
||||
<p><em>one_two</em> <strong>one_two</strong></p>
|
||||
<p><em>one*two</em> <strong>one*two</strong></p>
|
@ -1,18 +1,25 @@
|
||||
<pre><code><?php
|
||||
|
||||
$message = 'fenced code block';
|
||||
echo $message;</code></pre>
|
||||
<pre><code>tilde</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>
|
||||
echo $message;
|
||||
</code></pre>
|
||||
<pre><code>tilde
|
||||
</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"><?php
|
||||
echo "Hello World";
|
||||
?>
|
||||
<a href="http://auraphp.com" >Aura Project</a></code></pre>
|
||||
<a href="http://auraphp.com" >Aura Project</a>
|
||||
</code></pre>
|
||||
<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
|
||||
|
||||
|
||||
bar</code></pre>
|
||||
bar
|
||||
</code></pre>
|
@ -3,4 +3,5 @@
|
||||
$message = 'Hello World!';
|
||||
echo $message;
|
||||
|
||||
echo "following a blank line";</code></pre>
|
||||
echo "following a blank line";
|
||||
</code></pre>
|
@ -1 +1,2 @@
|
||||
<pre><code>code</code></pre>
|
||||
<pre><code>code
|
||||
</code></pre>
|
Loading…
Reference in New Issue
Block a user