@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.
Files changed (252) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +86 -28
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/atomizer.d.ts +218 -0
  5. package/dist/atomizer.d.ts.map +1 -0
  6. package/dist/atomizer.js +856 -0
  7. package/dist/atomizer.js.map +1 -0
  8. package/dist/baselines/atomizer/atomLcs.d.ts +96 -0
  9. package/dist/baselines/atomizer/atomLcs.d.ts.map +1 -0
  10. package/dist/baselines/atomizer/atomLcs.js +347 -0
  11. package/dist/baselines/atomizer/atomLcs.js.map +1 -0
  12. package/dist/baselines/atomizer/debug.d.ts +41 -0
  13. package/dist/baselines/atomizer/debug.d.ts.map +1 -0
  14. package/dist/baselines/atomizer/debug.js +85 -0
  15. package/dist/baselines/atomizer/debug.js.map +1 -0
  16. package/dist/baselines/atomizer/documentReconstructor.d.ts +64 -0
  17. package/dist/baselines/atomizer/documentReconstructor.d.ts.map +1 -0
  18. package/dist/baselines/atomizer/documentReconstructor.js +939 -0
  19. package/dist/baselines/atomizer/documentReconstructor.js.map +1 -0
  20. package/dist/baselines/atomizer/hierarchicalLcs.d.ts +111 -0
  21. package/dist/baselines/atomizer/hierarchicalLcs.d.ts.map +1 -0
  22. package/dist/baselines/atomizer/hierarchicalLcs.js +469 -0
  23. package/dist/baselines/atomizer/hierarchicalLcs.js.map +1 -0
  24. package/dist/baselines/atomizer/inPlaceModifier.d.ts +183 -0
  25. package/dist/baselines/atomizer/inPlaceModifier.d.ts.map +1 -0
  26. package/dist/baselines/atomizer/inPlaceModifier.js +1600 -0
  27. package/dist/baselines/atomizer/inPlaceModifier.js.map +1 -0
  28. package/dist/baselines/atomizer/numberingIntegration.d.ts +59 -0
  29. package/dist/baselines/atomizer/numberingIntegration.d.ts.map +1 -0
  30. package/dist/baselines/atomizer/numberingIntegration.js +209 -0
  31. package/dist/baselines/atomizer/numberingIntegration.js.map +1 -0
  32. package/dist/baselines/atomizer/pipeline.d.ts +65 -0
  33. package/dist/baselines/atomizer/pipeline.d.ts.map +1 -0
  34. package/dist/baselines/atomizer/pipeline.js +510 -0
  35. package/dist/baselines/atomizer/pipeline.js.map +1 -0
  36. package/dist/baselines/atomizer/premergeRuns.d.ts +26 -0
  37. package/dist/baselines/atomizer/premergeRuns.d.ts.map +1 -0
  38. package/dist/baselines/atomizer/premergeRuns.js +150 -0
  39. package/dist/baselines/atomizer/premergeRuns.js.map +1 -0
  40. package/dist/baselines/atomizer/trackChangesAcceptor.d.ts +63 -0
  41. package/dist/baselines/atomizer/trackChangesAcceptor.d.ts.map +1 -0
  42. package/dist/baselines/atomizer/trackChangesAcceptor.js +254 -0
  43. package/dist/baselines/atomizer/trackChangesAcceptor.js.map +1 -0
  44. package/dist/baselines/atomizer/trackChangesAcceptorAst.d.ts +64 -0
  45. package/dist/baselines/atomizer/trackChangesAcceptorAst.d.ts.map +1 -0
  46. package/dist/baselines/atomizer/trackChangesAcceptorAst.js +586 -0
  47. package/dist/baselines/atomizer/trackChangesAcceptorAst.js.map +1 -0
  48. package/dist/baselines/atomizer/xmlToWmlElement.d.ts +65 -0
  49. package/dist/baselines/atomizer/xmlToWmlElement.d.ts.map +1 -0
  50. package/dist/baselines/atomizer/xmlToWmlElement.js +95 -0
  51. package/dist/baselines/atomizer/xmlToWmlElement.js.map +1 -0
  52. package/dist/baselines/diffmatch/documentBuilder.d.ts +44 -0
  53. package/dist/baselines/diffmatch/documentBuilder.d.ts.map +1 -0
  54. package/dist/baselines/diffmatch/documentBuilder.js +227 -0
  55. package/dist/baselines/diffmatch/documentBuilder.js.map +1 -0
  56. package/dist/baselines/diffmatch/paragraphAlignment.d.ts +75 -0
  57. package/dist/baselines/diffmatch/paragraphAlignment.d.ts.map +1 -0
  58. package/dist/baselines/diffmatch/paragraphAlignment.js +206 -0
  59. package/dist/baselines/diffmatch/paragraphAlignment.js.map +1 -0
  60. package/dist/baselines/diffmatch/pipeline.d.ts +33 -0
  61. package/dist/baselines/diffmatch/pipeline.d.ts.map +1 -0
  62. package/dist/baselines/diffmatch/pipeline.js +84 -0
  63. package/dist/baselines/diffmatch/pipeline.js.map +1 -0
  64. package/dist/baselines/diffmatch/runDiff.d.ts +53 -0
  65. package/dist/baselines/diffmatch/runDiff.d.ts.map +1 -0
  66. package/dist/baselines/diffmatch/runDiff.js +253 -0
  67. package/dist/baselines/diffmatch/runDiff.js.map +1 -0
  68. package/dist/baselines/diffmatch/trackChangesRenderer.d.ts +64 -0
  69. package/dist/baselines/diffmatch/trackChangesRenderer.d.ts.map +1 -0
  70. package/dist/baselines/diffmatch/trackChangesRenderer.js +178 -0
  71. package/dist/baselines/diffmatch/trackChangesRenderer.js.map +1 -0
  72. package/dist/baselines/diffmatch/xmlParser.d.ts +45 -0
  73. package/dist/baselines/diffmatch/xmlParser.d.ts.map +1 -0
  74. package/dist/baselines/diffmatch/xmlParser.js +344 -0
  75. package/dist/baselines/diffmatch/xmlParser.js.map +1 -0
  76. package/dist/baselines/wmlcomparer/DocxodusWasm.d.ts +51 -0
  77. package/dist/baselines/wmlcomparer/DocxodusWasm.d.ts.map +1 -0
  78. package/dist/baselines/wmlcomparer/DocxodusWasm.js +83 -0
  79. package/dist/baselines/wmlcomparer/DocxodusWasm.js.map +1 -0
  80. package/dist/baselines/wmlcomparer/DotnetCli.d.ts +40 -0
  81. package/dist/baselines/wmlcomparer/DotnetCli.d.ts.map +1 -0
  82. package/dist/baselines/wmlcomparer/DotnetCli.js +135 -0
  83. package/dist/baselines/wmlcomparer/DotnetCli.js.map +1 -0
  84. package/dist/benchmark/metrics.d.ts +72 -0
  85. package/dist/benchmark/metrics.d.ts.map +1 -0
  86. package/dist/benchmark/metrics.js +45 -0
  87. package/dist/benchmark/metrics.js.map +1 -0
  88. package/dist/benchmark/reporter.d.ts +23 -0
  89. package/dist/benchmark/reporter.d.ts.map +1 -0
  90. package/dist/benchmark/reporter.js +147 -0
  91. package/dist/benchmark/reporter.js.map +1 -0
  92. package/dist/benchmark/runner.d.ts +30 -0
  93. package/dist/benchmark/runner.d.ts.map +1 -0
  94. package/dist/benchmark/runner.js +233 -0
  95. package/dist/benchmark/runner.js.map +1 -0
  96. package/dist/cli/compare-two.d.ts +28 -0
  97. package/dist/cli/compare-two.d.ts.map +1 -0
  98. package/dist/cli/compare-two.js +110 -0
  99. package/dist/cli/compare-two.js.map +1 -0
  100. package/dist/cli/index.d.ts +3 -0
  101. package/dist/cli/index.d.ts.map +1 -0
  102. package/dist/cli/index.js +21 -0
  103. package/dist/cli/index.js.map +1 -0
  104. package/dist/core-types.d.ts +296 -0
  105. package/dist/core-types.d.ts.map +1 -0
  106. package/dist/core-types.js +122 -0
  107. package/dist/core-types.js.map +1 -0
  108. package/dist/footnotes.d.ts +144 -0
  109. package/dist/footnotes.d.ts.map +1 -0
  110. package/dist/footnotes.js +291 -0
  111. package/dist/footnotes.js.map +1 -0
  112. package/dist/format-detection.d.ts +120 -0
  113. package/dist/format-detection.d.ts.map +1 -0
  114. package/dist/format-detection.js +338 -0
  115. package/dist/format-detection.js.map +1 -0
  116. package/dist/index.d.ts +177 -0
  117. package/dist/index.d.ts.map +1 -0
  118. package/dist/index.js +55 -0
  119. package/dist/index.js.map +1 -0
  120. package/dist/integration/output-artifacts.d.ts +6 -0
  121. package/dist/integration/output-artifacts.d.ts.map +1 -0
  122. package/dist/integration/output-artifacts.js +30 -0
  123. package/dist/integration/output-artifacts.js.map +1 -0
  124. package/dist/move-detection.d.ts +211 -0
  125. package/dist/move-detection.d.ts.map +1 -0
  126. package/dist/move-detection.js +391 -0
  127. package/dist/move-detection.js.map +1 -0
  128. package/dist/numbering.d.ts +136 -0
  129. package/dist/numbering.d.ts.map +1 -0
  130. package/dist/numbering.js +446 -0
  131. package/dist/numbering.js.map +1 -0
  132. package/dist/primitives/accept_changes.d.ts +30 -0
  133. package/dist/primitives/accept_changes.d.ts.map +1 -0
  134. package/dist/primitives/accept_changes.js +241 -0
  135. package/dist/primitives/accept_changes.js.map +1 -0
  136. package/dist/primitives/bookmarks.d.ts +12 -0
  137. package/dist/primitives/bookmarks.d.ts.map +1 -0
  138. package/dist/primitives/bookmarks.js +248 -0
  139. package/dist/primitives/bookmarks.js.map +1 -0
  140. package/dist/primitives/comments.d.ts +88 -0
  141. package/dist/primitives/comments.d.ts.map +1 -0
  142. package/dist/primitives/comments.js +703 -0
  143. package/dist/primitives/comments.js.map +1 -0
  144. package/dist/primitives/document.d.ts +168 -0
  145. package/dist/primitives/document.d.ts.map +1 -0
  146. package/dist/primitives/document.js +532 -0
  147. package/dist/primitives/document.js.map +1 -0
  148. package/dist/primitives/document_view.d.ts +93 -0
  149. package/dist/primitives/document_view.d.ts.map +1 -0
  150. package/dist/primitives/document_view.js +722 -0
  151. package/dist/primitives/document_view.js.map +1 -0
  152. package/dist/primitives/dom-helpers.d.ts +94 -0
  153. package/dist/primitives/dom-helpers.d.ts.map +1 -0
  154. package/dist/primitives/dom-helpers.js +219 -0
  155. package/dist/primitives/dom-helpers.js.map +1 -0
  156. package/dist/primitives/errors.d.ts +7 -0
  157. package/dist/primitives/errors.d.ts.map +1 -0
  158. package/dist/primitives/errors.js +10 -0
  159. package/dist/primitives/errors.js.map +1 -0
  160. package/dist/primitives/extract_revisions.d.ts +50 -0
  161. package/dist/primitives/extract_revisions.d.ts.map +1 -0
  162. package/dist/primitives/extract_revisions.js +340 -0
  163. package/dist/primitives/extract_revisions.js.map +1 -0
  164. package/dist/primitives/footnotes.d.ts +37 -0
  165. package/dist/primitives/footnotes.d.ts.map +1 -0
  166. package/dist/primitives/footnotes.js +552 -0
  167. package/dist/primitives/footnotes.js.map +1 -0
  168. package/dist/primitives/formatting_tags.d.ts +30 -0
  169. package/dist/primitives/formatting_tags.d.ts.map +1 -0
  170. package/dist/primitives/formatting_tags.js +217 -0
  171. package/dist/primitives/formatting_tags.js.map +1 -0
  172. package/dist/primitives/index.d.ts +26 -0
  173. package/dist/primitives/index.d.ts.map +1 -0
  174. package/dist/primitives/index.js +26 -0
  175. package/dist/primitives/index.js.map +1 -0
  176. package/dist/primitives/layout.d.ts +53 -0
  177. package/dist/primitives/layout.d.ts.map +1 -0
  178. package/dist/primitives/layout.js +178 -0
  179. package/dist/primitives/layout.js.map +1 -0
  180. package/dist/primitives/list_labels.d.ts +19 -0
  181. package/dist/primitives/list_labels.d.ts.map +1 -0
  182. package/dist/primitives/list_labels.js +57 -0
  183. package/dist/primitives/list_labels.js.map +1 -0
  184. package/dist/primitives/matching.d.ts +17 -0
  185. package/dist/primitives/matching.d.ts.map +1 -0
  186. package/dist/primitives/matching.js +144 -0
  187. package/dist/primitives/matching.js.map +1 -0
  188. package/dist/primitives/merge_runs.d.ts +23 -0
  189. package/dist/primitives/merge_runs.d.ts.map +1 -0
  190. package/dist/primitives/merge_runs.js +195 -0
  191. package/dist/primitives/merge_runs.js.map +1 -0
  192. package/dist/primitives/namespaces.d.ts +90 -0
  193. package/dist/primitives/namespaces.d.ts.map +1 -0
  194. package/dist/primitives/namespaces.js +107 -0
  195. package/dist/primitives/namespaces.js.map +1 -0
  196. package/dist/primitives/numbering.d.ts +27 -0
  197. package/dist/primitives/numbering.d.ts.map +1 -0
  198. package/dist/primitives/numbering.js +182 -0
  199. package/dist/primitives/numbering.js.map +1 -0
  200. package/dist/primitives/prevent_double_elevation.d.ts +18 -0
  201. package/dist/primitives/prevent_double_elevation.d.ts.map +1 -0
  202. package/dist/primitives/prevent_double_elevation.js +190 -0
  203. package/dist/primitives/prevent_double_elevation.js.map +1 -0
  204. package/dist/primitives/reject_changes.d.ts +27 -0
  205. package/dist/primitives/reject_changes.d.ts.map +1 -0
  206. package/dist/primitives/reject_changes.js +371 -0
  207. package/dist/primitives/reject_changes.js.map +1 -0
  208. package/dist/primitives/relationships.d.ts +7 -0
  209. package/dist/primitives/relationships.d.ts.map +1 -0
  210. package/dist/primitives/relationships.js +24 -0
  211. package/dist/primitives/relationships.js.map +1 -0
  212. package/dist/primitives/semantic_tags.d.ts +32 -0
  213. package/dist/primitives/semantic_tags.d.ts.map +1 -0
  214. package/dist/primitives/semantic_tags.js +139 -0
  215. package/dist/primitives/semantic_tags.js.map +1 -0
  216. package/dist/primitives/simplify_redlines.d.ts +19 -0
  217. package/dist/primitives/simplify_redlines.d.ts.map +1 -0
  218. package/dist/primitives/simplify_redlines.js +94 -0
  219. package/dist/primitives/simplify_redlines.js.map +1 -0
  220. package/dist/primitives/styles.d.ts +36 -0
  221. package/dist/primitives/styles.d.ts.map +1 -0
  222. package/dist/primitives/styles.js +190 -0
  223. package/dist/primitives/styles.js.map +1 -0
  224. package/dist/primitives/text.d.ts +27 -0
  225. package/dist/primitives/text.d.ts.map +1 -0
  226. package/dist/primitives/text.js +416 -0
  227. package/dist/primitives/text.js.map +1 -0
  228. package/dist/primitives/validate_document.d.ts +24 -0
  229. package/dist/primitives/validate_document.d.ts.map +1 -0
  230. package/dist/primitives/validate_document.js +147 -0
  231. package/dist/primitives/validate_document.js.map +1 -0
  232. package/dist/primitives/xml.d.ts +5 -0
  233. package/dist/primitives/xml.d.ts.map +1 -0
  234. package/dist/primitives/xml.js +19 -0
  235. package/dist/primitives/xml.js.map +1 -0
  236. package/dist/primitives/zip.d.ts +25 -0
  237. package/dist/primitives/zip.d.ts.map +1 -0
  238. package/dist/primitives/zip.js +78 -0
  239. package/dist/primitives/zip.js.map +1 -0
  240. package/dist/shared/docx/DocxArchive.d.ts +94 -0
  241. package/dist/shared/docx/DocxArchive.d.ts.map +1 -0
  242. package/dist/shared/docx/DocxArchive.js +169 -0
  243. package/dist/shared/docx/DocxArchive.js.map +1 -0
  244. package/dist/shared/ooxml/namespaces.d.ts +149 -0
  245. package/dist/shared/ooxml/namespaces.d.ts.map +1 -0
  246. package/dist/shared/ooxml/namespaces.js +224 -0
  247. package/dist/shared/ooxml/namespaces.js.map +1 -0
  248. package/dist/shared/ooxml/types.d.ts +136 -0
  249. package/dist/shared/ooxml/types.d.ts.map +1 -0
  250. package/dist/shared/ooxml/types.js +7 -0
  251. package/dist/shared/ooxml/types.js.map +1 -0
  252. 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"}