From 1a6408e0b170d3ec226f898c7070e5c9881c76ca Mon Sep 17 00:00:00 2001 From: Enes Uygur Date: Fri, 30 Oct 2026 14:19:43 +0300 Subject: [PATCH 1/2] Don't insert hard breaks inside multi-line inline HTML tags --- CHANGES.md | 1 + lib/markdown2.py | 32 ++++++++++++++++--- test/tm-cases/break_on_newline_html_tags.html | 7 ++++ test/tm-cases/break_on_newline_html_tags.opts | 1 + test/tm-cases/break_on_newline_html_tags.text | 7 ++++ test/tm-cases/hard_break_html_tags.html | 3 ++ test/tm-cases/hard_break_html_tags.text | 3 ++ 7 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 test/tm-cases/break_on_newline_html_tags.html create mode 100644 test/tm-cases/break_on_newline_html_tags.opts create mode 100644 test/tm-cases/break_on_newline_html_tags.text create mode 100644 test/tm-cases/hard_break_html_tags.html create mode 100644 test/tm-cases/hard_break_html_tags.text diff --git a/CHANGES.md b/CHANGES.md index cee783ed..ad177459 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -26,6 +26,7 @@ - [pull #737] Fix XSS from code spans that the span gamut doesn't treat as code spans in safe mode (#726) - [pull #743] Add a `strip-syntax` option to the `header-ids` extra that leaves link URLs, image paths, inline HTML tags and emphasis markers out of header ids (#192) - [pull #747] Fix `link-patterns` extra linking text inside Markdown links and images whose label wraps onto another line +- Fix hard breaks and the `breaks` extra inserting `
` inside inline HTML tags and link titles that span several lines ## python-markdown2 2.5.5 diff --git a/lib/markdown2.py b/lib/markdown2.py index 3632a54e..d068872f 100755 --- a/lib/markdown2.py +++ b/lib/markdown2.py @@ -1357,7 +1357,32 @@ def _run_span_gamut(self, text: str) -> str: text = self._do_italics_and_bold(text) # Do hard breaks - text = re.sub(r" {2,}\n(?!\<(?:\/?(ul|ol|li))\>)", " str: + ''' + Replace line endings matching `pattern` with `
` tags. Line endings + inside a multi-line HTML tag (eg: an `` with its attributes on + separate lines) are left alone, as a `
` there would break the tag. + ''' + tags = {} + + def hash_tag(match: re.Match[str]) -> str: + if '\n' not in match.group(0): + return match.group(0) + key = _hash_text(match.group(0)) + tags[key] = match.group(0) + return key + + if '<' in text and '\n' in text: # guard for perf + text = self._sorta_html_tokenize_re.sub(hash_tag, text) + + text = re.sub(pattern + r"\n(?!\<(?:\/?(ul|ol|li))\>)", ")", break_tag, text) - - return text + return self.md._do_hard_breaks(text, pattern) class CodeFriendly(GFMItalicAndBoldProcessor): diff --git a/test/tm-cases/break_on_newline_html_tags.html b/test/tm-cases/break_on_newline_html_tags.html new file mode 100644 index 00000000..16505deb --- /dev/null +++ b/test/tm-cases/break_on_newline_html_tags.html @@ -0,0 +1,7 @@ +

An image A cat sits on this line,
+and this line still gets a break.

+ +

A raw link and a Markdown link keep their attributes.

diff --git a/test/tm-cases/break_on_newline_html_tags.opts b/test/tm-cases/break_on_newline_html_tags.opts new file mode 100644 index 00000000..c74bb28a --- /dev/null +++ b/test/tm-cases/break_on_newline_html_tags.opts @@ -0,0 +1 @@ +{"extras": ["break-on-newline"]} diff --git a/test/tm-cases/break_on_newline_html_tags.text b/test/tm-cases/break_on_newline_html_tags.text new file mode 100644 index 00000000..30793c0b --- /dev/null +++ b/test/tm-cases/break_on_newline_html_tags.text @@ -0,0 +1,7 @@ +An image A cat sits on this line, +and this line still gets a break. + +A raw link and a [Markdown link](https://example.com/ "A title +that wraps") keep their attributes. diff --git a/test/tm-cases/hard_break_html_tags.html b/test/tm-cases/hard_break_html_tags.html new file mode 100644 index 00000000..a9639ae3 --- /dev/null +++ b/test/tm-cases/hard_break_html_tags.html @@ -0,0 +1,3 @@ +

An image A cat with trailing spaces inside the tag,
+and a hard break after it.

diff --git a/test/tm-cases/hard_break_html_tags.text b/test/tm-cases/hard_break_html_tags.text new file mode 100644 index 00000000..827905d8 --- /dev/null +++ b/test/tm-cases/hard_break_html_tags.text @@ -0,0 +1,3 @@ +An image A cat with trailing spaces inside the tag, +and a hard break after it. From 156ef81d985d8ae0a1bb8e2f0edc3c255408f790 Mon Sep 17 00:00:00 2001 From: Enes Uygur Date: Fri, 30 Oct 2026 14:20:10 +0300 Subject: [PATCH 2/2] Add the pull request number to the change note --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index ad177459..d1382edd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -26,7 +26,7 @@ - [pull #737] Fix XSS from code spans that the span gamut doesn't treat as code spans in safe mode (#726) - [pull #743] Add a `strip-syntax` option to the `header-ids` extra that leaves link URLs, image paths, inline HTML tags and emphasis markers out of header ids (#192) - [pull #747] Fix `link-patterns` extra linking text inside Markdown links and images whose label wraps onto another line -- Fix hard breaks and the `breaks` extra inserting `
` inside inline HTML tags and link titles that span several lines +- [pull #755] Fix hard breaks and the `breaks` extra inserting `
` inside inline HTML tags and link titles that span several lines ## python-markdown2 2.5.5