Skip to content

feat(pampa): block-level attrs on list items (<li class>) (bd-aeyss6p5)#314

Merged
cscheid merged 1 commit into
mainfrom
feature/bd-aeyss6p5-list-item-block-attrs
Jun 18, 2026
Merged

feat(pampa): block-level attrs on list items (<li class>) (bd-aeyss6p5)#314
cscheid merged 1 commit into
mainfrom
feature/bd-aeyss6p5-list-item-block-attrs

Conversation

@cscheid

@cscheid cscheid commented Jun 18, 2026

Copy link
Copy Markdown
Member

Summary

Extends the Para block-attr capability (bd-itqcfxc3, #310) to list items: - item {.foo} now renders <li class="foo"> across all three renderers — q2 render (HTML), q2 preview (JSON → React, including the revealjs incremental path), and AST→JSON→AST round-trips.

A Pandoc list item is Vec<Block> with no per-item Attr field, so an authored item attr lands as a trailing Inline::Attr in the item's last block. It is hoisted onto the <li> at write time and folded back at read time; the AST shape is unchanged. The JSON wire form mirrors the table rowsS precedent — a parallel sibling key on the list node that Pandoc ignores.

Changes

  • block_attr.rssplit_list_item_attr collects the trailing attr from an item's last Para/Plain and returns a stripped clone of that block. The clone is what keeps the class off an inner <p> (the precedence trap).
  • html.rswrite_list_item / composed_list_item_attr hoist onto <li>, composing with the incremental fragment class.
  • json.rs writer — parallel itemAttr sibling key, alphabetical key order (c, itemAttr, l?, s, t). A fast path keeps ordinary lists byte-for-byte unchanged.
  • json.rs readerfold_item_attrs restores the trailing Inline::Attr.
  • preview-renderer — shared liItemAttrProps helper applied in both the incremental component path (BulletList/OrderedList) and the editable registry path (dispatch.tsx).

Design decisions (v1)

  • itemAttr dropped on in-preview edits — the registry renderers' setLocalAst rebuilds the list node without itemAttr. Documented inline; follow-up if preservation is wanted.
  • Hoist only from a Para/Plain last block — exactly where the parser places authored attrs.

Testing

  • 21 new tests: 7 helper + 6 html + 4 json + 4 React vitest.
  • End-to-end through the binary: -t html<li id="one" class="alpha" data-key="val">; -t json emits itemAttr and pandoc -f json degrades gracefully (plain <li>, no error); json→html and json→qmd both round-trip the item attrs.
  • Full cargo xtask verify green (14/14) — incl. WASM rebuild + hub-client + preview-renderer suites.

Not done

No live browser q2 preview revealjs session against WASM-served output — the chain is covered piecewise (Rust JSON-contract tests + React vitest through the real component tree).

Plan: claude-notes/plans/2026-06-18-list-item-block-attrs.md. Strand: bd-aeyss6p5 (discovered-from bd-itqcfxc3, related bd-38ioql41).

🤖 Generated with Claude Code

Extend the Para block-attr capability (bd-itqcfxc3, PR #310) to list items:
`- item {.foo}` now renders `<li class="foo">` across all three renderers
(q2 render HTML, q2 preview JSON->React incl. revealjs incremental, and
JSON round-trips).

A Pandoc list item is `Vec<Block>` with no per-item Attr field, so an
authored item attr lands as a trailing `Inline::Attr` in the item's last
block. It is hoisted onto the `<li>` at write time and folded back at read
time; the AST shape is unchanged.

- block_attr.rs: `split_list_item_attr` collects the trailing attr from an
  item's last Para/Plain and returns a stripped clone of that block. The
  stripped clone is what keeps the class off an inner `<p>` (precedence trap).
- html.rs: `write_list_item` / `composed_list_item_attr` hoist onto `<li>`,
  composing with the incremental `fragment` class.
- json.rs writer: parallel `itemAttr` sibling key (the table `rowsS`
  precedent), alphabetical key order (c, itemAttr, l?, s, t). A fast path
  keeps ordinary lists byte-for-byte unchanged; Pandoc ignores `itemAttr`.
- json.rs reader: `fold_item_attrs` restores the trailing `Inline::Attr`.
- preview-renderer: shared `liItemAttrProps` helper applied in both the
  incremental component path (BulletList/OrderedList) and the editable
  registry path (dispatch). `itemAttr` is dropped on in-preview edits (v1).

Tests: 7 helper + 6 html + 4 json + 4 React vitest. End-to-end verified
through the binary (html; json + pandoc graceful degrade; json->html and
json->qmd round-trips). Full `cargo xtask verify` green (14/14).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@cscheid cscheid merged commit 79cb5e4 into main Jun 18, 2026
5 checks passed
@cscheid cscheid deleted the feature/bd-aeyss6p5-list-item-block-attrs branch June 18, 2026 18:58
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