diff --git a/src/lib/i18n/locales/de.ts b/src/lib/i18n/locales/de.ts index c1eb288..3873144 100644 --- a/src/lib/i18n/locales/de.ts +++ b/src/lib/i18n/locales/de.ts @@ -1111,6 +1111,7 @@ const de: Messages = { hfFlattened: 'Listen/Tabellen in Kopf- oder Fußzeilen wurden in Text umgewandelt', textBoxFlattened: 'In Tabellenzellen oder anderen Textfeldern verschachtelte Textfelder wurden aufgelöst', nestedTables: 'Verschachtelte Tabellen wurden in Absätze umgewandelt', + floatingTable: 'Eine frei positionierte Tabelle steht jetzt im Textfluss — was ihr folgt, kann tiefer sitzen als in Word', comments: 'Kommentare wurden entfernt', missingFonts: (fonts) => `Diese Schriftarten sind nicht installiert und wurden durch Ersatzschriften dargestellt: ${fonts}`, }, diff --git a/src/lib/i18n/locales/en.ts b/src/lib/i18n/locales/en.ts index c2290b8..2102367 100644 --- a/src/lib/i18n/locales/en.ts +++ b/src/lib/i18n/locales/en.ts @@ -1119,6 +1119,7 @@ const en = { hfFlattened: 'Lists/tables in headers or footers were flattened to text', textBoxFlattened: 'Text boxes nested in table cells or other text boxes were flattened', nestedTables: 'Nested tables were flattened to paragraphs', + floatingTable: 'A floating table was placed in the text flow — what follows it may sit lower than in Word', comments: 'Comments were removed', missingFonts: (fonts: string) => `These fonts aren't installed and were shown with a substitute: ${fonts}`, }, diff --git a/src/lib/import/CLAUDE.md b/src/lib/import/CLAUDE.md index 4a1a10e..9eb561b 100644 --- a/src/lib/import/CLAUDE.md +++ b/src/lib/import/CLAUDE.md @@ -115,6 +115,13 @@ a producer writing EMU there (360000 = 1cm in EMU, 635cm read as twips) would ot leave columns of no width. Under that width LibreOffice lays the declared gap out literally — probed to 10.16cm on a 15.24cm text — so only the unholdable value is dropped. +**A floating table stays in the flow, with a warning.** Word's `w:tblpPr` takes a table +out of it — a cover page's layout table is one, and what follows starts where the table +does — which the editor's block table cannot do. So the blocks after it (and any frame +anchored to them) sit as far down as the table is tall; LibreOffice models the same table +as a text frame wrapping it, which is why its own layout of such a cover differs from +ours. + **A heading in a cell carries its own 0.** No style name reaches a cell, so the editor draws the level's 12pt/6pt margins (`styles/headings.ts`) there — where a Word heading whose style chain sets no spacing has none. The baked-in chain's silence is therefore diff --git a/src/lib/import/docx.ts b/src/lib/import/docx.ts index a369a97..225d90b 100644 --- a/src/lib/import/docx.ts +++ b/src/lib/import/docx.ts @@ -2746,6 +2746,12 @@ function buildTable(tbl: Element, ctx: Ctx): Node | null { rows.push(row); } if (rows.length === 0) return null; + // A floating table (w:tblpPr) is out of Word's flow: what follows it starts where the + // table does. The editor has no such table, so it stays in the flow — and a frame + // anchored to the paragraph after it lands as far down as the table is tall. + if (fc(fc(tbl, 'tblPr'), 'tblpPr')) { + ctx.warnings.add('A floating table was placed in the text flow — what follows it may sit lower than in Word'); + } const attrs: Record = { ...(tableMargins(tbl, useWeights, ctx, padBase[3]) ?? {}) }; if (pad) attrs.cellPadding = pad; // w:tblHeader on the first row: Word repeats it at the top of every page the table