You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Insert a table of contents and each row comes out as title + tab character + PAGEREF, with no tab stop anywhere for that tab character to land on. The page number therefore sits one default tab (½ inch) after the title text instead of at the far edge of the text area, and there is no dot leader between them. It reads as one run-on line rather than a table of contents.
Three layers were checked, and the stop is in none of them:
The rows themselves — the inserted TOC paragraphs have no w:tabs in their pPr.
The styles they point at — the rows carry w:pStyleTOC1/TOC2/TOC3, but TOC1…TOC9are not defined in styles.xml. shared/common/data/blank.docx has 33 style definitions and none of them is a TOC*. What it does have is the latent declarations:
In Word those latent entries are the promise of a definition: inserting a TOC materialises TOC1…TOC9 from Word's built-in definitions — each with a right-aligned tab stop at the section's text width carrying the requested leader, and a per-level w:ind — and unhides them. SuperDoc writes the field and the rows but never creates the styles, so the w:pStyle reference resolves to nothing.
The document default — with no stop from either layer the tab falls back to w:defaultTabStop, which the shipped template sets to 720. Hence the half-inch jump, unrelated to the page width, and no leader.
The configure surface looks like it should cover this and does not: TocConfigurePatch offers tabLeader and rightAlignPageNumbers (packages/document-api/src/toc/toc.types.ts) —
/** Tab leader style between entry text and page number. */
tabLeader?: 'none'|'dot'|'hyphen'|'underscore'|'middleDot';/** Whether TOC entry page numbers use right-aligned tab stops. Stored as a PM node attribute (not a field switch). */
rightAlignPageNumbers?: boolean;
— but there is no tab stop for either of them to describe, and setting them does not create one. toc.configure with { tabLeader: 'dot' } or { rightAlignPageNumbers: true } returns success with no warnings, the instruction is unchanged, the value is not echoed back in displayConfig on the next toc.list(), and no w:tabs appears. { outlineLevels: { from: 1, to: 3 } } in the same patch does take effect (the instruction becomes TOC \o "1-3" \h), so the call itself is reaching the field — those two keys are being dropped. A following toc.update does not add a stop either.
Put the caret in a body paragraph and insert a table of contents.
Look at the result on screen: page number a fixed short gap after the title, no leader dots.
Save the .docx and inspect it:
the TOC1/TOC2/TOC3 paragraphs have no w:tabs;
word/styles.xml still has no TOC* style;
word/settings.xml still has <w:defaultTabStop w:val="720"/>.
toc.configure with { tabLeader: 'dot', rightAlignPageNumbers: true } — reports success, changes nothing. Add outlineLevels: { from: 1, to: 3 } to the same patch and the instruction does change, so the patch is being applied; those two keys are dropped.
toc.update — the rows are rebuilt, still with no stop.
Word, same document: the numbers form a right-aligned column at the edge of the text area with a dotted leader running to them, and styles.xml has gained TOC1…TOC3.
Suggested fix
On toc.insert (and on toc.update for rows that are new), materialise the TOC1…TOC9 definitions the field's level range needs, the way Word does:
w:tabs → <w:tab w:val="end" w:pos="<section text width>" w:leader="<tabLeader>"/>
per-level w:ind (Word steps 220 twips per level)
clear w:semiHidden/w:unhideWhenUsed on the materialised style, since it is now used
That also gives tabLeader and rightAlignPageNumbers something real to write to, and it makes the saved file open in Word looking the way it looked in SuperDoc.
One smaller thing noticed on the way, possibly related to #2580: the instruction the insert produces is TOC \h — no \o range switch at all, where Word writes TOC \o "1-3" \h \z \u.
Workaround
For anyone who lands here: the rows can be fixed up from the Document API after inserting, per row —
(with target = { kind: 'block', nodeType: 'paragraph', nodeId } for each TOC row; the block for the TOC node itself reports nodeType: 'tableOfContents' in blocks.list but is accepted as 'paragraph' here). In a right-to-left document two further corrections are needed, which is the third issue in this set.
SuperDoc version
2.13.0 (@superdoc/docx-engine 0.12.0). Chrome, Windows 10.
What happened?
Insert a table of contents and each row comes out as
title+ tab character +PAGEREF, with no tab stop anywhere for that tab character to land on. The page number therefore sits one default tab (½ inch) after the title text instead of at the far edge of the text area, and there is no dot leader between them. It reads as one run-on line rather than a table of contents.Three layers were checked, and the stop is in none of them:
The rows themselves — the inserted TOC paragraphs have no
w:tabsin theirpPr.The styles they point at — the rows carry
w:pStyleTOC1/TOC2/TOC3, butTOC1…TOC9are not defined instyles.xml.shared/common/data/blank.docxhas 33 style definitions and none of them is aTOC*. What it does have is the latent declarations:In Word those latent entries are the promise of a definition: inserting a TOC materialises
TOC1…TOC9from Word's built-in definitions — each with a right-aligned tab stop at the section's text width carrying the requested leader, and a per-levelw:ind— and unhides them. SuperDoc writes the field and the rows but never creates the styles, so thew:pStylereference resolves to nothing.The document default — with no stop from either layer the tab falls back to
w:defaultTabStop, which the shipped template sets to720. Hence the half-inch jump, unrelated to the page width, and no leader.The configure surface looks like it should cover this and does not:
TocConfigurePatchofferstabLeaderandrightAlignPageNumbers(packages/document-api/src/toc/toc.types.ts) —— but there is no tab stop for either of them to describe, and setting them does not create one.
toc.configurewith{ tabLeader: 'dot' }or{ rightAlignPageNumbers: true }returns success with no warnings, the instruction is unchanged, the value is not echoed back indisplayConfigon the nexttoc.list(), and now:tabsappears.{ outlineLevels: { from: 1, to: 3 } }in the same patch does take effect (the instruction becomesTOC \o "1-3" \h), so the call itself is reaching the field — those two keys are being dropped. A followingtoc.updatedoes not add a stop either.Steps to reproduce
ui.commands.executeAsync('linked-style', { style: 'Heading2' }).).docxand inspect it:TOC1/TOC2/TOC3paragraphs have now:tabs;word/styles.xmlstill has noTOC*style;word/settings.xmlstill has<w:defaultTabStop w:val="720"/>.toc.configurewith{ tabLeader: 'dot', rightAlignPageNumbers: true }— reports success, changes nothing. AddoutlineLevels: { from: 1, to: 3 }to the same patch and the instruction does change, so the patch is being applied; those two keys are dropped.toc.update— the rows are rebuilt, still with no stop.Word, same document: the numbers form a right-aligned column at the edge of the text area with a dotted leader running to them, and
styles.xmlhas gainedTOC1…TOC3.Suggested fix
On
toc.insert(and ontoc.updatefor rows that are new), materialise theTOC1…TOC9definitions the field's level range needs, the way Word does:w:tabs→<w:tab w:val="end" w:pos="<section text width>" w:leader="<tabLeader>"/>w:ind(Word steps 220 twips per level)w:semiHidden/w:unhideWhenUsedon the materialised style, since it is now usedThat also gives
tabLeaderandrightAlignPageNumberssomething real to write to, and it makes the saved file open in Word looking the way it looked in SuperDoc.One smaller thing noticed on the way, possibly related to #2580: the instruction the insert produces is
TOC \h— no\orange switch at all, where Word writesTOC \o "1-3" \h \z \u.Workaround
For anyone who lands here: the rows can be fixed up from the Document API after inserting, per row —
(with
target={ kind: 'block', nodeType: 'paragraph', nodeId }for each TOC row; the block for the TOC node itself reportsnodeType: 'tableOfContents'inblocks.listbut is accepted as'paragraph'here). In a right-to-left document two further corrections are needed, which is the third issue in this set.SuperDoc version
2.13.0 (
@superdoc/docx-engine0.12.0). Chrome, Windows 10.