From 15ad23264a2f2182aaf4e96f2d0a028a4abaf16e Mon Sep 17 00:00:00 2001 From: Afonso Ribeiro Date: Fri, 16 Oct 2026 06:56:26 +0100 Subject: [PATCH 1/2] Avoid quadratic text rebuilding in fenced_code preprocessor --- docs/changelog.md | 2 ++ markdown/extensions/fenced_code.py | 10 +++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 5e6fc0117..09c125c25 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -18,6 +18,8 @@ See the [Contributing Guide](contributing.md) for details. * For backwards compatibility in some languages, revert the enforcement of CommonMark style punctuation rules (#1657). +* Fix quadratic processing time in the `fenced_code` extension for documents + with many fenced code blocks (#XXXX). ## [3.11.1] - 2026-10-13 diff --git a/markdown/extensions/fenced_code.py b/markdown/extensions/fenced_code.py index 603f0bc7b..00dacfee4 100644 --- a/markdown/extensions/fenced_code.py +++ b/markdown/extensions/fenced_code.py @@ -102,6 +102,9 @@ def run(self, lines: list[str]) -> list[str]: self.checked_for_deps = True text = "\n".join(lines) + # Collect the output in pieces, as rebuilding the full text after each block is quadratic. + pieces: list[str] = [] + last = 0 index = 0 while 1: m = self.FENCED_BLOCK_RE.search(text, index) @@ -163,12 +166,13 @@ def run(self, lines: list[str]) -> list[str]: code = f'{code}' placeholder = self.md.htmlStash.store(code) - text = f'{text[:m.start()]}\n{placeholder}\n{text[m.end():]}' + pieces.append(f'{text[last:m.start()]}\n{placeholder}\n') # Continue from after the replaced text in the next iteration. - index = m.start() + 1 + len(placeholder) + index = last = m.end() else: break - return text.split("\n") + pieces.append(text[last:]) + return "".join(pieces).split("\n") def handle_attrs(self, attrs: Iterable[tuple[str, str]]) -> tuple[str, list[str], dict[str, Any]]: """ Return tuple: `(id, [list, of, classes], {configs})` """ From 45ea0eb65f83b36d189256c6ded2b81e83879ce7 Mon Sep 17 00:00:00 2001 From: Afonso Ribeiro Date: Fri, 16 Oct 2026 06:56:31 +0100 Subject: [PATCH 2/2] Add PR number to changelog --- docs/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index 09c125c25..074121705 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -19,7 +19,7 @@ See the [Contributing Guide](contributing.md) for details. * For backwards compatibility in some languages, revert the enforcement of CommonMark style punctuation rules (#1657). * Fix quadratic processing time in the `fenced_code` extension for documents - with many fenced code blocks (#XXXX). + with many fenced code blocks (#1660). ## [3.11.1] - 2026-10-13