Skip to content

fix: resolve OOXML lvlText templates in numbered list markers#271

Open
sted wants to merge 1 commit intoeigenpal:mainfrom
sted:fix/numbered-list-markers
Open

fix: resolve OOXML lvlText templates in numbered list markers#271
sted wants to merge 1 commit intoeigenpal:mainfrom
sted:fix/numbered-list-markers

Conversation

@sted
Copy link
Copy Markdown
Contributor

@sted sted commented Apr 16, 2026

Summary

  • fix: resolve OOXML lvlText templates in numbered list markers
    Numbered list markers were rendering as the raw lvlText template (e.g.
    "%1." or "%1.%2.") instead of resolved values like "1.", "A.", "II.1.".
    The parser stored level.lvlText verbatim on listRendering.marker, and
    toFlowBlocks only ran counter resolution when listMarker was unset, so
    any DOCX with parsed numbering definitions leaked %N tokens through to
    the painter — including inside table cells and text boxes, where a
    second code path bypassed marker resolution entirely.
    Changes:
  • paragraphParser collects per-level numFmts (0..ilvl) so multi-level
    templates like "%1.%2." can format each %N with its own format
    (e.g. upperRoman parent + decimal child)
  • ParagraphAttrs.listLevelNumFmts plumbs this through ProseMirror
  • toFlowBlocks centralises marker resolution in convertParagraphAttrs
    via a shared listCounters map, covering body, table, and text-box
    paragraphs in one place
  • resolveListTemplate handles decimal, upperLetter, lowerLetter,
    upperRoman, lowerRoman, decimalZero, none (ECMA-376 §17.9.11)
  • Unit tests cover each numFmt, multi-level templates, mixed formats,
    and the parser's per-level numFmt collection

Test plan

  • bun run typecheck passes
  • bun test passes
  • bun run build succeeds

Numbered list markers were rendering as the raw lvlText template (e.g.
"%1." or "%1.%2.") instead of resolved values like "1.", "A.", "II.1.".

The parser stored level.lvlText verbatim on listRendering.marker, and
toFlowBlocks only ran counter resolution when listMarker was unset, so
any DOCX with parsed numbering definitions leaked %N tokens through to
the painter — including inside table cells and text boxes, where a
second code path bypassed marker resolution entirely.

Changes:
- paragraphParser collects per-level numFmts (0..ilvl) so multi-level
  templates like "%1.%2." can format each %N with its own format
  (e.g. upperRoman parent + decimal child)
- ParagraphAttrs.listLevelNumFmts plumbs this through ProseMirror
- toFlowBlocks centralises marker resolution in convertParagraphAttrs
  via a shared listCounters map, covering body, table, and text-box
  paragraphs in one place
- resolveListTemplate handles decimal, upperLetter, lowerLetter,
  upperRoman, lowerRoman, decimalZero, none (ECMA-376 §17.9.11)
- Unit tests cover each numFmt, multi-level templates, mixed formats,
  and the parser's per-level numFmt collection
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 16, 2026

@sted is attempting to deploy a commit to the EigenPal Team on Vercel.

A member of the Team first needs to authorize it.

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