Fix fenced code blocks not rendering inside blockquotes #1585
+368
−82
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes an issue where fenced code blocks inside blockquotes were not rendered correctly. Previously, the following Markdown:
Would render the code as inline
<code>elements or plain text instead of a proper<pre><code>block.Problem
The
FencedBlockPreprocessorruns once at the beginning of the parsing pipeline, before any block-level processing occurs. At this point, blockquote lines still have their>prefixes, so the fenced code regex pattern (which expects the fence at the start of a line) doesn't match.When the
BlockQuoteProcessorlater strips the>prefixes and recursively parses the content viaparseChunk(), only block processors run—not preprocessors. Since fenced code detection was only implemented as a preprocessor, it was never invoked for blockquote content.Indented code blocks work correctly because they are handled by
CodeBlockProcessor, which is a block processor that runs during recursive parsing.Solution
Add a new
FencedCodeBlockProcessorclass that handles fenced code blocks as aBlockProcessor. This processor runs during recursive parsing, allowing it to detect fenced code blocks inside blockquotes and other nested contexts.To avoid code duplication between the existing
FencedBlockPreprocessorand the newFencedCodeBlockProcessor, common functionality has been extracted into aFencedCodeMixinclass:_check_for_deps()— Check for CodeHilite and AttrList extensions_handle_attrs()— Parse attributes from the fence line_generate_html()— Generate HTML output (with or without syntax highlighting)_escape()— Basic HTML escapingThe preprocessor is retained for top-level fenced code blocks, as it processes them efficiently in a single pass. The block processor complements it by handling nested contexts.
Testing
Added
TestFencedCodeInBlockquotetest class with 5 test cases: