From 13f28fb67551f78333aa465daef3b59d645e0f21 Mon Sep 17 00:00:00 2001 From: Rupayon Haldar <80724680+rupayon123@users.noreply.github.com> Date: Sat, 26 Sep 2026 02:50:27 -0400 Subject: [PATCH 1/5] Fix ASCII HTML block start matching --- markdown_it/rules_block/html_block.py | 13 +++++++++---- tests/test_html_block_ascii.py | 26 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 tests/test_html_block_ascii.py diff --git a/markdown_it/rules_block/html_block.py b/markdown_it/rules_block/html_block.py index fe7e464e..8b195933 100644 --- a/markdown_it/rules_block/html_block.py +++ b/markdown_it/rules_block/html_block.py @@ -14,16 +14,21 @@ # last argument defines whether it can terminate a paragraph or not HTML_SEQUENCES: list[tuple[re.Pattern[str], re.Pattern[str], bool]] = [ ( - re.compile(r"^<(script|pre|style|textarea)(?=(\s|>|$))", re.IGNORECASE), - re.compile(r"<\/(script|pre|style|textarea)>", re.IGNORECASE), + re.compile( + r"^<(script|pre|style|textarea)(?=(\s|>|$))", re.IGNORECASE | re.ASCII + ), + re.compile(r"<\/(script|pre|style|textarea)>", re.IGNORECASE | re.ASCII), True, ), (re.compile(r"^"), True), (re.compile(r"^<\?"), re.compile(r"\?>"), True), - (re.compile(r"^"), True), + (re.compile(r"^"), True), (re.compile(r"^"), True), ( - re.compile("^|$))", re.IGNORECASE), + re.compile( + "^|$))", + re.IGNORECASE | re.ASCII, + ), re.compile(r"^$"), True, ), diff --git a/tests/test_html_block_ascii.py b/tests/test_html_block_ascii.py new file mode 100644 index 00000000..4f388739 --- /dev/null +++ b/tests/test_html_block_ascii.py @@ -0,0 +1,26 @@ +"""CommonMark HTML block starts use ASCII letters for tag and declarations.""" + +import pytest + +from markdown_it import MarkdownIt + + +@pytest.mark.parametrize("declaration", ["", ""]) +def test_ascii_declaration_ends_paragraph(declaration: str) -> None: + md = MarkdownIt("commonmark") + assert md.render(f"para\n{declaration}\n") == f"

para

\n{declaration}\n" + + +@pytest.mark.parametrize("tag", ["\u017fcript", "\u017ftyle", "d\u0130v", "d\u0131v"]) +def test_unicode_casefold_does_not_start_html_block(tag: str) -> None: + md = MarkdownIt("commonmark") + assert md.render(f"para\n<{tag}>\ntext\n") == ( + f"

para\n<{tag}>\ntext

\n" + ) + + +def test_ascii_mixed_case_tag_still_starts_html_block() -> None: + md = MarkdownIt("commonmark") + assert md.render("para\n\n") == ( + "

para

\n\n" + ) From 3650b270365bc7f0fcaa6fbc22c734a4df5ca5ec Mon Sep 17 00:00:00 2001 From: Rupayon Haldar <80724680+rupayon123@users.noreply.github.com> Date: Sat, 26 Sep 2026 02:57:15 -0400 Subject: [PATCH 2/5] Keep HTML block regressions compatible with strict mypy --- tests/test_html_block_ascii.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/tests/test_html_block_ascii.py b/tests/test_html_block_ascii.py index 4f388739..7293180d 100644 --- a/tests/test_html_block_ascii.py +++ b/tests/test_html_block_ascii.py @@ -1,22 +1,20 @@ """CommonMark HTML block starts use ASCII letters for tag and declarations.""" -import pytest - from markdown_it import MarkdownIt -@pytest.mark.parametrize("declaration", ["", ""]) -def test_ascii_declaration_ends_paragraph(declaration: str) -> None: +def test_ascii_declaration_ends_paragraph() -> None: md = MarkdownIt("commonmark") - assert md.render(f"para\n{declaration}\n") == f"

para

\n{declaration}\n" + for declaration in ("", ""): + assert md.render(f"para\n{declaration}\n") == f"

para

\n{declaration}\n" -@pytest.mark.parametrize("tag", ["\u017fcript", "\u017ftyle", "d\u0130v", "d\u0131v"]) -def test_unicode_casefold_does_not_start_html_block(tag: str) -> None: +def test_unicode_casefold_does_not_start_html_block() -> None: md = MarkdownIt("commonmark") - assert md.render(f"para\n<{tag}>\ntext\n") == ( - f"

para\n<{tag}>\ntext

\n" - ) + for tag in ("\u017fcript", "\u017ftyle", "d\u0130v", "d\u0131v"): + assert md.render(f"para\n<{tag}>\ntext\n") == ( + f"

para\n<{tag}>\ntext

\n" + ) def test_ascii_mixed_case_tag_still_starts_html_block() -> None: From f70c2544fa9b4de81709d5675d1fcd3e958a40f4 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Mon, 9 Nov 2026 20:20:55 +0100 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=90=9B=20FIX:=20scope=20ASCII=20foldi?= =?UTF-8?q?ng=20to=20the=20HTML=20block=20tag=20name?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A global `re.ASCII` also narrows `\s` in the lookahead after the tag name, so a no-break space or other Unicode space after `|$))", re.IGNORECASE | re.ASCII - ), - re.compile(r"<\/(script|pre|style|textarea)>", re.IGNORECASE | re.ASCII), + re.compile(r"^<(?a:(script|pre|style|textarea))(?=(\s|>|$))", re.IGNORECASE), + re.compile(r"<\/(?a:(script|pre|style|textarea))>", re.IGNORECASE), True, ), (re.compile(r"^"), True), @@ -26,8 +24,7 @@ (re.compile(r"^"), True), ( re.compile( - "^|$))", - re.IGNORECASE | re.ASCII, + "^|$))", re.IGNORECASE ), re.compile(r"^$"), True, From e5064ce99ce47397c59b9b4ecead7070afa5f8fd Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Mon, 9 Nov 2026 20:22:07 +0100 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=A7=AA=20TEST:=20move=20the=20#437=20?= =?UTF-8?q?tests=20into=20the=20port=20fixtures?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add upstream markdown-it's own fixture for lowercase declarations (`foo\n`, from 15.0.0) to `commonmark_extras.md`, and the #437 cases to `issue-fixes.md`: lowercase ``, Unicode lookalikes that must neither open nor close a block, an ASCII mixed-case control, and no-break-space controls after ` None: - md = MarkdownIt("commonmark") - for declaration in ("", ""): - assert md.render(f"para\n{declaration}\n") == f"

para

\n{declaration}\n" - - -def test_unicode_casefold_does_not_start_html_block() -> None: - md = MarkdownIt("commonmark") - for tag in ("\u017fcript", "\u017ftyle", "d\u0130v", "d\u0131v"): - assert md.render(f"para\n<{tag}>\ntext\n") == ( - f"

para\n<{tag}>\ntext

\n" - ) - - -def test_ascii_mixed_case_tag_still_starts_html_block() -> None: - md = MarkdownIt("commonmark") - assert md.render("para\n\n") == ( - "

para

\n\n" - ) diff --git a/tests/test_port/fixtures/commonmark_extras.md b/tests/test_port/fixtures/commonmark_extras.md index 2de75e5d..cbf17b95 100644 --- a/tests/test_port/fixtures/commonmark_extras.md +++ b/tests/test_port/fixtures/commonmark_extras.md @@ -765,3 +765,12 @@ Inline HTML in image description .

a<b>c

. + +HTML block type 4 (declaration) starts with ` +. +

foo

+ +. diff --git a/tests/test_port/fixtures/issue-fixes.md b/tests/test_port/fixtures/issue-fixes.md index b630fcee..e6f7c4e9 100644 --- a/tests/test_port/fixtures/issue-fixes.md +++ b/tests/test_port/fixtures/issue-fixes.md @@ -54,3 +54,102 @@ Fix parsing of incorrect numeric character references

&#X22y; &#35y;

. + +#437 a lowercase declaration interrupts a paragraph +. +para + +. +

para

+ +. + +#437 Unicode lookalikes that case-fold to ASCII (U+017F, U+0130, U+0131) do not start an HTML block +. +para +<ſcript> +text + +para +<ſtyle> +text + +para + +text + +para + +text +. +

para +<ſcript> +text

+

para +<ſtyle> +text

+

para +<dİv> +text

+

para +<dıv> +text

+. + +#437 a Unicode lookalike does not close a type 1 HTML block +. + +after +. +

para

+ +

after

+. + +#437 a no-break space (U+00A0) after a type 6 tag name still starts an HTML block +. +para + +text +. +

para

+ +text +. + +#437 a no-break space (U+00A0) after a type 1 tag name still starts an HTML block +. +para + + +*a* + +. +

para

+ + +*a* + +. From 8e69a5e82a5339ccd04f861fee40485347814409 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Mon, 9 Nov 2026 21:30:18 +0100 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=A7=AA=20TEST:=20keep=20the=20upperca?= =?UTF-8?q?se=20declaration=20control=20from=20the=20removed=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The removed tests/test_html_block_ascii.py also checked that an uppercase interrupts a paragraph. Add it to the lowercase-declaration fixture, so every case from that file is now in the port fixtures. --- tests/test_port/fixtures/issue-fixes.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/test_port/fixtures/issue-fixes.md b/tests/test_port/fixtures/issue-fixes.md index e6f7c4e9..5d68eb4f 100644 --- a/tests/test_port/fixtures/issue-fixes.md +++ b/tests/test_port/fixtures/issue-fixes.md @@ -55,13 +55,18 @@ Fix parsing of incorrect numeric character references &#35y;

. -#437 a lowercase declaration interrupts a paragraph +#437 a lowercase declaration interrupts a paragraph, as an uppercase one does . para + +para + .

para

+

para

+ . #437 Unicode lookalikes that case-fold to ASCII (U+017F, U+0130, U+0131) do not start an HTML block