Skip to content

fix(block): HTML block start outside a list item closes the list - #442

Open
inchang-ing wants to merge 2 commits into
executablebooks:masterfrom
inchang-ing:fix/html-block-closes-list
Open

inchang-ing wants to merge 2 commits into
executablebooks:masterfrom
inchang-ing:fix/html-block-closes-list

Conversation

@inchang-ing

Copy link
Copy Markdown

Fixes #434

Problem

A line that starts an HTML block (any type) on a line under-indented for the list item's content was consumed as a lazy continuation of the item's paragraph:

## Opts

- a
<br>
## Next

rendered as <li>a\n<br></li> in markdown-it-py (and in the JS original), while cmark and commonmark.js close the list and open the HTML block at the outer level — because such a line can neither be item content nor a lazy continuation of it (it starts a new block). Flipping the type-7 "can terminate paragraph" flag is not a fix: it would let <br> interrupt a top-level paragraph, where all implementations agree it must not.

Change

  • html_block.py: new html_block_starts(state, line) helper — detects whether a line begins an HTML block of any type (same sequence table as the rule).
  • paragraph.py: while scanning continuation lines, end the paragraph when the next line starts an HTML block and is under-indented for the current container (sCount < blkIndent). The list rule then sees the line, finds no item marker, and closes the list, so the line is offered to the outer containers — reproducing cmark's container walk. At the same container level a type-7 sequence still does not interrupt the paragraph (the terminator rules are unchanged), and plain text at outer indentation remains a lazy continuation.

Verification

  • The issue's minimal input now renders exactly the cmark output: <h2>Opts</h2><ul><li>a</li></ul><br>\n## Next (the type-7 block swallows ## Next up to a blank line, as cmark does).
  • Four boundary cases are pinned in tests/test_html_block_list.py: HTML block at the item's content indent stays a lazy continuation; a top-level paragraph still continues through <br>; plain text at outer indentation is still a lazy continuation; a type-6 block (<div>) still closes the list as before.
  • Full suite: failure list is byte-identical to the pre-change baseline (74 pre-existing environment failures, git stash diffed — zero regressions; 958+ passed).
  • ruff check and ruff format clean on touched files.

Note

The JS markdown-it behaves the same way as this library currently does, so this change intentionally diverges from upstream JS toward the cmark/commonmark.js behavior documented in the issue; happy to align on whatever the maintainers decide.

Disclosure

This PR was prepared with AI assistance (ZCode/GLM, orchestrated via WorkBuddy).

inchang-ing and others added 2 commits September 28, 2026 21:44
A line that starts an HTML block on an under-indented line was consumed
as a lazy continuation of the item's paragraph, because the type-7
sequence is flagged as unable to terminate a paragraph. cmark and
commonmark.js instead end the list: the line cannot be item content,
and a block start is not a lazy continuation.

End the paragraph when the next line starts an HTML block while being
under-indented for the current container, so the list closes and the
line is offered to the outer containers. At the same container level a
type-7 sequence still cannot interrupt the paragraph, and plain text
remains a lazy continuation, so the behaviors all implementations agree
on are unchanged.

Fixes executablebooks#434

This branch has not been deployed

No deployments
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.

HTML block (type 7) glued to a list item is treated as lazy continuation; cmark and commonmark.js close the list

1 participant