feat: a table keeps the cell margins its file gave it
The cell padding was a constant in three places that disagreed with each other, so a narrow column lost 0.38cm it did not have: a bibliography marker column of 0.71cm wrapped "[2] " onto three lines and every entry grew with it, costing a fixture a whole page. The table now carries its own margins (w:tblCellMar, direct or from the table style; fo:padding on the ODF cell style) and both exports write them back. A side within a twentieth of a millimetre of the default is the default, or Word's 108 twips would tag every table.
This commit is contained in:
1 parent
e4b679ad8b
commit
db0fe71cdb
11 files changed
+174
-16
No files matched your search
@@ -4,6 +4,10 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { unzipSync, strFromU8 } from 'fflate';
|
||||
import { buildOdt } from '../../src/lib/export/odt';
|
||||
import { importOdt } from '../../src/lib/import/odt';
|
||||
import { buildDocx } from '../../src/lib/export/docx';
|
||||
import { importDocx } from '../../src/lib/import/docx';
|
||||
import { cellPaddingAttr } from '../../src/lib/editor/extensions/tableCellPadding';
|
||||
|
||||
type N = any;
|
||||
|
||||
@@ -37,4 +41,31 @@ describe('table cell padding', () => {
|
||||
expect(props).toMatch(/fo:padding-bottom="0cm"/);
|
||||
}
|
||||
});
|
||||
|
||||
it('collapses a producer-rounded default, keeps a real value', () => {
|
||||
// Word's 108 twips and LibreOffice's 0.191cm are both our 0.19cm default.
|
||||
expect(cellPaddingAttr([0, 0.1905, 0, 0.191])).toBeNull();
|
||||
expect(cellPaddingAttr([0.026, 0.026, 0.026, 0.026])).toEqual([0.026, 0.026, 0.026, 0.026]);
|
||||
});
|
||||
|
||||
it('round-trips a table’s own cell margins', async () => {
|
||||
const tight: N = structuredClone(doc);
|
||||
tight.content[1].attrs = { cellPadding: [0.03, 0.05, 0.03, 0.05] };
|
||||
const bytes = await buildOdt(tight, { top: 2, bottom: 2, left: 2, right: 2 }, 'portrait');
|
||||
const xml = strFromU8(unzipSync(bytes)['content.xml']);
|
||||
expect(xml).toMatch(/fo:padding-left="0\.05cm"/);
|
||||
expect(xml).toMatch(/fo:padding-top="0\.03cm"/);
|
||||
|
||||
const back = await importOdt(bytes);
|
||||
const table = back.content.content!.find((n: N) => n.type === 'table') as N;
|
||||
expect(table.attrs?.cellPadding).toEqual([0.03, 0.05, 0.03, 0.05]);
|
||||
|
||||
const docx = await buildDocx(tight, { top: 2, bottom: 2, left: 2, right: 2 }, 'portrait');
|
||||
const backDocx = importDocx(docx);
|
||||
const docxTable = backDocx.content.content!.find((n: N) => n.type === 'table') as N;
|
||||
// Word measures in twips, so 0.05cm comes back a twentieth of a point off.
|
||||
for (const [i, cm] of [0.03, 0.05, 0.03, 0.05].entries()) {
|
||||
expect(docxTable.attrs?.cellPadding[i]).toBeCloseTo(cm, 2);
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user