diff --git a/apps/server/src/provider/documentTextWorker.ts b/apps/server/src/provider/documentTextWorker.ts index 569493906d385..1abdbd78030d5 100644 --- a/apps/server/src/provider/documentTextWorker.ts +++ b/apps/server/src/provider/documentTextWorker.ts @@ -22,6 +22,8 @@ interface XmlNode { attrs: Record; children: Array; spaceCount?: number; + hasText?: boolean; + hasTextChoice?: boolean; } function xml(source: string, odfSpaces = false, htmlEntities = false): XmlNode { @@ -47,10 +49,22 @@ function xml(source: string, odfSpaces = false, htmlEntities = false): XmlNode { stack.push(node); }); parser.on("closetag", () => { - stack.pop(); + const node = stack.pop()!; + const parent = stack.at(-1)!; + // Markup-compatibility fallbacks repeat their mc:Choice content, e.g. Word text boxes. + // Keep one when no Choice carries text, such as a chart with a VML caption. + if (node.name === "Fallback" && parent.hasTextChoice) { + parent.children.pop(); + return; + } + if (!node.hasText) return; + parent.hasText = true; + if (node.name === "Choice") parent.hasTextChoice = true; }); const text = (value: string) => { - stack.at(-1)!.children.push(value); + const node = stack.at(-1)!; + node.children.push(value); + if (value.trim() !== "") node.hasText = true; }; parser.on("text", text); parser.on("cdata", text); diff --git a/apps/server/src/provider/userInputAttachments.test.ts b/apps/server/src/provider/userInputAttachments.test.ts index 81c167c038d87..9d8f3718dd4b8 100644 --- a/apps/server/src/provider/userInputAttachments.test.ts +++ b/apps/server/src/provider/userInputAttachments.test.ts @@ -554,6 +554,25 @@ describe("question answer paths", () => { expected: ["Start", "[Extracted text truncated at document extraction limits.]"], absent: ["Unneeded"], }, + { + ext: "docx", + bounded: true, + parts: { + "word/document.xml": + 'BodyCallout boxCallout box', + }, + expected: ["Body\nCallout box"], + occurrences: { text: "Callout box", count: 1 }, + }, + { + ext: "docx", + bounded: true, + parts: { + "word/document.xml": + 'Chart caption', + }, + expected: ["Chart caption"], + }, { ext: "docx", bounded: true,