From f7d77720180b34afd506c1aa6426bad7fbd8cdb3 Mon Sep 17 00:00:00 2001 From: Colin O'Dell Date: Sat, 25 Feb 2023 12:03:40 -0500 Subject: [PATCH] Update Strikethrough parsing to match updated GFM spec --- CHANGELOG.md | 1 + .../StrikethroughDelimiterProcessor.php | 12 ++++++--- .../StrikethroughExtensionTest.php} | 26 ++++++++++++++----- 3 files changed, 29 insertions(+), 10 deletions(-) rename tests/{unit/Extension/Strikethrough/IntegrationTest.php => functional/Extension/Strikethrough/StrikethroughExtensionTest.php} (66%) diff --git a/CHANGELOG.md b/CHANGELOG.md index e663489302..527ad6cb31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ Updates should follow the [Keep a CHANGELOG](https://keepachangelog.com/) princi - `HeadingPermalinkProcessor` now throws `InvalidConfigurationException` instead of `RuntimeException` when invalid config values are given. - `HtmlElement::setAttribute()` no longer requires the second parameter for boolean attributes - Several small micro-optimizations +- Changed Strikethrough to only allow 1 or 2 tildes per the updated GFM spec ### Fixed diff --git a/src/Extension/Strikethrough/StrikethroughDelimiterProcessor.php b/src/Extension/Strikethrough/StrikethroughDelimiterProcessor.php index f3fd70a9ae..af0fdb17c7 100644 --- a/src/Extension/Strikethrough/StrikethroughDelimiterProcessor.php +++ b/src/Extension/Strikethrough/StrikethroughDelimiterProcessor.php @@ -31,14 +31,20 @@ public function getClosingCharacter(): string public function getMinLength(): int { - return 2; + return 1; } public function getDelimiterUse(DelimiterInterface $opener, DelimiterInterface $closer): int { - $min = \min($opener->getLength(), $closer->getLength()); + if ($opener->getLength() > 2 && $closer->getLength() > 2) { + return 0; + } + + if ($opener->getLength() !== $closer->getLength()) { + return 0; + } - return $min >= 2 ? $min : 0; + return \min($opener->getLength(), $closer->getLength()); } public function process(AbstractStringContainer $opener, AbstractStringContainer $closer, int $delimiterUse): void diff --git a/tests/unit/Extension/Strikethrough/IntegrationTest.php b/tests/functional/Extension/Strikethrough/StrikethroughExtensionTest.php similarity index 66% rename from tests/unit/Extension/Strikethrough/IntegrationTest.php rename to tests/functional/Extension/Strikethrough/StrikethroughExtensionTest.php index e0786645f0..5d1b86762a 100644 --- a/tests/unit/Extension/Strikethrough/IntegrationTest.php +++ b/tests/functional/Extension/Strikethrough/StrikethroughExtensionTest.php @@ -11,7 +11,7 @@ * file that was distributed with this source code. */ -namespace League\CommonMark\Tests\Unit\Extension\Strikethrough; +namespace League\CommonMark\Tests\Functional\Extension\Strikethrough; use League\CommonMark\Environment\Environment; use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension; @@ -20,7 +20,7 @@ use League\CommonMark\Renderer\HtmlRenderer; use PHPUnit\Framework\TestCase; -final class IntegrationTest extends TestCase +final class StrikethroughExtensionTest extends TestCase { /** * @dataProvider dataForIntegrationTest @@ -47,23 +47,35 @@ public function testStrikethrough(string $string, string $expected): void public function dataForIntegrationTest(): array { return [ + ['~~Hi~~ Hello, ~there~ world!', "

Hi Hello, there world!

\n"], ['This is a test without any strikethroughs', "

This is a test without any strikethroughs

\n"], - ['This is a test without any ~valid~ strikethroughs', "

This is a test without any ~valid~ strikethroughs

\n"], - ['This is a test `without` any ~valid~ strikethroughs', "

This is a test without any ~valid~ strikethroughs

\n"], + ['This is a test with ~valid~ strikethroughs', "

This is a test with valid strikethroughs

\n"], + ['This is a test `with` ~valid~ strikethroughs', "

This is a test with valid strikethroughs

\n"], ['This is a ~~unit~~ integration test', "

This is a unit integration test

\n"], ['~~Strikethrough~~ on the left', "

Strikethrough on the left

\n"], ['Strikethrough on the ~~right~~', "

Strikethrough on the right

\n"], ['~~Strikethrough everywhere~~', "

Strikethrough everywhere

\n"], ['This ~~test has no ending match', "

This ~~test has no ending match

\n"], - ['This ~~test~~~ has mismatched tildes', "

This test~ has mismatched tildes

\n"], - ['This ~~~test~~ also has mismatched tildes', "

This ~test also has mismatched tildes

\n"], - ['This one has ~~~three~~~ tildes', "

This one has three tildes

\n"], + ['This ~~test~~~ has mismatched tildes', "

This ~~test~~~ has mismatched tildes

\n"], + ['This ~~~test~~ also has mismatched tildes', "

This ~~~test~~ also has mismatched tildes

\n"], + ['This one has ~~~three~~~ tildes', "

This one has ~~~three~~~ tildes

\n"], ["This ~~has a\n\nnew paragraph~~.", "

This ~~has a

\n

new paragraph~~.

\n"], ['Hello ~~ ~~ world', "

Hello ~~ ~~ world

\n"], ['This **is ~~a little** test of mismatched delimiters~~', "

This is ~~a little test of mismatched delimiters~~

\n"], ['Из: твоя ~~тест~~ ветка', "

Из: твоя тест ветка

\n"], ['This one combines ~~nested ~~strikethrough~~ text~~', "

This one combines nested strikethrough text

\n"], ['Here we have **emphasized text containing a ~~strikethrough~~**', "

Here we have emphasized text containing a strikethrough

\n"], + ['Four trailing tildes ~~~~', "

Four trailing tildes ~~~~

\n"], + ['~~Unmatched left', "

~~Unmatched left

\n"], + ['Unmatched right~~', "

Unmatched right~~

\n"], + ['~~foo~bar~~', "

foo~bar

\n"], + ['~~foo~~bar~~', "

foobar~~

\n"], + ['~~foo~~~bar~~', "

foo~~~bar

\n"], + ['~~foo~~~~bar~~', "

foo~~~~bar

\n"], + ['~~foo~~~~~bar~~', "

foo~~~~~bar

\n"], + ['~~foo~~~~~~bar~~', "

foo~~~~~~bar

\n"], + ['~~foo~~~~~~~bar~~', "

foo~~~~~~~bar

\n"], + ['> inside a ~~blockquote~~', "
\n

inside a blockquote

\n
\n"], ]; } }