Skip to content

Match the space after a block quote marker without backtracking - #317

Merged
frostming merged 1 commit into
frostming:masterfrom
RavSinghChandan:quote-prefix-backtracking
Nov 11, 2026
Merged

frostming merged 1 commit into
frostming:masterfrom
RavSinghChandan:quote-prefix-backtracking

Conversation

@RavSinghChandan

Copy link
Copy Markdown
Contributor

Part of #293 (the first case, nested block quotes).

Quote._prefix is " {,3}>[^\n\S]?", and the prefix of a line nested n quotes deep is that pattern n times. The space after a > can be matched either by its optional [^\n\S]? or by the {,3} of the next level, so when a line has fewer > than the depth, re.match() tries about 2 ** n ways before failing. "> " * 26 + "a" takes about 5 seconds to parse, and each level doubles it.

The space after > is now taken whenever there is one: (?:[^\n\S]|(?![^\n\S])) matches it if it is there and matches nothing only when it isn't. That is also what CommonMark says: a block quote marker is > together with a following space, if there is one. Depth 26 now takes 2 ms and depth 40 8 ms.

CodeBlock.match() built the prefix of an indented code block in a quote by removing the last ? of the prefix; it now replaces the quote's prefix with the same pattern with a required space.

This changes the result in one case: a list item inside a quote, followed by a line like > > b. Before, the space after the first > could go to the list item's indentation; now it belongs to the marker, so the line is not indented enough for the item. I compared 9 such documents with markdown-it-py: the new results match it in all 9, the old ones differed in 7. For instance, "> - a\n>\n> > b\n" now gives a quote after the list, not inside the item.

Added test_nested_quotes_scale_linearly, which compares depths 12 and 24 like the other scaling tests, and test_quote_marker_takes_the_following_space; both fail on master. pytest tests (including the spec tests), black, isort and flake8 pass, and mypy reports the same 5 errors as on master.

Used Claude (Opus) to help find and patch this; I reviewed and tested the change

@human-attestation

Copy link
Copy Markdown

🛡️ Human Attestation required. A human needs to confirm this PR once before it can merge.

Attest this PR — sign in with GitHub, pass the challenge, and confirm one of the statements.

@frostming
frostming merged commit 9b367d4 into frostming:master Nov 11, 2026
19 of 20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants