Skip to content

fix(convert): render a block inside a list item as a block - #212

Merged
willkg merged 2 commits into
mainfrom
fix/list-item-blocks
Sep 28, 2026
Merged

willkg merged 2 commits into
mainfrom
fix/list-item-blocks

Conversation

@willkg

@willkg willkg commented Sep 28, 2026

Copy link
Copy Markdown
Member

Fixes #211.

read/export sent every <li> child other than a <p> or a nested list through renderInline, so a code macro in a list item came out with its opening fence on the item's text line and its body unindented. The Confluence editor writes exactly that shape (<li>text<ac:structured-macro ac:name="code">…</li>), and SREIN Triage and Work Process has two of them. This is older than the line-break/paragraph work: renderListItem was unchanged from v0.1.0 until this PR.

What changes

  • A code block, <pre>, table, quote, callout or heading inside a list item now renders as a block indented under the item. Nested lists and blocks keep their document order.
  • A fence needs no blank line next to text, another fence or a nested list, so an item with text and a code block stays a tight list and publishes back to the storage it came from. Every other block gets a blank line, which it needs: a quote would swallow the text after it, a raw HTML table would swallow a fence, and text after a nested list would continue that list's last item.
  • Loose inline text in an item now renders as one run through renderInlineChildren. Text after a <br /> no longer gains a space on every round trip, and a mark split around a link is repaired the way it already is in a <p>.
  • <hr> is deliberately not handled as a block. - --- is a thematic break, not a list item, and the editor has no way to put a divider in a list.

Testing

  • New testdata/storage2md/list-blocks case covering the SREIN shape, the editor's <p> form, text after a block, an item that is only a code block, nested lists before and after blocks, a raw table followed by a fence, callouts, quotes, tables, and an inline status macro that must stay inline. Being a storage2md case, it also runs through TestRoundTripMarkdownIsAFixedPoint and the output-parses-as-Markdown check.
  • No other golden changed.
  • Ran against the live page: exporting it now differs from v0.2.0 only at the two code blocks, and check --show-html on the new export reproduces the page's original <li>text<ac:structured-macro …> storage.
  • make check passes.

Review findings left out (older, not caused by this change)

  • Text after a block that starts with Markdown block syntax (- , # ) is read back as that block. This is the read: paragraph text that looks like a Markdown block becomes structure on publish #203 class, now also reachable inside a list item.
  • A code macro nested inside a <p> still goes through the inline path. Confluence doesn't write that shape.
  • A block that needs a blank line makes the whole list loose, so sibling items publish with <p> around their text. This is CommonMark's rule, and the Markdown is still a fixed point.
  • Consecutive <p>s in one item are still joined with a space.

read/export sent every <li> child other than a <p> or a nested list
through renderInline. A code macro there rendered its fence onto the
item's text line, where it is not a fence, and its unindented body
ended the list. The editor writes exactly that shape for a code block
added to a list item. A table, a quote, a callout or a <pre> in a list
item was flattened into the item's text the same way.

A block now renders indented under the item, in document order. A
fence needs no blank line on either side, so an item with text and a
code block stays tight and publishes back to the storage it came from.
Every other block is set off by a blank line, which it needs.

Fixes #211.
A fence was tight beside any block, but a raw HTML table runs until a
blank line and swallowed a fence right after it. A fence is now tight
only beside text, another fence or a nested list.

Nested lists were still collected and written after everything else,
so one before a code block moved below it. They now render in document
order like every other child, and text after one is set off by a blank
line, which it needs or it continues the list's last item.

An <hr> is no longer a block: "- ---" is a thematic break rather than
an item, and the editor offers no divider in a list.

Loose inline children render as one run through renderInlineChildren,
so text after a <br /> no longer gains a space on every round trip, and
a mark split around a link is repaired as it is in a <p>. Every segment,
the first included, is indented the same way, and a fence is decided by
the node rather than by the rendered string.
@willkg
willkg merged commit b858c09 into main Sep 28, 2026
1 check passed
@willkg
willkg deleted the fix/list-item-blocks branch September 28, 2026 12:15
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.

read/export: a code block inside a list item is glued onto the item's text

1 participant