fix: read a header/footer wrapped in a content control

Word's inserted page number sits in a w:sdt, so the paragraph is not a child
of w:ftr and the whole zone came back empty. Mirrors what convertBlocks
already does for the body.
This commit is contained in:
Steffen Becker committed 2026-08-08 08:30:04 +00:00
1 parent 9d6b77a876
commit 58eadc3a2e
1 file changed
+16 -1
+16 -1
View File
@@ -1589,7 +1589,7 @@ function convertHfPart(relId: string | null, ctx: Ctx): HfDoc {
const inline: Node[] = [];
let textAlign: string | null = null;
const boxMaps: Record<string, string>[] = [];
for (const p of fcAll(root, 'p')) {
for (const p of hfParagraphs(root)) {
if (inline.length) inline.push({ type: 'hardBreak' });
const ppr = fc(p, 'pPr');
if (textAlign === null) {
@@ -1616,6 +1616,21 @@ function convertHfPart(relId: string | null, ctx: Ctx): HfDoc {
return { type: 'doc', content: [para] };
}
// A zone's paragraphs in document order, unwrapping the content controls Word puts
// around an inserted page number — its w:p is not a child of w:hdr/w:ftr.
function hfParagraphs(el: Element): Element[] {
const out: Element[] = [];
for (const c of Array.from(el.children)) {
if (c.namespaceURI !== W) continue;
if (c.localName === 'p') out.push(c);
else if (c.localName === 'sdt') {
const content = fc(c, 'sdtContent');
if (content) out.push(...hfParagraphs(content));
}
}
return out;
}
// Collapse several source paragraphs' box props into one (mirror of odt.ts mergeHfBox).
function mergeHfBox(maps: Record<string, string>[]): Record<string, string> {
const out: Record<string, string> = {};