Fix fenced code blocks not rendering inside blockquotes#1585
Fix fenced code blocks not rendering inside blockquotes#1585dahlia wants to merge 1 commit intoPython-Markdown:masterfrom
Conversation
The fenced code preprocessor only runs once before block parsing, so fenced code blocks inside blockquotes were not detected after the blockquote processor stripped the '>' prefixes. Add a new FencedCodeBlockProcessor (BlockProcessor) that handles fenced code blocks in nested contexts like blockquotes. Extract common functionality into FencedCodeMixin to avoid code duplication between the preprocessor and block processor.
4339b68 to
a13c849
Compare
The fenced_code extension doesn't properly render code blocks inside blockquotes. This uses a forked version with a fix until the upstream PR is merged and released: Python-Markdown/markdown#1585
|
I don't have time to review this right now, but have you reviewed #53? There are references to various tests and goals of a working solution. Also, I am curious why you left the current solution in place. Why not just provide a single working solution? Finally, what does this provide that the superfences extension doesn't or can't? See our documentation here. |
|
Thank you for the feedback and for pointing me to #53. I should have reviewed it before submitting this PR. After reading through the issue history, I now understand that:
My implementation only addresses blockquotes (not lists), and keeping both the preprocessor and block processor adds complexity without providing a complete solution. Given that SuperFences already solves this comprehensively and is the officially recommended approach, I'll close this PR. I apologize for not doing proper research beforehand. |
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: