import { BodyElement, Comment, RunProperties, Section, SectionProperties, ShapeFill } from '../core/document-model/index.js'; import { ColorResolver } from '../core/drawingml/colors.js'; import { Loss, ResourceId } from '../core/ir/index.js'; import { PoNode } from '../core/po-helpers.js'; import { ThemeFonts } from '../core/drawingml/theme-parser.js'; import { ThemeStyles } from './drawing-parser.js'; /** * Resolves a drawing relationship id to a content-addressed `ResourceId` — * supplied by the converter (which owns the OPC package and the `ResourceStore`). */ export type ImageResolver = (relId: string) => ResourceId | undefined; /** Resolves a `w:hyperlink` `r:id` to its external target URL. */ export type HyperlinkResolver = (relId: string) => string | undefined; /** * A SmartArt diagram's pre-rendered drawing override: its `dsp:spTree`, plus a * resolver for the picture fills its nodes name — those relationships belong to * the drawing part, not to the part that references the diagram. */ export interface ResolvedDiagram { readonly spTree: PoNode; readonly resolveImage?: ImageResolver; } /** * Document-wide resolvers every nested parser needs — one context object instead * of threading a parameter pair through ten signatures (oop-design §8). */ export interface ParseContext { /** Resolver for theme/scheme/auto colours. */ readonly resolveColor: ColorResolver; /** Resolver for a drawing relationship id to a stored image. */ readonly resolveImage?: ImageResolver; /** * §17.16.22 `w:hyperlink` `r:id` → external target URL from the owning part's * rels (`TargetMode="External"` only). Absent ⇒ links unwrap to plain text. */ readonly resolveHyperlink?: HyperlinkResolver; /** * SmartArt: a data relationship id (`dgm:relIds` `@r:dm`) → the diagram's * pre-rendered drawing override, or `undefined` when the file ships none * (E-SMARTART SA2). */ readonly resolveDiagram?: (relId: string, frame: { readonly cx: number; readonly cy: number; }) => ResolvedDiagram | undefined; /** * §21.2 a `c:chart` `@r:id` → the chart part's path, the key the reader files * parsed charts under. Relationship ids are scoped to their owning part, so a * footer's `rId1` and the body's `rId1` are different charts. Absent ⇒ the * raw rel id is kept. */ readonly resolveChartPart?: (relId: string) => string | undefined; /** * §20.1.4.2.19 — the theme's `a:lnStyleLst` widths in points, which a * gallery-styled shape's `a:lnRef idx` indexes for its outline weight. */ readonly themeLineWidths?: ReadonlyArray; /** * §20.1.4.1.14/§20.1.4.1.15 — the theme's format scheme: the fill, background * fill and effect styles a `` reference indexes for the fill and * the shadow a gallery-drawn shape wears. */ readonly themeStyles?: ThemeStyles; /** * §20.1.4.1.16 — the theme's font scheme, for the typefaces a run names by * slot (`w:asciiTheme="minorHAnsi"`) rather than by name. */ readonly themeFonts?: ThemeFonts; /** * Sink for graceful-degradation notices (E-SMARTART SA3): a SmartArt with no * drawing override records a dropped-feature {@link Loss} rather than vanishing. */ readonly onLoss?: (loss: Loss) => void; /** * §17.13.4 comment ranges currently open as the body is read — a mutable set * the run collector stamps onto each run (`commentRangeRefs`). A comment range * can span paragraphs, so the state is document-level, not per-paragraph. The * reference is readonly; its contents mutate during the walk (CM2c). */ readonly openCommentRanges?: Set; /** * §17.3.1.1/§17.3.1.3 — what `w:beforeAutospacing`/`w:afterAutospacing` * resolve to for THIS document: 14pt when it states no compatibility mode, * and nothing (the default) for every Word 2007-or-later one. */ readonly autoSpacingPt?: number; } /** The default {@link ParseContext} — just the default colour resolver. */ export declare const DEFAULT_PARSE_CONTEXT: ParseContext; /** * Parse `word/document.xml` (ECMA-376 Part 1 §17) into a flat list of * {@link BodyElement}, preserving the original interleaving of paragraphs and * tables. * * @param documentXml The raw `document.xml` bytes. * @param ctx The document-wide parse context. * @returns The body elements; empty when the `w:body` is absent. */ export declare function parseDocument(documentXml: Uint8Array, ctx?: ParseContext, blocks?: BlockCounter): Array; /** * §17.2.1 `w:background` — the colour the whole page is painted, as a six-digit * hex. Read from `@w:color` (Word's own attribute), falling back to the VML * `v:background @fillcolor` beside it. `auto` and a gradient-only background * (which carries no flat colour of its own) both come back undefined. * * @param documentXml The raw `document.xml` bytes. * @returns The colour, or undefined when the document names none. */ export declare function parseBackgroundColor(documentXml: Uint8Array): string | undefined; /** * §17.2.1 — the page background as the FILL it is. `@w:color` is only the flat * fallback: the `v:background` beside it carries the gradient or the picture * Word actually paints, and both references draw those. fill.docx runs a * five-stop radial sweep where we painted its fallback navy, and * tdf126533_pageBitmap.docx papers the page with an image. * * @param documentXml The raw `document.xml` bytes. * @param resolveImage Resolver for a picture background's `r:id`. * @returns The fill, or undefined when the document names no background. */ export declare function parseBackgroundFill(documentXml: Uint8Array, resolveImage?: (relId: string) => ResourceId | undefined): ShapeFill | undefined; /** * Lines a parsed body up with anything counted in SOURCE blocks. `index[i]` is * the ordinal of the `w:p`/`w:tbl` that produced body element `i`; `next` is the * running count. A paragraph carrying anchored drawings produces several * elements, so the two counts diverge — and {@link parseSections} counts blocks. */ export interface BlockCounter { readonly index: Array; next: number; } /** A fresh {@link BlockCounter}. */ export declare function newBlockCounter(): BlockCounter; /** * Translate a section boundary counted in source blocks into one counted in body * elements: the number of elements that came from a block before `blockEnd`. * * @param blocks The counter filled while parsing the body. * @param blockEnd The section's `endIndex`, in source blocks. * @returns The matching body-element index. */ export declare function bodyIndexForBlock(blocks: BlockCounter, blockEnd: number): number; /** * The empty {@link SectionProperties} fallback (no headers/footers). §17.6.13 — * on the page a document with no `w:sectPr` of its own is made on, which is the * same US Letter a section with no `w:pgSz` gets. */ export declare const EMPTY_SECTION: SectionProperties; /** * Parse the document's final section properties (ECMA-376 Part 1 §17.6.17 — the * body-level `sectPr` is the last child of `w:body` and describes the final * section). Returned as a single {@link SectionProperties} for backward * compatibility; multi-section documents use {@link parseSections} instead. * * @param documentXml The raw `document.xml` bytes. * @returns The final section's properties, or {@link EMPTY_SECTION} when there is none. */ export declare function parseSection(documentXml: Uint8Array): SectionProperties; /** * Collect every section in the document (ECMA-376 §17.6): one `sectPr` per * intermediate paragraph plus the body-final one. Each {@link Section} carries * the exclusive `endIndex` into the body-element list, so section `i` applies to * `body[sections[i-1].endIndex .. endIndex)`. A document with no `sectPr` at all * returns a single empty section spanning the whole body. * * @param documentXml The raw `document.xml` bytes. * @returns The sections in document order; empty when the `w:body` is absent. */ export declare function parseSections(documentXml: Uint8Array): Array
; /** * Parse `word/header*.xml` or `word/footer*.xml`. The root is `w:hdr` or * `w:ftr`, whose children are the same body-element shape as the main document. * * @param xml The raw header/footer part bytes. * @param ctx The document-wide parse context. * @returns The body elements; empty when neither root is found. */ export declare function parseHeaderFooter(xml: Uint8Array, ctx?: ParseContext): Array; /** * Parse a sequence of body-level children (`w:p`, `w:tbl`, `w:sdt`, * `w:bookmarkStart`) into {@link BodyElement}s, preserving order. A lone-drawing * paragraph collapses to a standalone image/shape/chart block; a block-level SDT * unwraps to its content; a body-level bookmark anchors onto the next paragraph. * * @param children The body-level child nodes. * @param ctx The document-wide parse context. * @returns The parsed body elements. */ export declare function parseBodyElements(children: ReadonlyArray, ctx?: ParseContext, blocks?: BlockCounter, sdtRunProps?: RunProperties): Array; /** * §17.5.2.28 `w:sdt/w:sdtPr/w:rPr` — the run properties a content control * lends what it holds, when it states any. * * @param sdt The `w:sdt` element. * @returns The properties, or `undefined` when the control states none. */ export declare function sdtRunProperties(sdt: PoNode, themeFonts?: ThemeFonts): RunProperties | undefined; /** * Parse `footnotes.xml` / `endnotes.xml` (§17.11) into note content by id. The * separator / continuationSeparator / continuationNotice stubs (negative ids or * an explicit `w:type`) are skipped — the layout draws its own separator. * * @param notesXml The raw notes-part bytes. * @param rootTag The part's root element (`w:footnotes` or `w:endnotes`). * @param noteTag The per-note element (`w:footnote` or `w:endnote`). * @param ctx The document-wide parse context. * @returns A map from note id to its body content. */ export declare function parseNotes(notesXml: Uint8Array, rootTag: 'w:footnotes' | 'w:endnotes', noteTag: 'w:footnote' | 'w:endnote', ctx?: ParseContext): Map>; /** * Parse `word/comments.xml` (§17.13.4) into {@link Comment}s by id, each with its * block content and author/initials/date attribution. Thread metadata is added * separately by {@link parseCommentThreads}. * * @param commentsXml The raw `comments.xml` bytes. * @param ctx The document-wide parse context. * @returns A map from comment id to the parsed comment. */ export declare function parseComments(commentsXml: Uint8Array, ctx?: ParseContext): Map; /** A commentsExtended entry, keyed by the comment's last-paragraph w14:paraId. */ export interface CommentExtension { /** The parent comment's paraId — present when this comment is a reply. */ readonly paraIdParent?: string; /** w15:done — the thread is resolved. */ readonly done: boolean; } /** * Parse `word/commentsExtended.xml` (Microsoft w15 `commentsEx`) — a flat list * of `commentEx`, each keyed by a comment's `paraId`: `paraIdParent` links a * reply to its parent, `done` flags a resolved thread. Prefix-agnostic (w15 by * convention). * * @param xml The raw `commentsExtended.xml` bytes. * @returns A map from `paraId` to its {@link CommentExtension}. */ export declare function parseCommentsExtended(xml: Uint8Array): Map; /** * Read comments with their thread metadata: `comments.xml` for content / * attribution plus the optional `commentsExtended.xml` for reply links and * resolved flags (CM4). A reply gains `parentId`, a resolved thread gains `done`. * * @param commentsXml The raw `comments.xml` bytes. * @param commentsExtendedXml The raw `commentsExtended.xml` bytes, or `undefined`. * @param ctx The document-wide parse context. * @returns A map from comment id to the parsed, thread-linked comment. */ export declare function parseCommentThreads(commentsXml: Uint8Array, commentsExtendedXml: Uint8Array | undefined, ctx?: ParseContext): Map; /** * Parse `word/people.xml` (Microsoft w15) — maps an author display name to a * presence identity (`w15:presenceInfo/@w15:userId`, usually an email), used to * enrich a comment's `authorId`. Prefix-agnostic. * * @param xml The raw `people.xml` bytes. * @returns A map from author name to userId. */ export declare function parsePeople(xml: Uint8Array): Map; /** * Attach each comment's `authorId` by matching its author name against the * {@link parsePeople} map. Comments without a matching author pass through * unchanged. * * @param comments The comments by id. * @param people The author → userId map from `people.xml`. * @returns The comments with `authorId` filled in where resolvable. */ export declare function applyAuthorIds(comments: Map, people: Map): Map;