docxmlater 10.1.4 → 10.1.5

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 (371) hide show
  1. package/README.md +759 -754
  2. package/dist/constants/legacyCompatFlags.js +1 -1
  3. package/dist/constants/legacyCompatFlags.js.map +1 -1
  4. package/dist/constants/limits.js.map +1 -1
  5. package/dist/core/Document.d.ts +50 -50
  6. package/dist/core/Document.d.ts.map +1 -1
  7. package/dist/core/Document.js +483 -471
  8. package/dist/core/Document.js.map +1 -1
  9. package/dist/core/DocumentContent.d.ts +9 -9
  10. package/dist/core/DocumentContent.d.ts.map +1 -1
  11. package/dist/core/DocumentContent.js +1 -1
  12. package/dist/core/DocumentContent.js.map +1 -1
  13. package/dist/core/DocumentGenerator.d.ts +11 -11
  14. package/dist/core/DocumentGenerator.d.ts.map +1 -1
  15. package/dist/core/DocumentGenerator.js +251 -251
  16. package/dist/core/DocumentGenerator.js.map +1 -1
  17. package/dist/core/DocumentIdManager.js.map +1 -1
  18. package/dist/core/DocumentParser.d.ts +15 -15
  19. package/dist/core/DocumentParser.d.ts.map +1 -1
  20. package/dist/core/DocumentParser.js +2123 -2155
  21. package/dist/core/DocumentParser.js.map +1 -1
  22. package/dist/core/DocumentValidator.d.ts.map +1 -1
  23. package/dist/core/DocumentValidator.js +2 -5
  24. package/dist/core/DocumentValidator.js.map +1 -1
  25. package/dist/core/Relationship.js.map +1 -1
  26. package/dist/core/RelationshipManager.d.ts.map +1 -1
  27. package/dist/core/RelationshipManager.js +3 -3
  28. package/dist/core/RelationshipManager.js.map +1 -1
  29. package/dist/elements/AlternateContent.js.map +1 -1
  30. package/dist/elements/Bookmark.d.ts.map +1 -1
  31. package/dist/elements/Bookmark.js +3 -1
  32. package/dist/elements/Bookmark.js.map +1 -1
  33. package/dist/elements/BookmarkManager.d.ts.map +1 -1
  34. package/dist/elements/BookmarkManager.js.map +1 -1
  35. package/dist/elements/Comment.d.ts.map +1 -1
  36. package/dist/elements/Comment.js +9 -6
  37. package/dist/elements/Comment.js.map +1 -1
  38. package/dist/elements/CommentManager.d.ts.map +1 -1
  39. package/dist/elements/CommentManager.js +18 -17
  40. package/dist/elements/CommentManager.js.map +1 -1
  41. package/dist/elements/CommonTypes.d.ts +21 -21
  42. package/dist/elements/CommonTypes.d.ts.map +1 -1
  43. package/dist/elements/CommonTypes.js +56 -56
  44. package/dist/elements/CommonTypes.js.map +1 -1
  45. package/dist/elements/CustomXml.js.map +1 -1
  46. package/dist/elements/Endnote.d.ts.map +1 -1
  47. package/dist/elements/Endnote.js +6 -6
  48. package/dist/elements/Endnote.js.map +1 -1
  49. package/dist/elements/EndnoteManager.d.ts.map +1 -1
  50. package/dist/elements/EndnoteManager.js +6 -7
  51. package/dist/elements/EndnoteManager.js.map +1 -1
  52. package/dist/elements/Field.d.ts.map +1 -1
  53. package/dist/elements/Field.js +82 -25
  54. package/dist/elements/Field.js.map +1 -1
  55. package/dist/elements/FieldHelpers.d.ts.map +1 -1
  56. package/dist/elements/FieldHelpers.js.map +1 -1
  57. package/dist/elements/FontManager.d.ts.map +1 -1
  58. package/dist/elements/FontManager.js +1 -1
  59. package/dist/elements/FontManager.js.map +1 -1
  60. package/dist/elements/Footer.js +2 -2
  61. package/dist/elements/Footer.js.map +1 -1
  62. package/dist/elements/Footnote.d.ts.map +1 -1
  63. package/dist/elements/Footnote.js +6 -6
  64. package/dist/elements/Footnote.js.map +1 -1
  65. package/dist/elements/FootnoteManager.d.ts.map +1 -1
  66. package/dist/elements/FootnoteManager.js +6 -7
  67. package/dist/elements/FootnoteManager.js.map +1 -1
  68. package/dist/elements/Header.js +2 -2
  69. package/dist/elements/Header.js.map +1 -1
  70. package/dist/elements/HeaderFooterManager.js.map +1 -1
  71. package/dist/elements/Hyperlink.d.ts +5 -3
  72. package/dist/elements/Hyperlink.d.ts.map +1 -1
  73. package/dist/elements/Hyperlink.js +134 -76
  74. package/dist/elements/Hyperlink.js.map +1 -1
  75. package/dist/elements/Image.d.ts.map +1 -1
  76. package/dist/elements/Image.js +238 -106
  77. package/dist/elements/Image.js.map +1 -1
  78. package/dist/elements/ImageManager.d.ts.map +1 -1
  79. package/dist/elements/ImageManager.js +1 -1
  80. package/dist/elements/ImageManager.js.map +1 -1
  81. package/dist/elements/ImageRun.js +1 -1
  82. package/dist/elements/ImageRun.js.map +1 -1
  83. package/dist/elements/MathElement.js.map +1 -1
  84. package/dist/elements/Paragraph.d.ts +24 -24
  85. package/dist/elements/Paragraph.d.ts.map +1 -1
  86. package/dist/elements/Paragraph.js +181 -188
  87. package/dist/elements/Paragraph.js.map +1 -1
  88. package/dist/elements/PreservedElement.js.map +1 -1
  89. package/dist/elements/PropertyChangeTypes.d.ts.map +1 -1
  90. package/dist/elements/PropertyChangeTypes.js +6 -6
  91. package/dist/elements/PropertyChangeTypes.js.map +1 -1
  92. package/dist/elements/RangeMarker.d.ts.map +1 -1
  93. package/dist/elements/RangeMarker.js.map +1 -1
  94. package/dist/elements/Revision.d.ts.map +1 -1
  95. package/dist/elements/Revision.js +4 -5
  96. package/dist/elements/Revision.js.map +1 -1
  97. package/dist/elements/RevisionContent.js.map +1 -1
  98. package/dist/elements/RevisionManager.d.ts.map +1 -1
  99. package/dist/elements/RevisionManager.js +40 -48
  100. package/dist/elements/RevisionManager.js.map +1 -1
  101. package/dist/elements/Run.d.ts +16 -16
  102. package/dist/elements/Run.d.ts.map +1 -1
  103. package/dist/elements/Run.js +256 -238
  104. package/dist/elements/Run.js.map +1 -1
  105. package/dist/elements/Section.d.ts.map +1 -1
  106. package/dist/elements/Section.js +36 -11
  107. package/dist/elements/Section.js.map +1 -1
  108. package/dist/elements/Shape.d.ts.map +1 -1
  109. package/dist/elements/Shape.js.map +1 -1
  110. package/dist/elements/StructuredDocumentTag.d.ts +6 -6
  111. package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
  112. package/dist/elements/StructuredDocumentTag.js +99 -104
  113. package/dist/elements/StructuredDocumentTag.js.map +1 -1
  114. package/dist/elements/Table.d.ts +11 -11
  115. package/dist/elements/Table.d.ts.map +1 -1
  116. package/dist/elements/Table.js +102 -107
  117. package/dist/elements/Table.js.map +1 -1
  118. package/dist/elements/TableCell.d.ts +10 -10
  119. package/dist/elements/TableCell.d.ts.map +1 -1
  120. package/dist/elements/TableCell.js +105 -106
  121. package/dist/elements/TableCell.js.map +1 -1
  122. package/dist/elements/TableGridChange.d.ts.map +1 -1
  123. package/dist/elements/TableGridChange.js.map +1 -1
  124. package/dist/elements/TableOfContents.d.ts.map +1 -1
  125. package/dist/elements/TableOfContents.js +4 -4
  126. package/dist/elements/TableOfContents.js.map +1 -1
  127. package/dist/elements/TableOfContentsElement.js.map +1 -1
  128. package/dist/elements/TableRow.d.ts.map +1 -1
  129. package/dist/elements/TableRow.js +13 -6
  130. package/dist/elements/TableRow.js.map +1 -1
  131. package/dist/elements/TextBox.d.ts.map +1 -1
  132. package/dist/elements/TextBox.js +3 -5
  133. package/dist/elements/TextBox.js.map +1 -1
  134. package/dist/formatting/AbstractNumbering.d.ts +4 -4
  135. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  136. package/dist/formatting/AbstractNumbering.js +54 -49
  137. package/dist/formatting/AbstractNumbering.js.map +1 -1
  138. package/dist/formatting/NumberingInstance.d.ts.map +1 -1
  139. package/dist/formatting/NumberingInstance.js +1 -3
  140. package/dist/formatting/NumberingInstance.js.map +1 -1
  141. package/dist/formatting/NumberingLevel.d.ts +5 -5
  142. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  143. package/dist/formatting/NumberingLevel.js +119 -125
  144. package/dist/formatting/NumberingLevel.js.map +1 -1
  145. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  146. package/dist/formatting/NumberingManager.js +9 -9
  147. package/dist/formatting/NumberingManager.js.map +1 -1
  148. package/dist/formatting/Style.d.ts +11 -11
  149. package/dist/formatting/Style.d.ts.map +1 -1
  150. package/dist/formatting/Style.js +219 -247
  151. package/dist/formatting/Style.js.map +1 -1
  152. package/dist/formatting/StylesManager.d.ts +2 -2
  153. package/dist/formatting/StylesManager.d.ts.map +1 -1
  154. package/dist/formatting/StylesManager.js +96 -102
  155. package/dist/formatting/StylesManager.js.map +1 -1
  156. package/dist/helpers/CleanupHelper.d.ts +1 -1
  157. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  158. package/dist/helpers/CleanupHelper.js +6 -6
  159. package/dist/helpers/CleanupHelper.js.map +1 -1
  160. package/dist/images/ImageOptimizer.js +7 -7
  161. package/dist/images/ImageOptimizer.js.map +1 -1
  162. package/dist/index.d.ts +9 -9
  163. package/dist/index.d.ts.map +1 -1
  164. package/dist/index.js.map +1 -1
  165. package/dist/managers/DrawingManager.js.map +1 -1
  166. package/dist/tracking/DocumentTrackingContext.d.ts.map +1 -1
  167. package/dist/tracking/DocumentTrackingContext.js +23 -7
  168. package/dist/tracking/DocumentTrackingContext.js.map +1 -1
  169. package/dist/tracking/TrackingContext.d.ts.map +1 -1
  170. package/dist/tracking/TrackingContext.js.map +1 -1
  171. package/dist/types/compatibility-types.js.map +1 -1
  172. package/dist/types/formatting.js.map +1 -1
  173. package/dist/types/list-types.d.ts +6 -6
  174. package/dist/types/list-types.js.map +1 -1
  175. package/dist/types/settings-types.js.map +1 -1
  176. package/dist/types/styleConfig.d.ts +2 -2
  177. package/dist/types/styleConfig.js.map +1 -1
  178. package/dist/utils/ChangelogGenerator.d.ts.map +1 -1
  179. package/dist/utils/ChangelogGenerator.js +97 -101
  180. package/dist/utils/ChangelogGenerator.js.map +1 -1
  181. package/dist/utils/CompatibilityUpgrader.d.ts.map +1 -1
  182. package/dist/utils/CompatibilityUpgrader.js +1 -1
  183. package/dist/utils/CompatibilityUpgrader.js.map +1 -1
  184. package/dist/utils/InMemoryRevisionAcceptor.d.ts.map +1 -1
  185. package/dist/utils/InMemoryRevisionAcceptor.js +1 -6
  186. package/dist/utils/InMemoryRevisionAcceptor.js.map +1 -1
  187. package/dist/utils/MoveOperationHelper.d.ts.map +1 -1
  188. package/dist/utils/MoveOperationHelper.js +1 -1
  189. package/dist/utils/MoveOperationHelper.js.map +1 -1
  190. package/dist/utils/RevisionAwareProcessor.d.ts.map +1 -1
  191. package/dist/utils/RevisionAwareProcessor.js +2 -4
  192. package/dist/utils/RevisionAwareProcessor.js.map +1 -1
  193. package/dist/utils/RevisionWalker.d.ts.map +1 -1
  194. package/dist/utils/RevisionWalker.js +4 -12
  195. package/dist/utils/RevisionWalker.js.map +1 -1
  196. package/dist/utils/SelectiveRevisionAcceptor.d.ts.map +1 -1
  197. package/dist/utils/SelectiveRevisionAcceptor.js +2 -6
  198. package/dist/utils/SelectiveRevisionAcceptor.js.map +1 -1
  199. package/dist/utils/ShadingResolver.d.ts.map +1 -1
  200. package/dist/utils/ShadingResolver.js +1 -1
  201. package/dist/utils/ShadingResolver.js.map +1 -1
  202. package/dist/utils/acceptRevisions.d.ts.map +1 -1
  203. package/dist/utils/acceptRevisions.js +23 -12
  204. package/dist/utils/acceptRevisions.js.map +1 -1
  205. package/dist/utils/cnfStyleDecoder.d.ts +1 -1
  206. package/dist/utils/cnfStyleDecoder.d.ts.map +1 -1
  207. package/dist/utils/cnfStyleDecoder.js +40 -40
  208. package/dist/utils/cnfStyleDecoder.js.map +1 -1
  209. package/dist/utils/corruptionDetection.d.ts.map +1 -1
  210. package/dist/utils/corruptionDetection.js.map +1 -1
  211. package/dist/utils/dateFormatting.js.map +1 -1
  212. package/dist/utils/deepClone.js +1 -1
  213. package/dist/utils/deepClone.js.map +1 -1
  214. package/dist/utils/diagnostics.d.ts.map +1 -1
  215. package/dist/utils/diagnostics.js +1 -1
  216. package/dist/utils/diagnostics.js.map +1 -1
  217. package/dist/utils/errorHandling.js.map +1 -1
  218. package/dist/utils/formatting.d.ts.map +1 -1
  219. package/dist/utils/formatting.js +10 -2
  220. package/dist/utils/formatting.js.map +1 -1
  221. package/dist/utils/list-detection.d.ts +2 -2
  222. package/dist/utils/list-detection.d.ts.map +1 -1
  223. package/dist/utils/list-detection.js +21 -23
  224. package/dist/utils/list-detection.js.map +1 -1
  225. package/dist/utils/logger.d.ts.map +1 -1
  226. package/dist/utils/logger.js +12 -7
  227. package/dist/utils/logger.js.map +1 -1
  228. package/dist/utils/parsingHelpers.js.map +1 -1
  229. package/dist/utils/stripTrackedChanges.d.ts.map +1 -1
  230. package/dist/utils/stripTrackedChanges.js +3 -3
  231. package/dist/utils/stripTrackedChanges.js.map +1 -1
  232. package/dist/utils/textDiff.d.ts +1 -1
  233. package/dist/utils/textDiff.js +8 -8
  234. package/dist/utils/textDiff.js.map +1 -1
  235. package/dist/utils/units.js.map +1 -1
  236. package/dist/utils/validation.d.ts.map +1 -1
  237. package/dist/utils/validation.js +24 -7
  238. package/dist/utils/validation.js.map +1 -1
  239. package/dist/utils/xmlSanitization.d.ts.map +1 -1
  240. package/dist/utils/xmlSanitization.js +3 -3
  241. package/dist/utils/xmlSanitization.js.map +1 -1
  242. package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
  243. package/dist/validation/RevisionAutoFixer.js +5 -5
  244. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  245. package/dist/validation/RevisionValidator.d.ts.map +1 -1
  246. package/dist/validation/RevisionValidator.js +7 -9
  247. package/dist/validation/RevisionValidator.js.map +1 -1
  248. package/dist/validation/ValidationRules.js +3 -3
  249. package/dist/validation/ValidationRules.js.map +1 -1
  250. package/dist/validation/index.js.map +1 -1
  251. package/dist/xml/XMLBuilder.d.ts +1 -1
  252. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  253. package/dist/xml/XMLBuilder.js +98 -100
  254. package/dist/xml/XMLBuilder.js.map +1 -1
  255. package/dist/xml/XMLParser.d.ts.map +1 -1
  256. package/dist/xml/XMLParser.js +61 -66
  257. package/dist/xml/XMLParser.js.map +1 -1
  258. package/dist/zip/ZipHandler.d.ts.map +1 -1
  259. package/dist/zip/ZipHandler.js.map +1 -1
  260. package/dist/zip/ZipReader.d.ts.map +1 -1
  261. package/dist/zip/ZipReader.js +1 -3
  262. package/dist/zip/ZipReader.js.map +1 -1
  263. package/dist/zip/ZipWriter.d.ts +1 -1
  264. package/dist/zip/ZipWriter.d.ts.map +1 -1
  265. package/dist/zip/ZipWriter.js +28 -36
  266. package/dist/zip/ZipWriter.js.map +1 -1
  267. package/dist/zip/types.js +1 -1
  268. package/dist/zip/types.js.map +1 -1
  269. package/package.json +92 -92
  270. package/src/__tests__/helper-methods.test.ts +512 -512
  271. package/src/constants/legacyCompatFlags.ts +138 -138
  272. package/src/constants/limits.ts +50 -50
  273. package/src/core/Document.ts +985 -1145
  274. package/src/core/DocumentContent.ts +461 -467
  275. package/src/core/DocumentGenerator.ts +1133 -1104
  276. package/src/core/DocumentIdManager.ts +158 -158
  277. package/src/core/DocumentParser.ts +2347 -2716
  278. package/src/core/DocumentValidator.ts +363 -372
  279. package/src/core/Relationship.ts +367 -367
  280. package/src/core/RelationshipManager.ts +429 -428
  281. package/src/elements/AlternateContent.ts +42 -42
  282. package/src/elements/Bookmark.ts +212 -210
  283. package/src/elements/BookmarkManager.ts +247 -250
  284. package/src/elements/Comment.ts +356 -359
  285. package/src/elements/CommentManager.ts +499 -502
  286. package/src/elements/CommonTypes.ts +524 -549
  287. package/src/elements/CustomXml.ts +36 -36
  288. package/src/elements/Endnote.ts +221 -217
  289. package/src/elements/EndnoteManager.ts +246 -249
  290. package/src/elements/Field.ts +1292 -1233
  291. package/src/elements/FieldHelpers.ts +329 -333
  292. package/src/elements/FontManager.ts +336 -339
  293. package/src/elements/Footer.ts +269 -269
  294. package/src/elements/Footnote.ts +221 -217
  295. package/src/elements/FootnoteManager.ts +246 -249
  296. package/src/elements/Header.ts +269 -269
  297. package/src/elements/HeaderFooterManager.ts +219 -219
  298. package/src/elements/Hyperlink.ts +1288 -1193
  299. package/src/elements/Image.ts +1982 -1756
  300. package/src/elements/ImageManager.ts +437 -432
  301. package/src/elements/ImageRun.ts +59 -59
  302. package/src/elements/MathElement.ts +65 -65
  303. package/src/elements/Paragraph.ts +4347 -4287
  304. package/src/elements/PreservedElement.ts +53 -53
  305. package/src/elements/PropertyChangeTypes.ts +458 -442
  306. package/src/elements/RangeMarker.ts +382 -400
  307. package/src/elements/Revision.ts +1198 -1217
  308. package/src/elements/RevisionContent.ts +73 -73
  309. package/src/elements/RevisionManager.ts +1070 -1070
  310. package/src/elements/Run.ts +3103 -3073
  311. package/src/elements/Section.ts +1521 -1421
  312. package/src/elements/Shape.ts +884 -873
  313. package/src/elements/StructuredDocumentTag.ts +1176 -1207
  314. package/src/elements/Table.ts +2468 -2524
  315. package/src/elements/TableCell.ts +1617 -1621
  316. package/src/elements/TableGridChange.ts +149 -151
  317. package/src/elements/TableOfContents.ts +701 -691
  318. package/src/elements/TableOfContentsElement.ts +89 -89
  319. package/src/elements/TableRow.ts +960 -929
  320. package/src/elements/TextBox.ts +766 -768
  321. package/src/formatting/AbstractNumbering.ts +580 -579
  322. package/src/formatting/NumberingInstance.ts +295 -299
  323. package/src/formatting/NumberingLevel.ts +981 -1040
  324. package/src/formatting/NumberingManager.ts +833 -827
  325. package/src/formatting/Style.ts +1785 -1879
  326. package/src/formatting/StylesManager.ts +1090 -1130
  327. package/src/helpers/CleanupHelper.ts +524 -524
  328. package/src/images/ImageOptimizer.ts +274 -274
  329. package/src/index.ts +559 -554
  330. package/src/managers/DrawingManager.ts +319 -319
  331. package/src/tracking/DocumentTrackingContext.ts +687 -674
  332. package/src/tracking/TrackingContext.ts +175 -173
  333. package/src/types/compatibility-types.ts +49 -49
  334. package/src/types/formatting.ts +210 -210
  335. package/src/types/list-types.ts +14 -14
  336. package/src/types/settings-types.ts +59 -59
  337. package/src/types/styleConfig.ts +189 -189
  338. package/src/utils/ChangelogGenerator.ts +1583 -1581
  339. package/src/utils/CompatibilityUpgrader.ts +235 -237
  340. package/src/utils/InMemoryRevisionAcceptor.ts +691 -696
  341. package/src/utils/MoveOperationHelper.ts +233 -238
  342. package/src/utils/RevisionAwareProcessor.ts +518 -526
  343. package/src/utils/RevisionWalker.ts +427 -457
  344. package/src/utils/SelectiveRevisionAcceptor.ts +662 -683
  345. package/src/utils/ShadingResolver.ts +105 -107
  346. package/src/utils/acceptRevisions.ts +723 -714
  347. package/src/utils/cnfStyleDecoder.ts +212 -217
  348. package/src/utils/corruptionDetection.ts +346 -345
  349. package/src/utils/dateFormatting.ts +20 -20
  350. package/src/utils/deepClone.ts +77 -78
  351. package/src/utils/diagnostics.ts +125 -129
  352. package/src/utils/errorHandling.ts +80 -80
  353. package/src/utils/formatting.ts +220 -213
  354. package/src/utils/list-detection.ts +32 -42
  355. package/src/utils/logger.ts +412 -404
  356. package/src/utils/parsingHelpers.ts +190 -190
  357. package/src/utils/stripTrackedChanges.ts +356 -353
  358. package/src/utils/textDiff.ts +100 -100
  359. package/src/utils/units.ts +421 -421
  360. package/src/utils/validation.ts +553 -542
  361. package/src/utils/xmlSanitization.ts +179 -182
  362. package/src/validation/RevisionAutoFixer.ts +541 -542
  363. package/src/validation/RevisionValidator.ts +470 -460
  364. package/src/validation/ValidationRules.ts +338 -338
  365. package/src/validation/index.ts +30 -30
  366. package/src/xml/XMLBuilder.ts +857 -871
  367. package/src/xml/XMLParser.ts +877 -919
  368. package/src/zip/ZipHandler.ts +629 -637
  369. package/src/zip/ZipReader.ts +295 -299
  370. package/src/zip/ZipWriter.ts +374 -390
  371. package/src/zip/types.ts +116 -116
package/README.md CHANGED
@@ -1,754 +1,759 @@
1
- # docXMLater
2
-
3
- A comprehensive, production-ready TypeScript/JavaScript framework for creating, reading, and manipulating Microsoft Word (.docx) documents programmatically.
4
-
5
- ## Features
6
-
7
- ### Core Document Operations
8
-
9
- - Create DOCX files from scratch
10
- - Read and modify existing DOCX files
11
- - Buffer-based operations (load/save from memory)
12
- - Document properties (core, extended, custom)
13
- - Memory management with dispose pattern
14
- - Bookmark pair validation and auto-repair (`validateBookmarkPairs()`)
15
- - App.xml metadata preservation (HeadingPairs, TotalTime, etc.)
16
- - Document background color/theme support
17
-
18
- ### Text & Paragraph Formatting
19
-
20
- - Character formatting: bold, italic, underline, strikethrough, subscript, superscript
21
- - Font properties: family, size, color (RGB and theme colors), highlight
22
- - Text effects: small caps, all caps, shadow, emboss, engrave
23
- - Paragraph alignment, indentation, spacing, borders, shading
24
- - Text search and replace with regex support
25
- - Custom styles (paragraph, character, table)
26
- - CJK/East Asian paragraph properties (kinsoku, wordWrap, overflowPunct, topLinePunct)
27
- - Underline color and theme color attributes
28
- - Theme font references (asciiTheme, hAnsiTheme, eastAsiaTheme, csTheme)
29
-
30
- ### Lists & Tables
31
-
32
- - Numbered lists (decimal, roman, alpha)
33
- - Bulleted lists with various bullet styles
34
- - Multi-level lists with custom numbering
35
- - Tables with formatting, borders, shading
36
- - Cell spanning (merge cells horizontally and vertically)
37
- - Advanced table properties (margins, widths, alignment)
38
- - Table navigation helpers (`getFirstParagraph()`, `getLastParagraph()`)
39
- - Legacy horizontal merge (`hMerge`) support
40
- - Table layout parsing (`fixed`/`auto`)
41
- - Table style shading updates (modify styles.xml colors)
42
- - Cell content management (trailing blank removal with structure preservation)
43
-
44
- ### Rich Content
45
-
46
- - Images (PNG, JPEG, GIF, SVG, EMF, WMF) with positioning, text wrapping, and full ECMA-376 DrawingML attribute coverage
47
- - Headers & footers (different first page, odd/even pages)
48
- - Hyperlinks (external URLs, internal bookmarks)
49
- - Hyperlink defragmentation utility (fixes fragmented links from Google Docs)
50
- - Bookmarks and cross-references
51
- - Body-level bookmark support (bookmarks between block elements)
52
- - Shapes and text boxes
53
-
54
- ### Advanced Features
55
-
56
- - Track changes (revisions for insertions, deletions, formatting)
57
- - Granular character-level tracked changes (text diff-based)
58
- - Comments and annotations
59
- - Compatibility mode detection and upgrade (Word 2003/2007/2010/2013+ modes)
60
- - Table of contents generation with customizable heading levels and relative indentation
61
- - Fields: merge fields, date/time, page numbers, TOC fields
62
- - Footnotes and endnotes (full round-trip with save pipeline, parsing, and clear API)
63
- - Content controls (Structured Document Tags)
64
- - Form field data preservation (text input, checkbox, dropdown per ECMA-376 §17.16)
65
- - w14 run effects passthrough (Word 2010+ ligatures, numForm, textOutline, etc.)
66
- - Expanded document settings (evenAndOddHeaders, mirrorMargins, autoHyphenation, decimalSymbol)
67
- - People.xml auto-registration for tracked changes authors
68
- - Style default attribute preservation (`w:default="1"`)
69
- - Namespace order preservation in generated XML
70
- - Multiple sections with different page layouts
71
- - Page orientation, size, and margins
72
- - Preserved element round-trip (math equations, alternate content, custom XML)
73
- - Unified shading model with theme color support and inheritance resolution
74
- - Lossless image optimization (PNG re-compression, BMP-to-PNG conversion)
75
- - Run property change tracking (w:rPrChange) with direct API access
76
- - Paragraph mark revision tracking (w:del/w:ins in w:pPr/w:rPr) for full tracked-changes fidelity
77
- - Normal/NormalWeb style linking with preservation flags
78
-
79
- ### Developer Tools
80
-
81
- - Complete XML generation and parsing (ReDoS-safe, position-based parser)
82
- - 40+ unit conversion functions (twips, EMUs, points, pixels, inches, cm)
83
- - Validation utilities and corruption detection
84
- - Text diff utility for character-level comparisons
85
- - webSettings.xml auto-generation
86
- - Safe OOXML parsing helpers (zero-value handling, boolean parsing)
87
- - Full TypeScript support with comprehensive type definitions
88
- - Error handling utilities
89
- - Logging infrastructure with multiple log levels
90
-
91
- ## Installation
92
-
93
- ```bash
94
- npm install docxmlater
95
- ```
96
-
97
- ## Quick Start
98
-
99
- ### Creating a New Document
100
-
101
- ```typescript
102
- import { Document } from "docxmlater";
103
-
104
- // Create a new document
105
- const doc = Document.create();
106
-
107
- // Add a paragraph
108
- const para = doc.createParagraph();
109
- para.addText("Hello, World!", { bold: true, fontSize: 24 });
110
-
111
- // Save to file
112
- await doc.save("hello.docx");
113
-
114
- // Don't forget to dispose
115
- doc.dispose();
116
- ```
117
-
118
- ### Loading and Modifying Documents
119
-
120
- ```typescript
121
- import { Document } from "docxmlater";
122
-
123
- // Load existing document
124
- const doc = await Document.load("input.docx");
125
-
126
- // Find and replace text
127
- doc.replaceText(/old text/g, "new text");
128
-
129
- // Add a new paragraph
130
- const para = doc.createParagraph();
131
- para.addText("Added paragraph", { italic: true });
132
-
133
- // Save modifications
134
- await doc.save("output.docx");
135
- doc.dispose();
136
- ```
137
-
138
- ### Working with Tables
139
-
140
- ```typescript
141
- import { Document } from "docxmlater";
142
-
143
- const doc = Document.create();
144
-
145
- // Create a 3x4 table
146
- const table = doc.createTable(3, 4);
147
-
148
- // Set header row
149
- const headerRow = table.getRow(0);
150
- headerRow.getCell(0).addParagraph().addText("Column 1", { bold: true });
151
- headerRow.getCell(1).addParagraph().addText("Column 2", { bold: true });
152
- headerRow.getCell(2).addParagraph().addText("Column 3", { bold: true });
153
- headerRow.getCell(3).addParagraph().addText("Column 4", { bold: true });
154
-
155
- // Add data
156
- table.getRow(1).getCell(0).addParagraph().addText("Data 1");
157
- table.getRow(1).getCell(1).addParagraph().addText("Data 2");
158
-
159
- // Apply borders
160
- table.setBorders({
161
- top: { style: "single", size: 4, color: "000000" },
162
- bottom: { style: "single", size: 4, color: "000000" },
163
- left: { style: "single", size: 4, color: "000000" },
164
- right: { style: "single", size: 4, color: "000000" },
165
- insideH: { style: "single", size: 4, color: "000000" },
166
- insideV: { style: "single", size: 4, color: "000000" },
167
- });
168
-
169
- await doc.save("table.docx");
170
- doc.dispose();
171
- ```
172
-
173
- ### Adding Images
174
-
175
- ```typescript
176
- import { Document } from "docxmlater";
177
- import { readFileSync } from "fs";
178
-
179
- const doc = Document.create();
180
-
181
- // Load image from file
182
- const imageBuffer = readFileSync("photo.jpg");
183
-
184
- // Add image to document
185
- const para = doc.createParagraph();
186
- await para.addImage(imageBuffer, {
187
- width: 400,
188
- height: 300,
189
- format: "jpg",
190
- });
191
-
192
- await doc.save("with-image.docx");
193
- doc.dispose();
194
- ```
195
-
196
- ### Hyperlink Management
197
-
198
- ```typescript
199
- import { Document } from "docxmlater";
200
-
201
- const doc = await Document.load("document.docx");
202
-
203
- // Get all hyperlinks
204
- const hyperlinks = doc.getHyperlinks();
205
- console.log(`Found ${hyperlinks.length} hyperlinks`);
206
-
207
- // Update URLs in batch (30-50% faster than manual iteration)
208
- doc.updateHyperlinkUrls("http://old-domain.com", "https://new-domain.com");
209
-
210
- // Fix fragmented hyperlinks from Google Docs
211
- const mergedCount = doc.defragmentHyperlinks({
212
- resetFormatting: true, // Fix corrupted fonts
213
- });
214
- console.log(`Merged ${mergedCount} fragmented hyperlinks`);
215
-
216
- await doc.save("updated.docx");
217
- doc.dispose();
218
- ```
219
-
220
- ### Custom Styles
221
-
222
- ```typescript
223
- import { Document, Style } from "docxmlater";
224
-
225
- const doc = Document.create();
226
-
227
- // Create custom paragraph style
228
- const customStyle = new Style("CustomHeading", "paragraph");
229
- customStyle.setName("Custom Heading");
230
- customStyle.setRunFormatting({
231
- bold: true,
232
- fontSize: 32,
233
- color: "0070C0",
234
- });
235
- customStyle.setParagraphFormatting({
236
- alignment: "center",
237
- spacingAfter: 240,
238
- });
239
-
240
- // Add style to document
241
- doc.getStylesManager().addStyle(customStyle);
242
-
243
- // Apply style to paragraph
244
- const para = doc.createParagraph();
245
- para.addText("Styled Heading");
246
- para.applyStyle("CustomHeading");
247
-
248
- await doc.save("styled.docx");
249
- doc.dispose();
250
- ```
251
-
252
- ### Compatibility Mode Detection and Upgrade
253
-
254
- ```typescript
255
- import { Document, CompatibilityMode } from "docxmlater";
256
-
257
- const doc = await Document.load("legacy.docx");
258
-
259
- // Check compatibility mode
260
- console.log(`Mode: ${doc.getCompatibilityMode()}`); // e.g., 12 (Word 2007)
261
-
262
- if (doc.isCompatibilityMode()) {
263
- // Get detailed compatibility info
264
- const info = doc.getCompatibilityInfo();
265
- console.log(`Legacy flags: ${info.legacyFlags.length}`);
266
-
267
- // Upgrade to Word 2013+ mode (equivalent to File > Info > Convert)
268
- const report = doc.upgradeToModernFormat();
269
- console.log(`Removed ${report.removedFlags.length} legacy flags`);
270
- console.log(`Added ${report.addedSettings.length} modern settings`);
271
- }
272
-
273
- await doc.save("modern.docx");
274
- doc.dispose();
275
- ```
276
-
277
- ## API Overview
278
-
279
- ### Document Class
280
-
281
- **Creation & Loading:**
282
-
283
- - `Document.create(options?)` - Create new document
284
- - `Document.load(filepath, options?)` - Load from file
285
- - `Document.loadFromBuffer(buffer, options?)` - Load from memory
286
-
287
- **Handling Tracked Changes:**
288
-
289
- By default, docXMLater accepts all tracked changes during document loading to prevent corruption:
290
-
291
- ```typescript
292
- // Default: Accepts all changes (recommended)
293
- const doc = await Document.load('document.docx');
294
-
295
- // Explicit control
296
- const doc = await Document.load('document.docx', {
297
- revisionHandling: 'accept' // Accept all changes (default)
298
- // OR
299
- revisionHandling: 'strip' // Remove all revision markup
300
- // OR
301
- revisionHandling: 'preserve' // Keep tracked changes (may cause corruption, but should not do so - report errors if found)
302
- });
303
- ```
304
-
305
- **Revision Handling Options:**
306
- - `'accept'` (default): Removes revision markup, keeps inserted content, removes deleted content
307
- - `'strip'`: Removes all revision markup completely
308
- - `'preserve'`: Keeps tracked changes as-is (may cause Word "unreadable content" errors)
309
-
310
- **Why Accept By Default?**
311
-
312
- 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.
313
-
314
- **Content Management:**
315
-
316
- - `createParagraph()` - Add paragraph
317
- - `createTable(rows, cols)` - Add table
318
- - `createSection()` - Add section
319
- - `getBodyElements()` - Get all body content
320
-
321
- **Search & Replace:**
322
-
323
- - `findText(pattern)` - Find text matches
324
- - `replaceText(pattern, replacement)` - Replace text
325
- - `findParagraphsByText(pattern)` - Find paragraphs containing text/regex
326
- - `getParagraphsByStyle(styleId)` - Get paragraphs with specific style
327
- - `getRunsByFont(fontName)` - Get runs using a specific font
328
- - `getRunsByColor(color)` - Get runs with a specific color
329
-
330
- **Bulk Formatting:**
331
-
332
- - `setAllRunsFont(fontName)` - Apply font to all text
333
- - `setAllRunsSize(size)` - Apply font size to all text
334
- - `setAllRunsColor(color)` - Apply color to all text
335
- - `getFormattingReport()` - Get document formatting statistics
336
-
337
- **Hyperlinks:**
338
-
339
- - `getHyperlinks()` - Get all hyperlinks
340
- - `updateHyperlinkUrls(oldUrl, newUrl)` - Batch URL update
341
- - `defragmentHyperlinks(options?)` - Fix fragmented links
342
- - `collectAllReferencedHyperlinkIds()` - Comprehensive scan of all hyperlink relationship IDs (includes nested tables, headers/footers, footnotes/endnotes)
343
-
344
- **Statistics:**
345
-
346
- - `getWordCount()` - Count words
347
- - `getCharacterCount(includeSpaces?)` - Count characters
348
- - `estimateSize()` - Estimate file size
349
-
350
- **Compatibility Mode:**
351
-
352
- - `getCompatibilityMode()` - Get document's Word version mode (11/12/14/15)
353
- - `isCompatibilityMode()` - Check if document targets a legacy Word version
354
- - `getCompatibilityInfo()` - Get full parsed compat settings
355
- - `upgradeToModernFormat()` - Upgrade to Word 2013+ mode (removes legacy flags)
356
-
357
- **Footnotes & Endnotes:**
358
-
359
- - `createFootnote(paragraph, text)` - Add footnote
360
- - `createEndnote(paragraph, text)` - Add endnote
361
- - `clearFootnotes()` / `clearEndnotes()` - Remove all notes
362
- - `getFootnoteManager()` / `getEndnoteManager()` - Access note managers
363
-
364
- **Numbering Cleanup:**
365
-
366
- - `cleanupUnusedNumbering()` - Remove unused numbering definitions (scans body, headers, footers, footnotes, endnotes)
367
- - `consolidateNumbering(options?)` - Merge duplicate abstract numbering definitions
368
- - `validateNumberingReferences()` - Fix orphaned numId references
369
-
370
- **Shading:**
371
-
372
- - `getComputedCellShading(table, row, col)` - Resolve effective cell shading with inheritance
373
-
374
- **Document Sanitization:**
375
-
376
- - `flattenFieldCodes()` - Strip INCLUDEPICTURE field markup, preserving embedded images
377
- - `stripOrphanRSIDs()` - Remove orphan RSIDs from settings.xml
378
- - `clearDirectSpacingForStyles(styleIds)` - Remove direct spacing overrides from styled paragraphs
379
-
380
- **Image Optimization:**
381
-
382
- - `optimizeImages()` - Lossless PNG re-compression and BMP-to-PNG conversion (zero dependencies)
383
-
384
- **Saving:**
385
-
386
- - `save(filepath)` - Save to file
387
- - `toBuffer()` - Save to Buffer
388
- - `dispose()` - Free resources (important!)
389
-
390
- ### Paragraph Class
391
-
392
- **Content:**
393
-
394
- - `addText(text, formatting?)` - Add text run
395
- - `addRun(run)` - Add custom run
396
- - `addHyperlink(hyperlink)` - Add hyperlink
397
- - `addImage(buffer, options)` - Add image
398
-
399
- **Formatting:**
400
-
401
- - `setAlignment(alignment)` - Left, center, right, justify
402
- - `setIndentation(options)` - First line, hanging, left, right
403
- - `setSpacing(options)` - Line spacing, before/after
404
- - `setBorders(borders)` - Paragraph borders
405
- - `setShading(shading)` - Background color
406
- - `applyStyle(styleId)` - Apply paragraph style
407
-
408
- **Properties:**
409
-
410
- - `setKeepNext(value)` - Keep with next paragraph
411
- - `setKeepLines(value)` - Keep lines together
412
- - `setPageBreakBefore(value)` - Page break before
413
- - `clearSpacing()` - Remove direct spacing (inherit from style)
414
-
415
- **Numbering:**
416
-
417
- - `setNumbering(numId, level)` - Apply list numbering
418
-
419
- ### Run Class
420
-
421
- **Text:**
422
-
423
- - `setText(text)` - Set run text
424
- - `getText()` - Get run text
425
-
426
- **Character Formatting:**
427
-
428
- - `setBold(value)` - Bold text
429
- - `setItalic(value)` - Italic text
430
- - `setUnderline(style?)` - Underline
431
- - `setStrikethrough(value)` - Strikethrough
432
- - `setFont(name)` - Font family
433
- - `setFontSize(size)` - Font size in points
434
- - `setColor(color)` - Text color (hex)
435
- - `setHighlight(color)` - Highlight color
436
-
437
- **Advanced:**
438
-
439
- - `setSubscript(value)` - Subscript
440
- - `setSuperscript(value)` - Superscript
441
- - `setSmallCaps(value)` - Small capitals
442
- - `setAllCaps(value)` - All capitals
443
- - `clearMatchingFormatting(styleFormatting)` - Remove formatting matching a style (for inheritance)
444
- - `getPropertyChangeRevision()` - Get run property change revision (w:rPrChange)
445
- - `setPropertyChangeRevision(propChange)` - Set run property change revision
446
-
447
- ### Table Class
448
-
449
- **Structure:**
450
-
451
- - `addRow()` - Add row
452
- - `getRow(index)` - Get row by index
453
- - `getCell(row, col)` - Get specific cell
454
-
455
- **Formatting:**
456
-
457
- - `setBorders(borders)` - Table borders
458
- - `setAlignment(alignment)` - Table alignment
459
- - `setWidth(width)` - Table width
460
- - `setLayout(layout)` - Fixed or auto layout
461
-
462
- **Style:**
463
-
464
- - `applyStyle(styleId)` - Apply table style
465
-
466
- ### TableCell Class
467
-
468
- **Content:**
469
-
470
- - `addParagraph()` - Add paragraph to cell
471
- - `getParagraphs()` - Get all paragraphs
472
-
473
- **Formatting:**
474
-
475
- - `setBorders(borders)` - Cell borders
476
- - `setShading(color)` - Cell background
477
- - `setVerticalAlignment(alignment)` - Top, center, bottom
478
- - `setWidth(width)` - Cell width
479
-
480
- **Spanning:**
481
-
482
- - `setHorizontalMerge(mergeType)` - Horizontal merge
483
- - `setVerticalMerge(mergeType)` - Vertical merge
484
-
485
- **Convenience Methods:**
486
-
487
- - `setTextAlignment(alignment)` - Set alignment for all paragraphs
488
- - `setAllParagraphsStyle(styleId)` - Apply style to all paragraphs
489
- - `setAllRunsFont(fontName)` - Apply font to all runs
490
- - `setAllRunsSize(size)` - Apply font size to all runs
491
- - `setAllRunsColor(color)` - Apply color to all runs
492
-
493
- **Content Management:**
494
-
495
- - `removeTrailingBlankParagraphs(options?)` - Remove trailing blank paragraphs from cell
496
- - `removeParagraph(index)` - Remove paragraph at index (updates nested content positions)
497
- - `addParagraphAt(index, paragraph)` - Insert paragraph at index (updates nested content positions)
498
-
499
- ### Document Class
500
-
501
- **Table Style Shading:**
502
-
503
- - `updateTableStyleShading(oldColor, newColor)` - Update shading colors in styles.xml
504
- - `updateTableStyleShadingBulk(settings)` - Bulk update table style shading
505
- - `removeTrailingBlanksInTableCells(options?)` - Remove trailing blanks from all table cells
506
-
507
- ### Table Class
508
-
509
- **Sorting:**
510
-
511
- - `sortRows(columnIndex, options?)` - Sort table rows by column
512
-
513
- ### Section Class
514
-
515
- **Line Numbering:**
516
-
517
- - `setLineNumbering(options)` - Enable line numbering
518
- - `getLineNumbering()` - Get line numbering settings
519
- - `clearLineNumbering()` - Disable line numbering
520
-
521
- ### Comment Class
522
-
523
- **Resolution:**
524
-
525
- - `resolve()` - Mark comment as resolved
526
- - `unresolve()` - Mark comment as unresolved
527
- - `isResolved()` - Check if comment is resolved
528
-
529
- ### CommentManager Class
530
-
531
- **Filtering:**
532
-
533
- - `getResolvedComments()` - Get all resolved comments
534
- - `getUnresolvedComments()` - Get all unresolved comments
535
-
536
- ### Utilities
537
-
538
- **Unit Conversions:**
539
-
540
- ```typescript
541
- import { twipsToPoints, inchesToTwips, emusToPixels } from "docxmlater";
542
-
543
- const points = twipsToPoints(240); // 240 twips = 12 points
544
- const twips = inchesToTwips(1); // 1 inch = 1440 twips
545
- const pixels = emusToPixels(914400, 96); // 914400 EMUs = 96 pixels at 96 DPI
546
- ```
547
-
548
- **Validation:**
549
-
550
- ```typescript
551
- import { validateRunText, detectXmlInText, cleanXmlFromText } from "docxmlater";
552
-
553
- // Detect XML patterns in text
554
- const result = validateRunText("Some <w:t>text</w:t>");
555
- if (result.hasXml) {
556
- console.warn(result.message);
557
- const cleaned = cleanXmlFromText(result.text);
558
- }
559
- ```
560
-
561
- **Corruption Detection:**
562
-
563
- ```typescript
564
- import { detectCorruptionInDocument } from "docxmlater";
565
-
566
- const doc = await Document.load("suspect.docx");
567
- const report = detectCorruptionInDocument(doc);
568
-
569
- if (report.isCorrupted) {
570
- console.log(`Found ${report.locations.length} corruption issues`);
571
- report.locations.forEach((loc) => {
572
- console.log(`Line ${loc.lineNumber}: ${loc.issue}`);
573
- console.log(`Suggested fix: ${loc.suggestedFix}`);
574
- });
575
- }
576
- ```
577
-
578
- ## TypeScript Support
579
-
580
- Full TypeScript definitions included:
581
-
582
- ```typescript
583
- import {
584
- Document,
585
- Paragraph,
586
- Run,
587
- Table,
588
- RunFormatting,
589
- ParagraphFormatting,
590
- DocumentProperties,
591
- } from "docxmlater";
592
-
593
- // Type-safe formatting
594
- const formatting: RunFormatting = {
595
- bold: true,
596
- fontSize: 12,
597
- color: "FF0000",
598
- };
599
-
600
- // Type-safe document properties
601
- const properties: DocumentProperties = {
602
- title: "My Document",
603
- author: "John Doe",
604
- created: new Date(),
605
- };
606
- ```
607
-
608
- ## Version History
609
-
610
- **Current Version: 10.0.4**
611
-
612
- See [CHANGELOG.md](CHANGELOG.md) for detailed version history.
613
-
614
- ## Testing
615
-
616
- The framework includes comprehensive test coverage:
617
-
618
- - **2,823 test cases** across 129 test suites
619
- - Tests cover all phases of implementation
620
- - Integration tests for complex scenarios
621
- - Performance benchmarks
622
- - Edge case validation
623
-
624
- Run tests:
625
-
626
- ```bash
627
- npm test # Run all tests
628
- npm run test:watch # Watch mode
629
- npm run test:coverage # Coverage report
630
- ```
631
-
632
- ## Performance Considerations
633
-
634
- - Use `dispose()` to free resources after document operations
635
- - Buffer-based operations are faster than file I/O
636
- - Batch hyperlink updates are 30-50% faster than manual iteration
637
- - Large documents (1000+ pages) supported with memory management
638
- - Streaming support for very large files
639
-
640
- ## Architecture
641
-
642
- The framework follows a modular architecture:
643
-
644
- ```
645
- src/
646
- ├── core/ # Document, Parser, Generator, Validator
647
- ├── elements/ # Paragraph, Run, Table, Image, etc.
648
- ├── formatting/ # Style, Numbering managers
649
- ├── managers/ # Drawing, Image, Relationship managers
650
- ├── constants/ # Compatibility mode constants, limits
651
- ├── types/ # Type definitions (compatibility, formatting, lists)
652
- ├── tracking/ # Change tracking context
653
- ├── validation/ # Revision validation rules
654
- ├── helpers/ # Cleanup utilities
655
- ├── xml/ # XML generation and parsing
656
- ├── zip/ # ZIP archive handling
657
- └── utils/ # Validation, units, error handling
658
- ```
659
-
660
- Key design principles:
661
-
662
- - KISS (Keep It Simple, Stupid) - no over-engineering
663
- - Position-based XML parsing (ReDoS-safe)
664
- - Defensive programming with comprehensive validation
665
- - Memory-efficient with explicit disposal pattern
666
- - Full ECMA-376 (OpenXML) compliance
667
-
668
- ## Security
669
-
670
- docXMLater includes multiple security measures to protect against common attack vectors:
671
-
672
- ### ReDoS Prevention
673
-
674
- The XML parser uses position-based parsing instead of regular expressions, preventing catastrophic backtracking attacks that can cause denial of service.
675
-
676
- ### Input Validation
677
-
678
- **Size Limits:**
679
- - Default document size limit: 150 MB (configurable)
680
- - Warning threshold: 50 MB
681
- - XML content size validation before parsing
682
-
683
- ```typescript
684
- // Configure size limits
685
- const doc = await Document.load("large.docx", {
686
- sizeLimits: {
687
- warningSizeMB: 100,
688
- maxSizeMB: 500,
689
- },
690
- });
691
- ```
692
-
693
- **Nesting Depth:**
694
- - Maximum XML nesting depth: 256 (configurable)
695
- - Prevents stack overflow attacks
696
-
697
- ```typescript
698
- import { XMLParser } from "docxmlater";
699
-
700
- // Parse with custom depth limit
701
- const obj = XMLParser.parseToObject(xml, {
702
- maxNestingDepth: 512, // Increase if needed
703
- });
704
- ```
705
-
706
- ### Path Traversal Prevention
707
-
708
- File paths within DOCX archives are validated to prevent directory traversal attacks:
709
- - Blocks `../` path sequences
710
- - Blocks absolute paths
711
- - Validates URL-encoded path components
712
-
713
- ### XML Injection Prevention
714
-
715
- All text content is properly escaped using:
716
- - `XMLBuilder.escapeXmlText()` for element content
717
- - `XMLBuilder.escapeXmlAttribute()` for attribute values
718
-
719
- This prevents injection of malicious XML elements through user-provided text content.
720
-
721
- ### UTF-8 Encoding
722
-
723
- All text files are explicitly UTF-8 encoded per ECMA-376 specification, preventing encoding-related vulnerabilities.
724
-
725
- ## Requirements
726
-
727
- - Node.js 18.0.0 or higher
728
- - TypeScript 5.0+ (for development)
729
-
730
- ## Dependencies
731
-
732
- - `jszip` - ZIP archive handling
733
-
734
- ## License
735
-
736
- MIT
737
-
738
- ## Contributing
739
-
740
- Contributions welcome! Please:
741
-
742
- 1. Fork the repository
743
- 2. Create a feature branch
744
- 3. Add tests for new features
745
- 4. Ensure all tests pass
746
- 5. Submit a pull request
747
-
748
- ## Support
749
-
750
- - GitHub Issues: https://github.com/ItMeDiaTech/docXMLater/issues
751
-
752
- ## Acknowledgments
753
-
754
- Built with careful attention to the ECMA-376 Office Open XML specification. Special thanks to the OpenXML community for comprehensive documentation and examples.
1
+ # docXMLater
2
+
3
+ A comprehensive, production-ready TypeScript/JavaScript framework for creating, reading, and manipulating Microsoft Word (.docx) documents programmatically.
4
+
5
+ ## Features
6
+
7
+ ### Core Document Operations
8
+
9
+ - Create DOCX files from scratch
10
+ - Read and modify existing DOCX files
11
+ - Buffer-based operations (load/save from memory)
12
+ - Document properties (core, extended, custom)
13
+ - Memory management with dispose pattern
14
+ - Bookmark pair validation and auto-repair (`validateBookmarkPairs()`)
15
+ - App.xml metadata preservation (HeadingPairs, TotalTime, etc.)
16
+ - Document background color/theme support
17
+
18
+ ### Text & Paragraph Formatting
19
+
20
+ - Character formatting: bold, italic, underline, strikethrough, subscript, superscript
21
+ - Font properties: family, size, color (RGB and theme colors), highlight
22
+ - Text effects: small caps, all caps, shadow, emboss, engrave
23
+ - Paragraph alignment, indentation, spacing, borders, shading
24
+ - Text search and replace with regex support
25
+ - Custom styles (paragraph, character, table)
26
+ - CJK/East Asian paragraph properties (kinsoku, wordWrap, overflowPunct, topLinePunct)
27
+ - Underline color and theme color attributes
28
+ - Theme font references (asciiTheme, hAnsiTheme, eastAsiaTheme, csTheme)
29
+
30
+ ### Lists & Tables
31
+
32
+ - Numbered lists (decimal, roman, alpha)
33
+ - Bulleted lists with various bullet styles
34
+ - Multi-level lists with custom numbering
35
+ - Tables with formatting, borders, shading
36
+ - Cell spanning (merge cells horizontally and vertically)
37
+ - Advanced table properties (margins, widths, alignment)
38
+ - Table navigation helpers (`getFirstParagraph()`, `getLastParagraph()`)
39
+ - Legacy horizontal merge (`hMerge`) support
40
+ - Table layout parsing (`fixed`/`auto`)
41
+ - Table style shading updates (modify styles.xml colors)
42
+ - Cell content management (trailing blank removal with structure preservation)
43
+
44
+ ### Rich Content
45
+
46
+ - Images (PNG, JPEG, GIF, SVG, EMF, WMF) with positioning, text wrapping, and full ECMA-376 DrawingML attribute coverage
47
+ - Headers & footers (different first page, odd/even pages)
48
+ - Hyperlinks (external URLs, internal bookmarks)
49
+ - Hyperlink defragmentation utility (fixes fragmented links from Google Docs)
50
+ - Bookmarks and cross-references
51
+ - Body-level bookmark support (bookmarks between block elements)
52
+ - Shapes and text boxes
53
+
54
+ ### Advanced Features
55
+
56
+ - Track changes (revisions for insertions, deletions, formatting)
57
+ - Granular character-level tracked changes (text diff-based)
58
+ - Comments and annotations
59
+ - Compatibility mode detection and upgrade (Word 2003/2007/2010/2013+ modes)
60
+ - Table of contents generation with customizable heading levels and relative indentation
61
+ - Fields: merge fields, date/time, page numbers, TOC fields
62
+ - Footnotes and endnotes (full round-trip with save pipeline, parsing, and clear API)
63
+ - Content controls (Structured Document Tags)
64
+ - Form field data preservation (text input, checkbox, dropdown per ECMA-376 §17.16)
65
+ - w14 run effects passthrough (Word 2010+ ligatures, numForm, textOutline, etc.)
66
+ - Expanded document settings (evenAndOddHeaders, mirrorMargins, autoHyphenation, decimalSymbol)
67
+ - People.xml auto-registration for tracked changes authors
68
+ - Style default attribute preservation (`w:default="1"`)
69
+ - Namespace order preservation in generated XML
70
+ - Multiple sections with different page layouts
71
+ - Page orientation, size, and margins
72
+ - Preserved element round-trip (math equations, alternate content, custom XML)
73
+ - Unified shading model with theme color support and inheritance resolution
74
+ - Lossless image optimization (PNG re-compression, BMP-to-PNG conversion)
75
+ - Run property change tracking (w:rPrChange) with direct API access
76
+ - Paragraph mark revision tracking (w:del/w:ins in w:pPr/w:rPr) for full tracked-changes fidelity
77
+ - Normal/NormalWeb style linking with preservation flags
78
+
79
+ ### Developer Tools
80
+
81
+ - Complete XML generation and parsing (ReDoS-safe, position-based parser)
82
+ - 40+ unit conversion functions (twips, EMUs, points, pixels, inches, cm)
83
+ - Validation utilities and corruption detection
84
+ - Text diff utility for character-level comparisons
85
+ - webSettings.xml auto-generation
86
+ - Safe OOXML parsing helpers (zero-value handling, boolean parsing)
87
+ - Full TypeScript support with comprehensive type definitions
88
+ - Error handling utilities
89
+ - Logging infrastructure with multiple log levels
90
+
91
+ ## Installation
92
+
93
+ ```bash
94
+ npm install docxmlater
95
+ ```
96
+
97
+ ## Quick Start
98
+
99
+ ### Creating a New Document
100
+
101
+ ```typescript
102
+ import { Document } from 'docxmlater';
103
+
104
+ // Create a new document
105
+ const doc = Document.create();
106
+
107
+ // Add a paragraph
108
+ const para = doc.createParagraph();
109
+ para.addText('Hello, World!', { bold: true, fontSize: 24 });
110
+
111
+ // Save to file
112
+ await doc.save('hello.docx');
113
+
114
+ // Don't forget to dispose
115
+ doc.dispose();
116
+ ```
117
+
118
+ ### Loading and Modifying Documents
119
+
120
+ ```typescript
121
+ import { Document } from 'docxmlater';
122
+
123
+ // Load existing document
124
+ const doc = await Document.load('input.docx');
125
+
126
+ // Find and replace text
127
+ doc.replaceText(/old text/g, 'new text');
128
+
129
+ // Add a new paragraph
130
+ const para = doc.createParagraph();
131
+ para.addText('Added paragraph', { italic: true });
132
+
133
+ // Save modifications
134
+ await doc.save('output.docx');
135
+ doc.dispose();
136
+ ```
137
+
138
+ ### Working with Tables
139
+
140
+ ```typescript
141
+ import { Document } from 'docxmlater';
142
+
143
+ const doc = Document.create();
144
+
145
+ // Create a 3x4 table
146
+ const table = doc.createTable(3, 4);
147
+
148
+ // Set header row
149
+ const headerRow = table.getRow(0);
150
+ headerRow.getCell(0).addParagraph().addText('Column 1', { bold: true });
151
+ headerRow.getCell(1).addParagraph().addText('Column 2', { bold: true });
152
+ headerRow.getCell(2).addParagraph().addText('Column 3', { bold: true });
153
+ headerRow.getCell(3).addParagraph().addText('Column 4', { bold: true });
154
+
155
+ // Add data
156
+ table.getRow(1).getCell(0).addParagraph().addText('Data 1');
157
+ table.getRow(1).getCell(1).addParagraph().addText('Data 2');
158
+
159
+ // Apply borders
160
+ table.setBorders({
161
+ top: { style: 'single', size: 4, color: '000000' },
162
+ bottom: { style: 'single', size: 4, color: '000000' },
163
+ left: { style: 'single', size: 4, color: '000000' },
164
+ right: { style: 'single', size: 4, color: '000000' },
165
+ insideH: { style: 'single', size: 4, color: '000000' },
166
+ insideV: { style: 'single', size: 4, color: '000000' },
167
+ });
168
+
169
+ await doc.save('table.docx');
170
+ doc.dispose();
171
+ ```
172
+
173
+ ### Adding Images
174
+
175
+ ```typescript
176
+ import { Document } from 'docxmlater';
177
+ import { readFileSync } from 'fs';
178
+
179
+ const doc = Document.create();
180
+
181
+ // Load image from file
182
+ const imageBuffer = readFileSync('photo.jpg');
183
+
184
+ // Add image to document
185
+ const para = doc.createParagraph();
186
+ await para.addImage(imageBuffer, {
187
+ width: 400,
188
+ height: 300,
189
+ format: 'jpg',
190
+ });
191
+
192
+ await doc.save('with-image.docx');
193
+ doc.dispose();
194
+ ```
195
+
196
+ ### Hyperlink Management
197
+
198
+ ```typescript
199
+ import { Document } from 'docxmlater';
200
+
201
+ const doc = await Document.load('document.docx');
202
+
203
+ // Get all hyperlinks
204
+ const hyperlinks = doc.getHyperlinks();
205
+ console.log(`Found ${hyperlinks.length} hyperlinks`);
206
+
207
+ // Update URLs in batch (30-50% faster than manual iteration)
208
+ doc.updateHyperlinkUrls('http://old-domain.com', 'https://new-domain.com');
209
+
210
+ // Fix fragmented hyperlinks from Google Docs
211
+ const mergedCount = doc.defragmentHyperlinks({
212
+ resetFormatting: true, // Fix corrupted fonts
213
+ });
214
+ console.log(`Merged ${mergedCount} fragmented hyperlinks`);
215
+
216
+ await doc.save('updated.docx');
217
+ doc.dispose();
218
+ ```
219
+
220
+ ### Custom Styles
221
+
222
+ ```typescript
223
+ import { Document, Style } from 'docxmlater';
224
+
225
+ const doc = Document.create();
226
+
227
+ // Create custom paragraph style
228
+ const customStyle = new Style('CustomHeading', 'paragraph');
229
+ customStyle.setName('Custom Heading');
230
+ customStyle.setRunFormatting({
231
+ bold: true,
232
+ fontSize: 32,
233
+ color: '0070C0',
234
+ });
235
+ customStyle.setParagraphFormatting({
236
+ alignment: 'center',
237
+ spacingAfter: 240,
238
+ });
239
+
240
+ // Add style to document
241
+ doc.getStylesManager().addStyle(customStyle);
242
+
243
+ // Apply style to paragraph
244
+ const para = doc.createParagraph();
245
+ para.addText('Styled Heading');
246
+ para.applyStyle('CustomHeading');
247
+
248
+ await doc.save('styled.docx');
249
+ doc.dispose();
250
+ ```
251
+
252
+ ### Compatibility Mode Detection and Upgrade
253
+
254
+ ```typescript
255
+ import { Document, CompatibilityMode } from 'docxmlater';
256
+
257
+ const doc = await Document.load('legacy.docx');
258
+
259
+ // Check compatibility mode
260
+ console.log(`Mode: ${doc.getCompatibilityMode()}`); // e.g., 12 (Word 2007)
261
+
262
+ if (doc.isCompatibilityMode()) {
263
+ // Get detailed compatibility info
264
+ const info = doc.getCompatibilityInfo();
265
+ console.log(`Legacy flags: ${info.legacyFlags.length}`);
266
+
267
+ // Upgrade to Word 2013+ mode (equivalent to File > Info > Convert)
268
+ const report = doc.upgradeToModernFormat();
269
+ console.log(`Removed ${report.removedFlags.length} legacy flags`);
270
+ console.log(`Added ${report.addedSettings.length} modern settings`);
271
+ }
272
+
273
+ await doc.save('modern.docx');
274
+ doc.dispose();
275
+ ```
276
+
277
+ ## API Overview
278
+
279
+ ### Document Class
280
+
281
+ **Creation & Loading:**
282
+
283
+ - `Document.create(options?)` - Create new document
284
+ - `Document.load(filepath, options?)` - Load from file
285
+ - `Document.loadFromBuffer(buffer, options?)` - Load from memory
286
+
287
+ **Handling Tracked Changes:**
288
+
289
+ By default, docXMLater accepts all tracked changes during document loading to prevent corruption:
290
+
291
+ ```typescript
292
+ // Default: Accepts all changes (recommended)
293
+ const doc = await Document.load('document.docx');
294
+
295
+ // Explicit control
296
+ const doc = await Document.load('document.docx', {
297
+ revisionHandling: 'accept' // Accept all changes (default)
298
+ // OR
299
+ revisionHandling: 'strip' // Remove all revision markup
300
+ // OR
301
+ revisionHandling: 'preserve' // Keep tracked changes (may cause corruption, but should not do so - report errors if found)
302
+ });
303
+ ```
304
+
305
+ **Revision Handling Options:**
306
+
307
+ - `'accept'` (default): Removes revision markup, keeps inserted content, removes deleted content
308
+ - `'strip'`: Removes all revision markup completely
309
+ - `'preserve'`: Keeps tracked changes as-is (may cause Word "unreadable content" errors)
310
+
311
+ **Why Accept By Default?**
312
+
313
+ 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.
314
+
315
+ **Content Management:**
316
+
317
+ - `createParagraph()` - Add paragraph
318
+ - `createTable(rows, cols)` - Add table
319
+ - `createSection()` - Add section
320
+ - `getBodyElements()` - Get all body content
321
+
322
+ **Search & Replace:**
323
+
324
+ - `findText(pattern)` - Find text matches
325
+ - `replaceText(pattern, replacement)` - Replace text
326
+ - `findParagraphsByText(pattern)` - Find paragraphs containing text/regex
327
+ - `getParagraphsByStyle(styleId)` - Get paragraphs with specific style
328
+ - `getRunsByFont(fontName)` - Get runs using a specific font
329
+ - `getRunsByColor(color)` - Get runs with a specific color
330
+
331
+ **Bulk Formatting:**
332
+
333
+ - `setAllRunsFont(fontName)` - Apply font to all text
334
+ - `setAllRunsSize(size)` - Apply font size to all text
335
+ - `setAllRunsColor(color)` - Apply color to all text
336
+ - `getFormattingReport()` - Get document formatting statistics
337
+
338
+ **Hyperlinks:**
339
+
340
+ - `getHyperlinks()` - Get all hyperlinks
341
+ - `updateHyperlinkUrls(oldUrl, newUrl)` - Batch URL update
342
+ - `defragmentHyperlinks(options?)` - Fix fragmented links
343
+ - `collectAllReferencedHyperlinkIds()` - Comprehensive scan of all hyperlink relationship IDs (includes nested tables, headers/footers, footnotes/endnotes)
344
+
345
+ **Statistics:**
346
+
347
+ - `getWordCount()` - Count words
348
+ - `getCharacterCount(includeSpaces?)` - Count characters
349
+ - `estimateSize()` - Estimate file size
350
+
351
+ **Compatibility Mode:**
352
+
353
+ - `getCompatibilityMode()` - Get document's Word version mode (11/12/14/15)
354
+ - `isCompatibilityMode()` - Check if document targets a legacy Word version
355
+ - `getCompatibilityInfo()` - Get full parsed compat settings
356
+ - `upgradeToModernFormat()` - Upgrade to Word 2013+ mode (removes legacy flags)
357
+
358
+ **Footnotes & Endnotes:**
359
+
360
+ - `createFootnote(paragraph, text)` - Add footnote
361
+ - `createEndnote(paragraph, text)` - Add endnote
362
+ - `clearFootnotes()` / `clearEndnotes()` - Remove all notes
363
+ - `getFootnoteManager()` / `getEndnoteManager()` - Access note managers
364
+
365
+ **Numbering Cleanup:**
366
+
367
+ - `cleanupUnusedNumbering()` - Remove unused numbering definitions (scans body, headers, footers, footnotes, endnotes)
368
+ - `consolidateNumbering(options?)` - Merge duplicate abstract numbering definitions
369
+ - `validateNumberingReferences()` - Fix orphaned numId references
370
+
371
+ **Shading:**
372
+
373
+ - `getComputedCellShading(table, row, col)` - Resolve effective cell shading with inheritance
374
+
375
+ **Document Sanitization:**
376
+
377
+ - `flattenFieldCodes()` - Strip INCLUDEPICTURE field markup, preserving embedded images
378
+ - `stripOrphanRSIDs()` - Remove orphan RSIDs from settings.xml
379
+ - `clearDirectSpacingForStyles(styleIds)` - Remove direct spacing overrides from styled paragraphs
380
+
381
+ **Image Optimization:**
382
+
383
+ - `optimizeImages()` - Lossless PNG re-compression and BMP-to-PNG conversion (zero dependencies)
384
+
385
+ **Saving:**
386
+
387
+ - `save(filepath)` - Save to file
388
+ - `toBuffer()` - Save to Buffer
389
+ - `dispose()` - Free resources (important!)
390
+
391
+ ### Paragraph Class
392
+
393
+ **Content:**
394
+
395
+ - `addText(text, formatting?)` - Add text run
396
+ - `addRun(run)` - Add custom run
397
+ - `addHyperlink(hyperlink)` - Add hyperlink
398
+ - `addImage(buffer, options)` - Add image
399
+
400
+ **Formatting:**
401
+
402
+ - `setAlignment(alignment)` - Left, center, right, justify
403
+ - `setIndentation(options)` - First line, hanging, left, right
404
+ - `setSpacing(options)` - Line spacing, before/after
405
+ - `setBorders(borders)` - Paragraph borders
406
+ - `setShading(shading)` - Background color
407
+ - `applyStyle(styleId)` - Apply paragraph style
408
+
409
+ **Properties:**
410
+
411
+ - `setKeepNext(value)` - Keep with next paragraph
412
+ - `setKeepLines(value)` - Keep lines together
413
+ - `setPageBreakBefore(value)` - Page break before
414
+ - `clearSpacing()` - Remove direct spacing (inherit from style)
415
+
416
+ **Numbering:**
417
+
418
+ - `setNumbering(numId, level)` - Apply list numbering
419
+
420
+ ### Run Class
421
+
422
+ **Text:**
423
+
424
+ - `setText(text)` - Set run text
425
+ - `getText()` - Get run text
426
+
427
+ **Character Formatting:**
428
+
429
+ - `setBold(value)` - Bold text
430
+ - `setItalic(value)` - Italic text
431
+ - `setUnderline(style?)` - Underline
432
+ - `setStrikethrough(value)` - Strikethrough
433
+ - `setFont(name)` - Font family
434
+ - `setFontSize(size)` - Font size in points
435
+ - `setColor(color)` - Text color (hex)
436
+ - `setHighlight(color)` - Highlight color
437
+
438
+ **Advanced:**
439
+
440
+ - `setSubscript(value)` - Subscript
441
+ - `setSuperscript(value)` - Superscript
442
+ - `setSmallCaps(value)` - Small capitals
443
+ - `setAllCaps(value)` - All capitals
444
+ - `clearMatchingFormatting(styleFormatting)` - Remove formatting matching a style (for inheritance)
445
+ - `getPropertyChangeRevision()` - Get run property change revision (w:rPrChange)
446
+ - `setPropertyChangeRevision(propChange)` - Set run property change revision
447
+
448
+ ### Table Class
449
+
450
+ **Structure:**
451
+
452
+ - `addRow()` - Add row
453
+ - `getRow(index)` - Get row by index
454
+ - `getCell(row, col)` - Get specific cell
455
+
456
+ **Formatting:**
457
+
458
+ - `setBorders(borders)` - Table borders
459
+ - `setAlignment(alignment)` - Table alignment
460
+ - `setWidth(width)` - Table width
461
+ - `setLayout(layout)` - Fixed or auto layout
462
+
463
+ **Style:**
464
+
465
+ - `applyStyle(styleId)` - Apply table style
466
+
467
+ ### TableCell Class
468
+
469
+ **Content:**
470
+
471
+ - `addParagraph()` - Add paragraph to cell
472
+ - `getParagraphs()` - Get all paragraphs
473
+
474
+ **Formatting:**
475
+
476
+ - `setBorders(borders)` - Cell borders
477
+ - `setShading(color)` - Cell background
478
+ - `setVerticalAlignment(alignment)` - Top, center, bottom
479
+ - `setWidth(width)` - Cell width
480
+
481
+ **Spanning:**
482
+
483
+ - `setHorizontalMerge(mergeType)` - Horizontal merge
484
+ - `setVerticalMerge(mergeType)` - Vertical merge
485
+
486
+ **Convenience Methods:**
487
+
488
+ - `setTextAlignment(alignment)` - Set alignment for all paragraphs
489
+ - `setAllParagraphsStyle(styleId)` - Apply style to all paragraphs
490
+ - `setAllRunsFont(fontName)` - Apply font to all runs
491
+ - `setAllRunsSize(size)` - Apply font size to all runs
492
+ - `setAllRunsColor(color)` - Apply color to all runs
493
+
494
+ **Content Management:**
495
+
496
+ - `removeTrailingBlankParagraphs(options?)` - Remove trailing blank paragraphs from cell
497
+ - `removeParagraph(index)` - Remove paragraph at index (updates nested content positions)
498
+ - `addParagraphAt(index, paragraph)` - Insert paragraph at index (updates nested content positions)
499
+
500
+ ### Document Class
501
+
502
+ **Table Style Shading:**
503
+
504
+ - `updateTableStyleShading(oldColor, newColor)` - Update shading colors in styles.xml
505
+ - `updateTableStyleShadingBulk(settings)` - Bulk update table style shading
506
+ - `removeTrailingBlanksInTableCells(options?)` - Remove trailing blanks from all table cells
507
+
508
+ ### Table Class
509
+
510
+ **Sorting:**
511
+
512
+ - `sortRows(columnIndex, options?)` - Sort table rows by column
513
+
514
+ ### Section Class
515
+
516
+ **Line Numbering:**
517
+
518
+ - `setLineNumbering(options)` - Enable line numbering
519
+ - `getLineNumbering()` - Get line numbering settings
520
+ - `clearLineNumbering()` - Disable line numbering
521
+
522
+ ### Comment Class
523
+
524
+ **Resolution:**
525
+
526
+ - `resolve()` - Mark comment as resolved
527
+ - `unresolve()` - Mark comment as unresolved
528
+ - `isResolved()` - Check if comment is resolved
529
+
530
+ ### CommentManager Class
531
+
532
+ **Filtering:**
533
+
534
+ - `getResolvedComments()` - Get all resolved comments
535
+ - `getUnresolvedComments()` - Get all unresolved comments
536
+
537
+ ### Utilities
538
+
539
+ **Unit Conversions:**
540
+
541
+ ```typescript
542
+ import { twipsToPoints, inchesToTwips, emusToPixels } from 'docxmlater';
543
+
544
+ const points = twipsToPoints(240); // 240 twips = 12 points
545
+ const twips = inchesToTwips(1); // 1 inch = 1440 twips
546
+ const pixels = emusToPixels(914400, 96); // 914400 EMUs = 96 pixels at 96 DPI
547
+ ```
548
+
549
+ **Validation:**
550
+
551
+ ```typescript
552
+ import { validateRunText, detectXmlInText, cleanXmlFromText } from 'docxmlater';
553
+
554
+ // Detect XML patterns in text
555
+ const result = validateRunText('Some <w:t>text</w:t>');
556
+ if (result.hasXml) {
557
+ console.warn(result.message);
558
+ const cleaned = cleanXmlFromText(result.text);
559
+ }
560
+ ```
561
+
562
+ **Corruption Detection:**
563
+
564
+ ```typescript
565
+ import { detectCorruptionInDocument } from 'docxmlater';
566
+
567
+ const doc = await Document.load('suspect.docx');
568
+ const report = detectCorruptionInDocument(doc);
569
+
570
+ if (report.isCorrupted) {
571
+ console.log(`Found ${report.locations.length} corruption issues`);
572
+ report.locations.forEach((loc) => {
573
+ console.log(`Line ${loc.lineNumber}: ${loc.issue}`);
574
+ console.log(`Suggested fix: ${loc.suggestedFix}`);
575
+ });
576
+ }
577
+ ```
578
+
579
+ ## TypeScript Support
580
+
581
+ Full TypeScript definitions included:
582
+
583
+ ```typescript
584
+ import {
585
+ Document,
586
+ Paragraph,
587
+ Run,
588
+ Table,
589
+ RunFormatting,
590
+ ParagraphFormatting,
591
+ DocumentProperties,
592
+ } from 'docxmlater';
593
+
594
+ // Type-safe formatting
595
+ const formatting: RunFormatting = {
596
+ bold: true,
597
+ fontSize: 12,
598
+ color: 'FF0000',
599
+ };
600
+
601
+ // Type-safe document properties
602
+ const properties: DocumentProperties = {
603
+ title: 'My Document',
604
+ author: 'John Doe',
605
+ created: new Date(),
606
+ };
607
+ ```
608
+
609
+ ## Version History
610
+
611
+ **Current Version: 10.0.4**
612
+
613
+ See [CHANGELOG.md](CHANGELOG.md) for detailed version history.
614
+
615
+ ## Testing
616
+
617
+ The framework includes comprehensive test coverage:
618
+
619
+ - **2,823 test cases** across 129 test suites
620
+ - Tests cover all phases of implementation
621
+ - Integration tests for complex scenarios
622
+ - Performance benchmarks
623
+ - Edge case validation
624
+
625
+ Run tests:
626
+
627
+ ```bash
628
+ npm test # Run all tests
629
+ npm run test:watch # Watch mode
630
+ npm run test:coverage # Coverage report
631
+ ```
632
+
633
+ ## Performance Considerations
634
+
635
+ - Use `dispose()` to free resources after document operations
636
+ - Buffer-based operations are faster than file I/O
637
+ - Batch hyperlink updates are 30-50% faster than manual iteration
638
+ - Large documents (1000+ pages) supported with memory management
639
+ - Streaming support for very large files
640
+
641
+ ## Architecture
642
+
643
+ The framework follows a modular architecture:
644
+
645
+ ```
646
+ src/
647
+ ├── core/ # Document, Parser, Generator, Validator
648
+ ├── elements/ # Paragraph, Run, Table, Image, etc.
649
+ ├── formatting/ # Style, Numbering managers
650
+ ├── managers/ # Drawing, Image, Relationship managers
651
+ ├── constants/ # Compatibility mode constants, limits
652
+ ├── types/ # Type definitions (compatibility, formatting, lists)
653
+ ├── tracking/ # Change tracking context
654
+ ├── validation/ # Revision validation rules
655
+ ├── helpers/ # Cleanup utilities
656
+ ├── xml/ # XML generation and parsing
657
+ ├── zip/ # ZIP archive handling
658
+ └── utils/ # Validation, units, error handling
659
+ ```
660
+
661
+ Key design principles:
662
+
663
+ - KISS (Keep It Simple, Stupid) - no over-engineering
664
+ - Position-based XML parsing (ReDoS-safe)
665
+ - Defensive programming with comprehensive validation
666
+ - Memory-efficient with explicit disposal pattern
667
+ - Full ECMA-376 (OpenXML) compliance
668
+
669
+ ## Security
670
+
671
+ docXMLater includes multiple security measures to protect against common attack vectors:
672
+
673
+ ### ReDoS Prevention
674
+
675
+ The XML parser uses position-based parsing instead of regular expressions, preventing catastrophic backtracking attacks that can cause denial of service.
676
+
677
+ ### Input Validation
678
+
679
+ **Size Limits:**
680
+
681
+ - Default document size limit: 150 MB (configurable)
682
+ - Warning threshold: 50 MB
683
+ - XML content size validation before parsing
684
+
685
+ ```typescript
686
+ // Configure size limits
687
+ const doc = await Document.load('large.docx', {
688
+ sizeLimits: {
689
+ warningSizeMB: 100,
690
+ maxSizeMB: 500,
691
+ },
692
+ });
693
+ ```
694
+
695
+ **Nesting Depth:**
696
+
697
+ - Maximum XML nesting depth: 256 (configurable)
698
+ - Prevents stack overflow attacks
699
+
700
+ ```typescript
701
+ import { XMLParser } from 'docxmlater';
702
+
703
+ // Parse with custom depth limit
704
+ const obj = XMLParser.parseToObject(xml, {
705
+ maxNestingDepth: 512, // Increase if needed
706
+ });
707
+ ```
708
+
709
+ ### Path Traversal Prevention
710
+
711
+ File paths within DOCX archives are validated to prevent directory traversal attacks:
712
+
713
+ - Blocks `../` path sequences
714
+ - Blocks absolute paths
715
+ - Validates URL-encoded path components
716
+
717
+ ### XML Injection Prevention
718
+
719
+ All text content is properly escaped using:
720
+
721
+ - `XMLBuilder.escapeXmlText()` for element content
722
+ - `XMLBuilder.escapeXmlAttribute()` for attribute values
723
+
724
+ This prevents injection of malicious XML elements through user-provided text content.
725
+
726
+ ### UTF-8 Encoding
727
+
728
+ All text files are explicitly UTF-8 encoded per ECMA-376 specification, preventing encoding-related vulnerabilities.
729
+
730
+ ## Requirements
731
+
732
+ - Node.js 18.0.0 or higher
733
+ - TypeScript 5.0+ (for development)
734
+
735
+ ## Dependencies
736
+
737
+ - `jszip` - ZIP archive handling
738
+
739
+ ## License
740
+
741
+ MIT
742
+
743
+ ## Contributing
744
+
745
+ Contributions welcome! Please:
746
+
747
+ 1. Fork the repository
748
+ 2. Create a feature branch
749
+ 3. Add tests for new features
750
+ 4. Ensure all tests pass
751
+ 5. Submit a pull request
752
+
753
+ ## Support
754
+
755
+ - GitHub Issues: https://github.com/ItMeDiaTech/docXMLater/issues
756
+
757
+ ## Acknowledgments
758
+
759
+ Built with careful attention to the ECMA-376 Office Open XML specification. Special thanks to the OpenXML community for comprehensive documentation and examples.