Skip to content

Close open blocks of the last list item and footnote at end of input - #160

Merged
bobzhang merged 4 commits into
mainfrom
conformance/end-doc-close-nested-blocks
Oct 2, 2026
Merged

bobzhang merged 4 commits into
mainfrom
conformance/end-doc-close-nested-blocks

Conversation

@bobzhang

@bobzhang bobzhang commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Split out of #152.

Bug: at the end of the document, end_doc drops the empty line that ends an unclosed fenced code block (or HTML block), but only for blocks at the top level or in block quotes. In the last item of a list or in a footnote, the block kept that line.

Repro:

- ```
  a

rendered <pre><code>a\n\n</code></pre>. Expected <pre><code>a\n</code></pre>. Same in nested lists and footnotes.

Fix: end_doc also processes the blocks of the last list item and of footnotes before closing them.

Second commit, from the Codex review: a last line is now dropped only if its raw line is empty, which is the line after a final newline. Before, any last line whose content span was empty was dropped. That included a line that is blank only after removing container markers or indentation, which is real content: "- ```\n a\n ", "> ```\n> a\n>" and " ```\n a\n " (no final newline) now keep it as an empty code line, as commonmark.js does. The block quote and indented-fence cases were already wrong on main.

Third commit, from the second Codex round: the line is dropped only from blocks that are still open (no closing fence, HTML end condition pending). Before, a closed fence's genuinely empty last line could be dropped: "- ```\n a\n\n ```" and, already on main, "```\na\n\n```" (no final newline) lost the empty line before the closing fence.

Spec examples: none (the spec suite passes either way).

Tests: src/cmark_html/unclosed_fence_in_container_test.mbt. It also checks that the list stays tight covers blank last lines without a final newline, and covers closed fences at the end of input.

Depends on: nothing, independent of the other PRs.

At the end of the document, end_doc drops the empty line that ends an
unclosed fenced code or HTML block, but only for blocks at the top level
or in block quotes. In the last item of a list or in a footnote the
block kept it: "- ```\n  a\n" rendered as <pre><code>a\n\n</code></pre>.

end_doc now also processes the blocks of the last list item and of
footnotes.
At the end of input, end_doc dropped the last line of an unclosed fenced
code or HTML block whenever its content span was empty, to remove the
empty line that follows a final newline. A last line that is blank only
after removing container markers or indentation ("- ```\n  a\n  ",
"> ```\n> a\n>", " ```\n a\n ") was dropped too, although it is
content. Only drop the line if its raw line is empty.

Found by Codex review.
end_doc now also visits the blocks of the last list item and of
footnotes, which may be closed fenced code blocks. Their last line can
be an empty line before the closing fence ("- ```\n  a\n\n  ```" without
a final newline), which was dropped as if it were the empty line after
a final newline. The same happened at the top level on main
("```\na\n\n```"). Only drop it from unclosed fenced code and HTML
blocks.

Found by Codex review.
Review feedback from Codex: the end-of-input tests only covered fenced
code blocks.
@bobzhang

bobzhang commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

Automated review: Codex CLI (codex exec, model reasoning effort high, read-only sandbox) on git diff against the base branch. 3 rounds.

  • Round 1: P2. A last line that is blank only after removing list indentation ("- ```\n a\n " with no final newline) was dropped. Fixed in 9a62016: only a line whose raw line is empty (the line after a final newline) is dropped. This also fixes the block quote and indented-fence cases that were already wrong on main.
  • Round 2: P2. The empty last line of an already closed fence ("- ```\n a\n\n ```") was dropped. Fixed in 092ccdf: the line is dropped only from blocks that are still open. This also fixes "```\na\n\n```" at the top level, which was wrong on main.
  • Round 3: signed off, with a non-blocking suggestion to test HTML blocks too. Added in e604cfb (tests only).

I sign off on the full diff. No concrete correctness or regression issues found against CommonMark 0.31.2.

The open-block guards fix the round-2 regression, and the raw-line check preserves real blank content after stripping indentation or container markers. The recursive cleanup and list-tightness handling look sound.

Codex could not run moon test in its read-only sandbox. The tests were run separately on native, js and wasm-gc and pass.

@bobzhang
bobzhang merged commit 70e1921 into main Oct 2, 2026
8 checks passed
@bobzhang
bobzhang deleted the conformance/end-doc-close-nested-blocks branch October 2, 2026 01:43
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.

1 participant