diff --git a/.github/workflows/merge-dependabot-upgrades.yml b/.github/workflows/merge-dependabot-upgrades.yml index 59ab55463f..430c4ca48e 100644 --- a/.github/workflows/merge-dependabot-upgrades.yml +++ b/.github/workflows/merge-dependabot-upgrades.yml @@ -17,7 +17,7 @@ jobs: steps: - name: Auto-Merge if: ${{ github.event.workflow_run.conclusion == 'success' }} - uses: ridedott/merge-me-action@v2.10.5 + uses: ridedott/merge-me-action@v2.10.15 with: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} PRESET: DEPENDABOT_MINOR diff --git a/CHANGELOG.md b/CHANGELOG.md index 372495b83d..a12a3c2049 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,19 @@ Updates should follow the [Keep a CHANGELOG](https://keepachangelog.com/) princi ## [Unreleased][unreleased] +## [2.3.4] - 2022-07-17 + +### Changed + +- Made a number of small tweaks to the embed extension's parsing behavior to fix #898: + - Changed `EmbedStartParser` to always capture embed-like lines in container blocks, regardless of parent block type + - Changed `EmbedProcessor` to also remove `Embed` blocks that aren't direct children of the `Document` + - Increased the priority of `EmbedProcessor` to `1010` + +### Fixed + +- Fixed `EmbedExtension` not parsing embeds following a list block (#898) + ## [2.3.3] - 2022-06-07 ### Fixed @@ -475,7 +488,8 @@ No changes were introduced since the previous release. - Alternative 1: Use `CommonMarkConverter` or `GithubFlavoredMarkdownConverter` if you don't need to customize the environment - Alternative 2: Instantiate a new `Environment` and add the necessary extensions yourself -[unreleased]: https://github.com/thephpleague/commonmark/compare/2.3.3...main +[unreleased]: https://github.com/thephpleague/commonmark/compare/2.3.4...main +[2.3.4]: https://github.com/thephpleague/commonmark/compare/2.3.3...2.3.4 [2.3.3]: https://github.com/thephpleague/commonmark/compare/2.3.2...2.3.3 [2.3.2]: https://github.com/thephpleague/commonmark/compare/2.3.2...main [2.3.1]: https://github.com/thephpleague/commonmark/compare/2.3.0...2.3.1 diff --git a/README.md b/README.md index df6187b151..7774afbb2b 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,7 @@ This code is partially based on the [CommonMark JS reference implementation][com We'd also like to extend our sincere thanks the following sponsors who support ongoing development of this project: - [Tidelift](https://tidelift.com/subscription/pkg/packagist-league-commonmark?utm_source=packagist-league-commonmark&utm_medium=referral&utm_campaign=readme) for offering support to both the maintainers and end-users through their [professional support](https://tidelift.com/subscription/pkg/packagist-league-commonmark?utm_source=packagist-league-commonmark&utm_medium=referral&utm_campaign=readme) program + - [Blackfire](https://www.blackfire.io/) for providing an Open-Source Profiler subscription - [JetBrains](https://www.jetbrains.com/) for supporting this project with complimentary [PhpStorm](https://www.jetbrains.com/phpstorm/) licenses - [Taylor Otwell](https://twitter.com/taylorotwell) for sponsoring this project through GitHub sponsors diff --git a/docs/_data/menu.yml b/docs/_data/menu.yml index ba92374502..aa69c89102 100644 --- a/docs/_data/menu.yml +++ b/docs/_data/menu.yml @@ -23,6 +23,7 @@ version: 'Embed': '/2.3/extensions/embed/' 'External Links': '/2.3/extensions/external-links/' 'Footnotes': '/2.3/extensions/footnotes/' + 'Front Matter': '/2.3/extensions/front-matter/' 'Heading Permalinks': '/2.3/extensions/heading-permalinks/' 'Inlines Only': '/2.3/extensions/inlines-only/' 'Mentions': '/2.3/extensions/mentions/' @@ -67,6 +68,7 @@ version: 'Disallowed Raw HTML': '/2.2/extensions/disallowed-raw-html/' 'External Links': '/2.2/extensions/external-links/' 'Footnotes': '/2.2/extensions/footnotes/' + 'Front Matter': '/2.2/extensions/front-matter/' 'Heading Permalinks': '/2.2/extensions/heading-permalinks/' 'Inlines Only': '/2.2/extensions/inlines-only/' 'Mentions': '/2.2/extensions/mentions/' @@ -110,6 +112,7 @@ version: 'Description Lists': '/2.1/extensions/description-lists/' 'Disallowed Raw HTML': '/2.1/extensions/disallowed-raw-html/' 'External Links': '/2.1/extensions/external-links/' + 'Front Matter': '/2.1/extensions/front-matter/' 'Footnotes': '/2.1/extensions/footnotes/' 'Heading Permalinks': '/2.1/extensions/heading-permalinks/' 'Inlines Only': '/2.1/extensions/inlines-only/' @@ -154,6 +157,7 @@ version: 'Description Lists': '/2.0/extensions/description-lists/' 'Disallowed Raw HTML': '/2.0/extensions/disallowed-raw-html/' 'External Links': '/2.0/extensions/external-links/' + 'Front Matter': '/2.0/extensions/front-matter/' 'Footnotes': '/2.0/extensions/footnotes/' 'Heading Permalinks': '/2.0/extensions/heading-permalinks/' 'Inlines Only': '/2.0/extensions/inlines-only/' diff --git a/src/Extension/Embed/EmbedExtension.php b/src/Extension/Embed/EmbedExtension.php index 616a837813..babf048d42 100644 --- a/src/Extension/Embed/EmbedExtension.php +++ b/src/Extension/Embed/EmbedExtension.php @@ -42,7 +42,7 @@ public function register(EnvironmentBuilderInterface $environment): void $environment ->addBlockStartParser(new EmbedStartParser(), 300) - ->addEventListener(DocumentParsedEvent::class, new EmbedProcessor($adapter, $environment->getConfiguration()->get('embed.fallback'))) + ->addEventListener(DocumentParsedEvent::class, new EmbedProcessor($adapter, $environment->getConfiguration()->get('embed.fallback')), 1010) ->addRenderer(Embed::class, new EmbedRenderer()); } } diff --git a/src/Extension/Embed/EmbedProcessor.php b/src/Extension/Embed/EmbedProcessor.php index 5df099eb66..68fb9eebc2 100644 --- a/src/Extension/Embed/EmbedProcessor.php +++ b/src/Extension/Embed/EmbedProcessor.php @@ -16,6 +16,7 @@ use League\CommonMark\Event\DocumentParsedEvent; use League\CommonMark\Extension\CommonMark\Node\Inline\Link; use League\CommonMark\Node\Block\Paragraph; +use League\CommonMark\Node\Inline\Text; use League\CommonMark\Node\NodeIterator; final class EmbedProcessor @@ -34,9 +35,18 @@ public function __construct(EmbedAdapterInterface $adapter, string $fallback = s public function __invoke(DocumentParsedEvent $event): void { - $embeds = []; - foreach (new NodeIterator($event->getDocument()) as $node) { - if ($node instanceof Embed) { + $document = $event->getDocument(); + $embeds = []; + foreach (new NodeIterator($document) as $node) { + if (! ($node instanceof Embed)) { + continue; + } + + if ($node->parent() !== $document) { + $replacement = new Paragraph(); + $replacement->appendChild(new Text($node->getUrl())); + $node->replaceWith($replacement); + } else { $embeds[] = $node; } } diff --git a/src/Extension/Embed/EmbedStartParser.php b/src/Extension/Embed/EmbedStartParser.php index 951e212d80..5ff38086dd 100644 --- a/src/Extension/Embed/EmbedStartParser.php +++ b/src/Extension/Embed/EmbedStartParser.php @@ -13,7 +13,6 @@ namespace League\CommonMark\Extension\Embed; -use League\CommonMark\Node\Block\Document; use League\CommonMark\Parser\Block\BlockStart; use League\CommonMark\Parser\Block\BlockStartParserInterface; use League\CommonMark\Parser\Cursor; @@ -24,7 +23,7 @@ class EmbedStartParser implements BlockStartParserInterface { public function tryStart(Cursor $cursor, MarkdownParserStateInterface $parserState): ?BlockStart { - if ($cursor->isIndented() || $parserState->getParagraphContent() !== null || ! ($parserState->getLastMatchedBlockParser()->getBlock() instanceof Document)) { + if ($cursor->isIndented() || $parserState->getParagraphContent() !== null || ! ($parserState->getActiveBlockParser()->isContainer())) { return BlockStart::none(); } diff --git a/tests/functional/Extension/Embed/EmbedExtensionTest.php b/tests/functional/Extension/Embed/EmbedExtensionTest.php index 96deff1b98..218d5edfbd 100644 --- a/tests/functional/Extension/Embed/EmbedExtensionTest.php +++ b/tests/functional/Extension/Embed/EmbedExtensionTest.php @@ -15,6 +15,7 @@ use League\CommonMark\ConverterInterface; use League\CommonMark\Environment\Environment; +use League\CommonMark\Extension\Autolink\AutolinkExtension; use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; use League\CommonMark\Extension\Embed\EmbedExtension; use League\CommonMark\MarkdownConverter; @@ -30,10 +31,17 @@ protected function createConverter(array $config = []): ConverterInterface { $config['embed']['adapter'] = new FakeAdapter(); + $enableAutolinkExtension = $config['enable_autolinks'] ?? false; + unset($config['enable_autolinks']); + $environment = new Environment($config); $environment->addExtension(new CommonMarkCoreExtension()); $environment->addExtension(new EmbedExtension()); + if ($enableAutolinkExtension) { + $environment->addExtension(new AutolinkExtension()); + } + return new MarkdownConverter($environment); } diff --git a/tests/functional/Extension/Embed/data/after_list_regression.html b/tests/functional/Extension/Embed/data/after_list_regression.html new file mode 100644 index 0000000000..f38362c524 --- /dev/null +++ b/tests/functional/Extension/Embed/data/after_list_regression.html @@ -0,0 +1,7 @@ +
This is an embed:
+ +So is this, with only three spaces of indentation:
+ +This is not, because it's fully indented:
+https://www.youtube.com/watch?v=dQw4w9WgXcQ
+
+This is not, because it has extra bits after the URL:
+https://www.youtube.com/watch?v=dQw4w9WgXcQ <-- you gotta watch this!
+This is not, because it's in a fenced code block:
+
+https://www.youtube.com/watch?v=dQw4w9WgXcQ
+
+
+And this isn't either because it's inline:
Embeds can't be nested in other blocks:
+This isn't valid because it's a lazy paragraph continuation: +https://www.youtube.com/watch?v=dQw4w9WgXcQ
+ +^ This is fine, though
diff --git a/tests/functional/Extension/Embed/data/embeds-with-autolinks-enabled.md b/tests/functional/Extension/Embed/data/embeds-with-autolinks-enabled.md new file mode 100644 index 0000000000..c3c2eea537 --- /dev/null +++ b/tests/functional/Extension/Embed/data/embeds-with-autolinks-enabled.md @@ -0,0 +1,40 @@ +--- +enable_autolinks: true +--- + +This is an embed: + +https://www.youtube.com/watch?v=dQw4w9WgXcQ + +So is this, with only three spaces of indentation: + + https://www.youtube.com/watch?v=dQw4w9WgXcQ + +This is not, because it's fully indented: + + https://www.youtube.com/watch?v=dQw4w9WgXcQ + +This is not, because it has extra bits after the URL: + +https://www.youtube.com/watch?v=dQw4w9WgXcQ <-- you gotta watch this! + +This is not, because it's in a fenced code block: + +```md + +https://www.youtube.com/watch?v=dQw4w9WgXcQ + +``` + +And this isn't either because it's inline:  + +Embeds can't be nested in other blocks: + +- https://www.youtube.com/watch?v=dQw4w9WgXcQ + - https://www.youtube.com/watch?v=dQw4w9WgXcQ + +This isn't valid because it's a lazy paragraph continuation: +https://www.youtube.com/watch?v=dQw4w9WgXcQ + +https://www.youtube.com/watch?v=dQw4w9WgXcQ +^ This is fine, though