fix: a zone's own margins survive the ODF round trip
The Header/Footer style carries them, and the band that grows to hold them is rebuilt from there on the way back in.
This commit is contained in:
1 parent
0fe1a8395d
commit
13e026fb8b
2 files changed
+39
No files matched your search
@@ -3637,6 +3637,11 @@ function hfParaPropsXml(para: TiptapNode): string {
|
||||
if (align) props.push(`fo:text-align="${align}"`);
|
||||
const s = paraStyleFromAttrs(para.attrs);
|
||||
if (s.background) props.push(`fo:background-color="${s.background}"`);
|
||||
// The zone's own margins, which grow the band on the way back in (import/CLAUDE.md).
|
||||
for (const [attr, side] of [['spaceBefore', 'top'], ['spaceAfter', 'bottom']] as const) {
|
||||
const v = para.attrs?.[attr];
|
||||
if (typeof v === 'number' && v) props.push(`fo:margin-${side}="${v}pt"`);
|
||||
}
|
||||
for (const [attr, side] of [
|
||||
['borderTop', 'top'], ['borderRight', 'right'], ['borderBottom', 'bottom'], ['borderLeft', 'left'],
|
||||
] as const) {
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
// A header/footer zone's own vertical margins: LibreOffice keeps them on the Header /
|
||||
// Footer paragraph style, and a footer's space above is what grows the band.
|
||||
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';
|
||||
|
||||
type N = any;
|
||||
|
||||
const doc: N = { type: 'doc', content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Body' }] }] };
|
||||
const zone = (attrs: N, text: string): N => ({
|
||||
type: 'doc',
|
||||
content: [{ type: 'paragraph', attrs, content: [{ type: 'text', text }] }],
|
||||
});
|
||||
const hf = {
|
||||
header: zone({ spaceAfter: 34 }, 'Kopf'),
|
||||
footer: zone({ spaceBefore: 24 }, 'Fuss'),
|
||||
headerFirst: null, footerFirst: null, differentFirstPage: false,
|
||||
headerEven: null, footerEven: null, differentOddEven: false,
|
||||
pageCount: 1,
|
||||
};
|
||||
|
||||
describe('header/footer zone margins', () => {
|
||||
it('ride the ODF zone styles and come back', async () => {
|
||||
const bytes = await buildOdt(doc, undefined, 'portrait', hf);
|
||||
const styles = strFromU8(unzipSync(bytes)['styles.xml']);
|
||||
expect(styles).toContain('fo:margin-bottom="34pt"');
|
||||
expect(styles).toContain('fo:margin-top="24pt"');
|
||||
|
||||
const back = await importOdt(bytes);
|
||||
expect(back.header?.content?.[0]?.attrs?.spaceAfter).toBeCloseTo(34, 1);
|
||||
expect(back.footer?.content?.[0]?.attrs?.spaceBefore).toBeCloseTo(24, 1);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user