import { type ReplacementPart } from './text.js'; import { type RevisionContext } from './track-changes-emitter.js'; import { type DocumentStyles, type DocumentViewNode } from './document_view.js'; import { type SerializeMarkdownOptions } from './serialize_markdown.js'; import { type SerializeHtmlOptions } from './serialize_html.js'; import { type SerializePlainTextOptions } from './serialize_plaintext.js'; import type { FormattingMode } from './formatting_tags.js'; import { type StylesModel } from './styles.js'; import { type NumberingModel } from './numbering.js'; import { type ParagraphSpacingMutation, type ParagraphSpacingMutationResult, type TableCellPaddingMutation, type TableCellPaddingMutationResult, type TableRowHeightMutation, type TableRowHeightMutationResult } from './layout.js'; import { type ExtractTablesOptions, type ExtractTablesResult } from './tables.js'; import { type MergeRunsOptions, type MergeRunsResult } from './merge_runs.js'; import { type ValidateDocumentResult } from './validate_document.js'; import { type AiRevisionValidationTouchedContext, type ValidateAiRevisionsResult } from './validate_ai_revisions.js'; import { type AcceptChangesResult } from './accept_changes.js'; import { type RejectChangesResult } from './reject_changes.js'; import { type AddCommentResult, type AddCommentReplyResult, type Comment } from './comments.js'; import { type Footnote, type AddFootnoteResult } from './footnotes.js'; export type NormalizationResult = { runsMerged: number; proofErrRemoved: number; wrappersConsolidated: number; doubleElevationsFixed: number; }; export type ParagraphRef = { id: string; text: string; }; export declare class DocxDocument { private zip; private documentXml; private stylesXml; private numberingXml; private footnotesXml; private relsMap; private dirty; private documentViewCache; /** * Raw document.xml text as loaded, before normalize()/edits mutate the DOM. * Reference for minimal re-serialization in toBuffer(); null for instances * not created via load(). */ private originalDocumentXmlText; private constructor(); static load(buffer: Buffer): Promise; getParagraphs(): Element[]; getParagraphElementById(bookmarkId: string): Element | null; getParagraphTextById(bookmarkId: string): string | null; insertParagraphBookmarks(attachmentId: string): { paragraphCount: number; }; /** * Normalize the document by merging format-identical adjacent runs and * consolidating adjacent same-author tracked-change wrappers. * Should be called BEFORE bookmark allocation. */ normalize(): NormalizationResult; /** * Validate structural integrity of the document. * Non-destructive, read-only check. */ validate(): ValidateDocumentResult; validateAiRevisions(aiAuthor: string, touched?: AiRevisionValidationTouchedContext): Promise; /** * Accept all tracked changes in document.xml plus supported revisionable * side-story parts, producing clean XML with no revision markup. */ acceptChanges(): Promise; /** * Reject all tracked changes in document.xml plus supported revisionable * side-story parts, restoring their pre-edit state where possible. */ rejectChanges(): Promise; removeJuniorBookmarks(): number; readParagraphs(opts?: { nodeIds?: string[]; offset?: number; limit?: number; }): { paragraphs: ParagraphRef[]; totalParagraphs: number; }; /** * Parsed `word/numbering.xml` model (abstract numberings + instances), or null when the * document has no numbering part. The document view's `numbering` field only carries * `num_id`/`ilvl`; semantic converters (DOCX → ODT) need `numFmt`/`lvlText`/`start` to * synthesize target-format list styles, so the full model is exposed here. */ getNumberingModel(): NumberingModel | null; /** * Parsed named-style model of the loaded document (empty when the package has no * `word/styles.xml`). Semantic converters (DOCX → ODT) resolve heading/body style chains * through it to seed their own style templates from the source's definitions. */ getStylesModel(): StylesModel; buildDocumentView(opts?: { includeSemanticTags?: boolean; showFormatting?: boolean; formattingMode?: FormattingMode; }): { nodes: DocumentViewNode[]; styles: DocumentStyles; }; replaceText(params: { targetParagraphId: string; findText: string; replaceText: string | ReplacementPart[]; }): void; /** * Replace text at a known character range without re-searching. * Used by the range-trimming approach where the caller has already located the match. */ replaceTextAtRange(params: { targetParagraphId: string; start: number; end: number; replaceText: string | ReplacementPart[]; }): void; insertParagraph(params: { positionalAnchorNodeId: string; relativePosition: 'BEFORE' | 'AFTER'; newText: string; newParagraphId?: string; styleSourceId?: string; }, ctx?: RevisionContext): { newParagraphId: string; newParagraphIds: string[]; styleSourceFallback?: boolean; }; setParagraphSpacing(mutation: ParagraphSpacingMutation, ctx?: RevisionContext): ParagraphSpacingMutationResult; setTableRowHeight(mutation: TableRowHeightMutation, ctx?: RevisionContext): TableRowHeightMutationResult; setTableCellPadding(mutation: TableCellPaddingMutation, ctx?: RevisionContext): TableCellPaddingMutationResult; /** * Extract tables from the document body. * Read-only operation — does not mutate document state. */ extractTables(options?: ExtractTablesOptions): ExtractTablesResult; /** * Merge format-identical adjacent runs only (no redline simplification). * Useful as a pre-processing step before text search when runs may be fragmented. * Pass `{ preserveRsidIdentity: true }` from edit pipelines that must not * disturb rsid attributes on runs the caller did not touch (#286). */ mergeRunsOnly(opts?: MergeRunsOptions): MergeRunsResult; /** * Add a root comment anchored to a text range within a paragraph. * * Bootstraps comment parts if missing (idempotent). * Returns the allocated comment ID. */ addComment(params: { paragraphId: string; start?: number; end?: number; author: string; text: string; initials?: string; }, ctx?: RevisionContext): Promise; /** * Add a threaded reply to an existing comment. * * Bootstraps comment parts if missing (idempotent). * Returns the allocated comment ID and parent ID. */ addCommentReply(params: { parentCommentId: number; author: string; text: string; initials?: string; }, ctx?: RevisionContext): Promise; getComments(): Promise; getComment(commentId: number): Promise; deleteComment(params: { commentId: number; }, ctx?: RevisionContext): Promise; private refreshFootnotesXml; getFootnotes(): Promise; /** * Serialize the document to GitHub-Flavored Markdown. Convenience wrapper that wires the * structured document view (with inline formatting) and footnotes into * {@link serializeToMarkdown}. Markdown is intentionally lossy — see that serializer. * * Async because footnote extraction reads the footnotes part from the zip. */ toMarkdown(opts?: SerializeMarkdownOptions): Promise; /** * Serialize the document to semantic HTML. Convenience wrapper that wires the structured * document view (with inline formatting) and footnotes into {@link serializeToHtml}. The * default output is a complete `` document; pass `{ fragment: true }` for the * body-level elements only. This is the semantic tier — exact layout is not reproduced. * * Async because footnote extraction reads the footnotes part from the zip. */ toHtml(opts?: SerializeHtmlOptions): Promise; /** * Serialize the document to plain text (no markup). Convenience wrapper that wires the * structured document view and footnotes into {@link serializeToPlainText}. All formatting * is stripped; block structure survives as blank-line-separated paragraphs, `- ` bullets, * and tab-separated table rows. Intentionally lossy — see that serializer. * * Uses the same `showFormatting: true` view as {@link toMarkdown} so the block structure * and injected `[^n]` footnote markers match; the inline tags it produces are then stripped. * * Async because footnote extraction reads the footnotes part from the zip. */ toPlainText(opts?: SerializePlainTextOptions): Promise; getFootnote(noteId: number): Promise; /** * Add a footnote anchored to a paragraph, optionally after specific text. * * Bootstraps footnote parts if missing (idempotent). * Returns the allocated footnote ID. */ addFootnote(params: { paragraphId: string; afterText?: string; text: string; }, ctx?: RevisionContext): Promise; /** * Update the text content of an existing footnote. */ updateFootnoteText(params: { noteId: number; newText: string; }, ctx?: RevisionContext): Promise; /** * Delete a footnote and its references from the document. */ deleteFootnote(params: { noteId: number; }, ctx?: RevisionContext): Promise; /** * Return a deep clone of the internal document.xml DOM. * Callers can mutate the clone (e.g. acceptChanges / rejectChanges) * without affecting session state. */ getDocumentXmlClone(): Document; /** * Return a deep clone of the comments.xml DOM, or null if the document * has no comments part. */ getCommentsXmlClone(): Promise; /** * Serialize the document to a .docx buffer. * * With `minimalReserialization` (requires `cleanBookmarks`), top-level body * blocks that no edit touched are restored element-for-element from the * original document.xml instead of carrying the open-time normalization * (proofErr stripping, run merging) to disk — so output diffs reflect the * actual edit blast radius. Edited/inserted blocks are emitted as-is. * Falls back to full re-serialization (blocksRestored: 0) when no original * text was captured or reconciliation fails. * * @see https://github.com/UseJunior/safe-docx/issues/408 */ toBuffer(opts?: { cleanBookmarks?: boolean; minimalReserialization?: boolean; }): Promise<{ buffer: Buffer; bookmarksRemoved: number; blocksRestored: number; }>; } //# sourceMappingURL=document.d.ts.map