docxmlater 10.4.1 → 11.0.6

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 (699) hide show
  1. package/README.md +411 -638
  2. package/dist/constants/legacyCompatFlags.d.ts +1 -1
  3. package/dist/constants/legacyCompatFlags.d.ts.map +1 -1
  4. package/dist/constants/legacyCompatFlags.js.map +1 -1
  5. package/dist/core/Document.d.ts +74 -67
  6. package/dist/core/Document.d.ts.map +1 -1
  7. package/dist/core/Document.js +605 -414
  8. package/dist/core/Document.js.map +1 -1
  9. package/dist/core/DocumentContent.d.ts +11 -10
  10. package/dist/core/DocumentContent.d.ts.map +1 -1
  11. package/dist/core/DocumentContent.js +19 -19
  12. package/dist/core/DocumentContent.js.map +1 -1
  13. package/dist/core/DocumentEvents.d.ts +39 -0
  14. package/dist/core/DocumentEvents.d.ts.map +1 -0
  15. package/dist/core/DocumentEvents.js +51 -0
  16. package/dist/core/DocumentEvents.js.map +1 -0
  17. package/dist/core/DocumentGenerator.d.ts +11 -11
  18. package/dist/core/DocumentGenerator.d.ts.map +1 -1
  19. package/dist/core/DocumentGenerator.js +72 -52
  20. package/dist/core/DocumentGenerator.js.map +1 -1
  21. package/dist/core/DocumentParser.d.ts +15 -15
  22. package/dist/core/DocumentParser.d.ts.map +1 -1
  23. package/dist/core/DocumentParser.js +2059 -1073
  24. package/dist/core/DocumentParser.js.map +1 -1
  25. package/dist/core/DocumentValidator.d.ts +3 -3
  26. package/dist/core/DocumentValidator.d.ts.map +1 -1
  27. package/dist/core/DocumentValidator.js +31 -31
  28. package/dist/core/DocumentValidator.js.map +1 -1
  29. package/dist/core/ElementRegistry.d.ts +22 -0
  30. package/dist/core/ElementRegistry.d.ts.map +1 -0
  31. package/dist/core/ElementRegistry.js +27 -0
  32. package/dist/core/ElementRegistry.js.map +1 -0
  33. package/dist/core/Relationship.js +4 -4
  34. package/dist/core/Relationship.js.map +1 -1
  35. package/dist/core/RelationshipManager.d.ts +1 -1
  36. package/dist/core/RelationshipManager.d.ts.map +1 -1
  37. package/dist/core/RelationshipManager.js +32 -32
  38. package/dist/core/RelationshipManager.js.map +1 -1
  39. package/dist/elements/AlternateContent.d.ts +1 -1
  40. package/dist/elements/AlternateContent.d.ts.map +1 -1
  41. package/dist/elements/AlternateContent.js.map +1 -1
  42. package/dist/elements/Bookmark.d.ts +6 -1
  43. package/dist/elements/Bookmark.d.ts.map +1 -1
  44. package/dist/elements/Bookmark.js +19 -3
  45. package/dist/elements/Bookmark.js.map +1 -1
  46. package/dist/elements/BookmarkManager.d.ts +1 -1
  47. package/dist/elements/BookmarkManager.d.ts.map +1 -1
  48. package/dist/elements/BookmarkManager.js +7 -7
  49. package/dist/elements/BookmarkManager.js.map +1 -1
  50. package/dist/elements/Comment.d.ts +2 -2
  51. package/dist/elements/Comment.d.ts.map +1 -1
  52. package/dist/elements/Comment.js +4 -4
  53. package/dist/elements/Comment.js.map +1 -1
  54. package/dist/elements/CommentManager.d.ts +2 -2
  55. package/dist/elements/CommentManager.d.ts.map +1 -1
  56. package/dist/elements/CommentManager.js +9 -9
  57. package/dist/elements/CommentManager.js.map +1 -1
  58. package/dist/elements/CommonTypes.d.ts +9 -4
  59. package/dist/elements/CommonTypes.d.ts.map +1 -1
  60. package/dist/elements/CommonTypes.js +1 -0
  61. package/dist/elements/CommonTypes.js.map +1 -1
  62. package/dist/elements/CustomXml.d.ts +1 -1
  63. package/dist/elements/CustomXml.d.ts.map +1 -1
  64. package/dist/elements/CustomXml.js.map +1 -1
  65. package/dist/elements/Endnote.d.ts +2 -2
  66. package/dist/elements/Endnote.d.ts.map +1 -1
  67. package/dist/elements/Endnote.js +9 -9
  68. package/dist/elements/Endnote.js.map +1 -1
  69. package/dist/elements/EndnoteManager.d.ts +1 -1
  70. package/dist/elements/EndnoteManager.d.ts.map +1 -1
  71. package/dist/elements/EndnoteManager.js +11 -11
  72. package/dist/elements/EndnoteManager.js.map +1 -1
  73. package/dist/elements/Field.d.ts +9 -5
  74. package/dist/elements/Field.d.ts.map +1 -1
  75. package/dist/elements/Field.js +21 -9
  76. package/dist/elements/Field.js.map +1 -1
  77. package/dist/elements/FieldHelpers.d.ts +1 -1
  78. package/dist/elements/FieldHelpers.d.ts.map +1 -1
  79. package/dist/elements/FieldHelpers.js +10 -10
  80. package/dist/elements/FieldHelpers.js.map +1 -1
  81. package/dist/elements/Footer.d.ts +3 -3
  82. package/dist/elements/Footer.d.ts.map +1 -1
  83. package/dist/elements/Footer.js +5 -5
  84. package/dist/elements/Footer.js.map +1 -1
  85. package/dist/elements/Footnote.d.ts +2 -2
  86. package/dist/elements/Footnote.d.ts.map +1 -1
  87. package/dist/elements/Footnote.js +9 -9
  88. package/dist/elements/Footnote.js.map +1 -1
  89. package/dist/elements/FootnoteManager.d.ts +1 -1
  90. package/dist/elements/FootnoteManager.d.ts.map +1 -1
  91. package/dist/elements/FootnoteManager.js +11 -11
  92. package/dist/elements/FootnoteManager.js.map +1 -1
  93. package/dist/elements/Header.d.ts +3 -3
  94. package/dist/elements/Header.d.ts.map +1 -1
  95. package/dist/elements/Header.js +5 -5
  96. package/dist/elements/Header.js.map +1 -1
  97. package/dist/elements/HeaderFooterManager.d.ts +2 -2
  98. package/dist/elements/HeaderFooterManager.d.ts.map +1 -1
  99. package/dist/elements/HeaderFooterManager.js.map +1 -1
  100. package/dist/elements/Hyperlink.d.ts +5 -5
  101. package/dist/elements/Hyperlink.d.ts.map +1 -1
  102. package/dist/elements/Hyperlink.js +29 -29
  103. package/dist/elements/Hyperlink.js.map +1 -1
  104. package/dist/elements/Image.d.ts +1 -1
  105. package/dist/elements/Image.d.ts.map +1 -1
  106. package/dist/elements/Image.js +67 -67
  107. package/dist/elements/Image.js.map +1 -1
  108. package/dist/elements/ImageManager.d.ts +1 -1
  109. package/dist/elements/ImageManager.d.ts.map +1 -1
  110. package/dist/elements/ImageManager.js +4 -4
  111. package/dist/elements/ImageManager.js.map +1 -1
  112. package/dist/elements/ImageRun.d.ts +3 -3
  113. package/dist/elements/ImageRun.d.ts.map +1 -1
  114. package/dist/elements/ImageRun.js +8 -3
  115. package/dist/elements/ImageRun.js.map +1 -1
  116. package/dist/elements/MathElement.d.ts +1 -1
  117. package/dist/elements/MathElement.d.ts.map +1 -1
  118. package/dist/elements/MathElement.js.map +1 -1
  119. package/dist/elements/Paragraph.d.ts +34 -19
  120. package/dist/elements/Paragraph.d.ts.map +1 -1
  121. package/dist/elements/Paragraph.js +286 -231
  122. package/dist/elements/Paragraph.js.map +1 -1
  123. package/dist/elements/PreservedElement.d.ts +1 -1
  124. package/dist/elements/PreservedElement.d.ts.map +1 -1
  125. package/dist/elements/PreservedElement.js.map +1 -1
  126. package/dist/elements/PropertyChangeTypes.d.ts +2 -2
  127. package/dist/elements/PropertyChangeTypes.d.ts.map +1 -1
  128. package/dist/elements/PropertyChangeTypes.js.map +1 -1
  129. package/dist/elements/RangeMarker.d.ts +14 -1
  130. package/dist/elements/RangeMarker.d.ts.map +1 -1
  131. package/dist/elements/RangeMarker.js +46 -8
  132. package/dist/elements/RangeMarker.js.map +1 -1
  133. package/dist/elements/RegisteredBodyElement.d.ts +15 -0
  134. package/dist/elements/RegisteredBodyElement.d.ts.map +1 -0
  135. package/dist/elements/RegisteredBodyElement.js +44 -0
  136. package/dist/elements/RegisteredBodyElement.js.map +1 -0
  137. package/dist/elements/Revision.d.ts +8 -8
  138. package/dist/elements/Revision.d.ts.map +1 -1
  139. package/dist/elements/Revision.js +12 -12
  140. package/dist/elements/Revision.js.map +1 -1
  141. package/dist/elements/RevisionContent.d.ts +3 -3
  142. package/dist/elements/RevisionContent.d.ts.map +1 -1
  143. package/dist/elements/RevisionContent.js.map +1 -1
  144. package/dist/elements/RevisionManager.d.ts +2 -2
  145. package/dist/elements/RevisionManager.d.ts.map +1 -1
  146. package/dist/elements/RevisionManager.js +2 -2
  147. package/dist/elements/RevisionManager.js.map +1 -1
  148. package/dist/elements/Run.d.ts +16 -10
  149. package/dist/elements/Run.d.ts.map +1 -1
  150. package/dist/elements/Run.js +199 -173
  151. package/dist/elements/Run.js.map +1 -1
  152. package/dist/elements/Section.d.ts +4 -2
  153. package/dist/elements/Section.d.ts.map +1 -1
  154. package/dist/elements/Section.js +152 -145
  155. package/dist/elements/Section.js.map +1 -1
  156. package/dist/elements/Shape.d.ts +3 -3
  157. package/dist/elements/Shape.d.ts.map +1 -1
  158. package/dist/elements/Shape.js +12 -12
  159. package/dist/elements/Shape.js.map +1 -1
  160. package/dist/elements/StructuredDocumentTag.d.ts +3 -3
  161. package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
  162. package/dist/elements/StructuredDocumentTag.js +39 -39
  163. package/dist/elements/StructuredDocumentTag.js.map +1 -1
  164. package/dist/elements/Table.d.ts +16 -10
  165. package/dist/elements/Table.d.ts.map +1 -1
  166. package/dist/elements/Table.js +118 -89
  167. package/dist/elements/Table.js.map +1 -1
  168. package/dist/elements/TableCell.d.ts +11 -11
  169. package/dist/elements/TableCell.d.ts.map +1 -1
  170. package/dist/elements/TableCell.js +108 -78
  171. package/dist/elements/TableCell.js.map +1 -1
  172. package/dist/elements/TableGridChange.d.ts +1 -1
  173. package/dist/elements/TableGridChange.d.ts.map +1 -1
  174. package/dist/elements/TableGridChange.js +3 -3
  175. package/dist/elements/TableGridChange.js.map +1 -1
  176. package/dist/elements/TableOfContents.d.ts +1 -1
  177. package/dist/elements/TableOfContents.d.ts.map +1 -1
  178. package/dist/elements/TableOfContents.js +2 -2
  179. package/dist/elements/TableOfContents.js.map +1 -1
  180. package/dist/elements/TableOfContentsElement.d.ts +2 -2
  181. package/dist/elements/TableOfContentsElement.d.ts.map +1 -1
  182. package/dist/elements/TableOfContentsElement.js +5 -5
  183. package/dist/elements/TableOfContentsElement.js.map +1 -1
  184. package/dist/elements/TableRow.d.ts +18 -7
  185. package/dist/elements/TableRow.d.ts.map +1 -1
  186. package/dist/elements/TableRow.js +127 -74
  187. package/dist/elements/TableRow.js.map +1 -1
  188. package/dist/elements/TextBox.d.ts +4 -4
  189. package/dist/elements/TextBox.d.ts.map +1 -1
  190. package/dist/elements/TextBox.js +6 -6
  191. package/dist/elements/TextBox.js.map +1 -1
  192. package/dist/esm/constants/legacyCompatFlags.js +97 -0
  193. package/dist/esm/constants/legacyCompatFlags.js.map +1 -0
  194. package/dist/esm/constants/limits.js +36 -0
  195. package/dist/esm/constants/limits.js.map +1 -0
  196. package/dist/esm/core/Document.js +8498 -0
  197. package/dist/esm/core/Document.js.map +1 -0
  198. package/dist/esm/core/DocumentContent.js +190 -0
  199. package/dist/esm/core/DocumentContent.js.map +1 -0
  200. package/dist/esm/core/DocumentEvents.js +47 -0
  201. package/dist/esm/core/DocumentEvents.js.map +1 -0
  202. package/dist/esm/core/DocumentGenerator.js +764 -0
  203. package/dist/esm/core/DocumentGenerator.js.map +1 -0
  204. package/dist/esm/core/DocumentIdManager.js +67 -0
  205. package/dist/esm/core/DocumentIdManager.js.map +1 -0
  206. package/dist/esm/core/DocumentParser.js +8763 -0
  207. package/dist/esm/core/DocumentParser.js.map +1 -0
  208. package/dist/esm/core/DocumentValidator.js +222 -0
  209. package/dist/esm/core/DocumentValidator.js.map +1 -0
  210. package/dist/esm/core/ElementRegistry.js +24 -0
  211. package/dist/esm/core/ElementRegistry.js.map +1 -0
  212. package/dist/esm/core/Relationship.js +177 -0
  213. package/dist/esm/core/Relationship.js.map +1 -0
  214. package/dist/esm/core/RelationshipManager.js +202 -0
  215. package/dist/esm/core/RelationshipManager.js.map +1 -0
  216. package/dist/esm/elements/AlternateContent.js +19 -0
  217. package/dist/esm/elements/AlternateContent.js.map +1 -0
  218. package/dist/esm/elements/Bookmark.js +115 -0
  219. package/dist/esm/elements/Bookmark.js.map +1 -0
  220. package/dist/esm/elements/BookmarkManager.js +99 -0
  221. package/dist/esm/elements/BookmarkManager.js.map +1 -0
  222. package/dist/esm/elements/Comment.js +181 -0
  223. package/dist/esm/elements/Comment.js.map +1 -0
  224. package/dist/esm/elements/CommentManager.js +233 -0
  225. package/dist/esm/elements/CommentManager.js.map +1 -0
  226. package/dist/esm/elements/CommonTypes.js +106 -0
  227. package/dist/esm/elements/CommonTypes.js.map +1 -0
  228. package/dist/esm/elements/CustomXml.js +19 -0
  229. package/dist/esm/elements/CustomXml.js.map +1 -0
  230. package/dist/esm/elements/Endnote.js +107 -0
  231. package/dist/esm/elements/Endnote.js.map +1 -0
  232. package/dist/esm/elements/EndnoteManager.js +119 -0
  233. package/dist/esm/elements/EndnoteManager.js.map +1 -0
  234. package/dist/esm/elements/Field.js +856 -0
  235. package/dist/esm/elements/Field.js.map +1 -0
  236. package/dist/esm/elements/FieldHelpers.js +134 -0
  237. package/dist/esm/elements/FieldHelpers.js.map +1 -0
  238. package/dist/esm/elements/FontManager.js +158 -0
  239. package/dist/esm/elements/FontManager.js.map +1 -0
  240. package/dist/esm/elements/Footer.js +141 -0
  241. package/dist/esm/elements/Footer.js.map +1 -0
  242. package/dist/esm/elements/Footnote.js +107 -0
  243. package/dist/esm/elements/Footnote.js.map +1 -0
  244. package/dist/esm/elements/FootnoteManager.js +119 -0
  245. package/dist/esm/elements/FootnoteManager.js.map +1 -0
  246. package/dist/esm/elements/Header.js +141 -0
  247. package/dist/esm/elements/Header.js.map +1 -0
  248. package/dist/esm/elements/HeaderFooterManager.js +87 -0
  249. package/dist/esm/elements/HeaderFooterManager.js.map +1 -0
  250. package/dist/esm/elements/Hyperlink.js +586 -0
  251. package/dist/esm/elements/Hyperlink.js.map +1 -0
  252. package/dist/esm/elements/Image.js +1288 -0
  253. package/dist/esm/elements/Image.js.map +1 -0
  254. package/dist/esm/elements/ImageManager.js +223 -0
  255. package/dist/esm/elements/ImageManager.js.map +1 -0
  256. package/dist/esm/elements/ImageRun.js +34 -0
  257. package/dist/esm/elements/ImageRun.js.map +1 -0
  258. package/dist/esm/elements/MathElement.js +37 -0
  259. package/dist/esm/elements/MathElement.js.map +1 -0
  260. package/dist/esm/elements/Paragraph.js +2308 -0
  261. package/dist/esm/elements/Paragraph.js.map +1 -0
  262. package/dist/esm/elements/PreservedElement.js +29 -0
  263. package/dist/esm/elements/PreservedElement.js.map +1 -0
  264. package/dist/esm/elements/PropertyChangeTypes.js +53 -0
  265. package/dist/esm/elements/PropertyChangeTypes.js.map +1 -0
  266. package/dist/esm/elements/RangeMarker.js +219 -0
  267. package/dist/esm/elements/RangeMarker.js.map +1 -0
  268. package/dist/esm/elements/RegisteredBodyElement.js +40 -0
  269. package/dist/esm/elements/RegisteredBodyElement.js.map +1 -0
  270. package/dist/esm/elements/Revision.js +498 -0
  271. package/dist/esm/elements/Revision.js.map +1 -0
  272. package/dist/esm/elements/RevisionContent.js +18 -0
  273. package/dist/esm/elements/RevisionContent.js.map +1 -0
  274. package/dist/esm/elements/RevisionManager.js +486 -0
  275. package/dist/esm/elements/RevisionManager.js.map +1 -0
  276. package/dist/esm/elements/Run.js +1465 -0
  277. package/dist/esm/elements/Run.js.map +1 -0
  278. package/dist/esm/elements/Section.js +978 -0
  279. package/dist/esm/elements/Section.js.map +1 -0
  280. package/dist/esm/elements/Shape.js +493 -0
  281. package/dist/esm/elements/Shape.js.map +1 -0
  282. package/dist/esm/elements/StructuredDocumentTag.js +471 -0
  283. package/dist/esm/elements/StructuredDocumentTag.js.map +1 -0
  284. package/dist/esm/elements/Table.js +1456 -0
  285. package/dist/esm/elements/Table.js.map +1 -0
  286. package/dist/esm/elements/TableCell.js +835 -0
  287. package/dist/esm/elements/TableCell.js.map +1 -0
  288. package/dist/esm/elements/TableGridChange.js +52 -0
  289. package/dist/esm/elements/TableGridChange.js.map +1 -0
  290. package/dist/esm/elements/TableOfContents.js +389 -0
  291. package/dist/esm/elements/TableOfContents.js.map +1 -0
  292. package/dist/esm/elements/TableOfContentsElement.js +29 -0
  293. package/dist/esm/elements/TableOfContentsElement.js.map +1 -0
  294. package/dist/esm/elements/TableRow.js +555 -0
  295. package/dist/esm/elements/TableRow.js.map +1 -0
  296. package/dist/esm/elements/TextBox.js +459 -0
  297. package/dist/esm/elements/TextBox.js.map +1 -0
  298. package/dist/esm/formatting/AbstractNumbering.js +325 -0
  299. package/dist/esm/formatting/AbstractNumbering.js.map +1 -0
  300. package/dist/esm/formatting/NumberingInstance.js +150 -0
  301. package/dist/esm/formatting/NumberingInstance.js.map +1 -0
  302. package/dist/esm/formatting/NumberingLevel.js +608 -0
  303. package/dist/esm/formatting/NumberingLevel.js.map +1 -0
  304. package/dist/esm/formatting/NumberingManager.js +423 -0
  305. package/dist/esm/formatting/NumberingManager.js.map +1 -0
  306. package/dist/esm/formatting/Style.js +1151 -0
  307. package/dist/esm/formatting/Style.js.map +1 -0
  308. package/dist/esm/formatting/StylesManager.js +557 -0
  309. package/dist/esm/formatting/StylesManager.js.map +1 -0
  310. package/dist/esm/helpers/CleanupHelper.js +350 -0
  311. package/dist/esm/helpers/CleanupHelper.js.map +1 -0
  312. package/dist/esm/images/ImageOptimizer.js +161 -0
  313. package/dist/esm/images/ImageOptimizer.js.map +1 -0
  314. package/dist/esm/index.js +75 -0
  315. package/dist/esm/index.js.map +1 -0
  316. package/dist/esm/internal.js +16 -0
  317. package/dist/esm/internal.js.map +1 -0
  318. package/dist/esm/managers/DrawingManager.js +163 -0
  319. package/dist/esm/managers/DrawingManager.js.map +1 -0
  320. package/dist/esm/package.json +3 -0
  321. package/dist/esm/processors/ChangelogGenerator.js +970 -0
  322. package/dist/esm/processors/ChangelogGenerator.js.map +1 -0
  323. package/dist/esm/processors/CompatibilityUpgrader.js +130 -0
  324. package/dist/esm/processors/CompatibilityUpgrader.js.map +1 -0
  325. package/dist/esm/processors/InMemoryRevisionAcceptor.js +530 -0
  326. package/dist/esm/processors/InMemoryRevisionAcceptor.js.map +1 -0
  327. package/dist/esm/processors/MoveOperationHelper.js +57 -0
  328. package/dist/esm/processors/MoveOperationHelper.js.map +1 -0
  329. package/dist/esm/processors/RevisionAwareProcessor.js +232 -0
  330. package/dist/esm/processors/RevisionAwareProcessor.js.map +1 -0
  331. package/dist/esm/processors/RevisionWalker.js +278 -0
  332. package/dist/esm/processors/RevisionWalker.js.map +1 -0
  333. package/dist/{utils → esm/processors}/SelectiveRevisionAcceptor.js +81 -42
  334. package/dist/esm/processors/SelectiveRevisionAcceptor.js.map +1 -0
  335. package/dist/esm/processors/ShadingResolver.js +66 -0
  336. package/dist/esm/processors/ShadingResolver.js.map +1 -0
  337. package/dist/esm/processors/acceptRevisions.js +416 -0
  338. package/dist/esm/processors/acceptRevisions.js.map +1 -0
  339. package/dist/esm/processors/cnfStyleDecoder.js +89 -0
  340. package/dist/esm/processors/cnfStyleDecoder.js.map +1 -0
  341. package/dist/esm/processors/stripTrackedChanges.js +201 -0
  342. package/dist/esm/processors/stripTrackedChanges.js.map +1 -0
  343. package/dist/esm/tracking/DocumentTrackingContext.js +531 -0
  344. package/dist/esm/tracking/DocumentTrackingContext.js.map +1 -0
  345. package/dist/esm/tracking/TrackingContext.js +2 -0
  346. package/dist/esm/tracking/TrackingContext.js.map +1 -0
  347. package/dist/esm/types/compatibility-types.js +8 -0
  348. package/dist/esm/types/compatibility-types.js.map +1 -0
  349. package/dist/esm/types/document-types.js +2 -0
  350. package/dist/esm/types/document-types.js.map +1 -0
  351. package/dist/esm/types/formatting.js +2 -0
  352. package/dist/esm/types/formatting.js.map +1 -0
  353. package/dist/esm/types/list-types.js +2 -0
  354. package/dist/esm/types/list-types.js.map +1 -0
  355. package/dist/esm/types/settings-types.js +2 -0
  356. package/dist/esm/types/settings-types.js.map +1 -0
  357. package/dist/esm/types/styleConfig.js +2 -0
  358. package/dist/esm/types/styleConfig.js.map +1 -0
  359. package/dist/esm/utils/KeyedRegistry.js +32 -0
  360. package/dist/esm/utils/KeyedRegistry.js.map +1 -0
  361. package/dist/esm/utils/corruptionDetection.js +155 -0
  362. package/dist/esm/utils/corruptionDetection.js.map +1 -0
  363. package/dist/esm/utils/dateFormatting.js +4 -0
  364. package/dist/esm/utils/dateFormatting.js.map +1 -0
  365. package/dist/esm/utils/deepClone.js +40 -0
  366. package/dist/esm/utils/deepClone.js.map +1 -0
  367. package/dist/esm/utils/deepEqual.js +47 -0
  368. package/dist/esm/utils/deepEqual.js.map +1 -0
  369. package/dist/esm/utils/diagnostics.js +69 -0
  370. package/dist/esm/utils/diagnostics.js.map +1 -0
  371. package/dist/esm/utils/errorHandling.js +36 -0
  372. package/dist/esm/utils/errorHandling.js.map +1 -0
  373. package/dist/esm/utils/formatting.js +93 -0
  374. package/dist/esm/utils/formatting.js.map +1 -0
  375. package/dist/esm/utils/list-detection.js +148 -0
  376. package/dist/esm/utils/list-detection.js.map +1 -0
  377. package/dist/esm/utils/logger.js +205 -0
  378. package/dist/esm/utils/logger.js.map +1 -0
  379. package/dist/esm/utils/parsingHelpers.js +56 -0
  380. package/dist/esm/utils/parsingHelpers.js.map +1 -0
  381. package/dist/esm/utils/textDiff.js +42 -0
  382. package/dist/esm/utils/textDiff.js.map +1 -0
  383. package/dist/esm/utils/units.js +152 -0
  384. package/dist/esm/utils/units.js.map +1 -0
  385. package/dist/esm/utils/validation.js +285 -0
  386. package/dist/esm/utils/validation.js.map +1 -0
  387. package/dist/esm/utils/xmlSanitization.js +54 -0
  388. package/dist/esm/utils/xmlSanitization.js.map +1 -0
  389. package/dist/esm/validation/RevisionAutoFixer.js +340 -0
  390. package/dist/esm/validation/RevisionAutoFixer.js.map +1 -0
  391. package/dist/esm/validation/RevisionValidator.js +240 -0
  392. package/dist/esm/validation/RevisionValidator.js.map +1 -0
  393. package/dist/esm/validation/ValidationRuleRegistry.js +40 -0
  394. package/dist/esm/validation/ValidationRuleRegistry.js.map +1 -0
  395. package/dist/esm/validation/ValidationRules.js +92 -0
  396. package/dist/esm/validation/ValidationRules.js.map +1 -0
  397. package/dist/esm/validation/index.js +4 -0
  398. package/dist/esm/validation/index.js.map +1 -0
  399. package/dist/esm/xml/XMLBuilder.js +434 -0
  400. package/dist/esm/xml/XMLBuilder.js.map +1 -0
  401. package/dist/esm/xml/XMLParser.js +486 -0
  402. package/dist/esm/xml/XMLParser.js.map +1 -0
  403. package/dist/esm/zip/ZipHandler.js +298 -0
  404. package/dist/esm/zip/ZipHandler.js.map +1 -0
  405. package/dist/esm/zip/ZipReader.js +147 -0
  406. package/dist/esm/zip/ZipReader.js.map +1 -0
  407. package/dist/esm/zip/ZipWriter.js +199 -0
  408. package/dist/esm/zip/ZipWriter.js.map +1 -0
  409. package/dist/esm/zip/errors.js +43 -0
  410. package/dist/esm/zip/errors.js.map +1 -0
  411. package/dist/esm/zip/types.js +31 -0
  412. package/dist/esm/zip/types.js.map +1 -0
  413. package/dist/formatting/AbstractNumbering.d.ts +2 -2
  414. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  415. package/dist/formatting/AbstractNumbering.js +33 -33
  416. package/dist/formatting/AbstractNumbering.js.map +1 -1
  417. package/dist/formatting/NumberingInstance.d.ts +2 -2
  418. package/dist/formatting/NumberingInstance.d.ts.map +1 -1
  419. package/dist/formatting/NumberingInstance.js +7 -7
  420. package/dist/formatting/NumberingInstance.js.map +1 -1
  421. package/dist/formatting/NumberingLevel.d.ts +11 -2
  422. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  423. package/dist/formatting/NumberingLevel.js +111 -25
  424. package/dist/formatting/NumberingLevel.js.map +1 -1
  425. package/dist/formatting/NumberingManager.d.ts +4 -4
  426. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  427. package/dist/formatting/NumberingManager.js +28 -28
  428. package/dist/formatting/NumberingManager.js.map +1 -1
  429. package/dist/formatting/Style.d.ts +14 -7
  430. package/dist/formatting/Style.d.ts.map +1 -1
  431. package/dist/formatting/Style.js +309 -112
  432. package/dist/formatting/Style.js.map +1 -1
  433. package/dist/formatting/StylesManager.d.ts +2 -2
  434. package/dist/formatting/StylesManager.d.ts.map +1 -1
  435. package/dist/formatting/StylesManager.js +52 -52
  436. package/dist/formatting/StylesManager.js.map +1 -1
  437. package/dist/helpers/CleanupHelper.d.ts +1 -1
  438. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  439. package/dist/helpers/CleanupHelper.js +15 -15
  440. package/dist/helpers/CleanupHelper.js.map +1 -1
  441. package/dist/index.d.ts +81 -90
  442. package/dist/index.d.ts.map +1 -1
  443. package/dist/index.js +286 -317
  444. package/dist/index.js.map +1 -1
  445. package/dist/internal.d.ts +16 -0
  446. package/dist/internal.d.ts.map +1 -0
  447. package/dist/internal.js +42 -0
  448. package/dist/internal.js.map +1 -0
  449. package/dist/managers/DrawingManager.d.ts +3 -3
  450. package/dist/managers/DrawingManager.d.ts.map +1 -1
  451. package/dist/managers/DrawingManager.js +12 -12
  452. package/dist/managers/DrawingManager.js.map +1 -1
  453. package/dist/{utils → processors}/ChangelogGenerator.d.ts +2 -2
  454. package/dist/processors/ChangelogGenerator.d.ts.map +1 -0
  455. package/dist/{utils → processors}/ChangelogGenerator.js +2 -2
  456. package/dist/processors/ChangelogGenerator.js.map +1 -0
  457. package/dist/processors/CompatibilityUpgrader.d.ts.map +1 -0
  458. package/dist/{utils → processors}/CompatibilityUpgrader.js +10 -10
  459. package/dist/processors/CompatibilityUpgrader.js.map +1 -0
  460. package/dist/{utils → processors}/InMemoryRevisionAcceptor.d.ts +3 -3
  461. package/dist/processors/InMemoryRevisionAcceptor.d.ts.map +1 -0
  462. package/dist/{utils → processors}/InMemoryRevisionAcceptor.js +84 -27
  463. package/dist/processors/InMemoryRevisionAcceptor.js.map +1 -0
  464. package/dist/{utils → processors}/MoveOperationHelper.d.ts +4 -4
  465. package/dist/processors/MoveOperationHelper.d.ts.map +1 -0
  466. package/dist/{utils → processors}/MoveOperationHelper.js +10 -10
  467. package/dist/processors/MoveOperationHelper.js.map +1 -0
  468. package/dist/{utils → processors}/RevisionAwareProcessor.d.ts +3 -3
  469. package/dist/processors/RevisionAwareProcessor.d.ts.map +1 -0
  470. package/dist/{utils → processors}/RevisionAwareProcessor.js +2 -2
  471. package/dist/processors/RevisionAwareProcessor.js.map +1 -0
  472. package/dist/{utils → processors}/RevisionWalker.d.ts +2 -1
  473. package/dist/processors/RevisionWalker.d.ts.map +1 -0
  474. package/dist/{utils → processors}/RevisionWalker.js +28 -0
  475. package/dist/processors/RevisionWalker.js.map +1 -0
  476. package/dist/{utils → processors}/SelectiveRevisionAcceptor.d.ts +4 -3
  477. package/dist/processors/SelectiveRevisionAcceptor.d.ts.map +1 -0
  478. package/dist/processors/SelectiveRevisionAcceptor.js +402 -0
  479. package/dist/processors/SelectiveRevisionAcceptor.js.map +1 -0
  480. package/dist/processors/ShadingResolver.d.ts +6 -0
  481. package/dist/processors/ShadingResolver.d.ts.map +1 -0
  482. package/dist/{utils → processors}/ShadingResolver.js +2 -2
  483. package/dist/processors/ShadingResolver.js.map +1 -0
  484. package/dist/{utils → processors}/acceptRevisions.d.ts +1 -1
  485. package/dist/processors/acceptRevisions.d.ts.map +1 -0
  486. package/dist/{utils → processors}/acceptRevisions.js +24 -4
  487. package/dist/processors/acceptRevisions.js.map +1 -0
  488. package/dist/{utils → processors}/cnfStyleDecoder.d.ts +1 -1
  489. package/dist/processors/cnfStyleDecoder.d.ts.map +1 -0
  490. package/dist/processors/cnfStyleDecoder.js.map +1 -0
  491. package/dist/processors/stripTrackedChanges.d.ts +3 -0
  492. package/dist/processors/stripTrackedChanges.d.ts.map +1 -0
  493. package/dist/{utils → processors}/stripTrackedChanges.js +16 -6
  494. package/dist/processors/stripTrackedChanges.js.map +1 -0
  495. package/dist/tracking/DocumentTrackingContext.d.ts +4 -4
  496. package/dist/tracking/DocumentTrackingContext.d.ts.map +1 -1
  497. package/dist/tracking/DocumentTrackingContext.js +38 -43
  498. package/dist/tracking/DocumentTrackingContext.js.map +1 -1
  499. package/dist/tracking/TrackingContext.d.ts +8 -8
  500. package/dist/tracking/TrackingContext.d.ts.map +1 -1
  501. package/dist/tracking/TrackingContext.js.map +1 -1
  502. package/dist/types/document-types.d.ts +28 -0
  503. package/dist/types/document-types.d.ts.map +1 -0
  504. package/dist/types/document-types.js +3 -0
  505. package/dist/types/document-types.js.map +1 -0
  506. package/dist/types/formatting.d.ts +4 -4
  507. package/dist/types/formatting.d.ts.map +1 -1
  508. package/dist/types/formatting.js.map +1 -1
  509. package/dist/types/settings-types.d.ts +6 -0
  510. package/dist/types/settings-types.d.ts.map +1 -1
  511. package/dist/types/settings-types.js.map +1 -1
  512. package/dist/utils/KeyedRegistry.d.ts +13 -0
  513. package/dist/utils/KeyedRegistry.d.ts.map +1 -0
  514. package/dist/utils/KeyedRegistry.js +36 -0
  515. package/dist/utils/KeyedRegistry.js.map +1 -0
  516. package/dist/utils/corruptionDetection.d.ts +1 -1
  517. package/dist/utils/corruptionDetection.d.ts.map +1 -1
  518. package/dist/utils/corruptionDetection.js +4 -4
  519. package/dist/utils/corruptionDetection.js.map +1 -1
  520. package/dist/utils/deepEqual.d.ts +2 -0
  521. package/dist/utils/deepEqual.d.ts.map +1 -0
  522. package/dist/utils/deepEqual.js +50 -0
  523. package/dist/utils/deepEqual.js.map +1 -0
  524. package/dist/utils/list-detection.d.ts +2 -2
  525. package/dist/utils/list-detection.d.ts.map +1 -1
  526. package/dist/utils/list-detection.js.map +1 -1
  527. package/dist/utils/parsingHelpers.d.ts +1 -1
  528. package/dist/utils/parsingHelpers.d.ts.map +1 -1
  529. package/dist/utils/parsingHelpers.js +2 -2
  530. package/dist/utils/parsingHelpers.js.map +1 -1
  531. package/dist/utils/validation.js +7 -7
  532. package/dist/utils/validation.js.map +1 -1
  533. package/dist/utils/xmlSanitization.js +2 -2
  534. package/dist/utils/xmlSanitization.js.map +1 -1
  535. package/dist/validation/RevisionAutoFixer.d.ts +4 -4
  536. package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
  537. package/dist/validation/RevisionAutoFixer.js +11 -11
  538. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  539. package/dist/validation/RevisionValidator.d.ts +5 -4
  540. package/dist/validation/RevisionValidator.d.ts.map +1 -1
  541. package/dist/validation/RevisionValidator.js +29 -30
  542. package/dist/validation/RevisionValidator.js.map +1 -1
  543. package/dist/validation/ValidationRuleRegistry.d.ts +27 -0
  544. package/dist/validation/ValidationRuleRegistry.d.ts.map +1 -0
  545. package/dist/validation/ValidationRuleRegistry.js +43 -0
  546. package/dist/validation/ValidationRuleRegistry.js.map +1 -0
  547. package/dist/validation/index.d.ts +3 -3
  548. package/dist/validation/index.d.ts.map +1 -1
  549. package/dist/validation/index.js +10 -10
  550. package/dist/validation/index.js.map +1 -1
  551. package/dist/xml/XMLBuilder.d.ts +6 -1
  552. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  553. package/dist/xml/XMLBuilder.js +11 -6
  554. package/dist/xml/XMLBuilder.js.map +1 -1
  555. package/dist/xml/XMLParser.js +6 -6
  556. package/dist/xml/XMLParser.js.map +1 -1
  557. package/dist/zip/ZipHandler.d.ts +1 -1
  558. package/dist/zip/ZipHandler.d.ts.map +1 -1
  559. package/dist/zip/ZipHandler.js +8 -8
  560. package/dist/zip/ZipHandler.js.map +1 -1
  561. package/dist/zip/ZipReader.d.ts +1 -1
  562. package/dist/zip/ZipReader.d.ts.map +1 -1
  563. package/dist/zip/ZipReader.js +14 -14
  564. package/dist/zip/ZipReader.js.map +1 -1
  565. package/dist/zip/ZipWriter.d.ts +1 -1
  566. package/dist/zip/ZipWriter.d.ts.map +1 -1
  567. package/dist/zip/ZipWriter.js +10 -10
  568. package/dist/zip/ZipWriter.js.map +1 -1
  569. package/package.json +35 -8
  570. package/src/constants/legacyCompatFlags.ts +1 -1
  571. package/src/core/Document.ts +461 -167
  572. package/src/core/DocumentContent.ts +14 -11
  573. package/src/core/DocumentEvents.ts +90 -0
  574. package/src/core/DocumentGenerator.ts +49 -22
  575. package/src/core/DocumentParser.ts +2187 -617
  576. package/src/core/DocumentValidator.ts +7 -7
  577. package/src/core/ElementRegistry.ts +69 -0
  578. package/src/core/Relationship.ts +1 -1
  579. package/src/core/RelationshipManager.ts +4 -4
  580. package/src/elements/AlternateContent.ts +1 -1
  581. package/src/elements/Bookmark.ts +52 -4
  582. package/src/elements/BookmarkManager.ts +2 -2
  583. package/src/elements/Comment.ts +3 -3
  584. package/src/elements/CommentManager.ts +4 -4
  585. package/src/elements/CommonTypes.ts +45 -7
  586. package/src/elements/CustomXml.ts +1 -1
  587. package/src/elements/Endnote.ts +2 -2
  588. package/src/elements/EndnoteManager.ts +3 -3
  589. package/src/elements/Field.ts +44 -10
  590. package/src/elements/FieldHelpers.ts +2 -2
  591. package/src/elements/Footer.ts +4 -4
  592. package/src/elements/Footnote.ts +2 -2
  593. package/src/elements/FootnoteManager.ts +3 -3
  594. package/src/elements/Header.ts +4 -4
  595. package/src/elements/HeaderFooterManager.ts +2 -2
  596. package/src/elements/Hyperlink.ts +16 -12
  597. package/src/elements/Image.ts +3 -3
  598. package/src/elements/ImageManager.ts +2 -2
  599. package/src/elements/ImageRun.ts +13 -4
  600. package/src/elements/MathElement.ts +1 -1
  601. package/src/elements/Paragraph.ts +221 -88
  602. package/src/elements/PreservedElement.ts +1 -1
  603. package/src/elements/PropertyChangeTypes.ts +2 -2
  604. package/src/elements/RangeMarker.ts +153 -12
  605. package/src/elements/RegisteredBodyElement.ts +52 -0
  606. package/src/elements/Revision.ts +14 -14
  607. package/src/elements/RevisionContent.ts +3 -3
  608. package/src/elements/RevisionManager.ts +3 -3
  609. package/src/elements/Run.ts +221 -94
  610. package/src/elements/Section.ts +136 -69
  611. package/src/elements/Shape.ts +4 -4
  612. package/src/elements/StructuredDocumentTag.ts +3 -3
  613. package/src/elements/Table.ts +91 -27
  614. package/src/elements/TableCell.ts +62 -34
  615. package/src/elements/TableGridChange.ts +1 -1
  616. package/src/elements/TableOfContents.ts +1 -1
  617. package/src/elements/TableOfContentsElement.ts +2 -2
  618. package/src/elements/TableRow.ts +192 -48
  619. package/src/elements/TextBox.ts +5 -5
  620. package/src/formatting/AbstractNumbering.ts +3 -3
  621. package/src/formatting/NumberingInstance.ts +2 -2
  622. package/src/formatting/NumberingLevel.ts +201 -10
  623. package/src/formatting/NumberingManager.ts +5 -5
  624. package/src/formatting/Style.ts +382 -86
  625. package/src/formatting/StylesManager.ts +4 -4
  626. package/src/helpers/CleanupHelper.ts +6 -6
  627. package/src/index.ts +118 -127
  628. package/src/internal.ts +79 -0
  629. package/src/managers/DrawingManager.ts +3 -3
  630. package/src/{utils → processors}/ChangelogGenerator.ts +3 -3
  631. package/src/{utils → processors}/CompatibilityUpgrader.ts +2 -2
  632. package/src/{utils → processors}/InMemoryRevisionAcceptor.ts +100 -12
  633. package/src/{utils → processors}/MoveOperationHelper.ts +5 -5
  634. package/src/{utils → processors}/RevisionAwareProcessor.ts +3 -3
  635. package/src/{utils → processors}/RevisionWalker.ts +42 -1
  636. package/src/{utils → processors}/SelectiveRevisionAcceptor.ts +98 -39
  637. package/src/{utils → processors}/ShadingResolver.ts +5 -5
  638. package/src/{utils → processors}/acceptRevisions.ts +77 -9
  639. package/src/{utils → processors}/cnfStyleDecoder.ts +1 -1
  640. package/src/{utils → processors}/stripTrackedChanges.ts +35 -10
  641. package/src/tracking/DocumentTrackingContext.ts +12 -14
  642. package/src/tracking/TrackingContext.ts +8 -8
  643. package/src/types/document-types.ts +53 -0
  644. package/src/types/formatting.ts +4 -4
  645. package/src/types/settings-types.ts +32 -0
  646. package/src/utils/KeyedRegistry.ts +41 -0
  647. package/src/utils/corruptionDetection.ts +2 -2
  648. package/src/utils/deepEqual.ts +58 -0
  649. package/src/utils/list-detection.ts +2 -2
  650. package/src/utils/parsingHelpers.ts +11 -3
  651. package/src/utils/validation.ts +3 -3
  652. package/src/utils/xmlSanitization.ts +1 -1
  653. package/src/validation/RevisionAutoFixer.ts +5 -5
  654. package/src/validation/RevisionValidator.ts +39 -28
  655. package/src/validation/ValidationRuleRegistry.ts +86 -0
  656. package/src/validation/index.ts +3 -3
  657. package/src/xml/XMLBuilder.ts +13 -3
  658. package/src/xml/XMLParser.ts +2 -2
  659. package/src/zip/ZipHandler.ts +4 -4
  660. package/src/zip/ZipReader.ts +3 -3
  661. package/src/zip/ZipWriter.ts +3 -3
  662. package/dist/utils/ChangelogGenerator.d.ts.map +0 -1
  663. package/dist/utils/ChangelogGenerator.js.map +0 -1
  664. package/dist/utils/CompatibilityUpgrader.d.ts.map +0 -1
  665. package/dist/utils/CompatibilityUpgrader.js.map +0 -1
  666. package/dist/utils/InMemoryRevisionAcceptor.d.ts.map +0 -1
  667. package/dist/utils/InMemoryRevisionAcceptor.js.map +0 -1
  668. package/dist/utils/MoveOperationHelper.d.ts.map +0 -1
  669. package/dist/utils/MoveOperationHelper.js.map +0 -1
  670. package/dist/utils/RevisionAwareProcessor.d.ts.map +0 -1
  671. package/dist/utils/RevisionAwareProcessor.js.map +0 -1
  672. package/dist/utils/RevisionWalker.d.ts.map +0 -1
  673. package/dist/utils/RevisionWalker.js.map +0 -1
  674. package/dist/utils/SelectiveRevisionAcceptor.d.ts.map +0 -1
  675. package/dist/utils/SelectiveRevisionAcceptor.js.map +0 -1
  676. package/dist/utils/ShadingResolver.d.ts +0 -6
  677. package/dist/utils/ShadingResolver.d.ts.map +0 -1
  678. package/dist/utils/ShadingResolver.js.map +0 -1
  679. package/dist/utils/acceptRevisions.d.ts.map +0 -1
  680. package/dist/utils/acceptRevisions.js.map +0 -1
  681. package/dist/utils/cnfStyleDecoder.d.ts.map +0 -1
  682. package/dist/utils/cnfStyleDecoder.js.map +0 -1
  683. package/dist/utils/stripTrackedChanges.d.ts +0 -3
  684. package/dist/utils/stripTrackedChanges.d.ts.map +0 -1
  685. package/dist/utils/stripTrackedChanges.js.map +0 -1
  686. package/src/__tests__/helper-methods.test.ts +0 -512
  687. package/src/constants/CLAUDE.md +0 -28
  688. package/src/core/CLAUDE.md +0 -113
  689. package/src/elements/CLAUDE.md +0 -142
  690. package/src/formatting/CLAUDE.md +0 -78
  691. package/src/managers/CLAUDE.md +0 -47
  692. package/src/tracking/CLAUDE.md +0 -30
  693. package/src/types/CLAUDE.md +0 -39
  694. package/src/utils/CLAUDE.md +0 -168
  695. package/src/validation/CLAUDE.md +0 -40
  696. package/src/xml/CLAUDE.md +0 -65
  697. package/src/zip/CLAUDE.md +0 -55
  698. /package/dist/{utils → processors}/CompatibilityUpgrader.d.ts +0 -0
  699. /package/dist/{utils → processors}/cnfStyleDecoder.js +0 -0
package/README.md CHANGED
@@ -1,116 +1,89 @@
1
- # docXMLater
1
+ # docxmlater
2
2
 
3
- A comprehensive, production-ready TypeScript/JavaScript framework for creating, reading, and manipulating Microsoft Word (.docx) documents programmatically.
3
+ **The TypeScript library for editing existing Word documents with full tracked-changes, comment, and bookmark fidelity.**
4
4
 
5
- ## When to Use docxmlater
5
+ Most DOCX libraries can generate documents from scratch. docxmlater is built for the harder problem: loading an existing `.docx`, modifying it, and saving it back without corrupting it. That includes documents that already contain tracked changes, comments, or bookmarks - which most other libraries silently break on round-trip.
6
6
 
7
- docxmlater is designed for **editing existing Word documents** with full round-trip XML fidelity. It excels at:
7
+ [Try it in your browser](https://stackblitz.com/github/ItMeDiaTech/docXMLater/tree/main/playground) | [Why docxmlater](#why-docxmlater) | [Quick Start](#quick-start) | [API Reference](#api-reference)
8
8
 
9
- - Loading a .docx, making targeted modifications, and saving without losing formatting or structure
10
- - Working with tracked changes, comments, and revision history
11
- - Preserving complex elements (math equations, charts, SmartArt) through raw XML passthrough
12
- - Programmatic batch processing of corporate documents
13
-
14
- If you only need to **generate documents from scratch** and don't need to load/edit existing files, consider the [docx](https://www.npmjs.com/package/docx) package which has a declarative builder API optimized for document creation.
15
-
16
- ## Features
17
-
18
- ### Core Document Operations
19
-
20
- - Create DOCX files from scratch
21
- - Read and modify existing DOCX files
22
- - Buffer-based operations (load/save from memory)
23
- - Document properties (core, extended, custom)
24
- - Memory management with dispose pattern
25
- - Bookmark pair validation and auto-repair (`validateBookmarkPairs()`)
26
- - App.xml metadata preservation (HeadingPairs, TotalTime, etc.)
27
- - Document background color/theme support
28
-
29
- ### Text & Paragraph Formatting
30
-
31
- - Character formatting: bold, italic, underline, strikethrough, subscript, superscript
32
- - Font properties: family, size, color (RGB and theme colors), highlight
33
- - Text effects: small caps, all caps, shadow, emboss, engrave
34
- - Paragraph alignment, indentation, spacing, borders, shading
35
- - Text search and replace with regex support
36
- - Custom styles (paragraph, character, table)
37
- - CJK/East Asian paragraph properties (kinsoku, wordWrap, overflowPunct, topLinePunct)
38
- - Underline color and theme color attributes
39
- - Theme font references (asciiTheme, hAnsiTheme, eastAsiaTheme, csTheme)
40
-
41
- ### Lists & Tables
42
-
43
- - Numbered lists (decimal, roman, alpha)
44
- - Bulleted lists with various bullet styles
45
- - Multi-level lists with custom numbering and restart control
46
- - Tables with formatting, borders, shading
47
- - Cell spanning (merge cells horizontally and vertically)
48
- - Advanced table properties (margins, widths, alignment)
49
- - Table navigation helpers (`getFirstParagraph()`, `getLastParagraph()`)
50
- - Legacy horizontal merge (`hMerge`) support
51
- - Table layout parsing (`fixed`/`auto`)
52
- - Table style shading updates (modify styles.xml colors)
53
- - Cell content management (trailing blank removal with structure preservation)
54
-
55
- ### Rich Content
56
-
57
- - Images (PNG, JPEG, GIF, SVG, EMF, WMF) with positioning, text wrapping, and full ECMA-376 DrawingML attribute coverage
58
- - Headers & footers (different first page, odd/even pages)
59
- - Hyperlinks (external URLs, internal bookmarks)
60
- - Hyperlink defragmentation utility (fixes fragmented links from Google Docs)
61
- - Hyperlink URL sanitization (strips browser extension prefixes from corrupted URLs)
62
- - Bookmarks and cross-references
63
- - Body-level bookmark support (bookmarks between block elements)
64
- - Shapes and text boxes
9
+ ```bash
10
+ npm install docxmlater
11
+ ```
65
12
 
66
- ### Advanced Features
67
-
68
- - Track changes (revisions for insertions, deletions, formatting)
69
- - Granular character-level tracked changes (text diff-based)
70
- - Comments and annotations
71
- - Compatibility mode detection and upgrade (Word 2003/2007/2010/2013+ modes)
72
- - Table of contents generation with customizable heading levels and relative indentation
73
- - Fields: merge fields, date/time, page numbers, TOC fields
74
- - Footnotes and endnotes (full round-trip with save pipeline, parsing, and clear API)
75
- - Content controls (Structured Document Tags)
76
- - Form field data preservation (text input, checkbox, dropdown per ECMA-376 §17.16)
77
- - w14 run effects passthrough (Word 2010+ ligatures, numForm, textOutline, etc.)
78
- - Expanded document settings (evenAndOddHeaders, mirrorMargins, autoHyphenation, decimalSymbol)
79
- - People.xml auto-registration for tracked changes authors
80
- - Style default attribute preservation (`w:default="1"`)
81
- - Namespace order preservation in generated XML
82
- - Multiple sections with different page layouts
83
- - Page orientation, size, and margins
84
- - Preserved element round-trip (math equations, alternate content, custom XML)
85
- - Unified shading model with theme color support and inheritance resolution
86
- - Lossless image optimization (PNG re-compression, BMP-to-PNG conversion)
87
- - Run property change tracking (w:rPrChange) with direct API access
88
- - Paragraph mark revision tracking (w:del/w:ins in w:pPr/w:rPr) for full tracked-changes fidelity
89
- - Normal/NormalWeb style linking with preservation flags
90
-
91
- ### Developer Tools
92
-
93
- - Complete XML generation and parsing (ReDoS-safe, position-based parser)
94
- - 40+ unit conversion functions (twips, EMUs, points, pixels, inches, cm)
95
- - Validation utilities and corruption detection
96
- - Text diff utility for character-level comparisons
97
- - webSettings.xml auto-generation
98
- - Safe OOXML parsing helpers (zero-value handling, boolean parsing)
99
- - Full TypeScript support with comprehensive type definitions
100
- - Error handling utilities with custom error types (`DocxError`, `InvalidDocxError`, `CorruptedArchiveError`)
101
- - Logging infrastructure with multiple log levels (`DOCXMLATER_LOG_LEVEL=debug|info|warn|error`)
102
- - Plain text extraction (`doc.toPlainText()`) and heading hierarchy (`doc.getHeadingHierarchy()`)
103
- - Accessibility auditing (`doc.findImagesWithoutAltText()`)
104
-
105
- ### Unsupported OOXML Features
106
-
107
- The following features are preserved as raw XML on round-trip but have no editing API:
108
-
109
- - **Charts** (c:chartSpace) -- preserved but not editable
110
- - **SmartArt** -- preserved as raw XML passthrough
111
- - **OLE embedded objects** (`<w:object>`) -- preserved, no API
112
- - **Glossary document** (glossary.xml) -- not handled
113
- - **DrawingML advanced features** -- gradient fills, pattern fills, group shapes, 3D effects, shape effects (shadow, reflection, glow)
13
+ ---
14
+
15
+ ## Why docxmlater
16
+
17
+ | | `docx` | `docxtemplater` | **docxmlater** |
18
+ | ------------------------------- | :----: | :--------------------------: | :------------: |
19
+ | Generate documents from scratch | ✓ | ✓ | ✓ |
20
+ | Load and edit existing files | ✗ | partial (templates only) | ✓ |
21
+ | Round-trip XML fidelity | ✗ | partial | ✓ |
22
+ | Tracked-changes preservation | ✗ | ✗ | ✓ |
23
+ | Comments (resolve / unresolve) | ✗ | ✗ | ✓ |
24
+ | Bookmarks (block and inline) | ✗ | partial | ✓ |
25
+ | Compatibility-mode upgrade | ✗ | ✗ | ✓ |
26
+ | Free / open-source | ✓ | partial (commercial modules) | ✓ |
27
+
28
+ ### When docxmlater is the right choice
29
+
30
+ - You need to **load existing Word documents** and modify any element with full fidelity.
31
+ - You're working with documents that contain **tracked changes**, **comments**, or **bookmarks** that must round-trip cleanly.
32
+ - You programmatically apply formatting on top of someone else's drafted document.
33
+ - You're processing documents from older Word versions and need **compatibility-mode upgrade**.
34
+ - You want a single library with no commercial tier behind features you actually need.
35
+
36
+ ### When you might want something else
37
+
38
+ - If you only need to **generate a document from scratch** with no edit or round-trip requirement, the `docx` package has a more declarative builder API.
39
+ - If your entire workflow is **template-fill** (placeholders in a designer-authored docx), `docxtemplater` may fit better.
40
+ - If you only need to **convert docx to HTML or Markdown for display**, `mammoth` is purpose-built.
41
+
42
+ ---
43
+
44
+ ## About the Project
45
+
46
+ docxmlater began in early 2025 as a personal effort to build a TypeScript framework capable of full programmatic interaction with `.docx` files. What started as a focused side project grew into a much larger undertaking as the depth of the OOXML specification revealed itself. The work is implemented directly against the 6,000+ page ECMA-376 standard, with attention paid to round-trip fidelity, schema correctness, and the practical edge cases real-world Word documents introduce.
47
+
48
+ The library is in active production use on a small team for day-to-day document formatting workflows. The aim is to provide a free, capable alternative to commercial DOCX engines that charge thousands of dollars per year per seat.
49
+
50
+ What distinguishes docxmlater from existing libraries is its first-class support for revision workflows. Tracked changes, comments, and bookmarks are fully integrated. Documents that already contain tracked changes can be processed without corruption, preserving the existing revision history where required while still applying new formatting on top.
51
+
52
+ If you encounter a use case that is not yet implemented and would be broadly useful, please open an issue.
53
+
54
+ ---
55
+
56
+ ## Table of Contents
57
+
58
+ - [Why docxmlater](#why-docxmlater)
59
+ - [Installation](#installation)
60
+ - [Quick Start](#quick-start)
61
+ - [Feature Overview](#feature-overview)
62
+ - [API Reference](#api-reference)
63
+ - [Document](#document)
64
+ - [Paragraph](#paragraph)
65
+ - [Run](#run)
66
+ - [Table](#table)
67
+ - [TableCell](#tablecell)
68
+ - [Section](#section)
69
+ - [Comment & CommentManager](#comment--commentmanager)
70
+ - [Utilities](#utilities)
71
+ - [Advanced Topics](#advanced-topics)
72
+ - [Tracked Changes](#tracked-changes)
73
+ - [Custom Styles](#custom-styles)
74
+ - [Hyperlink Management](#hyperlink-management)
75
+ - [Compatibility Mode](#compatibility-mode)
76
+ - [Templates](#templates)
77
+ - [Document Conversion](#document-conversion)
78
+ - [Performance & Memory Management](#performance--memory-management)
79
+ - [Architecture](#architecture)
80
+ - [Security](#security)
81
+ - [TypeScript Support](#typescript-support)
82
+ - [Requirements](#requirements)
83
+ - [Contributing](#contributing)
84
+ - [License](#license)
85
+
86
+ ---
114
87
 
115
88
  ## Installation
116
89
 
@@ -118,69 +91,51 @@ The following features are preserved as raw XML on round-trip but have no editin
118
91
  npm install docxmlater
119
92
  ```
120
93
 
94
+ Requires Node.js **18.0.0** or higher. TypeScript 5.0+ is recommended for development.
95
+
96
+ The only runtime dependency is `jszip` for ZIP archive handling.
97
+
98
+ ---
99
+
121
100
  ## Quick Start
122
101
 
123
- ### Creating a New Document
102
+ ### Create a new document
124
103
 
125
104
  ```typescript
126
105
  import { Document } from 'docxmlater';
127
106
 
128
- // Create a new document
129
107
  const doc = Document.create();
130
-
131
- // Add a paragraph
132
108
  const para = doc.createParagraph();
133
109
  para.addText('Hello, World!', { bold: true, fontSize: 24 });
134
110
 
135
- // Save to file
136
111
  await doc.save('hello.docx');
137
-
138
- // Don't forget to dispose
139
112
  doc.dispose();
140
113
  ```
141
114
 
142
- ### Loading and Modifying Documents
115
+ ### Load and modify an existing document
143
116
 
144
117
  ```typescript
145
118
  import { Document } from 'docxmlater';
146
119
 
147
- // Load existing document
148
120
  const doc = await Document.load('input.docx');
149
121
 
150
- // Find and replace text
151
122
  doc.replaceText(/old text/g, 'new text');
123
+ doc.createParagraph().addText('Added paragraph', { italic: true });
152
124
 
153
- // Add a new paragraph
154
- const para = doc.createParagraph();
155
- para.addText('Added paragraph', { italic: true });
156
-
157
- // Save modifications
158
125
  await doc.save('output.docx');
159
126
  doc.dispose();
160
127
  ```
161
128
 
162
- ### Working with Tables
129
+ ### Tables
163
130
 
164
131
  ```typescript
165
- import { Document } from 'docxmlater';
166
-
167
132
  const doc = Document.create();
168
-
169
- // Create a 3x4 table
170
133
  const table = doc.createTable(3, 4);
171
134
 
172
- // Set header row
173
- const headerRow = table.getRow(0);
174
- headerRow.getCell(0).addParagraph().addText('Column 1', { bold: true });
175
- headerRow.getCell(1).addParagraph().addText('Column 2', { bold: true });
176
- headerRow.getCell(2).addParagraph().addText('Column 3', { bold: true });
177
- headerRow.getCell(3).addParagraph().addText('Column 4', { bold: true });
135
+ const header = table.getRow(0);
136
+ header.getCell(0).createParagraph().addText('Column 1', { bold: true });
137
+ header.getCell(1).createParagraph().addText('Column 2', { bold: true });
178
138
 
179
- // Add data
180
- table.getRow(1).getCell(0).addParagraph().addText('Data 1');
181
- table.getRow(1).getCell(1).addParagraph().addText('Data 2');
182
-
183
- // Apply borders
184
139
  table.setBorders({
185
140
  top: { style: 'single', size: 4, color: '000000' },
186
141
  bottom: { style: 'single', size: 4, color: '000000' },
@@ -194,563 +149,397 @@ await doc.save('table.docx');
194
149
  doc.dispose();
195
150
  ```
196
151
 
197
- ### Adding Images
152
+ ### Images
198
153
 
199
154
  ```typescript
200
155
  import { Document } from 'docxmlater';
201
156
  import { readFileSync } from 'fs';
202
157
 
203
158
  const doc = Document.create();
204
-
205
- // Load image from file
206
159
  const imageBuffer = readFileSync('photo.jpg');
207
160
 
208
- // Add image to document
209
161
  const para = doc.createParagraph();
210
- await para.addImage(imageBuffer, {
211
- width: 400,
212
- height: 300,
213
- format: 'jpg',
214
- });
162
+ await para.addImage(imageBuffer, { width: 400, height: 300, format: 'jpg' });
215
163
 
216
164
  await doc.save('with-image.docx');
217
165
  doc.dispose();
218
166
  ```
219
167
 
220
- ### Hyperlink Management
221
-
222
- ```typescript
223
- import { Document } from 'docxmlater';
224
-
225
- const doc = await Document.load('document.docx');
226
-
227
- // Get all hyperlinks
228
- const hyperlinks = doc.getHyperlinks();
229
- console.log(`Found ${hyperlinks.length} hyperlinks`);
230
-
231
- // Update URLs in batch (30-50% faster than manual iteration)
232
- doc.updateHyperlinkUrls('http://old-domain.com', 'https://new-domain.com');
233
-
234
- // Fix fragmented hyperlinks from Google Docs
235
- const mergedCount = doc.defragmentHyperlinks({
236
- resetFormatting: true, // Fix corrupted fonts
237
- });
238
- console.log(`Merged ${mergedCount} fragmented hyperlinks`);
239
-
240
- await doc.save('updated.docx');
241
- doc.dispose();
242
- ```
243
-
244
- ### Custom Styles
245
-
246
- ```typescript
247
- import { Document, Style } from 'docxmlater';
248
-
249
- const doc = Document.create();
250
-
251
- // Create custom paragraph style
252
- const customStyle = new Style('CustomHeading', 'paragraph');
253
- customStyle.setName('Custom Heading');
254
- customStyle.setRunFormatting({
255
- bold: true,
256
- fontSize: 32,
257
- color: '0070C0',
258
- });
259
- customStyle.setParagraphFormatting({
260
- alignment: 'center',
261
- spacingAfter: 240,
262
- });
263
-
264
- // Add style to document
265
- doc.getStylesManager().addStyle(customStyle);
266
-
267
- // Apply style to paragraph
268
- const para = doc.createParagraph();
269
- para.addText('Styled Heading');
270
- para.applyStyle('CustomHeading');
271
-
272
- await doc.save('styled.docx');
273
- doc.dispose();
274
- ```
275
-
276
- ### Compatibility Mode Detection and Upgrade
168
+ ---
277
169
 
278
- ```typescript
279
- import { Document, CompatibilityMode } from 'docxmlater';
170
+ ## Feature Overview
280
171
 
281
- const doc = await Document.load('legacy.docx');
172
+ ### Document Operations
282
173
 
283
- // Check compatibility mode
284
- console.log(`Mode: ${doc.getCompatibilityMode()}`); // e.g., 12 (Word 2007)
174
+ Create, load, and save documents from files or buffers. Manage core, extended, and custom document properties. Validate and auto-repair bookmark pairs. Preserve `app.xml` metadata (HeadingPairs, TotalTime, etc.). Configurable document background color and theme support.
285
175
 
286
- if (doc.isCompatibilityMode()) {
287
- // Get detailed compatibility info
288
- const info = doc.getCompatibilityInfo();
289
- console.log(`Legacy flags: ${info.legacyFlags.length}`);
290
-
291
- // Upgrade to Word 2013+ mode (equivalent to File > Info > Convert)
292
- const report = doc.upgradeToModernFormat();
293
- console.log(`Removed ${report.removedFlags.length} legacy flags`);
294
- console.log(`Added ${report.addedSettings.length} modern settings`);
295
- }
296
-
297
- await doc.save('modern.docx');
298
- doc.dispose();
299
- ```
300
-
301
- ## API Overview
302
-
303
- ### Document Class
176
+ ### Text & Paragraph Formatting
304
177
 
305
- **Creation & Loading:**
178
+ - Character formatting: bold, italic, underline, strikethrough, sub/superscript, small caps, all caps, shadow, emboss, engrave
179
+ - Font properties: family, size, color (RGB and theme), highlight, underline color
180
+ - Theme font references (`asciiTheme`, `hAnsiTheme`, `eastAsiaTheme`, `csTheme`)
181
+ - Paragraph alignment, indentation, spacing, borders, shading
182
+ - CJK / East Asian properties (kinsoku, wordWrap, overflowPunct, topLinePunct)
183
+ - Cross-run text search and replace, regex supported
306
184
 
307
- - `Document.create(options?)` - Create new document
308
- - `Document.load(filepath, options?)` - Load from file
309
- - `Document.loadFromBuffer(buffer, options?)` - Load from memory
185
+ ### Lists & Tables
310
186
 
311
- **Handling Tracked Changes:**
187
+ - Numbered (decimal, roman, alpha) and bulleted lists
188
+ - Multi-level lists with custom numbering and restart control
189
+ - Tables with borders, shading, alignment, and width control
190
+ - Horizontal and vertical cell merging, including legacy `hMerge`
191
+ - Fixed and auto table layouts
192
+ - Cell content management with structure preservation
312
193
 
313
- By default, docXMLater accepts all tracked changes during document loading to prevent corruption:
194
+ ### Rich Content
314
195
 
315
- ```typescript
316
- // Default: Accepts all changes (recommended)
317
- const doc = await Document.load('document.docx');
196
+ - Images: PNG, JPEG, GIF, SVG, EMF, WMF - with positioning, text wrapping, and full DrawingML attribute coverage
197
+ - Headers and footers with first-page and odd/even variants
198
+ - Hyperlinks (external and internal), with defragmentation and URL sanitization utilities
199
+ - Bookmarks (block and inline level) and cross-references
200
+ - Shapes and text boxes
318
201
 
319
- // Explicit control
320
- const doc = await Document.load('document.docx', {
321
- revisionHandling: 'accept' // Accept all changes (default)
322
- // OR
323
- revisionHandling: 'strip' // Remove all revision markup
324
- // OR
325
- revisionHandling: 'preserve' // Keep tracked changes (may cause corruption, but should not do so - report errors if found)
326
- });
327
- ```
202
+ ### Revisions & Collaboration
328
203
 
329
- **Revision Handling Options:**
204
+ - Track changes (insertions, deletions, formatting)
205
+ - Character-level granular revisions via text diffing
206
+ - Comments with resolve/unresolve workflow
207
+ - Run property change tracking (`w:rPrChange`)
208
+ - Paragraph mark revision tracking (`w:del`/`w:ins` in `w:pPr`/`w:rPr`)
209
+ - People.xml auto-registration for revision authors
210
+ - Full round-trip preservation of pre-existing tracked changes
330
211
 
331
- - `'accept'` (default): Removes revision markup, keeps inserted content, removes deleted content
332
- - `'strip'`: Removes all revision markup completely
333
- - `'preserve'`: Keeps tracked changes as-is (may cause Word "unreadable content" errors)
212
+ ### Advanced Features
334
213
 
335
- **Why Accept By Default?**
214
+ - Compatibility mode detection and upgrade (Word 2003 / 2007 / 2010 / 2013+)
215
+ - Table of contents generation with customizable heading levels
216
+ - Fields: merge fields, date/time, page numbers, TOC fields
217
+ - Footnotes and endnotes (full round-trip and dedicated API)
218
+ - Content controls (Structured Document Tags)
219
+ - Form field data preservation (text, checkbox, dropdown per ECMA-376 §17.16)
220
+ - `w14` run effects passthrough (Word 2010+ ligatures, numForm, textOutline)
221
+ - Multiple sections with independent page layouts and orientations
222
+ - Lossless image optimization (PNG re-compression, BMP-to-PNG conversion)
223
+ - Unified shading model with theme color support and inheritance resolution
336
224
 
337
- Documents with tracked changes can cause Word corruption errors during round-trip processing due to revision ID conflicts. Accepting changes automatically prevents this issue while preserving document content.
225
+ ### Document Conversion
338
226
 
339
- **Content Management:**
227
+ Export to Markdown, HTML (fragment or full page), Base64, or Data URI. Create documents from Markdown.
340
228
 
341
- - `createParagraph()` - Add paragraph
342
- - `createTable(rows, cols)` - Add table
343
- - `createSection()` - Add section
344
- - `getBodyElements()` - Get all body content
229
+ ### Preserved (round-trip only)
345
230
 
346
- **Search & Replace:**
231
+ The following features round-trip safely as raw XML but have no editing API:
347
232
 
348
- - `findText(pattern)` - Find text matches
349
- - `replaceText(pattern, replacement)` - Replace text
350
- - `findParagraphsByText(pattern)` - Find paragraphs containing text/regex
351
- - `getParagraphsByStyle(styleId)` - Get paragraphs with specific style
352
- - `getRunsByFont(fontName)` - Get runs using a specific font
353
- - `getRunsByColor(color)` - Get runs with a specific color
233
+ - Charts (`c:chartSpace`)
234
+ - SmartArt
235
+ - OLE embedded objects (`w:object`)
236
+ - Math equations
237
+ - Glossary documents (`glossary.xml`)
238
+ - Advanced DrawingML (gradient/pattern fills, group shapes, 3D effects)
354
239
 
355
- **Bulk Formatting:**
240
+ ---
356
241
 
357
- - `setAllRunsFont(fontName)` - Apply font to all text
358
- - `setAllRunsSize(size)` - Apply font size to all text
359
- - `setAllRunsColor(color)` - Apply color to all text
360
- - `getFormattingReport()` - Get document formatting statistics
242
+ ## API Reference
361
243
 
362
- **Hyperlinks:**
244
+ ### Document
363
245
 
364
- - `getHyperlinks()` - Get all hyperlinks
365
- - `updateHyperlinkUrls(oldUrl, newUrl)` - Batch URL update
366
- - `defragmentHyperlinks(options?)` - Fix fragmented links
367
- - `collectAllReferencedHyperlinkIds()` - Comprehensive scan of all hyperlink relationship IDs (includes nested tables, headers/footers, footnotes/endnotes)
246
+ **Creation & Loading**
368
247
 
369
- **Statistics:**
248
+ | Method | Description |
249
+ | ------------------------------------------- | --------------------------- |
250
+ | `Document.create(options?)` | Create a new document |
251
+ | `Document.load(path, options?)` | Load from a file path |
252
+ | `Document.loadFromBuffer(buffer, options?)` | Load from a `Buffer` |
253
+ | `Document.fromMarkdown(md)` | Create from Markdown source |
254
+ | `Document.loadFromBase64(b64)` | Load from a Base64 string |
370
255
 
371
- - `getWordCount()` - Count words
372
- - `getCharacterCount(includeSpaces?)` - Count characters
373
- - `estimateSize()` - Estimate file size
256
+ **Content Management**
374
257
 
375
- **Compatibility Mode:**
258
+ - `createParagraph()`, `createTable(rows, cols)`, `createSection()`
259
+ - `addHeading(text, level?)`, `addPageBreak()`, `addHorizontalRule(color?, size?)`
260
+ - `addBulletListFromArray(items)`, `addNumberedListFromArray(items)`
261
+ - `createTableFromCSV(csv, delimiter?)`
262
+ - `getBodyElements()`, `clear()`, `clone()`
263
+ - `insertAfter(ref, el)`, `insertBefore(ref, el)`, `replaceElement(old, new)`, `removeElement(el)`
264
+ - `forEachParagraph(cb)`, `forEachTable(cb)`, `extractByHeading(maxLevel?)`, `getElementsBetween(start, end)`
376
265
 
377
- - `getCompatibilityMode()` - Get document's Word version mode (11/12/14/15)
378
- - `isCompatibilityMode()` - Check if document targets a legacy Word version
379
- - `getCompatibilityInfo()` - Get full parsed compat settings
380
- - `upgradeToModernFormat()` - Upgrade to Word 2013+ mode (removes legacy flags)
266
+ **Search & Replace**
381
267
 
382
- **Footnotes & Endnotes:**
268
+ - `findText(pattern)`, `replaceText(pattern, replacement)`
269
+ - `findParagraphsByText(pattern)`, `getParagraphsByStyle(styleId)`
270
+ - `getRunsByFont(name)`, `getRunsByColor(color)`
383
271
 
384
- - `createFootnote(paragraph, text)` - Add footnote
385
- - `createEndnote(paragraph, text)` - Add endnote
386
- - `clearFootnotes()` / `clearEndnotes()` - Remove all notes
387
- - `getFootnoteManager()` / `getEndnoteManager()` - Access note managers
272
+ **Bulk Formatting**
388
273
 
389
- **Numbering:**
274
+ - `setAllRunsFont(name)`, `setAllRunsSize(size)`, `setAllRunsColor(color)`
275
+ - `setDefaultFont(name, size?)`, `setDefaultFontSize(size)`
276
+ - `getFormattingReport()`
390
277
 
391
- - `restartNumbering(numId, level?, startValue?)` - Restart list numbering (creates new instance with startOverride)
392
- - `cleanupUnusedNumbering()` - Remove unused numbering definitions (scans body, headers, footers, footnotes, endnotes)
393
- - `consolidateNumbering(options?)` - Merge duplicate abstract numbering definitions
394
- - `validateNumberingReferences()` - Fix orphaned numId references
278
+ **Hyperlinks**
395
279
 
396
- **Shading:**
280
+ - `getHyperlinks()`, `updateHyperlinkUrls(oldUrl, newUrl)`
281
+ - `defragmentHyperlinks(options?)`, `collectAllReferencedHyperlinkIds()`
397
282
 
398
- - `getComputedCellShading(table, row, col)` - Resolve effective cell shading with inheritance
283
+ **Statistics**
399
284
 
400
- **Document Sanitization:**
285
+ - `getWordCount()`, `getCharacterCount(includeSpaces?)`
286
+ - `estimateSize()`, `getStatistics()`
401
287
 
402
- - `flattenFieldCodes()` - Strip INCLUDEPICTURE field markup, preserving embedded images
403
- - `stripOrphanRSIDs()` - Remove orphan RSIDs from settings.xml
404
- - `clearDirectSpacingForStyles(styleIds)` - Remove direct spacing overrides from styled paragraphs
288
+ **Compatibility**
405
289
 
406
- **Image Optimization:**
290
+ - `getCompatibilityMode()`, `isCompatibilityMode()`
291
+ - `getCompatibilityInfo()`, `upgradeToModernFormat()`
407
292
 
408
- - `optimizeImages()` - Lossless PNG re-compression and BMP-to-PNG conversion (zero dependencies)
293
+ **Footnotes & Endnotes**
409
294
 
410
- **Document Convenience:**
295
+ - `createFootnote(paragraph, text)`, `createEndnote(paragraph, text)`
296
+ - `clearFootnotes()`, `clearEndnotes()`
297
+ - `getFootnoteManager()`, `getEndnoteManager()`
411
298
 
412
- - `addHeading(text, level?)` - Add heading paragraph (H1-H9)
413
- - `addPageBreak()` - Insert page break
414
- - `addHorizontalRule(color?, size?)` - Insert horizontal line
415
- - `setDefaultFont(name, size?)` - Set document default font via Normal style
416
- - `setDefaultFontSize(size)` - Set document default font size
417
- - `clear()` - Remove all body content (preserves styles/settings)
418
- - `clone()` - Deep copy document for template batch generation
419
- - `addBulletListFromArray(items)` - Create bullet list from string array
420
- - `addNumberedListFromArray(items)` - Create numbered list from string array
421
- - `createTableFromCSV(csv, delimiter?)` - Create table from CSV data
299
+ **Numbering**
422
300
 
423
- **Template Engine:**
301
+ - `restartNumbering(numId, level?, startValue?)`
302
+ - `cleanupUnusedNumbering()`, `consolidateNumbering(options?)`
303
+ - `validateNumberingReferences()`
424
304
 
425
- - `fillTemplate(data, options?)` - Replace `{{key}}` placeholders across runs
426
- - `findAndHighlight(text, color?)` - Highlight all text occurrences
427
- - `findAndFormat(text, formatting)` - Apply formatting to all text occurrences
305
+ **Sanitization & Optimization**
428
306
 
429
- **Document Conversion:**
307
+ - `flattenFieldCodes()` - strip INCLUDEPICTURE markup, keep images
308
+ - `stripOrphanRSIDs()` - remove unused RSIDs from `settings.xml`
309
+ - `clearDirectSpacingForStyles(ids)` - remove direct spacing on styled paragraphs
310
+ - `optimizeImages()` - lossless PNG re-compression, BMP-to-PNG
430
311
 
431
- - `toMarkdown()` - Export as Markdown
432
- - `toHTML(options?)` - Export as HTML (fragment or full page)
433
- - `toBase64()` - Export as base64 string
434
- - `toDataUri()` - Export as data URI
435
- - `fromMarkdown(md)` - Create document from Markdown (static)
436
- - `loadFromBase64(base64)` - Load document from base64 (static)
312
+ **Templates & Highlighting**
437
313
 
438
- **Content Structure:**
314
+ - `fillTemplate(data, options?)` - replace `{{key}}` placeholders across runs
315
+ - `findAndHighlight(text, color?)`, `findAndFormat(text, formatting)`
439
316
 
440
- - `insertAfter(reference, element)` - Insert element after reference
441
- - `insertBefore(reference, element)` - Insert element before reference
442
- - `replaceElement(old, new)` - Replace body element in-place
443
- - `removeElement(element)` - Remove body element by reference
444
- - `extractByHeading(maxLevel?)` - Group content by heading sections
445
- - `getElementsBetween(start, end)` - Get elements between two references
446
- - `forEachParagraph(callback)` - Iterate top-level paragraphs
447
- - `forEachTable(callback)` - Iterate top-level tables
448
- - `getStatistics()` - Comprehensive document metrics
317
+ **Conversion**
449
318
 
450
- **Saving:**
319
+ - `toMarkdown()`, `toHTML(options?)`, `toPlainText()`
320
+ - `toBase64()`, `toDataUri()`, `getHeadingHierarchy()`
321
+ - `findImagesWithoutAltText()` (accessibility audit)
451
322
 
452
- - `save(filepath)` - Save to file
453
- - `toBuffer()` - Save to Buffer
454
- - `dispose()` - Free resources (important!)
323
+ **Saving**
455
324
 
456
- ### Paragraph Class
325
+ - `save(path)`, `toBuffer()`, `dispose()` - _always call `dispose()` when finished_
457
326
 
458
- **Content:**
327
+ ### Paragraph
459
328
 
460
- - `addText(text, formatting?)` - Add text run
461
- - `addRun(run)` - Add custom run
462
- - `addHyperlink(hyperlink)` - Add hyperlink
463
- - `addImage(buffer, options)` - Add image
329
+ **Content**: `addText(text, formatting?)`, `addRun(run)`, `addHyperlink(link)`, `addImage(buffer, options)`
464
330
 
465
- **Formatting:**
331
+ **Formatting**: `setAlignment`, `setIndentation`, `setSpacing`, `setBorders`, `setShading`, `applyStyle`, `setKeepNext`, `setKeepLines`, `setPageBreakBefore`, `clearSpacing`
466
332
 
467
- - `setAlignment(alignment)` - Left, center, right, justify
468
- - `setIndentation(options)` - First line, hanging, left, right
469
- - `setSpacing(options)` - Line spacing, before/after
470
- - `setBorders(borders)` - Paragraph borders
471
- - `setShading(shading)` - Background color
472
- - `applyStyle(styleId)` - Apply paragraph style
333
+ **Text manipulation**: `applyFormattingToRange`, `deleteRange`, `truncate`, `wrap`, `splitAt`, `consolidateRuns`, `replaceAll`, `findTextCrossRun`, `getRunAtOffset`, `getFormattingAtOffset`, `contains`, `toJSON` / `fromJSON`
473
334
 
474
- **Properties:**
335
+ **Numbering**: `setNumbering(numId, level)`
475
336
 
476
- - `setKeepNext(value)` - Keep with next paragraph
477
- - `setKeepLines(value)` - Keep lines together
478
- - `setPageBreakBefore(value)` - Page break before
479
- - `clearSpacing()` - Remove direct spacing (inherit from style)
337
+ ### Run
480
338
 
481
- **Text Manipulation:**
339
+ **Text**: `setText`, `getText`, `getPlainText`, `splitAt`
482
340
 
483
- - `applyFormattingToRange(start, end, formatting)` - Apply formatting to character range
484
- - `deleteRange(start, end)` - Delete character range
485
- - `truncate(maxLength, suffix?)` - Truncate text with ellipsis
486
- - `wrap(prefix, suffix, formatting?)` - Wrap content with prefix/suffix
487
- - `splitAt(offset)` - Split paragraph into two at character position
488
- - `consolidateRuns()` - Merge adjacent runs with identical formatting
489
- - `replaceAll(find, replace)` - Cross-run find and replace
490
- - `findTextCrossRun(find)` - Cross-run text search with offsets
491
- - `getRunAtOffset(offset)` - Get run at character position
492
- - `getFormattingAtOffset(offset)` - Get formatting at character position
493
- - `contains(text, caseSensitive?)` - Check if paragraph contains text
494
- - `toJSON()` / `fromJSON(data)` - Serialize/deserialize paragraph
341
+ **Character formatting**: `setBold`, `setItalic`, `setUnderline`, `setStrikethrough`, `setFont`, `setFontSize`, `setColor`, `setHighlight`
495
342
 
496
- **Numbering:**
343
+ **Advanced**: `setSubscript`, `setSuperscript`, `setSmallCaps`, `setAllCaps`, `clearMatchingFormatting`, `equals`, `hasSameFormatting`, `clone`
497
344
 
498
- - `setNumbering(numId, level)` - Apply list numbering
345
+ ### Table
499
346
 
500
- ### Run Class
347
+ **Structure**: `addRow`, `addRowFromArray`, `getRow`, `getCell`, `setCell`, `duplicateRow`, `addSummaryRow`
501
348
 
502
- **Text:**
349
+ **Data**: `fromArray` / `toArray`, `fromCSV` / `toCSV`, `toPlainText`, `transpose`, `clone`, `sortRows`
503
350
 
504
- - `setText(text)` - Set run text
505
- - `getText()` - Get run text
506
- - `getPlainText()` - Get text only (no tabs/breaks)
507
- - `splitAt(offset)` - Split run at character position
351
+ **Queries**: `getColumnCells`, `getColumnTexts`, `findCell`, `filterRows`, `forEachCell`, `mapColumn`
508
352
 
509
- **Character Formatting:**
353
+ **Formatting**: `setBorders`, `setAlignment`, `setWidth`, `setLayout`, `applyStyle`
510
354
 
511
- - `setBold(value)` - Bold text
512
- - `setItalic(value)` - Italic text
513
- - `setUnderline(style?)` - Underline
514
- - `setStrikethrough(value)` - Strikethrough
515
- - `setFont(name)` - Font family
516
- - `setFontSize(size)` - Font size in points
517
- - `setColor(color)` - Text color (hex)
518
- - `setHighlight(color)` - Highlight color
355
+ **Cleanup**: `removeEmptyRows`, `removeEmptyColumns`
519
356
 
520
- **Advanced:**
357
+ ### TableCell
521
358
 
522
- - `setSubscript(value)` - Subscript
523
- - `setSuperscript(value)` - Superscript
524
- - `setSmallCaps(value)` - Small capitals
525
- - `setAllCaps(value)` - All capitals
526
- - `clearMatchingFormatting(styleFormatting)` - Remove formatting matching a style (for inheritance)
527
- - `equals(other)` - Compare text and formatting equality
528
- - `hasSameFormatting(other)` - Compare formatting only
529
- - `clone()` - Deep copy run
359
+ **Content**: `addParagraph`, `getParagraphs`, `removeTrailingBlankParagraphs`, `removeParagraph`, `addParagraphAt`
530
360
 
531
- ### Table Class
361
+ **Formatting**: `setBorders`, `setShading`, `setBackgroundColor` / `getBackgroundColor`, `setVerticalAlignment`, `setWidth`
532
362
 
533
- **Structure:**
363
+ **Spanning**: `setHorizontalMerge`, `setVerticalMerge`
534
364
 
535
- - `addRow()` - Add row
536
- - `addRowFromArray(cells)` - Add row from string array
537
- - `getRow(index)` - Get row by index
538
- - `getCell(row, col)` - Get specific cell
539
- - `setCell(row, col, text)` - Set cell text by coordinates
540
- - `duplicateRow(index, count?)` - Clone a row in-place
541
- - `addSummaryRow(options?)` - Add computed totals row
365
+ **Convenience**: `setTextAlignment`, `setAllParagraphsStyle`, `setAllRunsFont`, `setAllRunsSize`, `setAllRunsColor`
542
366
 
543
- **Data Conversion:**
367
+ ### Section
544
368
 
545
- - `fromArray(data)` / `toArray()` - 2D string array I/O
546
- - `fromCSV(csv, delimiter?)` / `toCSV(delimiter?)` - CSV round-trip
547
- - `toPlainText(colSep?, rowSep?)` - Delimited text export
548
- - `transpose()` - Swap rows and columns
549
- - `clone()` - Deep copy table
369
+ **Line numbering**: `setLineNumbering(options)`, `getLineNumbering()`, `clearLineNumbering()`
550
370
 
551
- **Queries:**
371
+ ### Comment & CommentManager
552
372
 
553
- - `getColumnCells(colIndex)` - Get cells in a column
554
- - `getColumnTexts(colIndex)` - Get text values in a column
555
- - `findCell(predicate)` - Find first matching cell with coordinates
556
- - `filterRows(predicate)` - Get indices of matching rows
557
- - `forEachCell(callback)` - Iterate all cells with row/col
558
- - `mapColumn(colIndex, transform)` - Transform column values
373
+ **Comment**: `resolve()`, `unresolve()`, `isResolved()`
559
374
 
560
- **Cleanup:**
375
+ **CommentManager**: `getResolvedComments()`, `getUnresolvedComments()`
561
376
 
562
- - `removeEmptyRows()` - Remove rows with no text
563
- - `removeEmptyColumns()` - Remove columns with no text
377
+ ### Utilities
564
378
 
565
- **Formatting:**
379
+ **Unit conversion**
566
380
 
567
- - `setBorders(borders)` - Table borders
568
- - `setAlignment(alignment)` - Table alignment
569
- - `setWidth(width)` - Table width
570
- - `setLayout(layout)` - Fixed or auto layout
381
+ ```typescript
382
+ import { twipsToPoints, inchesToTwips, emusToPixels } from 'docxmlater';
571
383
 
572
- **Style:**
384
+ twipsToPoints(240); // 12 points
385
+ inchesToTwips(1); // 1440 twips
386
+ emusToPixels(914400, 96); // 96 pixels at 96 DPI
387
+ ```
573
388
 
574
- - `applyStyle(styleId)` - Apply table style
389
+ 40+ conversion helpers across twips, EMUs, points, pixels, inches, and centimeters.
575
390
 
576
- ### TableCell Class
391
+ **Validation**
577
392
 
578
- **Content:**
393
+ ```typescript
394
+ import { validateRunText, cleanXmlFromText } from 'docxmlater';
579
395
 
580
- - `addParagraph()` - Add paragraph to cell
581
- - `getParagraphs()` - Get all paragraphs
396
+ const result = validateRunText('Some <w:t>text</w:t>');
397
+ if (result.hasXml) {
398
+ const cleaned = cleanXmlFromText(result.text);
399
+ }
400
+ ```
582
401
 
583
- **Formatting:**
402
+ **Corruption detection**
584
403
 
585
- - `setBorders(borders)` - Cell borders
586
- - `setShading(shading)` - Cell shading/background
587
- - `setBackgroundColor(hex)` / `getBackgroundColor()` - Simple color shortcut
588
- - `setVerticalAlignment(alignment)` - Top, center, bottom
589
- - `setWidth(width)` - Cell width
404
+ ```typescript
405
+ import { detectCorruptionInDocument } from 'docxmlater';
590
406
 
591
- **Spanning:**
407
+ const doc = await Document.load('suspect.docx');
408
+ const report = detectCorruptionInDocument(doc);
592
409
 
593
- - `setHorizontalMerge(mergeType)` - Horizontal merge
594
- - `setVerticalMerge(mergeType)` - Vertical merge
410
+ if (report.isCorrupted) {
411
+ report.locations.forEach((loc) => {
412
+ console.log(`Line ${loc.lineNumber}: ${loc.issue}`);
413
+ });
414
+ }
415
+ ```
595
416
 
596
- **Convenience Methods:**
417
+ ---
597
418
 
598
- - `setTextAlignment(alignment)` - Set alignment for all paragraphs
599
- - `setAllParagraphsStyle(styleId)` - Apply style to all paragraphs
600
- - `setAllRunsFont(fontName)` - Apply font to all runs
601
- - `setAllRunsSize(size)` - Apply font size to all runs
602
- - `setAllRunsColor(color)` - Apply color to all runs
419
+ ## Advanced Topics
603
420
 
604
- **Content Management:**
421
+ ### Tracked Changes
605
422
 
606
- - `removeTrailingBlankParagraphs(options?)` - Remove trailing blank paragraphs from cell
607
- - `removeParagraph(index)` - Remove paragraph at index (updates nested content positions)
608
- - `addParagraphAt(index, paragraph)` - Insert paragraph at index (updates nested content positions)
423
+ By default, `Document.load()` accepts all tracked changes during loading. This prevents revision-ID conflicts that can cause Word to report "unreadable content" on round-trip.
609
424
 
610
- ### Document Class
425
+ ```typescript
426
+ const doc = await Document.load('document.docx', {
427
+ revisionHandling: 'accept', // default - keep insertions, drop deletions
428
+ // revisionHandling: 'strip', - remove all revision markup entirely
429
+ // revisionHandling: 'preserve', - keep tracked changes verbatim (advanced)
430
+ });
431
+ ```
611
432
 
612
- **Table Style Shading:**
433
+ | Mode | Behavior |
434
+ | ------------------ | ------------------------------------------------------------------------ |
435
+ | `accept` (default) | Removes revision markup, keeps inserted content, removes deleted content |
436
+ | `strip` | Removes all revision markup completely |
437
+ | `preserve` | Keeps tracked changes intact for advanced workflows |
613
438
 
614
- - `updateTableStyleShading(oldColor, newColor)` - Update shading colors in styles.xml
615
- - `updateTableStyleShadingBulk(settings)` - Bulk update table style shading
616
- - `removeTrailingBlanksInTableCells(options?)` - Remove trailing blanks from all table cells
439
+ ### Custom Styles
617
440
 
618
- ### Table Class
441
+ ```typescript
442
+ import { Document, Style } from 'docxmlater';
619
443
 
620
- **Sorting:**
444
+ const doc = Document.create();
621
445
 
622
- - `sortRows(columnIndex, options?)` - Sort table rows by column
446
+ const heading = new Style('CustomHeading', 'paragraph');
447
+ heading.setName('Custom Heading');
448
+ heading.setRunFormatting({ bold: true, fontSize: 32, color: '0070C0' });
449
+ heading.setParagraphFormatting({ alignment: 'center', spacingAfter: 240 });
623
450
 
624
- ### Section Class
451
+ doc.getStylesManager().addStyle(heading);
625
452
 
626
- **Line Numbering:**
453
+ const para = doc.createParagraph();
454
+ para.addText('Styled Heading');
455
+ para.applyStyle('CustomHeading');
627
456
 
628
- - `setLineNumbering(options)` - Enable line numbering
629
- - `getLineNumbering()` - Get line numbering settings
630
- - `clearLineNumbering()` - Disable line numbering
457
+ await doc.save('styled.docx');
458
+ doc.dispose();
459
+ ```
631
460
 
632
- ### Comment Class
461
+ ### Hyperlink Management
633
462
 
634
- **Resolution:**
463
+ ```typescript
464
+ const doc = await Document.load('document.docx');
635
465
 
636
- - `resolve()` - Mark comment as resolved
637
- - `unresolve()` - Mark comment as unresolved
638
- - `isResolved()` - Check if comment is resolved
466
+ const links = doc.getHyperlinks();
467
+ console.log(`Found ${links.length} hyperlinks`);
639
468
 
640
- ### CommentManager Class
469
+ doc.updateHyperlinkUrls('http://old-domain.com', 'https://new-domain.com');
641
470
 
642
- **Filtering:**
471
+ const merged = doc.defragmentHyperlinks({ resetFormatting: true });
472
+ console.log(`Merged ${merged} fragmented hyperlinks`);
643
473
 
644
- - `getResolvedComments()` - Get all resolved comments
645
- - `getUnresolvedComments()` - Get all unresolved comments
474
+ await doc.save('updated.docx');
475
+ doc.dispose();
476
+ ```
646
477
 
647
- ### Utilities
478
+ `defragmentHyperlinks` repairs fragmented links commonly produced by Google Docs exports. Batch URL updates run 30-50% faster than manual iteration.
648
479
 
649
- **Unit Conversions:**
480
+ ### Compatibility Mode
650
481
 
651
482
  ```typescript
652
- import { twipsToPoints, inchesToTwips, emusToPixels } from 'docxmlater';
653
-
654
- const points = twipsToPoints(240); // 240 twips = 12 points
655
- const twips = inchesToTwips(1); // 1 inch = 1440 twips
656
- const pixels = emusToPixels(914400, 96); // 914400 EMUs = 96 pixels at 96 DPI
657
- ```
483
+ const doc = await Document.load('legacy.docx');
658
484
 
659
- **Validation:**
485
+ console.log(`Mode: ${doc.getCompatibilityMode()}`); // e.g. 12 (Word 2007)
660
486
 
661
- ```typescript
662
- import { validateRunText, detectXmlInText, cleanXmlFromText } from 'docxmlater';
487
+ if (doc.isCompatibilityMode()) {
488
+ const info = doc.getCompatibilityInfo();
489
+ console.log(`Legacy flags: ${info.legacyFlags.length}`);
663
490
 
664
- // Detect XML patterns in text
665
- const result = validateRunText('Some <w:t>text</w:t>');
666
- if (result.hasXml) {
667
- console.warn(result.message);
668
- const cleaned = cleanXmlFromText(result.text);
491
+ const report = doc.upgradeToModernFormat();
492
+ console.log(`Removed ${report.removedFlags.length} legacy flags`);
493
+ console.log(`Added ${report.addedSettings.length} modern settings`);
669
494
  }
670
- ```
671
-
672
- **Corruption Detection:**
673
-
674
- ```typescript
675
- import { detectCorruptionInDocument } from 'docxmlater';
676
-
677
- const doc = await Document.load('suspect.docx');
678
- const report = detectCorruptionInDocument(doc);
679
495
 
680
- if (report.isCorrupted) {
681
- console.log(`Found ${report.locations.length} corruption issues`);
682
- report.locations.forEach((loc) => {
683
- console.log(`Line ${loc.lineNumber}: ${loc.issue}`);
684
- console.log(`Suggested fix: ${loc.suggestedFix}`);
685
- });
686
- }
496
+ await doc.save('modern.docx');
497
+ doc.dispose();
687
498
  ```
688
499
 
689
- ## TypeScript Support
500
+ `upgradeToModernFormat()` is the programmatic equivalent of _File → Info → Convert_ in Word.
690
501
 
691
- Full TypeScript definitions included:
502
+ ### Templates
692
503
 
693
504
  ```typescript
694
- import {
695
- Document,
696
- Paragraph,
697
- Run,
698
- Table,
699
- RunFormatting,
700
- ParagraphFormatting,
701
- DocumentProperties,
702
- } from 'docxmlater';
505
+ const doc = await Document.load('template.docx');
703
506
 
704
- // Type-safe formatting
705
- const formatting: RunFormatting = {
706
- bold: true,
707
- fontSize: 12,
708
- color: 'FF0000',
709
- };
507
+ doc.fillTemplate({
508
+ customer: 'Acme Corp',
509
+ date: '2025-04-25',
510
+ total: '$12,400.00',
511
+ });
710
512
 
711
- // Type-safe document properties
712
- const properties: DocumentProperties = {
713
- title: 'My Document',
714
- author: 'John Doe',
715
- created: new Date(),
716
- };
513
+ await doc.save('invoice-acme.docx');
514
+ doc.dispose();
717
515
  ```
718
516
 
719
- ## Version History
517
+ Placeholders use `{{key}}` syntax and are replaced safely across run boundaries.
720
518
 
721
- **Current Version: 10.4.0**
519
+ ### Document Conversion
722
520
 
723
- See [CHANGELOG.md](CHANGELOG.md) for detailed version history.
724
-
725
- ## Testing
726
-
727
- The framework includes comprehensive test coverage:
728
-
729
- - **4,134 test cases** across 195 test suites
730
- - Tests cover all phases of implementation
731
- - Integration tests for complex scenarios
732
- - Performance benchmarks
733
- - Edge case validation
521
+ ```typescript
522
+ const doc = await Document.load('report.docx');
734
523
 
735
- Run tests:
524
+ const md = doc.toMarkdown();
525
+ const html = doc.toHTML({ fullPage: true });
526
+ const base64 = doc.toBase64();
736
527
 
737
- ```bash
738
- npm test # Run all tests
739
- npm run test:watch # Watch mode
740
- npm run test:coverage # Coverage report
528
+ doc.dispose();
741
529
  ```
742
530
 
743
- ## Performance Considerations
531
+ ---
744
532
 
745
- - Use `dispose()` to free resources after document operations
746
- - Buffer-based operations are faster than file I/O
747
- - Batch hyperlink updates are 30-50% faster than manual iteration
748
- - Large documents (1000+ pages) supported with memory management
749
- - Streaming support for very large files
533
+ ## Performance & Memory Management
750
534
 
751
- ## Error Handling
535
+ - **Always call `dispose()`** to release ZIP handles and image buffers
536
+ - Buffer-based I/O (`loadFromBuffer` / `toBuffer`) is 20-30% faster than file-path I/O
537
+ - Default size limits: warn at 50 MB, error at 150 MB (configurable via `LoadOptions.sizeLimits`)
538
+ - Memory footprint: ~2 MB per `Document`, ~2 bytes/character, full buffer per embedded image, ~200 bytes/cell
539
+ - For repeated paragraph access, cache `getAllParagraphs()` rather than calling it inside a loop
540
+ - Large documents (1,000+ pages) are supported
752
541
 
753
- All document operations should be wrapped in try/finally to ensure proper cleanup:
542
+ ### Recommended Pattern
754
543
 
755
544
  ```typescript
756
545
  import { Document } from 'docxmlater';
@@ -767,11 +556,11 @@ try {
767
556
  }
768
557
  ```
769
558
 
770
- For buffer-based workflows (common in web servers):
559
+ For server-side buffer workflows:
771
560
 
772
561
  ```typescript
773
- async function processDocument(inputBuffer: Buffer): Promise<Buffer> {
774
- const doc = await Document.loadFromBuffer(inputBuffer);
562
+ async function processDocument(input: Buffer): Promise<Buffer> {
563
+ const doc = await Document.loadFromBuffer(input);
775
564
  try {
776
565
  doc.replaceText(/placeholder/g, 'actual value');
777
566
  return await doc.toBuffer();
@@ -781,132 +570,116 @@ async function processDocument(inputBuffer: Buffer): Promise<Buffer> {
781
570
  }
782
571
  ```
783
572
 
784
- Custom error types from `docxmlater` include `InvalidDocxError`, `CorruptedArchiveError`, and `FileOperationError` — all extend `DocxError`.
573
+ Custom error types are available from `docxmlater/internal`. These include `DocxError`, `InvalidDocxError`, `CorruptedArchiveError`, and `FileOperationError`.
785
574
 
786
- ## Working with Large Documents
575
+ Logging is configurable via `DOCXMLATER_LOG_LEVEL=debug|info|warn|error`.
787
576
 
788
- - Use buffer operations (`loadFromBuffer`/`toBuffer`) for 20-30% faster I/O
789
- - Call `dispose()` promptly to release ZIP handles and image buffers
790
- - Size limits default to warning at 50MB and error at 150MB (configurable via `LoadOptions.sizeLimits`)
791
- - Memory usage: ~2MB base per Document, ~2 bytes/char, full buffer per embedded image, ~200 bytes/cell
792
- - For repeated paragraph access, cache the result of `getAllParagraphs()` rather than calling it in a loop
577
+ ---
793
578
 
794
579
  ## Architecture
795
580
 
796
- The framework follows a modular architecture:
797
-
798
581
  ```
799
582
  src/
800
- ├── core/ # Document, Parser, Generator, Validator
801
- ├── elements/ # Paragraph, Run, Table, Image, etc.
802
- ├── formatting/ # Style, Numbering managers
803
- ├── managers/ # Drawing, Image, Relationship managers
804
- ├── constants/ # Compatibility mode constants, limits
805
- ├── types/ # Type definitions (compatibility, formatting, lists)
806
- ├── tracking/ # Change tracking context
807
- ├── validation/ # Revision validation rules
808
- ├── helpers/ # Cleanup utilities
809
- ├── xml/ # XML generation and parsing
810
- ├── zip/ # ZIP archive handling
811
- └── utils/ # Validation, units, error handling
583
+ ├── core/ Document, Parser, Generator, Validator
584
+ ├── elements/ Paragraph, Run, Table, Image, Section, ...
585
+ ├── formatting/ Style and Numbering managers
586
+ ├── managers/ Drawing, Image, Relationship managers
587
+ ├── tracking/ Revision tracking context
588
+ ├── validation/ Revision and structural validation
589
+ ├── helpers/ Cleanup utilities
590
+ ├── xml/ XML generation and parsing (ReDoS-safe)
591
+ ├── zip/ ZIP archive handling
592
+ ├── constants/ Compatibility flags, limits, schema constants
593
+ ├── types/ TypeScript type definitions
594
+ └── utils/ Units, validation, error handling
812
595
  ```
813
596
 
814
- Key design principles:
597
+ **Design principles**
815
598
 
816
- - KISS (Keep It Simple, Stupid) - no over-engineering
817
- - Position-based XML parsing (ReDoS-safe)
818
- - Defensive programming with comprehensive validation
819
- - Memory-efficient with explicit disposal pattern
820
- - Full ECMA-376 (OpenXML) compliance
599
+ - Strict adherence to ECMA-376 (Office Open XML)
600
+ - Position-based XML parsing (not regex) to prevent ReDoS
601
+ - Round-trip XML fidelity through `_originalXml` preservation and dirty-flag regeneration
602
+ - Explicit memory management via the `dispose()` pattern
603
+ - Defensive validation with comprehensive type coverage
821
604
 
822
- ## Security
605
+ ---
823
606
 
824
- docXMLater includes multiple security measures to protect against common attack vectors:
825
-
826
- ### ReDoS Prevention
827
-
828
- The XML parser uses position-based parsing instead of regular expressions, preventing catastrophic backtracking attacks that can cause denial of service.
829
-
830
- ### Input Validation
831
-
832
- **Size Limits:**
607
+ ## Security
833
608
 
834
- - Default document size limit: 150 MB (configurable)
835
- - Warning threshold: 50 MB
836
- - XML content size validation before parsing
609
+ - **ReDoS protection** - position-based XML parsing eliminates catastrophic backtracking
610
+ - **Path traversal prevention** - DOCX archive entries are validated against `../`, absolute paths, and URL-encoded traversal
611
+ - **XML injection prevention** - all text and attribute content is escaped via `XMLBuilder.escapeXmlText()` and `XMLBuilder.escapeXmlAttribute()`
612
+ - **Size limits** - configurable warning (50 MB) and hard cap (150 MB) on document size
613
+ - **Nesting limits** - XML parser caps nesting depth at 256 levels (configurable) to prevent stack overflow
614
+ - **UTF-8 enforcement** - all text content is explicitly UTF-8 encoded per ECMA-376
837
615
 
838
616
  ```typescript
839
- // Configure size limits
840
617
  const doc = await Document.load('large.docx', {
841
- sizeLimits: {
842
- warningSizeMB: 100,
843
- maxSizeMB: 500,
844
- },
618
+ sizeLimits: { warningSizeMB: 100, maxSizeMB: 500 },
845
619
  });
846
620
  ```
847
621
 
848
- **Nesting Depth:**
849
-
850
- - Maximum XML nesting depth: 256 (configurable)
851
- - Prevents stack overflow attacks
852
-
853
622
  ```typescript
854
- import { XMLParser } from 'docxmlater';
623
+ import { XMLParser } from 'docxmlater/internal';
855
624
 
856
- // Parse with custom depth limit
857
- const obj = XMLParser.parseToObject(xml, {
858
- maxNestingDepth: 512, // Increase if needed
859
- });
625
+ const obj = XMLParser.parseToObject(xml, { maxNestingDepth: 512 });
860
626
  ```
861
627
 
862
- ### Path Traversal Prevention
863
-
864
- File paths within DOCX archives are validated to prevent directory traversal attacks:
628
+ ---
865
629
 
866
- - Blocks `../` path sequences
867
- - Blocks absolute paths
868
- - Validates URL-encoded path components
869
-
870
- ### XML Injection Prevention
630
+ ## TypeScript Support
871
631
 
872
- All text content is properly escaped using:
632
+ Full type definitions are bundled with the package:
873
633
 
874
- - `XMLBuilder.escapeXmlText()` for element content
875
- - `XMLBuilder.escapeXmlAttribute()` for attribute values
634
+ ```typescript
635
+ import {
636
+ Document,
637
+ Paragraph,
638
+ Run,
639
+ Table,
640
+ RunFormatting,
641
+ ParagraphFormatting,
642
+ DocumentProperties,
643
+ } from 'docxmlater';
876
644
 
877
- This prevents injection of malicious XML elements through user-provided text content.
645
+ const formatting: RunFormatting = {
646
+ bold: true,
647
+ fontSize: 12,
648
+ color: 'FF0000',
649
+ };
878
650
 
879
- ### UTF-8 Encoding
651
+ const properties: DocumentProperties = {
652
+ title: 'My Document',
653
+ author: 'Jane Doe',
654
+ created: new Date(),
655
+ };
656
+ ```
880
657
 
881
- All text files are explicitly UTF-8 encoded per ECMA-376 specification, preventing encoding-related vulnerabilities.
658
+ ---
882
659
 
883
660
  ## Requirements
884
661
 
885
662
  - Node.js 18.0.0 or higher
886
663
  - TypeScript 5.0+ (for development)
887
664
 
888
- ## Dependencies
889
-
890
- - `jszip` - ZIP archive handling
665
+ Single runtime dependency: `jszip`.
891
666
 
892
- ## License
893
-
894
- MIT
667
+ ---
895
668
 
896
669
  ## Contributing
897
670
 
898
- Contributions welcome! Please:
671
+ Contributions are welcome. Please:
899
672
 
900
673
  1. Fork the repository
901
674
  2. Create a feature branch
902
- 3. Add tests for new features
903
- 4. Ensure all tests pass
904
- 5. Submit a pull request
675
+ 3. Add tests for any new functionality
676
+ 4. Ensure the full test suite passes (`npm test`)
677
+ 5. Open a pull request
905
678
 
906
- ## Support
679
+ If you have a use case that is not yet supported, opening an issue first is the best way to discuss design before code.
907
680
 
908
- - GitHub Issues: https://github.com/ItMeDiaTech/docXMLater/issues
681
+ ---
909
682
 
910
- ## Acknowledgments
683
+ ## License
911
684
 
912
- Built with careful attention to the ECMA-376 Office Open XML specification. Special thanks to the OpenXML community for comprehensive documentation and examples.
685
+ MIT