feat(page-number): chapter-prefixed section page numbering (SD-3029)#3620
Merged
harbournick merged 20 commits intoJun 4, 2026
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b4c1326be1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
789c091 to
25957c8
Compare
b3bce5f to
ec1fc52
Compare
Extend section page numbering with `chapterStyle` (w:chapStyle) and `chapterSeparator` (w:chapSep) support across the stack: - document-api: add fields to the setPageNumbering contract (anyOf now accepts chapterStyle/chapterSeparator), schemas, types, and validation - layout contracts: extend SectionNumbering with chapter fields and reuse PageNumberFormat/PageNumberChapterSeparator types - layout-adapter: extract w:chapStyle/w:chapSep from pgNumType, validate positive integers and known separators, and compare them in section signatures - sections-xml helpers: read/write chapter attributes on w:pgNumType - regenerate Document API reference docs
Resolve and paint chapter number prefixes (e.g. "1-1", "3:V") for sections that enable chapter numbering, deriving the chapter from the nearest numbered Heading N marker. - contracts: add formatSectionPageNumberText helper, chapter/format fields on Page and HeaderFooterPage, and headingLevel/listLevelOrdinal paragraph attrs - pageNumbering: add buildChapterContextByPage to track the active chapter per physical page, normalizeChapterMarkerText to accept only clean single-token markers, and thread chapter context through computeDisplayPageNumber - layout-bridge: build/cache chapter context across PAGE-token convergence, apply it to body pages, and disable header/footer digit bucketing when chapter prefixes can vary the rendered width - resolvePageTokens / text-run / renderer: preserve the chapter prefix when a run-local PAGE format switch applies - layout-adapter: resolve built-in heading level from style metadata (incl. localized names) and expose the structured list ordinal
25957c8 to
e2a88d6
Compare
ec1fc52 to
c95dfa0
Compare
1de645b
into
luccas/sd-3349-bug-numbering-issues
40 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds end-to-end support for Word's chapter-prefixed page numbering (
w:pgNumType/@w:chapStyle+@w:chapSep). When a section enables it, PAGE fields render as<chapter>-<page>(e.g.1-1,12-3), where the chapter number is sourced from the nearest preceding numbered Heading marker and the separator is one ofhyphen | period | colon | emDash | enDash.The feature threads through the entire pipeline — DOCX import/export, contracts, the v1 layout-adapter, the layout engine, the layout bridge, the DOM painter, the live editor extensions, and the Document API.
Changes by layer
Contracts (
layout-engine/contracts)PageNumberChapterSeparatortype and two formatting helpers:formatChapterPageNumberText(joins a chapter prefix + separator to a page component) andformatSectionPageNumberText(formats the page number then applies the chapter prefix). Hyphen maps to a non-breaking hyphen (\u2011) to match Word.SectionNumberingextended withchapterStyle/chapterSeparator;formatnow reusesPageNumberFormat.SectionBreakBlock.numberingreusesSectionNumbering.Page,HeaderFooterPage,ResolvedPage, andResolvedHeaderFooterPagecarrypageNumberFormat,pageNumberChapterText, andpageNumberChapterSeparator.ParagraphAttrsgainsheadingLevelandlistLevelOrdinal, used to identify chapter markers.Import / Export (
super-editor)sections-xmlread/write helpers parse and round-tripw:chapStyle/w:chapSep. Section signature equality now compares the new chapter fields so changes invalidate correctly.headingLevelfrom directoutlineLvl, built-in "Heading N" style names, or the style'soutlineLvl, and captureslistLevelOrdinalfrom structured numbering paths.Layout engine (
pageNumbering.ts)buildChapterContextByPagewalks layout pages in order, tracks the active chapter marker per heading level (clearing deeper levels when a higher one changes), and maps each page to its resolved chapter prefix. Marker text is normalized and validated; empty Heading 1 markers fall back to a structured ordinal, but nested prefixes are never synthesized.computeDisplayPageNumberandresolvePageNumberTokensproduce chapter-prefixed display text. Token resolution now returnsundefinedwhen nothing changed and preserves token metadata across convergence passes (cloneBlockWithResolvedTokensno longer strips tokens).Layout bridge (
incrementalLayout.ts,layoutHeaderFooter.ts,resolveHeaderFooterTokens.ts)1-1and12-1differ in width within one digit bucket), forcing per-page measurement.Painters (
painters/dom) —renderer.ts,text-run.ts, and shape text resolution render chapter-prefixed PAGE fields; the page-context signature includes the new fields.Live editor (
super-editorextensions) — the page-number node, header/footer editor managers, per-RId layout, story editor factory, presentation editor, and session manager all plumbcurrentPageChapterNumberText/currentPageChapterSeparatorso the editable header/footer surfaces match the painted layout. (#getPageNumberFormatForDomNodealso guards against a missing view.)Document API —
sections.setPageNumberingacceptschapterStyleandchapterSeparator. The input requirement relaxed fromoneOftoanyOf(any one ofstart/format/chapterStyle/chapterSeparator); schemas, types, validation, and generated reference docs updated.Tests
New/expanded coverage across the stack:
pageNumbering,resolvePageTokens,resolvePageNumberTokens, header/footer prelayout, bucketing, page-token convergence, per-RId layout, registry, paragraph heading-level extraction, section extraction/breaks,sections-xmlround-trip, the page-number extension, and the Document APIsectionssuite.Notes