@usejunior/docx-core 0.0.1 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +86 -28
- package/dist/.tsbuildinfo +1 -0
- package/dist/atomizer.d.ts +218 -0
- package/dist/atomizer.d.ts.map +1 -0
- package/dist/atomizer.js +856 -0
- package/dist/atomizer.js.map +1 -0
- package/dist/baselines/atomizer/atomLcs.d.ts +96 -0
- package/dist/baselines/atomizer/atomLcs.d.ts.map +1 -0
- package/dist/baselines/atomizer/atomLcs.js +347 -0
- package/dist/baselines/atomizer/atomLcs.js.map +1 -0
- package/dist/baselines/atomizer/debug.d.ts +41 -0
- package/dist/baselines/atomizer/debug.d.ts.map +1 -0
- package/dist/baselines/atomizer/debug.js +85 -0
- package/dist/baselines/atomizer/debug.js.map +1 -0
- package/dist/baselines/atomizer/documentReconstructor.d.ts +64 -0
- package/dist/baselines/atomizer/documentReconstructor.d.ts.map +1 -0
- package/dist/baselines/atomizer/documentReconstructor.js +939 -0
- package/dist/baselines/atomizer/documentReconstructor.js.map +1 -0
- package/dist/baselines/atomizer/hierarchicalLcs.d.ts +111 -0
- package/dist/baselines/atomizer/hierarchicalLcs.d.ts.map +1 -0
- package/dist/baselines/atomizer/hierarchicalLcs.js +469 -0
- package/dist/baselines/atomizer/hierarchicalLcs.js.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier.d.ts +183 -0
- package/dist/baselines/atomizer/inPlaceModifier.d.ts.map +1 -0
- package/dist/baselines/atomizer/inPlaceModifier.js +1600 -0
- package/dist/baselines/atomizer/inPlaceModifier.js.map +1 -0
- package/dist/baselines/atomizer/numberingIntegration.d.ts +59 -0
- package/dist/baselines/atomizer/numberingIntegration.d.ts.map +1 -0
- package/dist/baselines/atomizer/numberingIntegration.js +209 -0
- package/dist/baselines/atomizer/numberingIntegration.js.map +1 -0
- package/dist/baselines/atomizer/pipeline.d.ts +65 -0
- package/dist/baselines/atomizer/pipeline.d.ts.map +1 -0
- package/dist/baselines/atomizer/pipeline.js +510 -0
- package/dist/baselines/atomizer/pipeline.js.map +1 -0
- package/dist/baselines/atomizer/premergeRuns.d.ts +26 -0
- package/dist/baselines/atomizer/premergeRuns.d.ts.map +1 -0
- package/dist/baselines/atomizer/premergeRuns.js +150 -0
- package/dist/baselines/atomizer/premergeRuns.js.map +1 -0
- package/dist/baselines/atomizer/trackChangesAcceptor.d.ts +63 -0
- package/dist/baselines/atomizer/trackChangesAcceptor.d.ts.map +1 -0
- package/dist/baselines/atomizer/trackChangesAcceptor.js +254 -0
- package/dist/baselines/atomizer/trackChangesAcceptor.js.map +1 -0
- package/dist/baselines/atomizer/trackChangesAcceptorAst.d.ts +64 -0
- package/dist/baselines/atomizer/trackChangesAcceptorAst.d.ts.map +1 -0
- package/dist/baselines/atomizer/trackChangesAcceptorAst.js +586 -0
- package/dist/baselines/atomizer/trackChangesAcceptorAst.js.map +1 -0
- package/dist/baselines/atomizer/xmlToWmlElement.d.ts +65 -0
- package/dist/baselines/atomizer/xmlToWmlElement.d.ts.map +1 -0
- package/dist/baselines/atomizer/xmlToWmlElement.js +95 -0
- package/dist/baselines/atomizer/xmlToWmlElement.js.map +1 -0
- package/dist/baselines/diffmatch/documentBuilder.d.ts +44 -0
- package/dist/baselines/diffmatch/documentBuilder.d.ts.map +1 -0
- package/dist/baselines/diffmatch/documentBuilder.js +227 -0
- package/dist/baselines/diffmatch/documentBuilder.js.map +1 -0
- package/dist/baselines/diffmatch/paragraphAlignment.d.ts +75 -0
- package/dist/baselines/diffmatch/paragraphAlignment.d.ts.map +1 -0
- package/dist/baselines/diffmatch/paragraphAlignment.js +206 -0
- package/dist/baselines/diffmatch/paragraphAlignment.js.map +1 -0
- package/dist/baselines/diffmatch/pipeline.d.ts +33 -0
- package/dist/baselines/diffmatch/pipeline.d.ts.map +1 -0
- package/dist/baselines/diffmatch/pipeline.js +84 -0
- package/dist/baselines/diffmatch/pipeline.js.map +1 -0
- package/dist/baselines/diffmatch/runDiff.d.ts +53 -0
- package/dist/baselines/diffmatch/runDiff.d.ts.map +1 -0
- package/dist/baselines/diffmatch/runDiff.js +253 -0
- package/dist/baselines/diffmatch/runDiff.js.map +1 -0
- package/dist/baselines/diffmatch/trackChangesRenderer.d.ts +64 -0
- package/dist/baselines/diffmatch/trackChangesRenderer.d.ts.map +1 -0
- package/dist/baselines/diffmatch/trackChangesRenderer.js +178 -0
- package/dist/baselines/diffmatch/trackChangesRenderer.js.map +1 -0
- package/dist/baselines/diffmatch/xmlParser.d.ts +45 -0
- package/dist/baselines/diffmatch/xmlParser.d.ts.map +1 -0
- package/dist/baselines/diffmatch/xmlParser.js +344 -0
- package/dist/baselines/diffmatch/xmlParser.js.map +1 -0
- package/dist/baselines/wmlcomparer/DocxodusWasm.d.ts +51 -0
- package/dist/baselines/wmlcomparer/DocxodusWasm.d.ts.map +1 -0
- package/dist/baselines/wmlcomparer/DocxodusWasm.js +83 -0
- package/dist/baselines/wmlcomparer/DocxodusWasm.js.map +1 -0
- package/dist/baselines/wmlcomparer/DotnetCli.d.ts +40 -0
- package/dist/baselines/wmlcomparer/DotnetCli.d.ts.map +1 -0
- package/dist/baselines/wmlcomparer/DotnetCli.js +135 -0
- package/dist/baselines/wmlcomparer/DotnetCli.js.map +1 -0
- package/dist/benchmark/metrics.d.ts +72 -0
- package/dist/benchmark/metrics.d.ts.map +1 -0
- package/dist/benchmark/metrics.js +45 -0
- package/dist/benchmark/metrics.js.map +1 -0
- package/dist/benchmark/reporter.d.ts +23 -0
- package/dist/benchmark/reporter.d.ts.map +1 -0
- package/dist/benchmark/reporter.js +147 -0
- package/dist/benchmark/reporter.js.map +1 -0
- package/dist/benchmark/runner.d.ts +30 -0
- package/dist/benchmark/runner.d.ts.map +1 -0
- package/dist/benchmark/runner.js +233 -0
- package/dist/benchmark/runner.js.map +1 -0
- package/dist/cli/compare-two.d.ts +28 -0
- package/dist/cli/compare-two.d.ts.map +1 -0
- package/dist/cli/compare-two.js +110 -0
- package/dist/cli/compare-two.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +21 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/core-types.d.ts +296 -0
- package/dist/core-types.d.ts.map +1 -0
- package/dist/core-types.js +122 -0
- package/dist/core-types.js.map +1 -0
- package/dist/footnotes.d.ts +144 -0
- package/dist/footnotes.d.ts.map +1 -0
- package/dist/footnotes.js +291 -0
- package/dist/footnotes.js.map +1 -0
- package/dist/format-detection.d.ts +120 -0
- package/dist/format-detection.d.ts.map +1 -0
- package/dist/format-detection.js +338 -0
- package/dist/format-detection.js.map +1 -0
- package/dist/index.d.ts +177 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/integration/output-artifacts.d.ts +6 -0
- package/dist/integration/output-artifacts.d.ts.map +1 -0
- package/dist/integration/output-artifacts.js +30 -0
- package/dist/integration/output-artifacts.js.map +1 -0
- package/dist/move-detection.d.ts +211 -0
- package/dist/move-detection.d.ts.map +1 -0
- package/dist/move-detection.js +391 -0
- package/dist/move-detection.js.map +1 -0
- package/dist/numbering.d.ts +136 -0
- package/dist/numbering.d.ts.map +1 -0
- package/dist/numbering.js +446 -0
- package/dist/numbering.js.map +1 -0
- package/dist/primitives/accept_changes.d.ts +30 -0
- package/dist/primitives/accept_changes.d.ts.map +1 -0
- package/dist/primitives/accept_changes.js +241 -0
- package/dist/primitives/accept_changes.js.map +1 -0
- package/dist/primitives/bookmarks.d.ts +12 -0
- package/dist/primitives/bookmarks.d.ts.map +1 -0
- package/dist/primitives/bookmarks.js +248 -0
- package/dist/primitives/bookmarks.js.map +1 -0
- package/dist/primitives/comments.d.ts +88 -0
- package/dist/primitives/comments.d.ts.map +1 -0
- package/dist/primitives/comments.js +703 -0
- package/dist/primitives/comments.js.map +1 -0
- package/dist/primitives/document.d.ts +168 -0
- package/dist/primitives/document.d.ts.map +1 -0
- package/dist/primitives/document.js +532 -0
- package/dist/primitives/document.js.map +1 -0
- package/dist/primitives/document_view.d.ts +93 -0
- package/dist/primitives/document_view.d.ts.map +1 -0
- package/dist/primitives/document_view.js +722 -0
- package/dist/primitives/document_view.js.map +1 -0
- package/dist/primitives/dom-helpers.d.ts +94 -0
- package/dist/primitives/dom-helpers.d.ts.map +1 -0
- package/dist/primitives/dom-helpers.js +219 -0
- package/dist/primitives/dom-helpers.js.map +1 -0
- package/dist/primitives/errors.d.ts +7 -0
- package/dist/primitives/errors.d.ts.map +1 -0
- package/dist/primitives/errors.js +10 -0
- package/dist/primitives/errors.js.map +1 -0
- package/dist/primitives/extract_revisions.d.ts +50 -0
- package/dist/primitives/extract_revisions.d.ts.map +1 -0
- package/dist/primitives/extract_revisions.js +340 -0
- package/dist/primitives/extract_revisions.js.map +1 -0
- package/dist/primitives/footnotes.d.ts +37 -0
- package/dist/primitives/footnotes.d.ts.map +1 -0
- package/dist/primitives/footnotes.js +552 -0
- package/dist/primitives/footnotes.js.map +1 -0
- package/dist/primitives/formatting_tags.d.ts +30 -0
- package/dist/primitives/formatting_tags.d.ts.map +1 -0
- package/dist/primitives/formatting_tags.js +217 -0
- package/dist/primitives/formatting_tags.js.map +1 -0
- package/dist/primitives/index.d.ts +26 -0
- package/dist/primitives/index.d.ts.map +1 -0
- package/dist/primitives/index.js +26 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/primitives/layout.d.ts +53 -0
- package/dist/primitives/layout.d.ts.map +1 -0
- package/dist/primitives/layout.js +178 -0
- package/dist/primitives/layout.js.map +1 -0
- package/dist/primitives/list_labels.d.ts +19 -0
- package/dist/primitives/list_labels.d.ts.map +1 -0
- package/dist/primitives/list_labels.js +57 -0
- package/dist/primitives/list_labels.js.map +1 -0
- package/dist/primitives/matching.d.ts +17 -0
- package/dist/primitives/matching.d.ts.map +1 -0
- package/dist/primitives/matching.js +144 -0
- package/dist/primitives/matching.js.map +1 -0
- package/dist/primitives/merge_runs.d.ts +23 -0
- package/dist/primitives/merge_runs.d.ts.map +1 -0
- package/dist/primitives/merge_runs.js +195 -0
- package/dist/primitives/merge_runs.js.map +1 -0
- package/dist/primitives/namespaces.d.ts +90 -0
- package/dist/primitives/namespaces.d.ts.map +1 -0
- package/dist/primitives/namespaces.js +107 -0
- package/dist/primitives/namespaces.js.map +1 -0
- package/dist/primitives/numbering.d.ts +27 -0
- package/dist/primitives/numbering.d.ts.map +1 -0
- package/dist/primitives/numbering.js +182 -0
- package/dist/primitives/numbering.js.map +1 -0
- package/dist/primitives/prevent_double_elevation.d.ts +18 -0
- package/dist/primitives/prevent_double_elevation.d.ts.map +1 -0
- package/dist/primitives/prevent_double_elevation.js +190 -0
- package/dist/primitives/prevent_double_elevation.js.map +1 -0
- package/dist/primitives/reject_changes.d.ts +27 -0
- package/dist/primitives/reject_changes.d.ts.map +1 -0
- package/dist/primitives/reject_changes.js +371 -0
- package/dist/primitives/reject_changes.js.map +1 -0
- package/dist/primitives/relationships.d.ts +7 -0
- package/dist/primitives/relationships.d.ts.map +1 -0
- package/dist/primitives/relationships.js +24 -0
- package/dist/primitives/relationships.js.map +1 -0
- package/dist/primitives/semantic_tags.d.ts +32 -0
- package/dist/primitives/semantic_tags.d.ts.map +1 -0
- package/dist/primitives/semantic_tags.js +139 -0
- package/dist/primitives/semantic_tags.js.map +1 -0
- package/dist/primitives/simplify_redlines.d.ts +19 -0
- package/dist/primitives/simplify_redlines.d.ts.map +1 -0
- package/dist/primitives/simplify_redlines.js +94 -0
- package/dist/primitives/simplify_redlines.js.map +1 -0
- package/dist/primitives/styles.d.ts +36 -0
- package/dist/primitives/styles.d.ts.map +1 -0
- package/dist/primitives/styles.js +190 -0
- package/dist/primitives/styles.js.map +1 -0
- package/dist/primitives/text.d.ts +27 -0
- package/dist/primitives/text.d.ts.map +1 -0
- package/dist/primitives/text.js +416 -0
- package/dist/primitives/text.js.map +1 -0
- package/dist/primitives/validate_document.d.ts +24 -0
- package/dist/primitives/validate_document.d.ts.map +1 -0
- package/dist/primitives/validate_document.js +147 -0
- package/dist/primitives/validate_document.js.map +1 -0
- package/dist/primitives/xml.d.ts +5 -0
- package/dist/primitives/xml.d.ts.map +1 -0
- package/dist/primitives/xml.js +19 -0
- package/dist/primitives/xml.js.map +1 -0
- package/dist/primitives/zip.d.ts +25 -0
- package/dist/primitives/zip.d.ts.map +1 -0
- package/dist/primitives/zip.js +78 -0
- package/dist/primitives/zip.js.map +1 -0
- package/dist/shared/docx/DocxArchive.d.ts +94 -0
- package/dist/shared/docx/DocxArchive.d.ts.map +1 -0
- package/dist/shared/docx/DocxArchive.js +169 -0
- package/dist/shared/docx/DocxArchive.js.map +1 -0
- package/dist/shared/ooxml/namespaces.d.ts +149 -0
- package/dist/shared/ooxml/namespaces.d.ts.map +1 -0
- package/dist/shared/ooxml/namespaces.js +224 -0
- package/dist/shared/ooxml/namespaces.js.map +1 -0
- package/dist/shared/ooxml/types.d.ts +136 -0
- package/dist/shared/ooxml/types.d.ts.map +1 -0
- package/dist/shared/ooxml/types.js +7 -0
- package/dist/shared/ooxml/types.js.map +1 -0
- package/package.json +63 -6
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* reject_changes — reject all tracked changes in a OOXML document body.
|
|
3
|
+
*
|
|
4
|
+
* Produces the document as it was before tracked changes were made by:
|
|
5
|
+
* - Removing w:ins elements AND their content (insertions undone)
|
|
6
|
+
* - Unwrapping w:del elements and converting w:delText → w:t (deletions restored)
|
|
7
|
+
* - Unwrapping w:moveFrom (keep at original position), removing w:moveTo and content
|
|
8
|
+
* - Restoring original properties from *PrChange records
|
|
9
|
+
* - Preserving cross-paragraph bookmark boundaries when removing inserted paragraphs
|
|
10
|
+
* - Stripping paragraph-level revision markers and rsidDel attributes
|
|
11
|
+
*
|
|
12
|
+
* Operates on the W3C DOM (`@xmldom/xmldom`).
|
|
13
|
+
*/
|
|
14
|
+
import { OOXML } from './namespaces.js';
|
|
15
|
+
const W_NS = OOXML.W_NS;
|
|
16
|
+
// ── DOM helpers (internal) ──────────────────────────────────────────
|
|
17
|
+
function isW(node, localName) {
|
|
18
|
+
return (node.nodeType === 1 &&
|
|
19
|
+
node.namespaceURI === W_NS &&
|
|
20
|
+
node.localName === localName);
|
|
21
|
+
}
|
|
22
|
+
function isWElement(node) {
|
|
23
|
+
return node.nodeType === 1 && node.namespaceURI === W_NS;
|
|
24
|
+
}
|
|
25
|
+
function getDepth(node) {
|
|
26
|
+
let depth = 0;
|
|
27
|
+
let cur = node.parentNode;
|
|
28
|
+
while (cur) {
|
|
29
|
+
depth++;
|
|
30
|
+
cur = cur.parentNode;
|
|
31
|
+
}
|
|
32
|
+
return depth;
|
|
33
|
+
}
|
|
34
|
+
function collectByLocalName(container, localName) {
|
|
35
|
+
return Array.from(container.getElementsByTagNameNS(W_NS, localName));
|
|
36
|
+
}
|
|
37
|
+
function removeAllByLocalName(container, localName) {
|
|
38
|
+
const elements = collectByLocalName(container, localName);
|
|
39
|
+
let count = 0;
|
|
40
|
+
for (const el of elements) {
|
|
41
|
+
if (el.parentNode) {
|
|
42
|
+
el.parentNode.removeChild(el);
|
|
43
|
+
count++;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return count;
|
|
47
|
+
}
|
|
48
|
+
function unwrapAllByLocalName(container, localName) {
|
|
49
|
+
const elements = collectByLocalName(container, localName);
|
|
50
|
+
// Sort deepest-first to handle nested wrappers correctly
|
|
51
|
+
elements.sort((a, b) => getDepth(b) - getDepth(a));
|
|
52
|
+
let count = 0;
|
|
53
|
+
for (const el of elements) {
|
|
54
|
+
const parent = el.parentNode;
|
|
55
|
+
if (!parent)
|
|
56
|
+
continue;
|
|
57
|
+
while (el.firstChild) {
|
|
58
|
+
parent.insertBefore(el.firstChild, el);
|
|
59
|
+
}
|
|
60
|
+
parent.removeChild(el);
|
|
61
|
+
count++;
|
|
62
|
+
}
|
|
63
|
+
return count;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Check if a paragraph has a paragraph-level revision marker.
|
|
67
|
+
* Pattern: w:p > w:pPr > w:rPr > w:ins (or w:del)
|
|
68
|
+
*/
|
|
69
|
+
function paragraphHasParaMarker(p, markerLocalName) {
|
|
70
|
+
for (let i = 0; i < p.childNodes.length; i++) {
|
|
71
|
+
const child = p.childNodes[i];
|
|
72
|
+
if (!isW(child, 'pPr'))
|
|
73
|
+
continue;
|
|
74
|
+
for (let j = 0; j < child.childNodes.length; j++) {
|
|
75
|
+
const pPrChild = child.childNodes[j];
|
|
76
|
+
if (!isW(pPrChild, 'rPr'))
|
|
77
|
+
continue;
|
|
78
|
+
for (let k = 0; k < pPrChild.childNodes.length; k++) {
|
|
79
|
+
const rPrChild = pPrChild.childNodes[k];
|
|
80
|
+
if (isW(rPrChild, markerLocalName))
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Check if a node (or its descendants) contains any w:r elements.
|
|
89
|
+
*/
|
|
90
|
+
function containsRun(node) {
|
|
91
|
+
if (isW(node, 'r'))
|
|
92
|
+
return true;
|
|
93
|
+
for (let i = 0; i < node.childNodes.length; i++) {
|
|
94
|
+
if (containsRun(node.childNodes[i]))
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
// Tags that are "inserted" content — removal candidates when rejecting
|
|
100
|
+
const INSERTED_LOCALS = new Set(['ins', 'moveTo']);
|
|
101
|
+
// Tags that are "kept" content when rejecting
|
|
102
|
+
const KEPT_LOCALS = new Set(['del', 'moveFrom']);
|
|
103
|
+
// Range marker tags to ignore
|
|
104
|
+
const RANGE_MARKER_LOCALS = new Set([
|
|
105
|
+
'moveFromRangeStart', 'moveFromRangeEnd',
|
|
106
|
+
'moveToRangeStart', 'moveToRangeEnd',
|
|
107
|
+
]);
|
|
108
|
+
/**
|
|
109
|
+
* Determine if a paragraph's only content lives inside w:ins or w:moveTo
|
|
110
|
+
* (no w:r outside those wrappers, and no w:del/w:moveFrom siblings).
|
|
111
|
+
* These paragraphs should be removed when rejecting changes.
|
|
112
|
+
*/
|
|
113
|
+
function paragraphHasOnlyInsertedContent(p) {
|
|
114
|
+
for (let i = 0; i < p.childNodes.length; i++) {
|
|
115
|
+
const child = p.childNodes[i];
|
|
116
|
+
if (child.nodeType !== 1)
|
|
117
|
+
continue;
|
|
118
|
+
const el = child;
|
|
119
|
+
if (el.namespaceURI !== W_NS)
|
|
120
|
+
continue;
|
|
121
|
+
const local = el.localName;
|
|
122
|
+
// If the paragraph has kept content wrappers, it stays
|
|
123
|
+
if (KEPT_LOCALS.has(local))
|
|
124
|
+
return false;
|
|
125
|
+
// Skip pPr, range markers, and inserted wrappers
|
|
126
|
+
if (local === 'pPr' || RANGE_MARKER_LOCALS.has(local) || INSERTED_LOCALS.has(local))
|
|
127
|
+
continue;
|
|
128
|
+
// A bare w:r or any other element that contains runs means live content
|
|
129
|
+
if (local === 'r' || containsRun(el))
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
// We passed all children without finding live content — but there must be
|
|
133
|
+
// at least one inserted wrapper for this to be an "inserted content" paragraph
|
|
134
|
+
for (let i = 0; i < p.childNodes.length; i++) {
|
|
135
|
+
const child = p.childNodes[i];
|
|
136
|
+
if (child.nodeType === 1 && isWElement(child) && INSERTED_LOCALS.has(child.localName)) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
// Property change element local names (all 6 types)
|
|
143
|
+
const PR_CHANGE_LOCALS = [
|
|
144
|
+
'rPrChange', 'pPrChange', 'sectPrChange',
|
|
145
|
+
'tblPrChange', 'trPrChange', 'tcPrChange',
|
|
146
|
+
];
|
|
147
|
+
/**
|
|
148
|
+
* Relocate orphaned bookmarks from a paragraph being removed to an
|
|
149
|
+
* adjacent kept paragraph. This preserves cross-paragraph bookmark boundaries.
|
|
150
|
+
*/
|
|
151
|
+
function relocateBookmarks(p, paragraphsToRemove) {
|
|
152
|
+
const parent = p.parentNode;
|
|
153
|
+
if (!parent)
|
|
154
|
+
return;
|
|
155
|
+
// Find an adjacent kept paragraph (prefer next, fallback to previous)
|
|
156
|
+
let target = null;
|
|
157
|
+
let sibling = p.nextSibling;
|
|
158
|
+
while (sibling) {
|
|
159
|
+
if (sibling.nodeType === 1 && isW(sibling, 'p') && !paragraphsToRemove.has(sibling)) {
|
|
160
|
+
target = sibling;
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
sibling = sibling.nextSibling;
|
|
164
|
+
}
|
|
165
|
+
if (!target) {
|
|
166
|
+
sibling = p.previousSibling;
|
|
167
|
+
while (sibling) {
|
|
168
|
+
if (sibling.nodeType === 1 && isW(sibling, 'p') && !paragraphsToRemove.has(sibling)) {
|
|
169
|
+
target = sibling;
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
sibling = sibling.previousSibling;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (!target)
|
|
176
|
+
return;
|
|
177
|
+
// Move bookmarkStart/bookmarkEnd elements that are direct children of the paragraph
|
|
178
|
+
const toMove = [];
|
|
179
|
+
for (let i = 0; i < p.childNodes.length; i++) {
|
|
180
|
+
const child = p.childNodes[i];
|
|
181
|
+
if (child.nodeType !== 1)
|
|
182
|
+
continue;
|
|
183
|
+
const el = child;
|
|
184
|
+
if (isW(el, 'bookmarkStart') || isW(el, 'bookmarkEnd')) {
|
|
185
|
+
toMove.push(el);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Also check sibling bookmarks (sibling-style: <bookmarkStart/><p/><bookmarkEnd/>)
|
|
189
|
+
let prev = p.previousSibling;
|
|
190
|
+
while (prev) {
|
|
191
|
+
if (prev.nodeType === 1) {
|
|
192
|
+
const el = prev;
|
|
193
|
+
if (isW(el, 'bookmarkStart') || isW(el, 'bookmarkEnd')) {
|
|
194
|
+
toMove.push(el);
|
|
195
|
+
prev = prev.previousSibling;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
prev = prev.previousSibling;
|
|
201
|
+
}
|
|
202
|
+
let next = p.nextSibling;
|
|
203
|
+
while (next) {
|
|
204
|
+
if (next.nodeType === 1) {
|
|
205
|
+
const el = next;
|
|
206
|
+
if (isW(el, 'bookmarkStart') || isW(el, 'bookmarkEnd')) {
|
|
207
|
+
toMove.push(el);
|
|
208
|
+
next = next.nextSibling;
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
next = next.nextSibling;
|
|
214
|
+
}
|
|
215
|
+
for (const bm of toMove) {
|
|
216
|
+
// Insert at the beginning of the target paragraph (after pPr if present)
|
|
217
|
+
const firstNonPPr = Array.from(target.childNodes).find((n) => !(n.nodeType === 1 && isW(n, 'pPr')));
|
|
218
|
+
if (bm.parentNode)
|
|
219
|
+
bm.parentNode.removeChild(bm);
|
|
220
|
+
target.insertBefore(bm, firstNonPPr ?? null);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
// ── Public API ──────────────────────────────────────────────────────
|
|
224
|
+
/**
|
|
225
|
+
* Reject all tracked changes in the document body, restoring the
|
|
226
|
+
* document to its pre-edit state.
|
|
227
|
+
*
|
|
228
|
+
* Mutates the Document in place (same convention as acceptChanges).
|
|
229
|
+
*/
|
|
230
|
+
export function rejectChanges(doc) {
|
|
231
|
+
const body = doc.getElementsByTagNameNS(W_NS, 'body').item(0);
|
|
232
|
+
if (!body) {
|
|
233
|
+
return { insertionsRemoved: 0, deletionsRestored: 0, movesReverted: 0, propertyChangesReverted: 0 };
|
|
234
|
+
}
|
|
235
|
+
// Phase A — Identify paragraphs to remove (entirely inserted paragraphs)
|
|
236
|
+
const paragraphsToRemove = new Set();
|
|
237
|
+
const allParagraphs = collectByLocalName(body, 'p');
|
|
238
|
+
for (const p of allParagraphs) {
|
|
239
|
+
// Paragraph-level insertion marker: w:p > w:pPr > w:rPr > w:ins
|
|
240
|
+
if (paragraphHasParaMarker(p, 'ins')) {
|
|
241
|
+
paragraphsToRemove.add(p);
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
// Paragraphs whose only content is inside w:ins or w:moveTo
|
|
245
|
+
if (paragraphHasOnlyInsertedContent(p)) {
|
|
246
|
+
paragraphsToRemove.add(p);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// Phase B — Preserve cross-paragraph bookmark boundaries
|
|
250
|
+
for (const p of paragraphsToRemove) {
|
|
251
|
+
relocateBookmarks(p, paragraphsToRemove);
|
|
252
|
+
}
|
|
253
|
+
// Phase C — Remove insertions and move destinations
|
|
254
|
+
const insertionsRemoved = removeAllByLocalName(body, 'ins');
|
|
255
|
+
const moveToRemoved = removeAllByLocalName(body, 'moveTo');
|
|
256
|
+
removeAllByLocalName(body, 'moveToRangeStart');
|
|
257
|
+
removeAllByLocalName(body, 'moveToRangeEnd');
|
|
258
|
+
removeAllByLocalName(body, 'moveFromRangeStart');
|
|
259
|
+
removeAllByLocalName(body, 'moveFromRangeEnd');
|
|
260
|
+
// Phase D — Unwrap deletions and convert w:delText → w:t
|
|
261
|
+
const deletionsRestored = unwrapAllByLocalName(body, 'del');
|
|
262
|
+
// Rename all w:delText elements to w:t so getParagraphText() sees them
|
|
263
|
+
const delTexts = collectByLocalName(body, 'delText');
|
|
264
|
+
for (const dt of delTexts) {
|
|
265
|
+
const parent = dt.parentNode;
|
|
266
|
+
if (!parent)
|
|
267
|
+
continue;
|
|
268
|
+
const t = doc.createElementNS(W_NS, 'w:t');
|
|
269
|
+
// Copy text content
|
|
270
|
+
if (dt.textContent) {
|
|
271
|
+
t.appendChild(doc.createTextNode(dt.textContent));
|
|
272
|
+
}
|
|
273
|
+
// Copy xml:space attribute if present
|
|
274
|
+
const xmlSpace = dt.getAttributeNS('http://www.w3.org/XML/1998/namespace', 'space')
|
|
275
|
+
?? dt.getAttribute('xml:space');
|
|
276
|
+
if (xmlSpace) {
|
|
277
|
+
t.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', xmlSpace);
|
|
278
|
+
}
|
|
279
|
+
parent.replaceChild(t, dt);
|
|
280
|
+
}
|
|
281
|
+
// Phase E — Unwrap move sources (keep content at original position)
|
|
282
|
+
const moveFromUnwrapped = unwrapAllByLocalName(body, 'moveFrom');
|
|
283
|
+
// Phase F — Restore original properties from *PrChange records
|
|
284
|
+
let propertyChangesReverted = 0;
|
|
285
|
+
for (const localName of PR_CHANGE_LOCALS) {
|
|
286
|
+
const changes = collectByLocalName(body, localName);
|
|
287
|
+
// Sort deepest-first
|
|
288
|
+
changes.sort((a, b) => getDepth(b) - getDepth(a));
|
|
289
|
+
for (const change of changes) {
|
|
290
|
+
const parentProp = change.parentNode;
|
|
291
|
+
if (!parentProp)
|
|
292
|
+
continue;
|
|
293
|
+
const grandParent = parentProp.parentNode;
|
|
294
|
+
if (!grandParent)
|
|
295
|
+
continue;
|
|
296
|
+
// The *PrChange element contains the original properties.
|
|
297
|
+
// Extract the original property element (e.g. rPr inside rPrChange).
|
|
298
|
+
// The expected mapping:
|
|
299
|
+
// rPrChange → child rPr = original run properties
|
|
300
|
+
// pPrChange → child pPr = original paragraph properties
|
|
301
|
+
// etc.
|
|
302
|
+
const expectedChildLocal = localName.replace('Change', '');
|
|
303
|
+
let originalProps = null;
|
|
304
|
+
for (let i = 0; i < change.childNodes.length; i++) {
|
|
305
|
+
const child = change.childNodes[i];
|
|
306
|
+
if (child.nodeType === 1 && isW(child, expectedChildLocal)) {
|
|
307
|
+
originalProps = child;
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if (originalProps) {
|
|
312
|
+
// Replace the current property element with the original
|
|
313
|
+
const restored = originalProps.cloneNode(true);
|
|
314
|
+
grandParent.replaceChild(restored, parentProp);
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
// Original props were empty — remove the parent property element entirely
|
|
318
|
+
grandParent.removeChild(parentProp);
|
|
319
|
+
}
|
|
320
|
+
propertyChangesReverted++;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
// Phase G — Cleanup
|
|
324
|
+
// Strip paragraph-level revision markers from w:pPr/w:rPr
|
|
325
|
+
for (const p of collectByLocalName(body, 'p')) {
|
|
326
|
+
for (let i = 0; i < p.childNodes.length; i++) {
|
|
327
|
+
const child = p.childNodes[i];
|
|
328
|
+
if (!isW(child, 'pPr'))
|
|
329
|
+
continue;
|
|
330
|
+
for (let j = 0; j < child.childNodes.length; j++) {
|
|
331
|
+
const pPrChild = child.childNodes[j];
|
|
332
|
+
if (!isW(pPrChild, 'rPr'))
|
|
333
|
+
continue;
|
|
334
|
+
const toRemove = [];
|
|
335
|
+
for (let k = 0; k < pPrChild.childNodes.length; k++) {
|
|
336
|
+
const rPrChild = pPrChild.childNodes[k];
|
|
337
|
+
if (isW(rPrChild, 'ins') || isW(rPrChild, 'del')) {
|
|
338
|
+
toRemove.push(rPrChild);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
for (const el of toRemove) {
|
|
342
|
+
pPrChild.removeChild(el);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// Remove paragraphs collected in Phase A
|
|
348
|
+
for (const p of paragraphsToRemove) {
|
|
349
|
+
if (p.parentNode) {
|
|
350
|
+
p.parentNode.removeChild(p);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
// Strip w:rsidDel attributes on remaining elements
|
|
354
|
+
const allElements = body.getElementsByTagNameNS(W_NS, '*');
|
|
355
|
+
for (let i = 0; i < allElements.length; i++) {
|
|
356
|
+
const el = allElements[i];
|
|
357
|
+
if (el.hasAttributeNS(W_NS, 'rsidDel')) {
|
|
358
|
+
el.removeAttributeNS(W_NS, 'rsidDel');
|
|
359
|
+
}
|
|
360
|
+
if (el.hasAttribute('w:rsidDel')) {
|
|
361
|
+
el.removeAttribute('w:rsidDel');
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return {
|
|
365
|
+
insertionsRemoved,
|
|
366
|
+
deletionsRestored,
|
|
367
|
+
movesReverted: moveFromUnwrapped + moveToRemoved,
|
|
368
|
+
propertyChangesReverted,
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
//# sourceMappingURL=reject_changes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reject_changes.js","sourceRoot":"","sources":["../../src/primitives/reject_changes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type RelsMap = Map<string, string>;
|
|
2
|
+
/**
|
|
3
|
+
* Parse a document.xml.rels DOM and return a Map<rId, targetUrl> for external hyperlinks only.
|
|
4
|
+
* Returns an empty map when the rels document is null (e.g. file missing from the DOCX archive).
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseDocumentRels(relsDoc: Document | null): RelsMap;
|
|
7
|
+
//# sourceMappingURL=relationships.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../src/primitives/relationships.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE1C;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,QAAQ,GAAG,IAAI,GAAG,OAAO,CAiBnE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Parser for word/_rels/document.xml.rels — extracts external hyperlink relationships.
|
|
2
|
+
import { OOXML } from './namespaces.js';
|
|
3
|
+
/**
|
|
4
|
+
* Parse a document.xml.rels DOM and return a Map<rId, targetUrl> for external hyperlinks only.
|
|
5
|
+
* Returns an empty map when the rels document is null (e.g. file missing from the DOCX archive).
|
|
6
|
+
*/
|
|
7
|
+
export function parseDocumentRels(relsDoc) {
|
|
8
|
+
const map = new Map();
|
|
9
|
+
if (!relsDoc)
|
|
10
|
+
return map;
|
|
11
|
+
const relationships = relsDoc.getElementsByTagName('Relationship');
|
|
12
|
+
for (let i = 0; i < relationships.length; i++) {
|
|
13
|
+
const rel = relationships.item(i);
|
|
14
|
+
const type = rel.getAttribute('Type');
|
|
15
|
+
const targetMode = rel.getAttribute('TargetMode');
|
|
16
|
+
const id = rel.getAttribute('Id');
|
|
17
|
+
const target = rel.getAttribute('Target');
|
|
18
|
+
if (type === OOXML.HYPERLINK_REL_TYPE && targetMode === 'External' && id && target) {
|
|
19
|
+
map.set(id, target);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return map;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=relationships.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relationships.js","sourceRoot":"","sources":["../../src/primitives/relationships.ts"],"names":[],"mappings":"AAAA,uFAAuF;AAEvF,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAIxC;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAwB;IACxD,MAAM,GAAG,GAAY,IAAI,GAAG,EAAE,CAAC;IAC/B,IAAI,CAAC,OAAO;QAAE,OAAO,GAAG,CAAC;IAEzB,MAAM,aAAa,GAAG,OAAO,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;IACnE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC;QACnC,MAAM,IAAI,GAAG,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,UAAU,GAAG,GAAG,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAClD,MAAM,EAAE,GAAG,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;QAE1C,IAAI,IAAI,KAAK,KAAK,CAAC,kBAAkB,IAAI,UAAU,KAAK,UAAU,IAAI,EAAE,IAAI,MAAM,EAAE,CAAC;YACnF,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare const DEFINITION_TAG = "definition";
|
|
2
|
+
export declare const HIGHLIGHT_TAG = "highlighting";
|
|
3
|
+
export declare function hasDefinitionTags(text: string): boolean;
|
|
4
|
+
export declare function hasHighlightTags(text: string): boolean;
|
|
5
|
+
export declare function emitDefinitionTagsFromString(text: string): string;
|
|
6
|
+
export declare function findInlineDefinitionSpan(text: string): {
|
|
7
|
+
term: string;
|
|
8
|
+
term_start: number;
|
|
9
|
+
term_end: number;
|
|
10
|
+
} | null;
|
|
11
|
+
export declare function stripDefinitionTags(text: string): string;
|
|
12
|
+
export declare function stripHighlightTags(text: string): string;
|
|
13
|
+
export declare function hasFormattingTags(text: string): boolean;
|
|
14
|
+
export declare function stripFormattingTags(text: string): string;
|
|
15
|
+
export declare function hasHyperlinkTags(text: string): boolean;
|
|
16
|
+
export declare function stripHyperlinkTags(text: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Detect definition spans on plain text, returning character offset ranges
|
|
19
|
+
* and the defined term. Used by the formatting tag emitter to interleave
|
|
20
|
+
* <definition> tags with formatting tags in a single consistent pass.
|
|
21
|
+
*
|
|
22
|
+
* Returns spans where:
|
|
23
|
+
* - `start` = index of the opening quote character
|
|
24
|
+
* - `end` = index one past the closing quote character
|
|
25
|
+
* - `term` = the defined term text (excluding quotes)
|
|
26
|
+
*/
|
|
27
|
+
export declare function detectDefinitionSpans(text: string): Array<{
|
|
28
|
+
start: number;
|
|
29
|
+
end: number;
|
|
30
|
+
term: string;
|
|
31
|
+
}>;
|
|
32
|
+
//# sourceMappingURL=semantic_tags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic_tags.d.ts","sourceRoot":"","sources":["../../src/primitives/semantic_tags.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,cAAc,eAAe,CAAC;AAC3C,eAAO,MAAM,aAAa,iBAAiB,CAAC;AA0B5C,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA2BjE;AAED,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAUpH;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKxD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIvD;AAQD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAmBvG"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Semantic tag emission + stripping for Safe-Docx TS.
|
|
2
|
+
//
|
|
3
|
+
// Parity goals (Python):
|
|
4
|
+
// - Emit <definition> tags for explicit definitions, absorbing quotes:
|
|
5
|
+
// Input: "Company" means ...
|
|
6
|
+
// Output: <definition>Company</definition> means ...
|
|
7
|
+
//
|
|
8
|
+
// Headers are represented via a dedicated column (not inline tags) in TOON output.
|
|
9
|
+
export const DEFINITION_TAG = 'definition';
|
|
10
|
+
export const HIGHLIGHT_TAG = 'highlighting';
|
|
11
|
+
// Quote variants (subset of Python workflows/shared/regex/definitions.py).
|
|
12
|
+
// Includes ASCII and common smart quotes.
|
|
13
|
+
const QUOTES = `"'\u201c\u201d\u2018\u2019\u00ab\u00bb\u2039\u203a`;
|
|
14
|
+
const QUOTE_CHARS_CLASS = escapeForCharClass(QUOTES);
|
|
15
|
+
const QUOTE_CLASS = `[${QUOTE_CHARS_CLASS}]`;
|
|
16
|
+
// Port of DEFINITION_VERB_PATTERN (simplified but compatible with the Python export).
|
|
17
|
+
const DEF_VERB = '(?:' +
|
|
18
|
+
'(?:shall\\s+)?means?|' +
|
|
19
|
+
'(?:shall\\s+have|has|have)\\s+the\\s+meaning(?:\\s+(?:set\\s+forth|given|ascribed)\\s+in)?|' +
|
|
20
|
+
'(?:is|are)\\s+defined\\s+as|' +
|
|
21
|
+
'refers?\\s+to|' +
|
|
22
|
+
'(?:shall\\s+)?mean\\s+and\\s+include' +
|
|
23
|
+
')';
|
|
24
|
+
const INLINE_DEFINITION_RE = new RegExp(`${QUOTE_CLASS}([^${QUOTE_CHARS_CLASS}]+)${QUOTE_CLASS}\\s+${DEF_VERB}`, 'gi');
|
|
25
|
+
const INLINE_DEFINITION_RE_ONE = new RegExp(`${QUOTE_CLASS}([^${QUOTE_CHARS_CLASS}]+)${QUOTE_CLASS}\\s+${DEF_VERB}`, 'i');
|
|
26
|
+
function escapeForCharClass(s) {
|
|
27
|
+
// Escape characters that have meaning in a regex character class.
|
|
28
|
+
return s.replace(/[-\\\]^]/g, '\\$&');
|
|
29
|
+
}
|
|
30
|
+
export function hasDefinitionTags(text) {
|
|
31
|
+
return text.includes(`<${DEFINITION_TAG}>`) || text.includes(`</${DEFINITION_TAG}>`);
|
|
32
|
+
}
|
|
33
|
+
export function hasHighlightTags(text) {
|
|
34
|
+
return text.includes(`<${HIGHLIGHT_TAG}>`) || text.includes(`</${HIGHLIGHT_TAG}>`);
|
|
35
|
+
}
|
|
36
|
+
export function emitDefinitionTagsFromString(text) {
|
|
37
|
+
if (!text)
|
|
38
|
+
return text;
|
|
39
|
+
const matches = Array.from(text.matchAll(INLINE_DEFINITION_RE));
|
|
40
|
+
if (matches.length === 0)
|
|
41
|
+
return text;
|
|
42
|
+
let tagged = text;
|
|
43
|
+
// Replace from end to start to preserve offsets.
|
|
44
|
+
for (let i = matches.length - 1; i >= 0; i--) {
|
|
45
|
+
const m = matches[i];
|
|
46
|
+
const term = m[1] ?? '';
|
|
47
|
+
if (!term)
|
|
48
|
+
continue;
|
|
49
|
+
const matchStart = m.index ?? -1;
|
|
50
|
+
if (matchStart < 0)
|
|
51
|
+
continue;
|
|
52
|
+
// Find the opening quote at matchStart, and the closing quote right after the term.
|
|
53
|
+
// We want to replace the quoted term including both quotes.
|
|
54
|
+
const openQuoteIdx = matchStart;
|
|
55
|
+
const closeQuoteIdx = openQuoteIdx + 1 + term.length; // quote + term
|
|
56
|
+
if (closeQuoteIdx >= tagged.length)
|
|
57
|
+
continue;
|
|
58
|
+
const before = tagged.slice(0, openQuoteIdx);
|
|
59
|
+
const after = tagged.slice(closeQuoteIdx + 1); // +1 for closing quote
|
|
60
|
+
tagged = `${before}<${DEFINITION_TAG}>${term}</${DEFINITION_TAG}>${after}`;
|
|
61
|
+
}
|
|
62
|
+
return tagged;
|
|
63
|
+
}
|
|
64
|
+
export function findInlineDefinitionSpan(text) {
|
|
65
|
+
// Find the first explicit definition in text and return the defined-term span (excluding quotes).
|
|
66
|
+
const m = INLINE_DEFINITION_RE_ONE.exec(text);
|
|
67
|
+
if (!m || m.index == null)
|
|
68
|
+
return null;
|
|
69
|
+
const term = m[1] ?? '';
|
|
70
|
+
if (!term)
|
|
71
|
+
return null;
|
|
72
|
+
const openQuoteIdx = m.index;
|
|
73
|
+
const termStart = openQuoteIdx + 1;
|
|
74
|
+
const termEnd = termStart + term.length;
|
|
75
|
+
return { term, term_start: termStart, term_end: termEnd };
|
|
76
|
+
}
|
|
77
|
+
export function stripDefinitionTags(text) {
|
|
78
|
+
// SINGLE SOURCE OF TRUTH for stripping: replace tags with quotes.
|
|
79
|
+
return text
|
|
80
|
+
.replaceAll(new RegExp(`<${DEFINITION_TAG}>`, 'g'), '"')
|
|
81
|
+
.replaceAll(new RegExp(`</${DEFINITION_TAG}>`, 'g'), '"');
|
|
82
|
+
}
|
|
83
|
+
export function stripHighlightTags(text) {
|
|
84
|
+
return text
|
|
85
|
+
.replaceAll(new RegExp(`<${HIGHLIGHT_TAG}>`, 'g'), '')
|
|
86
|
+
.replaceAll(new RegExp(`</${HIGHLIGHT_TAG}>`, 'g'), '');
|
|
87
|
+
}
|
|
88
|
+
// ── Formatting tag helpers ───────────────────────────────────────────
|
|
89
|
+
const FORMATTING_TAG_RE = /<\/?[biu]>/g;
|
|
90
|
+
const HYPERLINK_OPEN_RE = /<a\s+href="[^"]*">/g;
|
|
91
|
+
const HYPERLINK_CLOSE_RE = /<\/a>/g;
|
|
92
|
+
export function hasFormattingTags(text) {
|
|
93
|
+
return FORMATTING_TAG_RE.test(text);
|
|
94
|
+
}
|
|
95
|
+
export function stripFormattingTags(text) {
|
|
96
|
+
// Reset lastIndex since these are global regexes.
|
|
97
|
+
FORMATTING_TAG_RE.lastIndex = 0;
|
|
98
|
+
return text.replace(FORMATTING_TAG_RE, '');
|
|
99
|
+
}
|
|
100
|
+
export function hasHyperlinkTags(text) {
|
|
101
|
+
return text.includes('<a ') || text.includes('</a>');
|
|
102
|
+
}
|
|
103
|
+
export function stripHyperlinkTags(text) {
|
|
104
|
+
return text.replace(HYPERLINK_OPEN_RE, '').replace(HYPERLINK_CLOSE_RE, '');
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Detect definition spans on plain text, returning character offset ranges
|
|
108
|
+
* and the defined term. Used by the formatting tag emitter to interleave
|
|
109
|
+
* <definition> tags with formatting tags in a single consistent pass.
|
|
110
|
+
*
|
|
111
|
+
* Returns spans where:
|
|
112
|
+
* - `start` = index of the opening quote character
|
|
113
|
+
* - `end` = index one past the closing quote character
|
|
114
|
+
* - `term` = the defined term text (excluding quotes)
|
|
115
|
+
*/
|
|
116
|
+
export function detectDefinitionSpans(text) {
|
|
117
|
+
if (!text)
|
|
118
|
+
return [];
|
|
119
|
+
// Reset global regex state.
|
|
120
|
+
INLINE_DEFINITION_RE.lastIndex = 0;
|
|
121
|
+
const matches = Array.from(text.matchAll(INLINE_DEFINITION_RE));
|
|
122
|
+
const spans = [];
|
|
123
|
+
for (const m of matches) {
|
|
124
|
+
const term = m[1] ?? '';
|
|
125
|
+
if (!term)
|
|
126
|
+
continue;
|
|
127
|
+
const matchStart = m.index ?? -1;
|
|
128
|
+
if (matchStart < 0)
|
|
129
|
+
continue;
|
|
130
|
+
const openQuoteIdx = matchStart;
|
|
131
|
+
const termEnd = openQuoteIdx + 1 + term.length;
|
|
132
|
+
// Verify close quote exists.
|
|
133
|
+
if (termEnd < text.length) {
|
|
134
|
+
spans.push({ start: openQuoteIdx, end: termEnd + 1, term });
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return spans;
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=semantic_tags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semantic_tags.js","sourceRoot":"","sources":["../../src/primitives/semantic_tags.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* simplify_redlines — merge adjacent same-author tracked-change wrappers.
|
|
3
|
+
*
|
|
4
|
+
* Consolidates consecutive `w:ins`, `w:del`, `w:moveFrom`, or `w:moveTo`
|
|
5
|
+
* wrappers that share the same `w:author` attribute and local name.
|
|
6
|
+
* Does not merge across different change types or non-whitespace separators.
|
|
7
|
+
*/
|
|
8
|
+
export type SimplifyRedlinesResult = {
|
|
9
|
+
wrappersConsolidated: number;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Simplify tracked-change wrappers across all paragraphs in the document
|
|
13
|
+
* body by merging adjacent same-type, same-author wrappers.
|
|
14
|
+
*
|
|
15
|
+
* This reduces visual clutter in redline documents without altering
|
|
16
|
+
* semantics (every run's tracked-change attribution is preserved).
|
|
17
|
+
*/
|
|
18
|
+
export declare function simplifyRedlines(doc: Document): SimplifyRedlinesResult;
|
|
19
|
+
//# sourceMappingURL=simplify_redlines.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"simplify_redlines.d.ts","sourceRoot":"","sources":["../../src/primitives/simplify_redlines.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,MAAM,sBAAsB,GAAG;IACnC,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AA2FF;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,GAAG,sBAAsB,CAetE"}
|