fix: keep blank lines inside fenced code blocks - #2446
Open
kevin (kevin9327) wants to merge 1 commit into
Open
Conversation
The output normalization collapsed every run of blank lines, including the ones inside a code fence, so a notebook cell or a <pre> block that separated two definitions with two blank lines came back with one. The collapsing now steps over closed fenced blocks.
Razin M (R-zin)
approved these changes
Sep 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Converting a notebook whose code cell holds
produces the same code with the two blank lines between the definitions reduced to one:
Two blank lines between top-level definitions is what PEP 8 asks for, so this is the common case, not an odd one. The same happens to any
<pre>block routed through the HTML converter, and so to DOCX, PPTX, EPUB and RSS content that carries one.MarkItDown._convertnormalizes a converter's result withre.sub(r"\n{3,}", "\n\n", ...). That is right for the ragged whitespace converters leave between blocks, but a fenced code block is the document's own content: its blank lines are data, and rewriting them means the code in the Markdown is not the code in the source.The collapsing now steps over fenced code blocks. Only a closed fence is treated as a block, so an unterminated one is still normalized, and everything outside a fence collapses exactly as before.
Reproduction
New test file, on unmodified
main(packages/markitdown):with the failure being the rewritten code:
The three tests that pass before and after are the pins: two paragraphs still separate with exactly one blank line, the blank lines around a code block still collapse, and an unterminated fence is still normalized.
With the fix:
Verification
Whole suite, before and after — the five new tests are the whole difference:
(The deselected tests fail on
mainon this Windows machine for reasons unrelated to the change: console encoding, file-URI paths, and a missingffmpeg.)blackreports both touched files unchanged.