From 2cbb194dc0d28df4c2790295adb19a2b6d1543f0 Mon Sep 17 00:00:00 2001 From: awais-ur-rehman Date: Fri, 30 Oct 2026 21:36:43 +0500 Subject: [PATCH] fix(parser): restore multiline code spans --- README.md | 3 +++ lib/markdown2.py | 7 +++++-- test/test_markdown2.py | 13 +++++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0051a940..4275bcbb 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,9 @@ The `tables` extra supports code spans delimited by single or multiple backticks including an operator cell such as ```` ``|`` ````. A pipe immediately after the closing delimiter separates the next cell. +Inline code spans can wrap onto the next line in hard-wrapped text. The +line ending remains inside the generated `` element. + There are a number of currently implemented extras for tables, footnotes, syntax coloring of `
`-blocks, auto-linking patterns, table of contents,
 Smarty Pants (for fancy quotes, dashes, etc.) and more. See the [Extras
diff --git a/lib/markdown2.py b/lib/markdown2.py
index 3632a54e..2c96df60 100755
--- a/lib/markdown2.py
+++ b/lib/markdown2.py
@@ -1468,7 +1468,7 @@ def _is_comment(token):
         code_hashes = {}
         lt_hash = _hash_text('<')
         self._code_table['<'] = lt_hash
-        text = self._code_span_re.sub(
+        text = self._safe_mode_code_span_re.sub(
             lambda m: self._hash_span(m.group(0).replace('<', lt_hash), code_hashes),
             text
         )
@@ -2119,7 +2119,10 @@ def _do_code_blocks(self, text: str) -> str:
             (? str:
         c = match.group(2).strip(" \t")
diff --git a/test/test_markdown2.py b/test/test_markdown2.py
index f4d105ac..7cb2d6ca 100755
--- a/test/test_markdown2.py
+++ b/test/test_markdown2.py
@@ -249,6 +249,19 @@ def test_footnote_numbers_reset_between_conversions(self):
         self.assertIn('1', html)
         self.assertIn('
  • ', html) + def test_multiline_code_spans(self): + for safe_mode in (None, "escape", "replace"): + with self.subTest(safe_mode=safe_mode): + self.assertEqual( + markdown2.markdown("Call the `foo\nbar()` function.", + safe_mode=safe_mode), + "

    Call the foo\nbar() function.

    \n") + + def test_multiline_code_span_does_not_hide_link_definition_html(self): + source = '`\n\n[x]: `' + self.assertEqual(markdown2.markdown(source, safe_mode="replace"), + "

    `\n[HTML_REMOVED]

    \n") + def test_many_distinct_code_spans(self): source = '\n\n'.join('`value_%s`' % i for i in range(1000)) expected = '\n\n'.join('

    value_%s

    ' % i for i in range(1000)) + '\n'