Skip to content

Commit 9f9cbc7

Browse files
committed
Merge remote-tracking branch 'origin/2.5'
2 parents 3b8b60d + ac81592 commit 9f9cbc7

File tree

7 files changed

+64
-8
lines changed

7 files changed

+64
-8
lines changed

CHANGELOG.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ Updates should follow the [Keep a CHANGELOG](https://keepachangelog.com/) princi
66

77
## [Unreleased][unreleased]
88

9+
## [2.5.1] - 2024-07-24
10+
11+
### Fixed
12+
13+
- Fixed attribute parsing incorrectly parsing mustache-like syntax (#1035)
14+
- Fixed incorrect `Table` start line numbers (#1037)
15+
916
## [2.5.0] - 2024-07-22
1017

1118
### Added
@@ -607,7 +614,8 @@ No changes were introduced since the previous release.
607614
- Alternative 1: Use `CommonMarkConverter` or `GithubFlavoredMarkdownConverter` if you don't need to customize the environment
608615
- Alternative 2: Instantiate a new `Environment` and add the necessary extensions yourself
609616

610-
[unreleased]: https://github.com/thephpleague/commonmark/compare/2.5.0....main
617+
[unreleased]: https://github.com/thephpleague/commonmark/compare/2.5.1....main
618+
[2.5.1]: https://github.com/thephpleague/commonmark/compare/2.5.0....2.5.1
611619
[2.5.0]: https://github.com/thephpleague/commonmark/compare/2.4.4...2.5.0
612620
[2.4.4]: https://github.com/thephpleague/commonmark/compare/2.4.3...2.4.4
613621
[2.4.3]: https://github.com/thephpleague/commonmark/compare/2.4.2...2.4.3

src/Extension/Attributes/Util/AttributesHelper.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
final class AttributesHelper
2525
{
2626
private const SINGLE_ATTRIBUTE = '\s*([.]-?[_a-z][^\s}]*|[#][^\s}]+|' . RegexHelper::PARTIAL_ATTRIBUTENAME . RegexHelper::PARTIAL_ATTRIBUTEVALUESPEC . '?)\s*';
27-
private const ATTRIBUTE_LIST = '/^{:?(' . self::SINGLE_ATTRIBUTE . ')+}/i';
27+
private const ATTRIBUTE_LIST = '/^{:?(' . self::SINGLE_ATTRIBUTE . ')+}(?!})/i';
2828

2929
/**
3030
* @return array<string, mixed>

src/Parser/MarkdownParser.php

+12-6
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,13 @@ private function parseLine(string $line): void
158158
$unmatchedBlocks = 0;
159159
}
160160

161+
$oldBlockLineStart = null;
161162
if ($blockStart->isReplaceActiveBlockParser()) {
162-
$this->prepareActiveBlockParserForReplacement();
163+
$oldBlockLineStart = $this->prepareActiveBlockParserForReplacement();
163164
}
164165

165166
foreach ($blockStart->getBlockParsers() as $newBlockParser) {
166-
$blockParser = $this->addChild($newBlockParser);
167+
$blockParser = $this->addChild($newBlockParser, $oldBlockLineStart);
167168
$tryBlockStarts = $newBlockParser->isContainer();
168169
}
169170
}
@@ -275,12 +276,12 @@ private function processInlines(): void
275276
* Add block of type tag as a child of the tip. If the tip can't accept children, close and finalize it and try
276277
* its parent, and so on til we find a block that can accept children.
277278
*/
278-
private function addChild(BlockContinueParserInterface $blockParser): BlockContinueParserInterface
279+
private function addChild(BlockContinueParserInterface $blockParser, ?int $startLineNumber = null): BlockContinueParserInterface
279280
{
280-
$blockParser->getBlock()->setStartLine($this->lineNumber);
281+
$blockParser->getBlock()->setStartLine($startLineNumber ?? $this->lineNumber);
281282

282283
while (! $this->getActiveBlockParser()->canContain($blockParser->getBlock())) {
283-
$this->closeBlockParsers(1, $this->lineNumber - 1);
284+
$this->closeBlockParsers(1, ($startLineNumber ?? $this->lineNumber) - 1);
284285
}
285286

286287
$this->getActiveBlockParser()->getBlock()->appendChild($blockParser->getBlock());
@@ -307,7 +308,10 @@ private function deactivateBlockParser(): BlockContinueParserInterface
307308
return $popped;
308309
}
309310

310-
private function prepareActiveBlockParserForReplacement(): void
311+
/**
312+
* @return int|null The line number where the old block started
313+
*/
314+
private function prepareActiveBlockParserForReplacement(): ?int
311315
{
312316
// Note that we don't want to parse inlines or finalize this block, as it's getting replaced.
313317
$old = $this->deactivateBlockParser();
@@ -317,6 +321,8 @@ private function prepareActiveBlockParserForReplacement(): void
317321
}
318322

319323
$old->getBlock()->detach();
324+
325+
return $old->getBlock()->getStartLine();
320326
}
321327

322328
/**

tests/functional/Extension/Attributes/data/special_attributes.html

+3
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ <h2 class="main shine" id="the-site">The Site</h2>
1313
<p>Attributes without quote and non-whitespace char and a dot <a target="_blank" href="http://url.com" rel="noopener noreferrer">link</a>.</p>
1414
<p>Multiple attributes without quote and non-whitespace char and a dot <a class="class" id="id" target="_blank" href="http://url.com" rel="noopener noreferrer">link</a>.</p>
1515
<p><img valueless-attribute src="/assets/image.jpg" alt="image" /></p>
16+
<p>A paragraph containing {{ mustache }} templating</p>
17+
<p>A paragraph ending with {{ mustache }} templating</p>
18+
<p>{{ mustache }} A paragraph starting with mustache templating</p>

tests/functional/Extension/Attributes/data/special_attributes.md

+7
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,10 @@ Attributes without quote and non-whitespace char and a dot [link](http://url.com
3030
Multiple attributes without quote and non-whitespace char and a dot [link](http://url.com){#id .class target=_blank}.
3131

3232
![image](/assets/image.jpg){valueless-attribute}
33+
34+
A paragraph containing {{ mustache }} templating
35+
36+
A paragraph ending with {{ mustache }} templating
37+
38+
{{ mustache }} A paragraph starting with mustache templating
39+

tests/functional/Extension/Table/TableMarkdownTest.php

+27
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@
1818
use League\CommonMark\ConverterInterface;
1919
use League\CommonMark\Environment\Environment;
2020
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
21+
use League\CommonMark\Extension\Table\Table;
2122
use League\CommonMark\Extension\Table\TableExtension;
2223
use League\CommonMark\MarkdownConverter;
24+
use League\CommonMark\Parser\MarkdownParser;
2325
use League\CommonMark\Tests\Functional\AbstractLocalDataTestCase;
2426

2527
/**
@@ -46,4 +48,29 @@ public static function dataProvider(): iterable
4648
{
4749
yield from self::loadTests(__DIR__ . '/md');
4850
}
51+
52+
public function testStartEndLinesProperlySet(): void
53+
{
54+
$markdown = <<<MD
55+
56+
## Tabelle
57+
58+
| Datum | Programm | Ort |
59+
| --- | --- | --- |
60+
| 22. Mai | Anreise | Eichberg |
61+
| 23. Mai | Programm | Eichberg |
62+
MD;
63+
64+
$environment = new Environment([]);
65+
$environment->addExtension(new CommonMarkCoreExtension());
66+
$environment->addExtension(new TableExtension());
67+
68+
$parser = new MarkdownParser($environment);
69+
$doc = $parser->parse($markdown);
70+
71+
$table = $doc->lastChild();
72+
$this->assertInstanceOf(Table::class, $table);
73+
$this->assertSame(4, $table->getStartLine());
74+
$this->assertSame(7, $table->getEndLine());
75+
}
4976
}

tests/unit/Extension/Attributes/Util/AttributesHelperTest.php

+5
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ public static function dataForTestParseAttributes(): iterable
101101
// Curly braces inside of values
102102
yield [new Cursor('{: data-json="{1,2,3}" }'), ['data-json' => '{1,2,3}']];
103103
yield [new Cursor('{data-json={1,2,3}} test'), ['data-json' => '{1,2,3}'], ' test'];
104+
105+
// Avoid mustache style templating language being parsed as attributes
106+
yield [new Cursor('{{ foo }}'), [], '{{ foo }}'];
107+
yield [new Cursor(' {{ foo }}'), [], ' {{ foo }}'];
108+
yield [new Cursor('{ foo }}'), [], '{ foo }}'];
104109
}
105110

106111
/**

0 commit comments

Comments
 (0)