Skip to content

Commit dfe07db

Browse files
committed
Merge remote-tracking branch 'origin/2.6'
2 parents 88365ec + d990688 commit dfe07db

25 files changed

+150
-337
lines changed

.github/workflows/tests.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
strategy:
3434
fail-fast: false
3535
matrix:
36-
php: ['7.4', '8.0', '8.1', '8.2', '8.3']
36+
php: ['7.4', '8.0', '8.1', '8.2', '8.3', '8.4']
3737
stable: [true]
3838
coverage: [true]
3939
composer-flags: ['']
@@ -42,7 +42,7 @@ jobs:
4242
stable: true
4343
coverage: false
4444
composer-flags: '--prefer-lowest'
45-
- php: '8.4'
45+
- php: '8.5'
4646
stable: false
4747
coverage: false
4848
composer-flags: '--ignore-platform-req=php'
@@ -114,7 +114,7 @@ jobs:
114114
runs-on: ubuntu-latest
115115

116116
steps:
117-
- uses: actions/checkout@v3
117+
- uses: actions/checkout@v4
118118

119119
- uses: shivammathur/setup-php@v2
120120
with:

CHANGELOG.md

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

77
## [Unreleased][unreleased]
88

9+
## [2.6.1] - 2024-12-29
10+
11+
### Fixed
12+
13+
- Rendered list items should only add newlines around block-level children (#1059, #1061)
14+
915
## [2.6.0] - 2024-12-07
1016

1117
This is a **security release** to address potential denial of service attacks when parsing specially crafted,
@@ -677,7 +683,8 @@ No changes were introduced since the previous release.
677683
- Alternative 1: Use `CommonMarkConverter` or `GithubFlavoredMarkdownConverter` if you don't need to customize the environment
678684
- Alternative 2: Instantiate a new `Environment` and add the necessary extensions yourself
679685

680-
[unreleased]: https://github.com/thephpleague/commonmark/compare/2.6.0...main
686+
[unreleased]: https://github.com/thephpleague/commonmark/compare/2.6.1...main
687+
[2.6.1]: https://github.com/thephpleague/commonmark/compare/2.6.0...2.6.1
681688
[2.6.0]: https://github.com/thephpleague/commonmark/compare/2.5.3...2.6.0
682689
[2.5.3]: https://github.com/thephpleague/commonmark/compare/2.5.2...2.5.3
683690
[2.5.2]: https://github.com/thephpleague/commonmark/compare/2.5.1...2.5.2

src/Extension/CommonMark/Renderer/Block/ListItemRenderer.php

+12-6
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
namespace League\CommonMark\Extension\CommonMark\Renderer\Block;
1818

1919
use League\CommonMark\Extension\CommonMark\Node\Block\ListItem;
20-
use League\CommonMark\Extension\TaskList\TaskListItemMarker;
20+
use League\CommonMark\Node\Block\AbstractBlock;
2121
use League\CommonMark\Node\Block\Paragraph;
22+
use League\CommonMark\Node\Block\TightBlockInterface;
2223
use League\CommonMark\Node\Node;
2324
use League\CommonMark\Renderer\ChildNodeRendererInterface;
2425
use League\CommonMark\Renderer\NodeRendererInterface;
@@ -39,11 +40,14 @@ public function render(Node $node, ChildNodeRendererInterface $childRenderer): \
3940
ListItem::assertInstanceOf($node);
4041

4142
$contents = $childRenderer->renderNodes($node->children());
42-
if (\substr($contents, 0, 1) === '<' && ! $this->startsTaskListItem($node)) {
43+
44+
$inTightList = ($parent = $node->parent()) && $parent instanceof TightBlockInterface && $parent->isTight();
45+
46+
if ($this->needsBlockSeparator($node->firstChild(), $inTightList)) {
4347
$contents = "\n" . $contents;
4448
}
4549

46-
if (\substr($contents, -1, 1) === '>') {
50+
if ($this->needsBlockSeparator($node->lastChild(), $inTightList)) {
4751
$contents .= "\n";
4852
}
4953

@@ -65,10 +69,12 @@ public function getXmlAttributes(Node $node): array
6569
return [];
6670
}
6771

68-
private function startsTaskListItem(ListItem $block): bool
72+
private function needsBlockSeparator(?Node $child, bool $inTightList): bool
6973
{
70-
$firstChild = $block->firstChild();
74+
if ($child instanceof Paragraph && $inTightList) {
75+
return false;
76+
}
7177

72-
return $firstChild instanceof Paragraph && $firstChild->firstChild() instanceof TaskListItemMarker;
78+
return $child instanceof AbstractBlock;
7379
}
7480
}

tests/functional/CMarkRegressionTest.php

-6
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@ public static function dataProvider(): \Generator
2727
{
2828
$tests = SpecReader::readFile(__DIR__ . '/../../vendor/commonmark/cmark/test/regression.txt');
2929
foreach ($tests as $example) {
30-
// We can't currently render spec example 13 exactly how the upstream library does. We'll likely need to overhaul
31-
// our rendering approach in order to fix that, so we'll use this temporary workaround for now.
32-
if ($example['number'] === 13) {
33-
$example['output'] = \str_replace('</script></li>', "</script>\n</li>", $example['output']);
34-
}
35-
3630
// The case-fold test from example 21 fails on PHP 8.0.* and below due to the behavior of mb_convert_case().
3731
// See https://3v4l.org/7TeXJ.
3832
if (\PHP_VERSION_ID < 81000 && $example['number'] === 21) {

tests/functional/CommonMarkJSRegressionTest.php

+1-12
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,6 @@ final class CommonMarkJSRegressionTest extends AbstractSpecTestCase
2525
{
2626
public static function dataProvider(): \Generator
2727
{
28-
$tests = SpecReader::readFile(__DIR__ . '/../../vendor/commonmark/commonmark.js/test/regression.txt');
29-
foreach ($tests as $example) {
30-
// We can't currently render spec examples 18 or 24 exactly how the upstream library does. We'll likely need to overhaul
31-
// our rendering approach in order to fix that, so we'll use this temporary workaround for now.
32-
if ($example['number'] === 18) {
33-
$example['output'] = \str_replace('</script></li>', "</script>\n</li>", $example['output']);
34-
} elseif ($example['number'] === 24) {
35-
$example['output'] = \str_replace("<pre>The following line is part of HTML block.\n\n</li>", "<pre>The following line is part of HTML block.\n</li>", $example['output']);
36-
}
37-
38-
yield $example;
39-
}
28+
yield from SpecReader::readFile(__DIR__ . '/../../vendor/commonmark/commonmark.js/test/regression.txt');
4029
}
4130
}

tests/functional/Delimiter/DelimiterProcessingTest.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public function testAsymmetricDelimiterProcessing(string $input, string $expecte
4949

5050
$converter = new MarkdownConverter($e);
5151

52-
$this->assertEquals($expected, $converter->convert($input));
52+
$this->assertEquals($expected, $converter->convert($input)->getContent());
5353
}
5454

5555
/**

tests/functional/Extension/Autolink/UrlAutolinkParserTest.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public static function dataProviderForAutolinkTests(): iterable
4949
yield ['www.google.com', '<p><a href="http://www.google.com">www.google.com</a></p>'];
5050
yield [' http://leadingwhitespace.example.com', '<p><a href="http://leadingwhitespace.example.com">http://leadingwhitespace.example.com</a></p>'];
5151
yield ['http://trailingwhitespace.example.com ', '<p><a href="http://trailingwhitespace.example.com">http://trailingwhitespace.example.com</a></p>'];
52-
yield ['- https://example.com/list-item', "<ul>\n<li>\n<a href=\"https://example.com/list-item\">https://example.com/list-item</a>\n</li>\n</ul>"];
52+
yield ['- https://example.com/list-item', "<ul>\n<li><a href=\"https://example.com/list-item\">https://example.com/list-item</a></li>\n</ul>"];
5353

5454
// Tests of "incomplete" URLs
5555
yield ['google.com is missing www and/or a protocol', '<p>google.com is missing www and/or a protocol</p>'];
@@ -60,7 +60,7 @@ public static function dataProviderForAutolinkTests(): iterable
6060
yield ['Maybe you\'re interested in https://www.google.com/search?q=php+commonmark!', '<p>Maybe you\'re interested in <a href="https://www.google.com/search?q=php+commonmark">https://www.google.com/search?q=php+commonmark</a>!</p>'];
6161
yield ['Or perhaps you\'re looking for my personal website https://www.colinodell.com...?', '<p>Or perhaps you\'re looking for my personal website <a href="https://www.colinodell.com">https://www.colinodell.com</a>...?</p>'];
6262
yield ['Check https://www.stackoverflow.com: they have all the answers', '<p>Check <a href="https://www.stackoverflow.com">https://www.stackoverflow.com</a>: they have all the answers</p>'];
63-
yield ['- https://example.com/list-item-with-trailing-colon:', "<ul>\n<li>\n<a href=\"https://example.com/list-item-with-trailing-colon\">https://example.com/list-item-with-trailing-colon</a>:</li>\n</ul>"];
63+
yield ['- https://example.com/list-item-with-trailing-colon:', "<ul>\n<li><a href=\"https://example.com/list-item-with-trailing-colon\">https://example.com/list-item-with-trailing-colon</a>:</li>\n</ul>"];
6464
yield ['Visit www.commonmark.org.', '<p>Visit <a href="http://www.commonmark.org">www.commonmark.org</a>.</p>'];
6565
yield ['Visit www.commonmark.org/a.b.', '<p>Visit <a href="http://www.commonmark.org/a.b">www.commonmark.org/a.b</a>.</p>'];
6666

tests/functional/Extension/Footnote/spec.txt

+3-6
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,9 @@ A [footnote identifier] can come immediately after a word, or have a space betwe
106106
[^5]: Not allowed
107107
.
108108
<ul>
109-
<li>No spaces<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" role="doc-noteref">1</a></sup>
110-
</li>
111-
<li>One space <sup id="fnref:2"><a class="footnote-ref" href="#fn:2" role="doc-noteref">2</a></sup>
112-
</li>
113-
<li>Exclamation mark with space! <sup id="fnref:3"><a class="footnote-ref" href="#fn:3" role="doc-noteref">3</a></sup>
114-
</li>
109+
<li>No spaces<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" role="doc-noteref">1</a></sup></li>
110+
<li>One space <sup id="fnref:2"><a class="footnote-ref" href="#fn:2" role="doc-noteref">2</a></sup></li>
111+
<li>Exclamation mark with space! <sup id="fnref:3"><a class="footnote-ref" href="#fn:3" role="doc-noteref">3</a></sup></li>
115112
<li>Exclamation mark with no space![^4]</li>
116113
<li>Another exclamation mark![^5](not allowed)</li>
117114
</ul>

tests/functional/Extension/Mention/MentionExtensionTest.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function testNoConfig(): void
4444

4545
$converter = new MarkdownConverter($environment);
4646

47-
$this->assertEquals($expected, $converter->convert($input));
47+
$this->assertEquals($expected, $converter->convert($input)->getContent());
4848
}
4949

5050
public function testConfigStringGenerator(): void
@@ -72,7 +72,7 @@ public function testConfigStringGenerator(): void
7272

7373
$converter = new MarkdownConverter($environment);
7474

75-
$this->assertEquals($expected, $converter->convert($input));
75+
$this->assertEquals($expected, $converter->convert($input)->getContent());
7676
}
7777

7878
public function testConfigCallableGenerator(): void
@@ -104,7 +104,7 @@ public function testConfigCallableGenerator(): void
104104

105105
$converter = new MarkdownConverter($environment);
106106

107-
$this->assertEquals($expected, $converter->convert($input));
107+
$this->assertEquals($expected, $converter->convert($input)->getContent());
108108
}
109109

110110
public function testConfigObjectImplementingMentionGeneratorInterface(): void
@@ -139,7 +139,7 @@ public function generateMention(Mention $mention): ?AbstractInline
139139

140140
$converter = new MarkdownConverter($environment);
141141

142-
$this->assertEquals($expected, $converter->convert($input));
142+
$this->assertEquals($expected, $converter->convert($input)->getContent());
143143
}
144144

145145
public function testConfigUnknownGenerator(): void

tests/functional/Extension/TableOfContents/md/custom-class.html

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
<ul class="markdown-toc">
2-
<li>
3-
<a href="#content-hello">Hello</a>
2+
<li><a href="#content-hello">Hello</a>
43
<ul>
5-
<li>
6-
<a href="#content-world">World</a>
7-
</li>
4+
<li><a href="#content-world">World</a></li>
85
</ul>
96
</li>
107
</ul>

tests/functional/Extension/TableOfContents/md/headings-with-inlines.html

+3-9
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
<ul class="table-of-contents">
2-
<li>
3-
<a href="#content-this-heading-has-a-link">This heading has a link</a>
4-
</li>
5-
<li>
6-
<a href="#content-20-reasons-why-marquee-tags-should-make-a-comeback">20 Reasons Why &lt;marquee&gt; Tags Should Make A Comeback</a>
7-
</li>
8-
<li>
9-
<a href="#content-i-love-using--characters-in-markdown">I love using * characters in Markdown!</a>
10-
</li>
2+
<li><a href="#content-this-heading-has-a-link">This heading has a link</a></li>
3+
<li><a href="#content-20-reasons-why-marquee-tags-should-make-a-comeback">20 Reasons Why &lt;marquee&gt; Tags Should Make A Comeback</a></li>
4+
<li><a href="#content-i-love-using--characters-in-markdown">I love using * characters in Markdown!</a></li>
115
</ul>
126
<p>My Awesome Blog Post</p>
137
<h2><a id="content-this-heading-has-a-link" href="#content-this-heading-has-a-link" class="heading-permalink" aria-hidden="true" title="Permalink"></a><a href="https://example.com">This heading</a> has a link</h2>

tests/functional/Extension/TableOfContents/md/html-in-headings.html

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
<ul class="table-of-contents">
2-
<li>
3-
<a href="#content-hello-world">Hello World! </a>
4-
</li>
2+
<li><a href="#content-hello-world">Hello World! </a></li>
53
</ul>
64
<p>Here's a sample Markdown document</p>
75
<h1><a id="content-hello-world" href="#content-hello-world" class="heading-permalink" aria-hidden="true" title="Permalink"></a>Hello World! <i class="icon icon-waving-hand"></i></h1>

tests/functional/Extension/TableOfContents/md/min-max.html

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
<ul class="table-of-contents">
2-
<li>
3-
<a href="#content-level-2">Level 2</a>
2+
<li><a href="#content-level-2">Level 2</a>
43
<ul>
5-
<li>
6-
<a href="#content-level-3">Level 3</a>
4+
<li><a href="#content-level-3">Level 3</a>
75
<ul>
8-
<li>
9-
<a href="#content-level-4">Level 4</a>
6+
<li><a href="#content-level-4">Level 4</a>
107
<ul>
11-
<li>
12-
<a href="#content-level-5">Level 5</a>
13-
</li>
8+
<li><a href="#content-level-5">Level 5</a></li>
149
</ul>
1510
</li>
1611
</ul>

tests/functional/Extension/TableOfContents/md/position-before-headings.html

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
<p>This is my document.</p>
22
<ul class="table-of-contents">
3-
<li>
4-
<a href="#content-hello-world">Hello World!</a>
3+
<li><a href="#content-hello-world">Hello World!</a>
54
<ul>
6-
<li>
7-
<a href="#content-isnt-markdown-great">Isn't Markdown Great?</a>
8-
</li>
5+
<li><a href="#content-isnt-markdown-great">Isn't Markdown Great?</a></li>
96
</ul>
107
</li>
118
</ul>

tests/functional/Extension/TableOfContents/md/position-placeholder-multiple.html

+6-16
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,18 @@
11
<p>This is my document.</p>
22
<ul class="table-of-contents">
3-
<li>
4-
<a href="#content-another-copy-of-my-toc-is-here">Another copy of my TOC is here</a>
3+
<li><a href="#content-another-copy-of-my-toc-is-here">Another copy of my TOC is here</a>
54
<ul>
6-
<li>
7-
<a href="#content-this-contains-something-that-looks-like-a-placeholder-but-actually-isnt">This contains something that looks like a placeholder but actually isn't</a>
8-
</li>
9-
<li>
10-
<a href="#content-just-a-link-reference-down-here">Just a link reference down here</a>
11-
</li>
5+
<li><a href="#content-this-contains-something-that-looks-like-a-placeholder-but-actually-isnt">This contains something that looks like a placeholder but actually isn't</a></li>
6+
<li><a href="#content-just-a-link-reference-down-here">Just a link reference down here</a></li>
127
</ul>
138
</li>
149
</ul>
1510
<h1><a id="content-another-copy-of-my-toc-is-here" href="#content-another-copy-of-my-toc-is-here" class="heading-permalink" aria-hidden="true" title="Permalink"></a>Another copy of my TOC is here</h1>
1611
<ul class="table-of-contents">
17-
<li>
18-
<a href="#content-another-copy-of-my-toc-is-here">Another copy of my TOC is here</a>
12+
<li><a href="#content-another-copy-of-my-toc-is-here">Another copy of my TOC is here</a>
1913
<ul>
20-
<li>
21-
<a href="#content-this-contains-something-that-looks-like-a-placeholder-but-actually-isnt">This contains something that looks like a placeholder but actually isn't</a>
22-
</li>
23-
<li>
24-
<a href="#content-just-a-link-reference-down-here">Just a link reference down here</a>
25-
</li>
14+
<li><a href="#content-this-contains-something-that-looks-like-a-placeholder-but-actually-isnt">This contains something that looks like a placeholder but actually isn't</a></li>
15+
<li><a href="#content-just-a-link-reference-down-here">Just a link reference down here</a></li>
2616
</ul>
2717
</li>
2818
</ul>

tests/functional/Extension/TableOfContents/md/position-top.html

+2-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
<ul class="table-of-contents">
2-
<li>
3-
<a href="#content-hello-world">Hello World!</a>
2+
<li><a href="#content-hello-world">Hello World!</a>
43
<ul>
5-
<li>
6-
<a href="#content-isnt-markdown-great">Isn't Markdown Great?</a>
7-
</li>
4+
<li><a href="#content-isnt-markdown-great">Isn't Markdown Great?</a></li>
85
</ul>
96
</li>
107
</ul>

0 commit comments

Comments
 (0)