diff --git a/docs/changelog.md b/docs/changelog.md index f20687c0a..a6939f91f 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -16,6 +16,7 @@ See the [Contributing Guide](contributing.md) for details. * Update serializer to be non-recursive (#1644). * Improve ancestor handling in the inline `Treeprocessor` (#1646). +* Fix issue where inline HTML attributes were rejected if they had `<` or `>` in the attribute (#1647). ## [3.11.0] - 2026-09-25 diff --git a/markdown/inlinepatterns.py b/markdown/inlinepatterns.py index 1908625a5..d3c3bef26 100644 --- a/markdown/inlinepatterns.py +++ b/markdown/inlinepatterns.py @@ -159,10 +159,14 @@ def build_inlinepatterns(md: Markdown, **kwargs: Any) -> util.Registry[InlinePro """ Match an automatic email link (``). """ HTML_RE = ( - r'(<(\/?[a-zA-Z][^<>@ ]*( [^<>]*)?|' # Tag - r'!--(?:(?!).)*--|' # Comment - r'[?](?:(?!<[?]|[?]>).)*[?]|' # Processing instruction - r'!\[CDATA\[(?:(?!).)*\]\]' # `CDATA` + # Tag + r'''(<(\/?+[a-zA-Z][^\s"'<>@]*+(?:\s+[^\s"'=<>]++(?:\s*+=\s*+(?:"[^"]*+"|'[^']*+'|[^\s"'=<>]++))?+)*+\s*+/?|''' + # Comment + r'!--(?:(?!).)*--|' + # Processing instruction + r'[?](?:(?!<[?]|[?]>).)*[?]|' + # `CDATA` + r'!\[CDATA\[(?:(?!).)*\]\]' ')>)' ) """ Match an HTML tag (`<...>`). """ diff --git a/tests/test_syntax/inline/test_raw_html.py b/tests/test_syntax/inline/test_raw_html.py index 79d49a507..83bb9f479 100644 --- a/tests/test_syntax/inline/test_raw_html.py +++ b/tests/test_syntax/inline/test_raw_html.py @@ -40,3 +40,10 @@ def test_markdown_nested_in_inline_comment(self): 'Example: ', '

Example:

' ) + + def test_angle_brackets_in_attributes(self): + # https://github.com/Python-Markdown/markdown/issues/1647 + self.assertMarkdownRenders( + 'Anything', + '

Anything

' + )