This file helps AI coding agents understand @ansonlai/docx-redline-js quickly. Read this instead of exploring the full source tree.
Converts text/markdown edits into valid Office Open XML (OOXML) with Word-native tracked changes. Feed it original OOXML + desired text and it returns OOXML with w:ins/w:del revision markup.
Input: (paragraph OOXML, original text, modified text, options)
|
v
Engine routes to: format-only | surgical | reconstruction | list | table mode
|
v
Output: { oxml: string, hasChanges: boolean, status?: string, error?: object, warnings?: string[] }
The engine usually works at paragraph/range/table scope. For full-document
operations, use the standalone operation runner so the result is safe to write
back to word/document.xml.
import { applyRedlineToOxml, configureXmlProvider } from '@ansonlai/docx-redline-js';index.js is the single package entry point.
import { DOMParser, XMLSerializer } from '@xmldom/xmldom';
configureXmlProvider({ DOMParser, XMLSerializer });Browsers have native DOM APIs, so no provider injection is typically needed.
const result = await applyRedlineToOxml(oxml, originalText, modifiedText, {
generateRedlines: true,
author: 'Agent Name',
existingRevisions: 'reject-input'
});existingRevisions defaults to 'reject-input'. Use 'accept-all-first' only
when the caller intentionally wants to accept prior tracked changes before
applying a new edit.
const result = await applyRedlineToOxml(oxml, originalText, modifiedText, {
generateRedlines: false
});import { ingestWordOoxmlToPlainText, ingestWordOoxmlToMarkdown } from '@ansonlai/docx-redline-js';
const plainText = ingestWordOoxmlToPlainText(documentXml);
const markdown = ingestWordOoxmlToMarkdown(documentXml);import { injectCommentsIntoOoxml } from '@ansonlai/docx-redline-js';
const result = injectCommentsIntoOoxml(paragraphOoxml, [
{ text: 'Review this clause', targetText: 'force majeure', author: 'Agent' }
]);import { acceptTrackedChangesInOoxml } from '@ansonlai/docx-redline-js';
const acceptedMine = acceptTrackedChangesInOoxml(documentXml, { author: 'Agent' });
const acceptedAll = acceptTrackedChangesInOoxml(documentXml, { allAuthors: true });import { rejectTrackedChangesInOoxml } from '@ansonlai/docx-redline-js';
const rejectedMine = rejectTrackedChangesInOoxml(documentXml, { author: 'Agent' });
const rejectedAll = rejectTrackedChangesInOoxml(documentXml, { allAuthors: true });Move revisions are consumed too: accept removes w:moveFrom and unwraps
w:moveTo; reject unwraps w:moveFrom and removes w:moveTo.
import { deleteCommentsByAuthorInOoxml } from '@ansonlai/docx-redline-js';
const removedMine = deleteCommentsByAuthorInOoxml(packageOrDocumentOoxml, { author: 'Agent' });
const removedAll = deleteCommentsByAuthorInOoxml(packageOrDocumentOoxml, { allAuthors: true });import {
applyOperationToDocumentXml,
applyOperationsToDocumentXml
} from '@ansonlai/docx-redline-js/services/standalone-operation-runner.js';
const result = await applyOperationsToDocumentXml(documentXml, operations, 'Agent', runtimeContext, options);Use result.documentXml from these APIs when replacing full word/document.xml.
For mixed batches, prefer applyOperationsToDocumentXml(...); it applies comments
before replacements so earlier edits cannot invalidate their anchors.
import { containsTrackedChanges } from '@ansonlai/docx-redline-js';
const hasTrackedChanges = containsTrackedChanges(xmlDoc);const result = await applyRedlineToOxml(oxml, 'Item text', '1. Item text', {
generateRedlines: true
});import { reconcileMarkdownTableOoxml } from '@ansonlai/docx-redline-js';
const result = await reconcileMarkdownTableOoxml(tableOoxml, originalText, markdownTable);index.js
adapters/
config.js
xml-adapter.js
logger.js
core/
types.js
word-xml.js
paragraph-targeting.js
list-targeting.js
table-targeting.js
engine/
oxml-engine.js
surgical-mode.js
surgical-run-splitting.js
surgical-diff-application.js
surgical-spans.js
reconstruction-mode.js
reconstruction-writer.js
format-application.js
formatting-removal.js
run-builders.js
table-mode.js
pipeline/
pipeline.js
ingestion.js
ingestion-export.js
diff-engine.js
markdown-processor.js
serialization.js
list-generation.js
services/
standalone-operation-runner.js
standalone-docx-plumbing.js
numbering-helpers.js
comment-engine.js
revision-comment-management.js
table-reconciliation.js
package-builder.js
orchestration/
route-plan.js
list-markdown.js
list-structural-fallback.js
{
generateRedlines: true,
author: 'Name',
existingRevisions: 'reject-input',
removeFormatting: false
}{
oxml: string,
hasChanges: boolean,
status?: 'ok' | 'no-op' | 'error',
error?: { code: string, message: string },
warnings?: string[],
numberingXml?: string,
useNativeApi?: boolean
}Known error codes include PARSE_ERROR, TARGET_NOT_FOUND, and
EXISTING_REVISIONS.
import { wrapInDocumentFragment } from '@ansonlai/docx-redline-js';
const wrapped = wrapInDocumentFragment(rawOoxml, { includeNumbering: true, numberingXml });When consuming result.oxml, do not assume the payload is always safe to write
directly into word/document.xml.
- Paragraph/range/table APIs can return a fragment,
<w:document>, or package payload (<pkg:package>). applyOperationToDocumentXml(...).documentXmlis the document-safe path when you need a fullword/document.xmlreplacement.- Use
extractReplacementNodesFromOoxml(payload)to normalize unknown payloads. - If
sourceType === 'package'or the payload starts with<pkg:package, do not write it intoword/document.xmlas-is.
- Call
configureXmlProviderfirst in Node.js. applyRedlineToOxmlis async.- Paragraph APIs expect paragraph-level OOXML, not full
word/document.xmlin all cases. - List operations may return
numberingXmlthat must be merged into package parts. useNativeApi: truemeans standalone mode cannot fully handle that operation path.deleteCommentsByAuthorInOoxmlremoves matchingcomments.xmlentries and linked comment anchors/references in the document.- If output begins with
<pkg:package, treat it as package-level OOXML and normalize it before writing anything back toword/document.xml. - Existing revisions are rejected by default; pass
existingRevisions: 'accept-all-first'only when that is desired. - Hyperlinks, bookmarks, comment markers, tabs/breaks, and footnote/endnote references are structural OOXML and should survive adjacent redline edits.
- Internally, create Word elements through
createWordElementand tracked-change metadata throughcreateRevisionMetadata.
npm test
npm run test:isolation
npm run check:types
node scripts/export-validation-fixtures.mjsOptional Windows/Word smoke test for a completed .docx:
npm run smoke:word -- path/to/file.docx