diff --git a/src/lib/editor/extensions/tableOfContents.ts b/src/lib/editor/extensions/tableOfContents.ts index db0616d..1b00206 100644 --- a/src/lib/editor/extensions/tableOfContents.ts +++ b/src/lib/editor/extensions/tableOfContents.ts @@ -16,6 +16,8 @@ const FALLBACK_PAGE_HEIGHT = 1123; // The heading above the entries. An imported TOC keeps the one its file used // ("Inhalt", "Sommaire", …); a freshly inserted one takes this. const TITLE = 'Table of Contents'; +// Enough leader dots to cross the widest gap a page can offer; the row clips the rest. +const LEADER_DOTS = 200; declare module '@tiptap/core' { interface Commands { @@ -183,6 +185,9 @@ class TocView { text.textContent = e.text; const leader = document.createElement('span'); leader.className = 'toc-leader'; + // Real dots, as a word processor fills the gap: they scale with the font and + // reach the PDF as text. The row clips whatever the gap has no room for. + leader.textContent = '.'.repeat(LEADER_DOTS); const page = document.createElement('span'); page.className = 'toc-page'; page.textContent = String(e.page); diff --git a/src/lib/styles/styleSheet.ts b/src/lib/styles/styleSheet.ts index fa081ba..7428bf7 100644 --- a/src/lib/styles/styleSheet.ts +++ b/src/lib/styles/styleSheet.ts @@ -270,7 +270,10 @@ export function styleCss(sheet: StyleSheet): string { const attr = `[data-style="${style.name.replace(/"/g, '\\"')}"]`; const selectors = [`.paper .tiptap ${attr}`]; if (style.outlineLevel) selectors.push(`.paper .tiptap h${style.outlineLevel}:not([data-style])`); - if (style.name === DEFAULT_STYLE) selectors.push('.paper .tiptap p:not([data-style])'); + if (style.outlineLevel === 1) selectors.push('.paper .tiptap .toc-title'); // the index heads its list like any chapter + // The generated index carries no style name, and a word processor bases its own + // index styles on the default one — so it follows the document's body text. + if (style.name === DEFAULT_STYLE) selectors.push('.paper .tiptap p:not([data-style])', '.paper .tiptap .toc'); rules.push(`${selectors.join(',\n')} {\n ${decls.join(';\n ')};\n}`); // A list marker inherits the item's own font, never its paragraph's, so the item diff --git a/src/styles/editor.css b/src/styles/editor.css index ea33ed1..9f418cd 100644 --- a/src/styles/editor.css +++ b/src/styles/editor.css @@ -214,13 +214,13 @@ text-overflow: ellipsis; flex: 0 1 auto; } -/* Dotted leader filling the gap; nudged up to sit on the text baseline. */ +/* Leader dots filling the gap: the row grants the span the space that is left and + clips the dots that do not fit, so the page number stays put. */ .paper .tiptap .toc-leader { - flex: 1 1 auto; + flex: 1 1 0; /* basis 0: the dots are decoration, they must not size the row */ min-width: 1em; - margin: 0 4px; - border-bottom: 1px dotted currentColor; - transform: translateY(-0.25em); + overflow: hidden; + white-space: nowrap; } .paper .tiptap .toc-page { flex: 0 0 auto;