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

Improve indent handling by lists

This commit is contained in:
Aidan Woods 2019-01-22 20:52:12 +00:00
parent 51c3d9d445
commit bb424e606f
No known key found for this signature in database
GPG Key ID: 9A6A8EFAA512BBB9
3 changed files with 74 additions and 29 deletions

View File

@ -9,6 +9,7 @@ use Erusev\Parsedown\Components\ContinuableBlock;
use Erusev\Parsedown\Html\Renderables\Element; use Erusev\Parsedown\Html\Renderables\Element;
use Erusev\Parsedown\Parsedown; use Erusev\Parsedown\Parsedown;
use Erusev\Parsedown\Parsing\Context; use Erusev\Parsedown\Parsing\Context;
use Erusev\Parsedown\Parsing\Line;
use Erusev\Parsedown\Parsing\Lines; use Erusev\Parsedown\Parsing\Lines;
use Erusev\Parsedown\State; use Erusev\Parsedown\State;
@ -34,6 +35,9 @@ final class TList implements ContinuableBlock
/** @var string */ /** @var string */
private $marker; private $marker;
/** @var int */
private $afterMarkerSpaces;
/** @var string */ /** @var string */
private $markerType; private $markerType;
@ -47,6 +51,7 @@ final class TList implements ContinuableBlock
* @param int $indent * @param int $indent
* @param 'ul'|'ol' $type * @param 'ul'|'ol' $type
* @param string $marker * @param string $marker
* @param int $afterMarkerSpaces
* @param string $markerType * @param string $markerType
* @param string $markerTypeRegex * @param string $markerTypeRegex
*/ */
@ -57,6 +62,7 @@ final class TList implements ContinuableBlock
$indent, $indent,
$type, $type,
$marker, $marker,
$afterMarkerSpaces,
$markerType, $markerType,
$markerTypeRegex $markerTypeRegex
) { ) {
@ -66,6 +72,7 @@ final class TList implements ContinuableBlock
$this->indent = $indent; $this->indent = $indent;
$this->type = $type; $this->type = $type;
$this->marker = $marker; $this->marker = $marker;
$this->afterMarkerSpaces = $afterMarkerSpaces;
$this->markerType = $markerType; $this->markerType = $markerType;
$this->markerTypeRegex = $markerTypeRegex; $this->markerTypeRegex = $markerTypeRegex;
} }
@ -88,30 +95,32 @@ final class TList implements ContinuableBlock
); );
if (\preg_match( if (\preg_match(
'/^('.$pattern.'([ ]++|$))(.*+)/', '/^('.$pattern.')([\t ]++.*|$)/',
$Context->line()->text(), $Context->line()->text(),
$matches $matches
)) { )) {
$contentIndent = \strlen($matches[2]); $marker = $matches[1];
if ($contentIndent >= 5) { $preAfterMarkerSpacesIndentOffset = $Context->line()->indentOffset() + $Context->line()->indent() + \strlen($marker);
$contentIndent -= 1;
$matches[1] = \substr($matches[1], 0, -$contentIndent); $LineWithMarkerIndent = new Line(isset($matches[2]) ? $matches[2] : '', $preAfterMarkerSpacesIndentOffset);
$matches[3] = \str_repeat(' ', $contentIndent) . $matches[3]; $indentAfterMarker = $LineWithMarkerIndent->indent();
} elseif ($contentIndent === 0) {
$matches[1] .= ' '; if ($indentAfterMarker > 4) {
$perceivedIndent = $indentAfterMarker -1;
$afterMarkerSpaces = 1;
} else {
$perceivedIndent = 0;
$afterMarkerSpaces = $indentAfterMarker;
} }
$text = $matches[3]; $indentOffset = $preAfterMarkerSpacesIndentOffset + $afterMarkerSpaces;
$text = \str_repeat(' ', $perceivedIndent) . $LineWithMarkerIndent->text();
$markerWithoutWhitespace = \rtrim($matches[1], " \t");
$marker = $matches[1];
$indent = $Context->line()->indent();
$indentOffset = $Context->line()->indentOffset() + $Context->line()->indent() + \strlen($marker);
$markerType = ( $markerType = (
$type === 'ul' $type === 'ul'
? $markerWithoutWhitespace ? $marker
: \substr($markerWithoutWhitespace, -1) : \substr($marker, -1)
); );
$markerTypeRegex = \preg_quote($markerType, '/'); $markerTypeRegex = \preg_quote($markerType, '/');
@ -137,9 +146,10 @@ final class TList implements ContinuableBlock
[!empty($text) ? Lines::fromTextLines($text, $indentOffset) : Lines::none()], [!empty($text) ? Lines::fromTextLines($text, $indentOffset) : Lines::none()],
$listStart, $listStart,
false, false,
$indent, $Context->line()->indent(),
$type, $type,
$marker, $marker,
$afterMarkerSpaces,
$markerType, $markerType,
$markerTypeRegex $markerTypeRegex
); );
@ -156,7 +166,9 @@ final class TList implements ContinuableBlock
return null; return null;
} }
$requiredIndent = $this->indent + \strlen($this->marker); $newlines = \str_repeat("\n", $Context->previousEmptyLines());
$requiredIndent = $this->indent + \strlen($this->marker) + $this->afterMarkerSpaces;
$isLoose = $this->isLoose; $isLoose = $this->isLoose;
$indent = $Context->line()->indent(); $indent = $Context->line()->indent();
@ -165,10 +177,10 @@ final class TList implements ContinuableBlock
if ($Context->line()->indent() < $requiredIndent if ($Context->line()->indent() < $requiredIndent
&& (( && ((
$this->type === 'ol' $this->type === 'ol'
&& \preg_match('/^([0-9]++'.$this->markerTypeRegex.')(?:[ ]++(.*)|$)/', $Context->line()->text(), $matches) && \preg_match('/^([0-9]++'.$this->markerTypeRegex.')([\t ]++.*|$)/', $Context->line()->text(), $matches)
) || ( ) || (
$this->type === 'ul' $this->type === 'ul'
&& \preg_match('/^('.$this->markerTypeRegex.')(?:[ ]++(.*)|$)/', $Context->line()->text(), $matches) && \preg_match('/^('.$this->markerTypeRegex.')([\t ]++.*|$)/', $Context->line()->text(), $matches)
)) ))
) { ) {
if ($Context->previousEmptyLines() > 0) { if ($Context->previousEmptyLines() > 0) {
@ -177,10 +189,25 @@ final class TList implements ContinuableBlock
$isLoose = true; $isLoose = true;
} }
$text = isset($matches[2]) ? $matches[2] : ''; $marker = $matches[1];
$indentOffset = $Context->line()->indentOffset() + $Context->line()->indent() + \strlen($matches[1]);
$Lis[] = Lines::fromTextLines($text, $indentOffset); $preAfterMarkerSpacesIndentOffset = $Context->line()->indentOffset() + $Context->line()->indent() + \strlen($marker);
$LineWithMarkerIndent = new Line(isset($matches[2]) ? $matches[2] : '', $preAfterMarkerSpacesIndentOffset);
$indentAfterMarker = $LineWithMarkerIndent->indent();
if ($indentAfterMarker > 4) {
$perceivedIndent = $indentAfterMarker -1;
$afterMarkerSpaces = 1;
} else {
$perceivedIndent = 0;
$afterMarkerSpaces = $indentAfterMarker;
}
$indentOffset = $preAfterMarkerSpacesIndentOffset + $afterMarkerSpaces;
$text = \str_repeat(' ', $perceivedIndent) . $LineWithMarkerIndent->text();
$Lis[] = Lines::fromTextLines($newlines . $text, $indentOffset);
return new self( return new self(
$Lis, $Lis,
@ -188,7 +215,8 @@ final class TList implements ContinuableBlock
$isLoose, $isLoose,
$indent, $indent,
$this->type, $this->type,
$this->marker, $marker,
$afterMarkerSpaces,
$this->markerType, $this->markerType,
$this->markerTypeRegex $this->markerTypeRegex
); );
@ -198,13 +226,13 @@ final class TList implements ContinuableBlock
if ($Context->line()->indent() >= $requiredIndent) { if ($Context->line()->indent() >= $requiredIndent) {
if ($Context->previousEmptyLines() > 0) { if ($Context->previousEmptyLines() > 0) {
$Lis[\count($Lis) -1] = $Lis[\count($Lis) -1]->appendingBlankLines(1); $Lis[\count($Lis) -1] = $Lis[\count($Lis) -1]->appendingBlankLines($Context->previousEmptyLines());
$isLoose = true; $isLoose = true;
} }
$text = $Context->line()->ltrimBodyUpto($requiredIndent); $text = $Context->line()->ltrimBodyUpto($requiredIndent);
$indentOffset = $Context->line()->indentOffset() + $Context->line()->indent(); $indentOffset = $Context->line()->indentOffset() + \min($requiredIndent, $Context->line()->indent());
$Lis[\count($Lis) -1] = $Lis[\count($Lis) -1]->appendingTextLines($text, $indentOffset); $Lis[\count($Lis) -1] = $Lis[\count($Lis) -1]->appendingTextLines($text, $indentOffset);
@ -215,6 +243,7 @@ final class TList implements ContinuableBlock
$this->indent, $this->indent,
$this->type, $this->type,
$this->marker, $this->marker,
$this->afterMarkerSpaces,
$this->markerType, $this->markerType,
$this->markerTypeRegex $this->markerTypeRegex
); );
@ -222,9 +251,11 @@ final class TList implements ContinuableBlock
if (! $Context->previousEmptyLines() > 0) { if (! $Context->previousEmptyLines() > 0) {
$text = $Context->line()->ltrimBodyUpto($requiredIndent); $text = $Context->line()->ltrimBodyUpto($requiredIndent);
$indentOffset = $Context->line()->indentOffset() + $Context->line()->indent();
$Lis[\count($Lis) -1] = $Lis[\count($Lis) -1]->appendingTextLines($text, $indentOffset); $Lis[\count($Lis) -1] = $Lis[\count($Lis) -1]->appendingTextLines(
$newlines . \str_repeat(' ', $Context->line()->indent()) . $text,
$Context->line()->indentOffset() + \min($requiredIndent, $Context->line()->indent())
);
return new self( return new self(
$Lis, $Lis,
@ -233,6 +264,7 @@ final class TList implements ContinuableBlock
$this->indent, $this->indent,
$this->type, $this->type,
$this->marker, $this->marker,
$this->afterMarkerSpaces,
$this->markerType, $this->markerType,
$this->markerTypeRegex $this->markerTypeRegex
); );

View File

@ -10,4 +10,11 @@ echo $message;</code></pre>
<pre><code>foo <pre><code>foo
bar</code></pre> bar</code></pre>
<hr />
<ul>
<li>
<p>foo</p>
<pre><code> bar</code></pre>
</li>
</ul>

View File

@ -14,4 +14,10 @@
foo foo
bar bar
---
- foo
bar