/** * Minimal ODF (.odt) document view over `content.xml`. * * Phase 1 scope: enumerate block-level text elements (`text:p` / `text:h`) in * document order — including those nested in `table:table-cell` — with deterministic * structural paragraph IDs, read a paragraph's visible text, and replace text within * a paragraph when the match lies in a single `#text` node. See the `add-odf-core` * OpenSpec change for the full rationale. * * Namespaces: ODF is heavily namespaced and prefixes are not guaranteed, so all * element matching is by `namespaceURI` + `localName`, never by prefixed tag name. */ import { type OdfComment } from './comments.js'; export type OdfParagraph = { /** Deterministic structural ID (document-order ordinal), stable for identical bytes. */ id: string; /** Visible text with `text:s` expanded to spaces and `text:tab` to a tab. */ text: string; }; export type ReplaceResult = { ok: true; } | { ok: false; code: 'ANCHOR_NOT_FOUND' | 'TEXT_NOT_FOUND' | 'MATCH_SPANS_MULTIPLE_NODES'; message: string; }; export type InsertResult = { ok: true; newIds: string[]; } | { ok: false; code: 'ANCHOR_NOT_FOUND'; message: string; }; /** Parameters for {@link OdfDocument.addComment}. A `start`/`end` range is optional; omit for whole-paragraph. */ export type AddCommentParams = { paragraphId: string; start?: number; end?: number; author: string; text: string; initials?: string; }; export type AddCommentResult = { ok: true; commentId: number; } | { ok: false; code: 'ANCHOR_NOT_FOUND' | 'MATCH_SPANS_MULTIPLE_NODES' | 'INVALID_RANGE'; message: string; }; export declare class OdfDocument { private doc; /** Block-level text elements in document order; index is the structural ID ordinal. */ private blocks; private constructor(); /** Parse a `content.xml` string into a document view. */ static fromContentXml(contentXml: string): OdfDocument; private idForIndex; private blockForId; /** All paragraphs in document order. */ getParagraphs(): OdfParagraph[]; /** Visible text of a paragraph by ID, or null if the ID does not resolve. */ getParagraphTextById(id: string): string | null; /** * Replace `findText` with `replaceWith` in the paragraph identified by `id`. * Phase 1 only edits when the match lies entirely within a single `#text` node. */ replaceTextById(id: string, findText: string, replaceWith: string): ReplaceResult; /** * Insert one or more paragraphs relative to the anchor paragraph identified by `id`. * * `text` is split on blank lines (`\n{2,}`) into separate `text:p` blocks (parity with * the DOCX `insert_paragraph` tool); a single `\n` within a block becomes a * `text:line-break`. Inserted blocks inherit the anchor's `text:style-name` ONLY when * the anchor is itself a `text:p` — inserting after a heading (`text:h`) produces * default body paragraphs, never more headings. * * Paragraph IDs are positional ordinals, so every ID at or after the insertion point * shifts by the number of inserted blocks. Returns the inserted blocks' freshly * recomputed IDs in document order; callers must re-read before issuing further edits * that target IDs near or after the insertion point. */ insertParagraph(id: string, text: string, position: 'BEFORE' | 'AFTER'): InsertResult; /** * Insert an `office:annotation` comment on the paragraph identified by `paragraphId`. * Omit `start`/`end` to bracket the whole paragraph (structural insertion, independent of * text segmentation); supply a visible `start`/`end` range to bracket a substring (which must * lie within a single `#text` node, else `MATCH_SPANS_MULTIPLE_NODES`). Annotations are inline * children, so positional paragraph IDs do NOT shift. */ addComment(params: AddCommentParams): AddCommentResult; /** All `office:annotation` comments in document order. */ getComments(): OdfComment[]; /** Serialize the (possibly edited) document back to a `content.xml` string. */ toXml(): string; } //# sourceMappingURL=document.d.ts.map