docxmlater 11.0.10 → 12.1.0

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 (361) hide show
  1. package/README.md +53 -13
  2. package/dist/core/Document.d.ts +29 -3
  3. package/dist/core/Document.d.ts.map +1 -1
  4. package/dist/core/Document.js +733 -170
  5. package/dist/core/Document.js.map +1 -1
  6. package/dist/core/DocumentGenerator.d.ts +1 -0
  7. package/dist/core/DocumentGenerator.d.ts.map +1 -1
  8. package/dist/core/DocumentGenerator.js +77 -25
  9. package/dist/core/DocumentGenerator.js.map +1 -1
  10. package/dist/core/DocumentParser.d.ts +7 -3
  11. package/dist/core/DocumentParser.d.ts.map +1 -1
  12. package/dist/core/DocumentParser.js +427 -81
  13. package/dist/core/DocumentParser.js.map +1 -1
  14. package/dist/core/RelationshipManager.d.ts.map +1 -1
  15. package/dist/core/RelationshipManager.js +2 -2
  16. package/dist/core/RelationshipManager.js.map +1 -1
  17. package/dist/elements/Comment.d.ts +15 -1
  18. package/dist/elements/Comment.d.ts.map +1 -1
  19. package/dist/elements/Comment.js +67 -12
  20. package/dist/elements/Comment.js.map +1 -1
  21. package/dist/elements/CommentManager.d.ts +4 -0
  22. package/dist/elements/CommentManager.d.ts.map +1 -1
  23. package/dist/elements/CommentManager.js +74 -16
  24. package/dist/elements/CommentManager.js.map +1 -1
  25. package/dist/elements/EndnoteManager.d.ts.map +1 -1
  26. package/dist/elements/EndnoteManager.js.map +1 -1
  27. package/dist/elements/Field.d.ts +10 -1
  28. package/dist/elements/Field.d.ts.map +1 -1
  29. package/dist/elements/Field.js +76 -34
  30. package/dist/elements/Field.js.map +1 -1
  31. package/dist/elements/FieldHelpers.d.ts +1 -0
  32. package/dist/elements/FieldHelpers.d.ts.map +1 -1
  33. package/dist/elements/FieldHelpers.js +8 -4
  34. package/dist/elements/FieldHelpers.js.map +1 -1
  35. package/dist/elements/Footer.d.ts +3 -1
  36. package/dist/elements/Footer.d.ts.map +1 -1
  37. package/dist/elements/Footer.js +39 -53
  38. package/dist/elements/Footer.js.map +1 -1
  39. package/dist/elements/FootnoteManager.d.ts.map +1 -1
  40. package/dist/elements/FootnoteManager.js.map +1 -1
  41. package/dist/elements/Header.d.ts +3 -1
  42. package/dist/elements/Header.d.ts.map +1 -1
  43. package/dist/elements/Header.js +39 -53
  44. package/dist/elements/Header.js.map +1 -1
  45. package/dist/elements/HeaderFooterManager.d.ts +4 -2
  46. package/dist/elements/HeaderFooterManager.d.ts.map +1 -1
  47. package/dist/elements/HeaderFooterManager.js +36 -6
  48. package/dist/elements/HeaderFooterManager.js.map +1 -1
  49. package/dist/elements/Hyperlink.d.ts +6 -1
  50. package/dist/elements/Hyperlink.d.ts.map +1 -1
  51. package/dist/elements/Hyperlink.js +69 -44
  52. package/dist/elements/Hyperlink.js.map +1 -1
  53. package/dist/elements/Image.d.ts.map +1 -1
  54. package/dist/elements/Image.js +33 -6
  55. package/dist/elements/Image.js.map +1 -1
  56. package/dist/elements/ImageManager.d.ts +1 -0
  57. package/dist/elements/ImageManager.d.ts.map +1 -1
  58. package/dist/elements/ImageManager.js +11 -0
  59. package/dist/elements/ImageManager.js.map +1 -1
  60. package/dist/elements/Paragraph.d.ts +3 -0
  61. package/dist/elements/Paragraph.d.ts.map +1 -1
  62. package/dist/elements/Paragraph.js +91 -26
  63. package/dist/elements/Paragraph.js.map +1 -1
  64. package/dist/elements/Revision.d.ts +4 -0
  65. package/dist/elements/Revision.d.ts.map +1 -1
  66. package/dist/elements/Revision.js +369 -29
  67. package/dist/elements/Revision.js.map +1 -1
  68. package/dist/elements/Run.d.ts +1 -0
  69. package/dist/elements/Run.d.ts.map +1 -1
  70. package/dist/elements/Run.js +24 -4
  71. package/dist/elements/Run.js.map +1 -1
  72. package/dist/elements/Section.d.ts.map +1 -1
  73. package/dist/elements/Section.js +17 -7
  74. package/dist/elements/Section.js.map +1 -1
  75. package/dist/elements/Shape.d.ts.map +1 -1
  76. package/dist/elements/Shape.js +50 -42
  77. package/dist/elements/Shape.js.map +1 -1
  78. package/dist/elements/StructuredDocumentTag.d.ts +9 -1
  79. package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
  80. package/dist/elements/StructuredDocumentTag.js +46 -6
  81. package/dist/elements/StructuredDocumentTag.js.map +1 -1
  82. package/dist/elements/Table.d.ts +2 -0
  83. package/dist/elements/Table.d.ts.map +1 -1
  84. package/dist/elements/Table.js +90 -42
  85. package/dist/elements/Table.js.map +1 -1
  86. package/dist/elements/TableCell.d.ts +1 -0
  87. package/dist/elements/TableCell.d.ts.map +1 -1
  88. package/dist/elements/TableCell.js +32 -13
  89. package/dist/elements/TableCell.js.map +1 -1
  90. package/dist/elements/TableOfContents.d.ts.map +1 -1
  91. package/dist/elements/TableOfContents.js +5 -7
  92. package/dist/elements/TableOfContents.js.map +1 -1
  93. package/dist/elements/TableRow.d.ts +1 -0
  94. package/dist/elements/TableRow.d.ts.map +1 -1
  95. package/dist/elements/TableRow.js +16 -1
  96. package/dist/elements/TableRow.js.map +1 -1
  97. package/dist/elements/TextBox.d.ts.map +1 -1
  98. package/dist/elements/TextBox.js +55 -42
  99. package/dist/elements/TextBox.js.map +1 -1
  100. package/dist/esm/core/Document.js +735 -172
  101. package/dist/esm/core/Document.js.map +1 -1
  102. package/dist/esm/core/DocumentGenerator.js +77 -25
  103. package/dist/esm/core/DocumentGenerator.js.map +1 -1
  104. package/dist/esm/core/DocumentParser.js +427 -81
  105. package/dist/esm/core/DocumentParser.js.map +1 -1
  106. package/dist/esm/core/RelationshipManager.js +2 -2
  107. package/dist/esm/core/RelationshipManager.js.map +1 -1
  108. package/dist/esm/elements/Comment.js +67 -12
  109. package/dist/esm/elements/Comment.js.map +1 -1
  110. package/dist/esm/elements/CommentManager.js +74 -16
  111. package/dist/esm/elements/CommentManager.js.map +1 -1
  112. package/dist/esm/elements/EndnoteManager.js.map +1 -1
  113. package/dist/esm/elements/Field.js +77 -35
  114. package/dist/esm/elements/Field.js.map +1 -1
  115. package/dist/esm/elements/FieldHelpers.js +7 -4
  116. package/dist/esm/elements/FieldHelpers.js.map +1 -1
  117. package/dist/esm/elements/Footer.js +39 -53
  118. package/dist/esm/elements/Footer.js.map +1 -1
  119. package/dist/esm/elements/FootnoteManager.js.map +1 -1
  120. package/dist/esm/elements/Header.js +39 -53
  121. package/dist/esm/elements/Header.js.map +1 -1
  122. package/dist/esm/elements/HeaderFooterManager.js +36 -6
  123. package/dist/esm/elements/HeaderFooterManager.js.map +1 -1
  124. package/dist/esm/elements/Hyperlink.js +69 -44
  125. package/dist/esm/elements/Hyperlink.js.map +1 -1
  126. package/dist/esm/elements/Image.js +33 -6
  127. package/dist/esm/elements/Image.js.map +1 -1
  128. package/dist/esm/elements/ImageManager.js +11 -0
  129. package/dist/esm/elements/ImageManager.js.map +1 -1
  130. package/dist/esm/elements/Paragraph.js +91 -26
  131. package/dist/esm/elements/Paragraph.js.map +1 -1
  132. package/dist/esm/elements/Revision.js +369 -29
  133. package/dist/esm/elements/Revision.js.map +1 -1
  134. package/dist/esm/elements/Run.js +24 -4
  135. package/dist/esm/elements/Run.js.map +1 -1
  136. package/dist/esm/elements/Section.js +17 -7
  137. package/dist/esm/elements/Section.js.map +1 -1
  138. package/dist/esm/elements/Shape.js +50 -42
  139. package/dist/esm/elements/Shape.js.map +1 -1
  140. package/dist/esm/elements/StructuredDocumentTag.js +46 -6
  141. package/dist/esm/elements/StructuredDocumentTag.js.map +1 -1
  142. package/dist/esm/elements/Table.js +90 -42
  143. package/dist/esm/elements/Table.js.map +1 -1
  144. package/dist/esm/elements/TableCell.js +32 -13
  145. package/dist/esm/elements/TableCell.js.map +1 -1
  146. package/dist/esm/elements/TableOfContents.js +5 -7
  147. package/dist/esm/elements/TableOfContents.js.map +1 -1
  148. package/dist/esm/elements/TableRow.js +16 -1
  149. package/dist/esm/elements/TableRow.js.map +1 -1
  150. package/dist/esm/elements/TextBox.js +55 -42
  151. package/dist/esm/elements/TextBox.js.map +1 -1
  152. package/dist/esm/formatting/AbstractNumbering.js +1 -1
  153. package/dist/esm/formatting/AbstractNumbering.js.map +1 -1
  154. package/dist/esm/formatting/NumberingLevel.js +8 -6
  155. package/dist/esm/formatting/NumberingLevel.js.map +1 -1
  156. package/dist/esm/formatting/NumberingManager.js +16 -1
  157. package/dist/esm/formatting/NumberingManager.js.map +1 -1
  158. package/dist/esm/formatting/Style.js +14 -0
  159. package/dist/esm/formatting/Style.js.map +1 -1
  160. package/dist/esm/formatting/StylesManager.js +14 -2
  161. package/dist/esm/formatting/StylesManager.js.map +1 -1
  162. package/dist/esm/helpers/CleanupHelper.js +103 -26
  163. package/dist/esm/helpers/CleanupHelper.js.map +1 -1
  164. package/dist/esm/images/ImageOptimizer.js +52 -4
  165. package/dist/esm/images/ImageOptimizer.js.map +1 -1
  166. package/dist/esm/index.js +1 -0
  167. package/dist/esm/index.js.map +1 -1
  168. package/dist/esm/internal.js +1 -1
  169. package/dist/esm/internal.js.map +1 -1
  170. package/dist/esm/processors/CompatibilityUpgrader.js +7 -1
  171. package/dist/esm/processors/CompatibilityUpgrader.js.map +1 -1
  172. package/dist/esm/processors/InMemoryRevisionAcceptor.js +134 -13
  173. package/dist/esm/processors/InMemoryRevisionAcceptor.js.map +1 -1
  174. package/dist/esm/processors/RevisionWalker.js +223 -39
  175. package/dist/esm/processors/RevisionWalker.js.map +1 -1
  176. package/dist/esm/processors/SelectiveRevisionAcceptor.js +116 -17
  177. package/dist/esm/processors/SelectiveRevisionAcceptor.js.map +1 -1
  178. package/dist/esm/processors/acceptRevisions.js +20 -11
  179. package/dist/esm/processors/acceptRevisions.js.map +1 -1
  180. package/dist/esm/processors/cnfStyleDecoder.js +7 -7
  181. package/dist/esm/processors/cnfStyleDecoder.js.map +1 -1
  182. package/dist/esm/processors/stripTrackedChanges.js +16 -5
  183. package/dist/esm/processors/stripTrackedChanges.js.map +1 -1
  184. package/dist/esm/utils/deepClone.js +24 -11
  185. package/dist/esm/utils/deepClone.js.map +1 -1
  186. package/dist/esm/utils/units.js +1 -1
  187. package/dist/esm/utils/units.js.map +1 -1
  188. package/dist/esm/utils/validation.js +11 -23
  189. package/dist/esm/utils/validation.js.map +1 -1
  190. package/dist/esm/utils/xmlSanitization.js +131 -7
  191. package/dist/esm/utils/xmlSanitization.js.map +1 -1
  192. package/dist/esm/validation/RevisionAutoFixer.js +69 -55
  193. package/dist/esm/validation/RevisionAutoFixer.js.map +1 -1
  194. package/dist/esm/validation/RevisionValidator.js +24 -20
  195. package/dist/esm/validation/RevisionValidator.js.map +1 -1
  196. package/dist/esm/xml/XMLBuilder.js +52 -20
  197. package/dist/esm/xml/XMLBuilder.js.map +1 -1
  198. package/dist/esm/xml/XMLParser.js +55 -13
  199. package/dist/esm/xml/XMLParser.js.map +1 -1
  200. package/dist/esm/zip/ZipHandler.js +37 -13
  201. package/dist/esm/zip/ZipHandler.js.map +1 -1
  202. package/dist/esm/zip/ZipReader.js +53 -6
  203. package/dist/esm/zip/ZipReader.js.map +1 -1
  204. package/dist/esm/zip/errors.js +7 -0
  205. package/dist/esm/zip/errors.js.map +1 -1
  206. package/dist/esm/zip/types.js +4 -0
  207. package/dist/esm/zip/types.js.map +1 -1
  208. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  209. package/dist/formatting/AbstractNumbering.js +1 -1
  210. package/dist/formatting/AbstractNumbering.js.map +1 -1
  211. package/dist/formatting/NumberingLevel.d.ts +1 -1
  212. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  213. package/dist/formatting/NumberingLevel.js +8 -6
  214. package/dist/formatting/NumberingLevel.js.map +1 -1
  215. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  216. package/dist/formatting/NumberingManager.js +16 -1
  217. package/dist/formatting/NumberingManager.js.map +1 -1
  218. package/dist/formatting/Style.d.ts.map +1 -1
  219. package/dist/formatting/Style.js +14 -0
  220. package/dist/formatting/Style.js.map +1 -1
  221. package/dist/formatting/StylesManager.d.ts +2 -0
  222. package/dist/formatting/StylesManager.d.ts.map +1 -1
  223. package/dist/formatting/StylesManager.js +14 -2
  224. package/dist/formatting/StylesManager.js.map +1 -1
  225. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  226. package/dist/helpers/CleanupHelper.js +103 -26
  227. package/dist/helpers/CleanupHelper.js.map +1 -1
  228. package/dist/images/ImageOptimizer.d.ts.map +1 -1
  229. package/dist/images/ImageOptimizer.js +52 -4
  230. package/dist/images/ImageOptimizer.js.map +1 -1
  231. package/dist/index.d.ts +3 -1
  232. package/dist/index.d.ts.map +1 -1
  233. package/dist/index.js +4 -2
  234. package/dist/index.js.map +1 -1
  235. package/dist/internal.d.ts +1 -1
  236. package/dist/internal.d.ts.map +1 -1
  237. package/dist/internal.js +2 -1
  238. package/dist/internal.js.map +1 -1
  239. package/dist/processors/CompatibilityUpgrader.d.ts.map +1 -1
  240. package/dist/processors/CompatibilityUpgrader.js +7 -1
  241. package/dist/processors/CompatibilityUpgrader.js.map +1 -1
  242. package/dist/processors/InMemoryRevisionAcceptor.d.ts +1 -0
  243. package/dist/processors/InMemoryRevisionAcceptor.d.ts.map +1 -1
  244. package/dist/processors/InMemoryRevisionAcceptor.js +135 -13
  245. package/dist/processors/InMemoryRevisionAcceptor.js.map +1 -1
  246. package/dist/processors/RevisionWalker.d.ts +9 -3
  247. package/dist/processors/RevisionWalker.d.ts.map +1 -1
  248. package/dist/processors/RevisionWalker.js +223 -39
  249. package/dist/processors/RevisionWalker.js.map +1 -1
  250. package/dist/processors/SelectiveRevisionAcceptor.d.ts.map +1 -1
  251. package/dist/processors/SelectiveRevisionAcceptor.js +116 -17
  252. package/dist/processors/SelectiveRevisionAcceptor.js.map +1 -1
  253. package/dist/processors/acceptRevisions.d.ts +1 -0
  254. package/dist/processors/acceptRevisions.d.ts.map +1 -1
  255. package/dist/processors/acceptRevisions.js +21 -11
  256. package/dist/processors/acceptRevisions.js.map +1 -1
  257. package/dist/processors/cnfStyleDecoder.d.ts.map +1 -1
  258. package/dist/processors/cnfStyleDecoder.js +7 -7
  259. package/dist/processors/cnfStyleDecoder.js.map +1 -1
  260. package/dist/processors/stripTrackedChanges.d.ts.map +1 -1
  261. package/dist/processors/stripTrackedChanges.js +16 -5
  262. package/dist/processors/stripTrackedChanges.js.map +1 -1
  263. package/dist/utils/deepClone.d.ts.map +1 -1
  264. package/dist/utils/deepClone.js +24 -11
  265. package/dist/utils/deepClone.js.map +1 -1
  266. package/dist/utils/units.d.ts.map +1 -1
  267. package/dist/utils/units.js +1 -1
  268. package/dist/utils/units.js.map +1 -1
  269. package/dist/utils/validation.d.ts.map +1 -1
  270. package/dist/utils/validation.js +11 -23
  271. package/dist/utils/validation.js.map +1 -1
  272. package/dist/utils/xmlSanitization.d.ts +2 -0
  273. package/dist/utils/xmlSanitization.d.ts.map +1 -1
  274. package/dist/utils/xmlSanitization.js +133 -7
  275. package/dist/utils/xmlSanitization.js.map +1 -1
  276. package/dist/validation/RevisionAutoFixer.d.ts +6 -2
  277. package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
  278. package/dist/validation/RevisionAutoFixer.js +68 -54
  279. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  280. package/dist/validation/RevisionValidator.d.ts +2 -0
  281. package/dist/validation/RevisionValidator.d.ts.map +1 -1
  282. package/dist/validation/RevisionValidator.js +26 -21
  283. package/dist/validation/RevisionValidator.js.map +1 -1
  284. package/dist/xml/XMLBuilder.d.ts +1 -0
  285. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  286. package/dist/xml/XMLBuilder.js +52 -20
  287. package/dist/xml/XMLBuilder.js.map +1 -1
  288. package/dist/xml/XMLParser.d.ts +1 -0
  289. package/dist/xml/XMLParser.d.ts.map +1 -1
  290. package/dist/xml/XMLParser.js +55 -13
  291. package/dist/xml/XMLParser.js.map +1 -1
  292. package/dist/zip/ZipHandler.d.ts.map +1 -1
  293. package/dist/zip/ZipHandler.js +37 -13
  294. package/dist/zip/ZipHandler.js.map +1 -1
  295. package/dist/zip/ZipReader.d.ts.map +1 -1
  296. package/dist/zip/ZipReader.js +52 -5
  297. package/dist/zip/ZipReader.js.map +1 -1
  298. package/dist/zip/errors.d.ts +3 -0
  299. package/dist/zip/errors.d.ts.map +1 -1
  300. package/dist/zip/errors.js +9 -1
  301. package/dist/zip/errors.js.map +1 -1
  302. package/dist/zip/types.d.ts +4 -0
  303. package/dist/zip/types.d.ts.map +1 -1
  304. package/dist/zip/types.js +4 -0
  305. package/dist/zip/types.js.map +1 -1
  306. package/package.json +2 -2
  307. package/src/core/Document.ts +1184 -242
  308. package/src/core/DocumentGenerator.ts +106 -26
  309. package/src/core/DocumentParser.ts +681 -114
  310. package/src/core/RelationshipManager.ts +446 -442
  311. package/src/elements/Comment.ts +123 -18
  312. package/src/elements/CommentManager.ts +121 -22
  313. package/src/elements/EndnoteManager.ts +4 -1
  314. package/src/elements/Field.ts +134 -43
  315. package/src/elements/FieldHelpers.ts +20 -4
  316. package/src/elements/Footer.ts +62 -67
  317. package/src/elements/FootnoteManager.ts +4 -1
  318. package/src/elements/Header.ts +62 -67
  319. package/src/elements/HeaderFooterManager.ts +56 -8
  320. package/src/elements/Hyperlink.ts +150 -55
  321. package/src/elements/Image.ts +51 -7
  322. package/src/elements/ImageManager.ts +24 -0
  323. package/src/elements/Paragraph.ts +161 -40
  324. package/src/elements/Revision.ts +446 -47
  325. package/src/elements/Run.ts +44 -6
  326. package/src/elements/Section.ts +25 -9
  327. package/src/elements/Shape.ts +52 -44
  328. package/src/elements/StructuredDocumentTag.ts +83 -8
  329. package/src/elements/Table.ts +151 -50
  330. package/src/elements/TableCell.ts +57 -17
  331. package/src/elements/TableOfContents.ts +10 -9
  332. package/src/elements/TableRow.ts +35 -3
  333. package/src/elements/TextBox.ts +58 -43
  334. package/src/formatting/AbstractNumbering.ts +4 -2
  335. package/src/formatting/NumberingLevel.ts +50 -12
  336. package/src/formatting/NumberingManager.ts +32 -3
  337. package/src/formatting/Style.ts +14 -0
  338. package/src/formatting/StylesManager.ts +29 -2
  339. package/src/helpers/CleanupHelper.ts +122 -30
  340. package/src/images/ImageOptimizer.ts +64 -5
  341. package/src/index.ts +7 -0
  342. package/src/internal.ts +1 -0
  343. package/src/processors/CompatibilityUpgrader.ts +15 -2
  344. package/src/processors/InMemoryRevisionAcceptor.ts +276 -17
  345. package/src/processors/RevisionWalker.ts +390 -46
  346. package/src/processors/SelectiveRevisionAcceptor.ts +164 -28
  347. package/src/processors/acceptRevisions.ts +67 -17
  348. package/src/processors/cnfStyleDecoder.ts +18 -12
  349. package/src/processors/stripTrackedChanges.ts +47 -10
  350. package/src/utils/deepClone.ts +48 -14
  351. package/src/utils/units.ts +3 -1
  352. package/src/utils/validation.ts +30 -32
  353. package/src/utils/xmlSanitization.ts +218 -22
  354. package/src/validation/RevisionAutoFixer.ts +109 -65
  355. package/src/validation/RevisionValidator.ts +48 -23
  356. package/src/xml/XMLBuilder.ts +82 -22
  357. package/src/xml/XMLParser.ts +87 -20
  358. package/src/zip/ZipHandler.ts +61 -21
  359. package/src/zip/ZipReader.ts +135 -13
  360. package/src/zip/errors.ts +15 -0
  361. package/src/zip/types.ts +44 -2
@@ -75,6 +75,7 @@ const acceptRevisions_js_1 = require("../processors/acceptRevisions.js");
75
75
  const InMemoryRevisionAcceptor_js_1 = require("../processors/InMemoryRevisionAcceptor.js");
76
76
  const stripTrackedChanges_js_1 = require("../processors/stripTrackedChanges.js");
77
77
  const textDiff_js_1 = require("../utils/textDiff.js");
78
+ const xmlSanitization_js_1 = require("../utils/xmlSanitization.js");
78
79
  const XMLBuilder_js_1 = require("../xml/XMLBuilder.js");
79
80
  const XMLParser_js_1 = require("../xml/XMLParser.js");
80
81
  const DocumentTrackingContext_js_1 = require("../tracking/DocumentTrackingContext.js");
@@ -111,6 +112,9 @@ class Document {
111
112
  this.bookmarkManager.setIdProvider(() => this.documentIdManager.getNextId(), (existingId) => this.documentIdManager.ensureNextIdAbove(existingId));
112
113
  this.revisionManager.setIdProvider(() => this.documentIdManager.getNextId(), (existingId) => this.documentIdManager.ensureNextIdAbove(existingId));
113
114
  this.commentManager.setIdProvider(() => this.documentIdManager.getNextId(), (existingId) => this.documentIdManager.ensureNextIdAbove(existingId));
115
+ this.commentManager.setModifiedNotifier(() => {
116
+ this._commentsModified = true;
117
+ });
114
118
  this.trackingContext = new DocumentTrackingContext_js_1.DocumentTrackingContext(this.revisionManager);
115
119
  this.parser = new DocumentParser_js_1.DocumentParser();
116
120
  this.generator = new DocumentGenerator_js_1.DocumentGenerator();
@@ -165,6 +169,7 @@ class Document {
165
169
  _originalNumberingXml;
166
170
  _originalSettingsXml;
167
171
  _originalAppPropsXml;
172
+ _originalCorePropsXml;
168
173
  _originalFootnotesXml;
169
174
  _originalEndnotesXml;
170
175
  _originalCommentsXml;
@@ -174,6 +179,7 @@ class Document {
174
179
  _saveQueue = Promise.resolve();
175
180
  _removedParts = new Set();
176
181
  _appPropsModified = false;
182
+ _corePropsModified = false;
177
183
  _footnotesModified = false;
178
184
  _endnotesModified = false;
179
185
  _settingsModified = false;
@@ -373,7 +379,7 @@ class Document {
373
379
  const logger = getLogger();
374
380
  logger.info('Loading document from file', { path: filePath });
375
381
  const zipHandler = new ZipHandler_js_1.ZipHandler();
376
- await zipHandler.load(filePath);
382
+ await zipHandler.load(filePath, { sizeLimits: options?.sizeLimits });
377
383
  const doc = await Document.initializeFromZip(zipHandler, options);
378
384
  doc._events.emit('afterLoad', { source: 'file', path: filePath });
379
385
  return doc;
@@ -382,7 +388,7 @@ class Document {
382
388
  const logger = getLogger();
383
389
  logger.info('Loading document from buffer', { bufferSize: buffer.length });
384
390
  const zipHandler = new ZipHandler_js_1.ZipHandler();
385
- await zipHandler.loadFromBuffer(buffer);
391
+ await zipHandler.loadFromBuffer(buffer, { sizeLimits: options?.sizeLimits });
386
392
  const doc = await Document.initializeFromZip(zipHandler, options);
387
393
  doc._events.emit('afterLoad', { source: 'buffer' });
388
394
  return doc;
@@ -390,12 +396,20 @@ class Document {
390
396
  static async initializeFromZip(zipHandler, options) {
391
397
  const logger = getLogger();
392
398
  const useInMemoryAccept = options?.acceptRevisions === true;
399
+ if (useInMemoryAccept && options?.revisionHandling === 'reject') {
400
+ throw new Error("Conflicting load options: 'acceptRevisions: true' (in-memory accept) cannot be combined " +
401
+ 'with \'revisionHandling: "reject"\'. Use \'revisionHandling: "reject"\' on its own to ' +
402
+ 'revert the document to its original pre-edit state.');
403
+ }
393
404
  const revisionHandling = useInMemoryAccept
394
405
  ? 'preserve'
395
406
  : (options?.revisionHandling ?? 'accept');
396
407
  if (revisionHandling === 'accept') {
397
408
  await (0, acceptRevisions_js_1.acceptAllRevisions)(zipHandler);
398
409
  }
410
+ else if (revisionHandling === 'reject') {
411
+ await (0, acceptRevisions_js_1.rejectAllRevisions)(zipHandler);
412
+ }
399
413
  else if (revisionHandling === 'strip') {
400
414
  await (0, stripTrackedChanges_js_1.stripTrackedChanges)(zipHandler);
401
415
  }
@@ -422,7 +436,7 @@ class Document {
422
436
  }
423
437
  const numberingXml = zipHandler.getFileAsString(types_js_1.DOCX_PATHS.NUMBERING);
424
438
  if (numberingXml) {
425
- doc._originalNumberingXml = numberingXml;
439
+ doc._originalNumberingXml = (0, xmlSanitization_js_1.reorderRunPropertyChildren)(numberingXml);
426
440
  }
427
441
  const settingsXml = zipHandler.getFileAsString(types_js_1.DOCX_PATHS.SETTINGS);
428
442
  if (settingsXml) {
@@ -433,6 +447,10 @@ class Document {
433
447
  if (appPropsXml) {
434
448
  doc._originalAppPropsXml = appPropsXml;
435
449
  }
450
+ const corePropsXml = zipHandler.getFileAsString(types_js_1.DOCX_PATHS.CORE_PROPS);
451
+ if (corePropsXml) {
452
+ doc._originalCorePropsXml = corePropsXml;
453
+ }
436
454
  const webSettingsXml = zipHandler.getFileAsString(types_js_1.DOCX_PATHS.WEB_SETTINGS);
437
455
  if (webSettingsXml) {
438
456
  doc._originalWebSettingsXml = webSettingsXml;
@@ -695,17 +713,17 @@ class Document {
695
713
  try {
696
714
  const headersFooters = await this.parser.parseHeadersAndFooters(this.zipHandler, result.section, this.relationshipManager, this.imageManager);
697
715
  const registeredHeaderRIds = new Set();
698
- for (const { header, relationshipId } of headersFooters.headers) {
716
+ for (const { header, relationshipId, filename } of headersFooters.headers) {
699
717
  if (registeredHeaderRIds.has(relationshipId))
700
718
  continue;
701
- this.headerFooterManager.registerHeader(header, relationshipId);
719
+ this.headerFooterManager.registerHeader(header, relationshipId, filename);
702
720
  registeredHeaderRIds.add(relationshipId);
703
721
  }
704
722
  const registeredFooterRIds = new Set();
705
- for (const { footer, relationshipId } of headersFooters.footers) {
723
+ for (const { footer, relationshipId, filename } of headersFooters.footers) {
706
724
  if (registeredFooterRIds.has(relationshipId))
707
725
  continue;
708
- this.headerFooterManager.registerFooter(footer, relationshipId);
726
+ this.headerFooterManager.registerFooter(footer, relationshipId, filename);
709
727
  registeredFooterRIds.add(relationshipId);
710
728
  }
711
729
  }
@@ -748,7 +766,7 @@ class Document {
748
766
  }
749
767
  }
750
768
  const parser = new DocumentParser_js_1.DocumentParser();
751
- const comments = parser.parseCommentsXml(commentsXml);
769
+ const comments = parser.parseCommentsXml(commentsXml, this._originalCommentCompanionFiles.get(types_js_1.DOCX_PATHS.COMMENTS_EXTENDED));
752
770
  for (const comment of comments) {
753
771
  this.commentManager.registerExisting(comment);
754
772
  }
@@ -762,7 +780,9 @@ class Document {
762
780
  this._originalFootnotesXml = footnotesXml;
763
781
  try {
764
782
  const parser = new DocumentParser_js_1.DocumentParser();
765
- const footnotes = parser.parseFootnotesXml(footnotesXml);
783
+ const relsXml = this.zipHandler.getFileAsString('word/_rels/footnotes.xml.rels');
784
+ const partRels = relsXml ? RelationshipManager_js_1.RelationshipManager.fromXml(relsXml) : undefined;
785
+ const footnotes = parser.parseFootnotesXml(footnotesXml, partRels);
766
786
  for (const footnote of footnotes) {
767
787
  const id = footnote.getId();
768
788
  if (!this.footnoteManager.hasFootnote(id)) {
@@ -784,7 +804,9 @@ class Document {
784
804
  this._originalEndnotesXml = endnotesXml;
785
805
  try {
786
806
  const parser = new DocumentParser_js_1.DocumentParser();
787
- const endnotes = parser.parseEndnotesXml(endnotesXml);
807
+ const relsXml = this.zipHandler.getFileAsString('word/_rels/endnotes.xml.rels');
808
+ const partRels = relsXml ? RelationshipManager_js_1.RelationshipManager.fromXml(relsXml) : undefined;
809
+ const endnotes = parser.parseEndnotesXml(endnotesXml, partRels);
788
810
  for (const endnote of endnotes) {
789
811
  const id = endnote.getId();
790
812
  if (!this.endnoteManager.hasEndnote(id)) {
@@ -876,12 +898,13 @@ class Document {
876
898
  paragraph._setStylesManager(this.stylesManager);
877
899
  if (this.trackChangesEnabled && this.trackingContext.isEnabled()) {
878
900
  this.bindTrackingToElement(paragraph);
879
- const runs = paragraph.getRuns();
880
- if (runs.length > 0) {
881
- const author = this.trackingContext.getAuthor();
882
- const insertion = Revision_js_1.Revision.createInsertion(author, runs);
883
- this.trackingContext.getRevisionManager().register(insertion);
884
- paragraph.addRevision(insertion);
901
+ const author = this.trackingContext.getAuthor();
902
+ for (const item of paragraph.getContent()) {
903
+ if (item instanceof Run_js_1.Run || item instanceof Hyperlink_js_1.Hyperlink) {
904
+ const insertion = Revision_js_1.Revision.createInsertion(author, item);
905
+ this.trackingContext.getRevisionManager().register(insertion);
906
+ paragraph.replaceContent(item, [insertion]);
907
+ }
885
908
  }
886
909
  }
887
910
  this.bodyElements.push(paragraph);
@@ -1097,14 +1120,17 @@ class Document {
1097
1120
  }
1098
1121
  setTitle(title) {
1099
1122
  this.properties.title = title;
1123
+ this._corePropsModified = true;
1100
1124
  return this;
1101
1125
  }
1102
1126
  setSubject(subject) {
1103
1127
  this.properties.subject = subject;
1128
+ this._corePropsModified = true;
1104
1129
  return this;
1105
1130
  }
1106
1131
  setCreator(creator) {
1107
1132
  this.properties.creator = creator;
1133
+ this._corePropsModified = true;
1108
1134
  return this;
1109
1135
  }
1110
1136
  setAuthor(author) {
@@ -1112,18 +1138,22 @@ class Document {
1112
1138
  }
1113
1139
  setKeywords(keywords) {
1114
1140
  this.properties.keywords = keywords;
1141
+ this._corePropsModified = true;
1115
1142
  return this;
1116
1143
  }
1117
1144
  setDescription(description) {
1118
1145
  this.properties.description = description;
1146
+ this._corePropsModified = true;
1119
1147
  return this;
1120
1148
  }
1121
1149
  setCategory(category) {
1122
1150
  this.properties.category = category;
1151
+ this._corePropsModified = true;
1123
1152
  return this;
1124
1153
  }
1125
1154
  setContentStatus(status) {
1126
1155
  this.properties.contentStatus = status;
1156
+ this._corePropsModified = true;
1127
1157
  return this;
1128
1158
  }
1129
1159
  setApplication(application) {
@@ -1570,8 +1600,48 @@ class Document {
1570
1600
  if (this._removedParts.has(types_js_1.DOCX_PATHS.CORE_PROPS) ||
1571
1601
  this._removedParts.has('docProps/core.xml'))
1572
1602
  return;
1573
- const xml = this.generator.generateCoreProps(this.properties);
1574
- this.zipHandler.updateFile(types_js_1.DOCX_PATHS.CORE_PROPS, xml);
1603
+ if (this._originalCorePropsXml && !this._corePropsModified) {
1604
+ return;
1605
+ }
1606
+ if (this._originalCorePropsXml && this._corePropsModified) {
1607
+ const mergedXml = this.mergeCorePropsWithOriginal();
1608
+ this.zipHandler.updateFile(types_js_1.DOCX_PATHS.CORE_PROPS, mergedXml);
1609
+ }
1610
+ else {
1611
+ const xml = this.generator.generateCoreProps(this.properties);
1612
+ this.zipHandler.updateFile(types_js_1.DOCX_PATHS.CORE_PROPS, xml);
1613
+ }
1614
+ }
1615
+ mergeCorePropsWithOriginal() {
1616
+ if (!this._originalCorePropsXml) {
1617
+ return this.generator.generateCoreProps(this.properties);
1618
+ }
1619
+ let xml = this._originalCorePropsXml;
1620
+ const mergeField = (tag, value) => {
1621
+ if (value === undefined)
1622
+ return;
1623
+ const escaped = XMLBuilder_js_1.XMLBuilder.sanitizeXmlContent(value);
1624
+ const openClose = new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?</${tag}>`);
1625
+ const selfClosing = new RegExp(`<${tag}\\b[^>]*/>`);
1626
+ if (openClose.test(xml)) {
1627
+ xml = xml.replace(openClose, `<${tag}>${escaped}</${tag}>`);
1628
+ }
1629
+ else if (selfClosing.test(xml)) {
1630
+ xml = xml.replace(selfClosing, `<${tag}>${escaped}</${tag}>`);
1631
+ }
1632
+ else {
1633
+ xml = xml.replace(/<\/cp:coreProperties>/, ` <${tag}>${escaped}</${tag}>\n</cp:coreProperties>`);
1634
+ }
1635
+ };
1636
+ mergeField('dc:title', this.properties.title);
1637
+ mergeField('dc:subject', this.properties.subject);
1638
+ mergeField('dc:creator', this.properties.creator);
1639
+ mergeField('cp:keywords', this.properties.keywords);
1640
+ mergeField('dc:description', this.properties.description);
1641
+ mergeField('cp:category', this.properties.category);
1642
+ mergeField('cp:contentStatus', this.properties.contentStatus);
1643
+ mergeField('dc:language', this.properties.language);
1644
+ return xml;
1575
1645
  }
1576
1646
  updateAppProps() {
1577
1647
  if (this._removedParts.has(types_js_1.DOCX_PATHS.APP_PROPS) || this._removedParts.has('docProps/app.xml'))
@@ -1601,24 +1671,36 @@ class Document {
1601
1671
  else if (xml.includes('<Company/>')) {
1602
1672
  xml = xml.replace(/<Company\/>/, `<Company>${escaped}</Company>`);
1603
1673
  }
1674
+ else {
1675
+ xml = xml.replace(/<\/Properties>/, ` <Company>${escaped}</Company>\n</Properties>`);
1676
+ }
1604
1677
  }
1605
1678
  if (this.properties.application !== undefined) {
1606
1679
  const escaped = XMLBuilder_js_1.XMLBuilder.sanitizeXmlContent(this.properties.application);
1607
1680
  if (xml.includes('<Application>')) {
1608
1681
  xml = xml.replace(/<Application>[^<]*<\/Application>/, `<Application>${escaped}</Application>`);
1609
1682
  }
1683
+ else {
1684
+ xml = xml.replace(/<\/Properties>/, ` <Application>${escaped}</Application>\n</Properties>`);
1685
+ }
1610
1686
  }
1611
1687
  if (this.properties.appVersion !== undefined) {
1612
1688
  const escaped = XMLBuilder_js_1.XMLBuilder.sanitizeXmlContent(this.properties.appVersion);
1613
1689
  if (xml.includes('<AppVersion>')) {
1614
1690
  xml = xml.replace(/<AppVersion>[^<]*<\/AppVersion>/, `<AppVersion>${escaped}</AppVersion>`);
1615
1691
  }
1692
+ else {
1693
+ xml = xml.replace(/<\/Properties>/, ` <AppVersion>${escaped}</AppVersion>\n</Properties>`);
1694
+ }
1616
1695
  }
1617
1696
  if (this.properties.manager !== undefined) {
1618
1697
  const escaped = XMLBuilder_js_1.XMLBuilder.sanitizeXmlContent(this.properties.manager);
1619
1698
  if (xml.includes('<Manager>')) {
1620
1699
  xml = xml.replace(/<Manager>[^<]*<\/Manager>/, `<Manager>${escaped}</Manager>`);
1621
1700
  }
1701
+ else {
1702
+ xml = xml.replace(/<\/Properties>/, ` <Manager>${escaped}</Manager>\n</Properties>`);
1703
+ }
1622
1704
  }
1623
1705
  return xml;
1624
1706
  }
@@ -1744,7 +1826,8 @@ class Document {
1744
1826
  return this.stylesManager.generateStylesXml();
1745
1827
  }
1746
1828
  const modifiedStyleIds = this.stylesManager.getModifiedStyleIds();
1747
- if (modifiedStyleIds.size === 0) {
1829
+ const removedStyleIds = this.stylesManager.getRemovedStyleIds();
1830
+ if (modifiedStyleIds.size === 0 && removedStyleIds.size === 0) {
1748
1831
  return this._originalStylesXml;
1749
1832
  }
1750
1833
  const modifiedStyles = new Map();
@@ -1766,6 +1849,11 @@ class Document {
1766
1849
  resultXml = resultXml.replace('</w:styles>', `${newStyleXml}\n</w:styles>`);
1767
1850
  }
1768
1851
  }
1852
+ for (const styleId of removedStyleIds) {
1853
+ const escapedStyleId = styleId.replace(/[.*+?^${}()|[\]\\"]/g, '\\$&');
1854
+ const removedPattern = new RegExp(`\\s*<w:style[^>]*\\sw:styleId="${escapedStyleId}"[^>]*>[\\s\\S]*?</w:style>`);
1855
+ resultXml = resultXml.replace(removedPattern, '');
1856
+ }
1769
1857
  return resultXml;
1770
1858
  }
1771
1859
  updateNumberingXml() {
@@ -1964,8 +2052,14 @@ class Document {
1964
2052
  xml = xml.replace(/<w:revisionView\b[^>]*>[\s\S]*?<\/w:revisionView>/g, '');
1965
2053
  let trackBlock = '';
1966
2054
  const view = this.revisionViewSettings;
1967
- if (!view.showInsertionsAndDeletions || !view.showFormatting || !view.showInkAnnotations) {
1968
- trackBlock += `\n <w:revisionView w:insDel="${view.showInsertionsAndDeletions ? '1' : '0'}" w:formatting="${view.showFormatting ? '1' : '0'}" w:inkAnnotations="${view.showInkAnnotations ? '1' : '0'}"/>`;
2055
+ if (!view.showInsertionsAndDeletions ||
2056
+ !view.showFormatting ||
2057
+ !view.showInkAnnotations ||
2058
+ view.showMarkup === false ||
2059
+ view.showComments === false) {
2060
+ const markupAttr = view.showMarkup === false ? ' w:markup="0"' : '';
2061
+ const commentsAttr = view.showComments === false ? ' w:comments="0"' : '';
2062
+ trackBlock += `\n <w:revisionView w:insDel="${view.showInsertionsAndDeletions ? '1' : '0'}" w:formatting="${view.showFormatting ? '1' : '0'}" w:inkAnnotations="${view.showInkAnnotations ? '1' : '0'}"${markupAttr}${commentsAttr}/>`;
1969
2063
  }
1970
2064
  if (this.trackChangesEnabled) {
1971
2065
  trackBlock += '\n <w:trackRevisions/>';
@@ -2001,6 +2095,8 @@ class Document {
2001
2095
  const prot = this.documentProtection;
2002
2096
  const esc = XMLBuilder_js_1.XMLBuilder.escapeXmlAttribute;
2003
2097
  let protXml = `\n <w:documentProtection w:edit="${esc(prot.edit)}" w:enforcement="${prot.enforcement ? '1' : '0'}"`;
2098
+ if (prot.formatting !== undefined)
2099
+ protXml += ` w:formatting="${prot.formatting ? '1' : '0'}"`;
2004
2100
  if (prot.cryptProviderType)
2005
2101
  protXml += ` w:cryptProviderType="${esc(prot.cryptProviderType)}"`;
2006
2102
  if (prot.cryptAlgorithmClass)
@@ -2015,6 +2111,12 @@ class Document {
2015
2111
  protXml += ` w:hash="${esc(prot.hash)}"`;
2016
2112
  if (prot.salt)
2017
2113
  protXml += ` w:salt="${esc(prot.salt)}"`;
2114
+ if (prot.algorithmName)
2115
+ protXml += ` w:algorithmName="${esc(prot.algorithmName)}"`;
2116
+ if (prot.hashValue)
2117
+ protXml += ` w:hashValue="${esc(prot.hashValue)}"`;
2118
+ if (prot.saltValue)
2119
+ protXml += ` w:saltValue="${esc(prot.saltValue)}"`;
2018
2120
  protXml += '/>';
2019
2121
  if (/<w:autoFormatOverride\b/.test(xml)) {
2020
2122
  xml = xml.replace(/<w:autoFormatOverride\b/, protXml + '\n <w:autoFormatOverride');
@@ -2768,6 +2870,18 @@ class Document {
2768
2870
  }
2769
2871
  }
2770
2872
  }
2873
+ for (const style of this.stylesManager.getAllStyles()) {
2874
+ const styleNumId = style.getProperties().numPr?.numId;
2875
+ if (styleNumId !== undefined) {
2876
+ usedNumIds.add(styleNumId);
2877
+ }
2878
+ }
2879
+ for (const filePath of [types_js_1.DOCX_PATHS.STYLES, 'word/comments.xml']) {
2880
+ const xml = this.zipHandler.getFileAsString(filePath);
2881
+ if (xml) {
2882
+ this.collectNumIdsFromXml(xml, usedNumIds);
2883
+ }
2884
+ }
2771
2885
  this.numberingManager.cleanupUnusedNumbering(usedNumIds);
2772
2886
  }
2773
2887
  validateNumberingReferences() {
@@ -2869,7 +2983,67 @@ class Document {
2869
2983
  maxRevId = rev.getId();
2870
2984
  }
2871
2985
  const registeredSet = new Set(existingRevisions);
2872
- let docPrId = 1;
2986
+ let maxPreservedDocPrId = 0;
2987
+ const collectPreservedDocPrIds = (rawXml) => {
2988
+ if (!rawXml || !rawXml.includes('wp:docPr'))
2989
+ return;
2990
+ const docPrPattern = /<wp:docPr\b[^>]*\bid="(\d+)"/g;
2991
+ let match;
2992
+ while ((match = docPrPattern.exec(rawXml)) !== null) {
2993
+ const id = parseInt(match[1], 10);
2994
+ if (id > maxPreservedDocPrId)
2995
+ maxPreservedDocPrId = id;
2996
+ }
2997
+ };
2998
+ const collectFromRun = (run) => {
2999
+ if (run instanceof ImageRun_js_1.ImageRun) {
3000
+ collectPreservedDocPrIds(run.getRawRunXml());
3001
+ return;
3002
+ }
3003
+ for (const contentItem of run.getContent()) {
3004
+ collectPreservedDocPrIds(contentItem.rawXml);
3005
+ }
3006
+ };
3007
+ const collectFromParagraph = (para) => {
3008
+ for (const item of para.getContent()) {
3009
+ if (item instanceof Revision_js_1.Revision) {
3010
+ for (const revItem of item.getContent()) {
3011
+ if (revItem instanceof Run_js_1.Run)
3012
+ collectFromRun(revItem);
3013
+ }
3014
+ }
3015
+ else if (item instanceof Run_js_1.Run) {
3016
+ collectFromRun(item);
3017
+ }
3018
+ else if (item instanceof PreservedElement_js_1.PreservedElement) {
3019
+ collectPreservedDocPrIds(item.getRawXml());
3020
+ }
3021
+ }
3022
+ };
3023
+ for (const element of this.bodyElements) {
3024
+ if (element instanceof Paragraph_js_1.Paragraph) {
3025
+ collectFromParagraph(element);
3026
+ }
3027
+ else if (element instanceof Table_js_1.Table) {
3028
+ for (const row of element.getRows()) {
3029
+ for (const cell of row.getCells()) {
3030
+ for (const para of cell.getParagraphs()) {
3031
+ collectFromParagraph(para);
3032
+ }
3033
+ for (const nested of cell.getRawNestedContent()) {
3034
+ collectPreservedDocPrIds(nested.xml);
3035
+ }
3036
+ }
3037
+ }
3038
+ }
3039
+ else {
3040
+ const passthrough = element;
3041
+ if (typeof passthrough.getRawXml === 'function') {
3042
+ collectPreservedDocPrIds(passthrough.getRawXml());
3043
+ }
3044
+ }
3045
+ }
3046
+ let docPrId = maxPreservedDocPrId + 1;
2873
3047
  const existingParaIds = new Set();
2874
3048
  const paragraphsNeedingIds = [];
2875
3049
  const generateUniqueParaId = () => {
@@ -2901,6 +3075,13 @@ class Document {
2901
3075
  else if (item instanceof ImageRun_js_1.ImageRun) {
2902
3076
  item.getImageElement().setDocPrId(docPrId++);
2903
3077
  }
3078
+ else if (item instanceof Revision_js_1.Revision) {
3079
+ for (const revItem of item.getContent()) {
3080
+ if (revItem instanceof ImageRun_js_1.ImageRun) {
3081
+ revItem.getImageElement().setDocPrId(docPrId++);
3082
+ }
3083
+ }
3084
+ }
2904
3085
  }
2905
3086
  if (para.formatting.paraId) {
2906
3087
  existingParaIds.add(para.formatting.paraId);
@@ -3190,6 +3371,7 @@ class Document {
3190
3371
  numLevel.setLeftIndent(720 * (levelIndex + 1));
3191
3372
  numLevel.setHangingIndent(360);
3192
3373
  }
3374
+ this.numberingManager.markAbstractNumberingModified(abstractNumId);
3193
3375
  this.applyFormattingToListParagraphs(instance.getNumId());
3194
3376
  count++;
3195
3377
  }
@@ -3216,6 +3398,7 @@ class Document {
3216
3398
  numLevel.setHangingIndent(360);
3217
3399
  numLevel.setAlignment('left');
3218
3400
  }
3401
+ this.numberingManager.markAbstractNumberingModified(abstractNumId);
3219
3402
  this.applyFormattingToListParagraphs(instance.getNumId());
3220
3403
  count++;
3221
3404
  }
@@ -5038,39 +5221,39 @@ class Document {
5038
5221
  return this;
5039
5222
  }
5040
5223
  setHeader(header) {
5041
- const relationship = this.relationshipManager.addHeader(`${header.getFilename(1)}`);
5224
+ const relationship = this.relationshipManager.addHeader(this.headerFooterManager.peekHeaderFilename(header));
5042
5225
  this.headerFooterManager.registerHeader(header, relationship.getId());
5043
5226
  this.section.setHeaderReference('default', relationship.getId());
5044
5227
  return this;
5045
5228
  }
5046
5229
  setFirstPageHeader(header) {
5047
5230
  this.section.setTitlePage(true);
5048
- const relationship = this.relationshipManager.addHeader(`${header.getFilename(this.headerFooterManager.getHeaderCount() + 1)}`);
5231
+ const relationship = this.relationshipManager.addHeader(this.headerFooterManager.peekHeaderFilename(header));
5049
5232
  this.headerFooterManager.registerHeader(header, relationship.getId());
5050
5233
  this.section.setHeaderReference('first', relationship.getId());
5051
5234
  return this;
5052
5235
  }
5053
5236
  setEvenPageHeader(header) {
5054
- const relationship = this.relationshipManager.addHeader(`${header.getFilename(this.headerFooterManager.getHeaderCount() + 1)}`);
5237
+ const relationship = this.relationshipManager.addHeader(this.headerFooterManager.peekHeaderFilename(header));
5055
5238
  this.headerFooterManager.registerHeader(header, relationship.getId());
5056
5239
  this.section.setHeaderReference('even', relationship.getId());
5057
5240
  return this;
5058
5241
  }
5059
5242
  setFooter(footer) {
5060
- const relationship = this.relationshipManager.addFooter(`${footer.getFilename(1)}`);
5243
+ const relationship = this.relationshipManager.addFooter(this.headerFooterManager.peekFooterFilename(footer));
5061
5244
  this.headerFooterManager.registerFooter(footer, relationship.getId());
5062
5245
  this.section.setFooterReference('default', relationship.getId());
5063
5246
  return this;
5064
5247
  }
5065
5248
  setFirstPageFooter(footer) {
5066
5249
  this.section.setTitlePage(true);
5067
- const relationship = this.relationshipManager.addFooter(`${footer.getFilename(this.headerFooterManager.getFooterCount() + 1)}`);
5250
+ const relationship = this.relationshipManager.addFooter(this.headerFooterManager.peekFooterFilename(footer));
5068
5251
  this.headerFooterManager.registerFooter(footer, relationship.getId());
5069
5252
  this.section.setFooterReference('first', relationship.getId());
5070
5253
  return this;
5071
5254
  }
5072
5255
  setEvenPageFooter(footer) {
5073
- const relationship = this.relationshipManager.addFooter(`${footer.getFilename(this.headerFooterManager.getFooterCount() + 1)}`);
5256
+ const relationship = this.relationshipManager.addFooter(this.headerFooterManager.peekFooterFilename(footer));
5074
5257
  this.headerFooterManager.registerFooter(footer, relationship.getId());
5075
5258
  this.section.setFooterReference('even', relationship.getId());
5076
5259
  return this;
@@ -5216,6 +5399,20 @@ class Document {
5216
5399
  }
5217
5400
  }
5218
5401
  this.removeCommentCompanionFiles();
5402
+ const extendedXml = this.commentManager.generateCommentsExtendedXml();
5403
+ if (extendedXml) {
5404
+ this.zipHandler.addFile(types_js_1.DOCX_PATHS.COMMENTS_EXTENDED, extendedXml);
5405
+ const hasExtendedRel = this.relationshipManager
5406
+ .getAllRelationships()
5407
+ .some((rel) => rel.getTarget() === 'commentsExtended.xml');
5408
+ if (!hasExtendedRel) {
5409
+ this.relationshipManager.addRelationship(Relationship_js_1.Relationship.create({
5410
+ id: this.relationshipManager.generateId(),
5411
+ type: 'http://schemas.microsoft.com/office/2011/relationships/commentsExtended',
5412
+ target: 'commentsExtended.xml',
5413
+ }));
5414
+ }
5415
+ }
5219
5416
  }
5220
5417
  else if (this._originalCommentsXml) {
5221
5418
  this.zipHandler.addFile('word/comments.xml', this._originalCommentsXml);
@@ -5253,7 +5450,8 @@ class Document {
5253
5450
  }
5254
5451
  }
5255
5452
  saveFootnotes() {
5256
- if (this._footnotesModified || this.footnoteManager.getCount() > 0) {
5453
+ if (this._footnotesModified ||
5454
+ (!this._originalFootnotesXml && this.footnoteManager.getCount() > 0)) {
5257
5455
  const xml = this.footnoteManager.generateFootnotesXml();
5258
5456
  this.zipHandler.addFile(types_js_1.DOCX_PATHS.FOOTNOTES, xml);
5259
5457
  const existingRels = this.relationshipManager.getRelationshipsByType(Relationship_js_1.RelationshipType.FOOTNOTES);
@@ -5271,7 +5469,8 @@ class Document {
5271
5469
  }
5272
5470
  }
5273
5471
  saveEndnotes() {
5274
- if (this._endnotesModified || this.endnoteManager.getCount() > 0) {
5472
+ if (this._endnotesModified ||
5473
+ (!this._originalEndnotesXml && this.endnoteManager.getCount() > 0)) {
5275
5474
  const xml = this.endnoteManager.generateEndnotesXml();
5276
5475
  this.zipHandler.addFile(types_js_1.DOCX_PATHS.ENDNOTES, xml);
5277
5476
  const existingRels = this.relationshipManager.getRelationshipsByType(Relationship_js_1.RelationshipType.ENDNOTES);
@@ -5340,7 +5539,12 @@ class Document {
5340
5539
  xml += '</Relationships>';
5341
5540
  this.zipHandler.addFile(relsPath, xml);
5342
5541
  for (const rel of hyperlinkRels) {
5343
- this.relationshipManager.removeRelationship(rel.id);
5542
+ const mainRel = this.relationshipManager.getRelationship(rel.id);
5543
+ if (mainRel &&
5544
+ mainRel.getType() === Relationship_js_1.RelationshipType.HYPERLINK &&
5545
+ mainRel.getTarget() === rel.url) {
5546
+ this.relationshipManager.removeRelationship(rel.id);
5547
+ }
5344
5548
  }
5345
5549
  }
5346
5550
  }
@@ -5458,13 +5662,25 @@ class Document {
5458
5662
  parseContentTypes(xml) {
5459
5663
  const defaults = new Set();
5460
5664
  const overrides = new Set();
5461
- const defaultMatches = xml.matchAll(/<Default\s+Extension="([^"]+)"\s+ContentType="([^"]+)"\s*\/>/g);
5462
- for (const match of defaultMatches) {
5463
- defaults.add(`${match[1]}|${match[2]}`);
5665
+ const readAttr = (tag, name) => {
5666
+ const match = tag.match(new RegExp(`(?:^|\\s)${name}\\s*=\\s*("([^"]*)"|'([^']*)')`));
5667
+ if (!match)
5668
+ return undefined;
5669
+ return XMLBuilder_js_1.XMLBuilder.unescapeXml(match[2] ?? match[3] ?? '');
5670
+ };
5671
+ for (const tagMatch of xml.matchAll(/<Default\b[^>]*>/g)) {
5672
+ const ext = readAttr(tagMatch[0], 'Extension');
5673
+ const contentType = readAttr(tagMatch[0], 'ContentType');
5674
+ if (ext && contentType) {
5675
+ defaults.add(`${ext}|${contentType}`);
5676
+ }
5464
5677
  }
5465
- const overrideMatches = xml.matchAll(/<Override\s+PartName="([^"]+)"\s+ContentType="([^"]+)"\s*\/>/g);
5466
- for (const match of overrideMatches) {
5467
- overrides.add(`${match[1]}|${match[2]}`);
5678
+ for (const tagMatch of xml.matchAll(/<Override\b[^>]*>/g)) {
5679
+ const partName = readAttr(tagMatch[0], 'PartName');
5680
+ const contentType = readAttr(tagMatch[0], 'ContentType');
5681
+ if (partName && contentType) {
5682
+ overrides.add(`${partName}|${contentType}`);
5683
+ }
5468
5684
  }
5469
5685
  return { defaults, overrides };
5470
5686
  }
@@ -5784,9 +6000,7 @@ class Document {
5784
6000
  }
5785
6001
  if (element && typeof element.getContent === 'function') {
5786
6002
  for (const item of element.getContent()) {
5787
- if (item &&
5788
- typeof item._setTrackingContext === 'function' &&
5789
- typeof item.getInstruction === 'function') {
6003
+ if (item && typeof item._setTrackingContext === 'function') {
5790
6004
  item._setTrackingContext(this.trackingContext);
5791
6005
  }
5792
6006
  }
@@ -5953,6 +6167,7 @@ class Document {
5953
6167
  updated.size = sizeInPoints;
5954
6168
  }
5955
6169
  normalStyle.setRunFormatting(updated);
6170
+ this.stylesManager.addStyle(normalStyle);
5956
6171
  return this;
5957
6172
  }
5958
6173
  setDefaultFontSize(sizeInPoints) {
@@ -5968,6 +6183,7 @@ class Document {
5968
6183
  }
5969
6184
  const existing = normalStyle.getRunFormatting() ?? {};
5970
6185
  normalStyle.setRunFormatting({ ...existing, size: sizeInPoints });
6186
+ this.stylesManager.addStyle(normalStyle);
5971
6187
  return this;
5972
6188
  }
5973
6189
  getUpdateFields() {
@@ -6159,6 +6375,40 @@ class Document {
6159
6375
  this.endnoteManager.clear();
6160
6376
  this._endnotesModified = true;
6161
6377
  }
6378
+ removeFootnote(id) {
6379
+ const removed = this.footnoteManager.removeFootnote(id);
6380
+ if (removed) {
6381
+ this._footnotesModified = true;
6382
+ this.removeNoteReferenceRuns('footnoteReference', id);
6383
+ }
6384
+ return removed;
6385
+ }
6386
+ removeEndnote(id) {
6387
+ const removed = this.endnoteManager.removeEndnote(id);
6388
+ if (removed) {
6389
+ this._endnotesModified = true;
6390
+ this.removeNoteReferenceRuns('endnoteReference', id);
6391
+ }
6392
+ return removed;
6393
+ }
6394
+ removeNoteReferenceRuns(refType, id) {
6395
+ for (const para of this.getAllParagraphs()) {
6396
+ const content = para.getContent();
6397
+ for (let i = content.length - 1; i >= 0; i--) {
6398
+ const item = content[i];
6399
+ if (!(item instanceof Run_js_1.Run)) {
6400
+ continue;
6401
+ }
6402
+ const matches = item
6403
+ .getContent()
6404
+ .some((c) => c.type === refType &&
6405
+ (refType === 'footnoteReference' ? c.footnoteId === id : c.endnoteId === id));
6406
+ if (matches) {
6407
+ para.removeContentAt(i);
6408
+ }
6409
+ }
6410
+ }
6411
+ }
6162
6412
  addCommentToParagraph(paragraph, commentOrAuthor, content, initials) {
6163
6413
  const comment = typeof commentOrAuthor === 'string'
6164
6414
  ? this.createComment(commentOrAuthor, content, initials)
@@ -6209,12 +6459,52 @@ class Document {
6209
6459
  return this.commentManager.hasReplies(commentId);
6210
6460
  }
6211
6461
  removeComment(id) {
6462
+ const replyIds = this.commentManager.getReplies(id).map((reply) => reply.getId());
6212
6463
  const removed = this.commentManager.removeComment(id);
6213
6464
  if (removed) {
6465
+ this.removeCommentAnchors([id, ...replyIds]);
6214
6466
  this._commentsModified = true;
6215
6467
  }
6216
6468
  return removed;
6217
6469
  }
6470
+ removeCommentAnchors(commentIds) {
6471
+ const strip = (paragraphs) => {
6472
+ let removed = false;
6473
+ for (const paragraph of paragraphs) {
6474
+ for (const commentId of commentIds) {
6475
+ if (paragraph.removeCommentAnchor(commentId)) {
6476
+ removed = true;
6477
+ }
6478
+ }
6479
+ }
6480
+ return removed;
6481
+ };
6482
+ strip(this.getAllParagraphs());
6483
+ for (const entry of this.headerFooterManager.getAllHeaders()) {
6484
+ strip(this.extractParagraphsFromElements(entry.header.getElements()));
6485
+ }
6486
+ for (const entry of this.headerFooterManager.getAllFooters()) {
6487
+ strip(this.extractParagraphsFromElements(entry.footer.getElements()));
6488
+ }
6489
+ let footnotesChanged = false;
6490
+ for (const footnote of this.footnoteManager.getAllFootnotes()) {
6491
+ if (strip(footnote.getParagraphs())) {
6492
+ footnotesChanged = true;
6493
+ }
6494
+ }
6495
+ if (footnotesChanged) {
6496
+ this._footnotesModified = true;
6497
+ }
6498
+ let endnotesChanged = false;
6499
+ for (const endnote of this.endnoteManager.getAllEndnotes()) {
6500
+ if (strip(endnote.getParagraphs())) {
6501
+ endnotesChanged = true;
6502
+ }
6503
+ }
6504
+ if (endnotesChanged) {
6505
+ this._endnotesModified = true;
6506
+ }
6507
+ }
6218
6508
  hasNoRevisions() {
6219
6509
  return this.revisionManager.isEmpty();
6220
6510
  }
@@ -6470,8 +6760,8 @@ class Document {
6470
6760
  this.parser.clearParseErrors();
6471
6761
  this.stylesManager.clear();
6472
6762
  this.numberingManager.clear();
6473
- this.imageManager.clear();
6474
6763
  this.imageManager.releaseAllImageData();
6764
+ this.imageManager.clear();
6475
6765
  this.relationshipManager.clear();
6476
6766
  this.headerFooterManager.clear();
6477
6767
  this.bookmarkManager.clear();
@@ -6485,6 +6775,7 @@ class Document {
6485
6775
  this._originalNumberingXml = undefined;
6486
6776
  this._originalSettingsXml = undefined;
6487
6777
  this._originalAppPropsXml = undefined;
6778
+ this._originalCorePropsXml = undefined;
6488
6779
  this._originalFootnotesXml = undefined;
6489
6780
  this._originalEndnotesXml = undefined;
6490
6781
  this._originalCommentsXml = undefined;
@@ -6493,6 +6784,7 @@ class Document {
6493
6784
  this._originalContentTypes = undefined;
6494
6785
  this._settingsModified = false;
6495
6786
  this._appPropsModified = false;
6787
+ this._corePropsModified = false;
6496
6788
  this._footnotesModified = false;
6497
6789
  this._endnotesModified = false;
6498
6790
  this._originalWebSettingsXml = undefined;
@@ -7050,7 +7342,7 @@ class Document {
7050
7342
  const matches = originalText.match(wordPattern);
7051
7343
  if (matches) {
7052
7344
  replacementCount += matches.length;
7053
- newText = originalText.replace(wordPattern, replace);
7345
+ newText = originalText.replace(wordPattern, () => replace);
7054
7346
  }
7055
7347
  }
7056
7348
  else {
@@ -7058,7 +7350,7 @@ class Document {
7058
7350
  const matches = originalText.match(searchPattern);
7059
7351
  if (matches) {
7060
7352
  replacementCount += matches.length;
7061
- newText = originalText.replace(searchPattern, replace);
7353
+ newText = originalText.replace(searchPattern, () => replace);
7062
7354
  }
7063
7355
  }
7064
7356
  if (newText !== originalText) {
@@ -7338,90 +7630,303 @@ class Document {
7338
7630
  }
7339
7631
  toPlainText(separator = '\n') {
7340
7632
  const paragraphs = this.getAllParagraphs();
7341
- return paragraphs.map((p) => p.getText()).join(separator);
7342
- }
7343
- toMarkdown() {
7633
+ return paragraphs.map((p) => p.getTextIncludingRevisions()).join(separator);
7634
+ }
7635
+ toMarkdown(options) {
7636
+ const ctx = {
7637
+ opts: {
7638
+ htmlFallback: options?.htmlFallback ?? true,
7639
+ footnotes: options?.footnotes ?? true,
7640
+ images: options?.images ?? true,
7641
+ },
7642
+ notes: [],
7643
+ noteMarkers: new Set(),
7644
+ };
7344
7645
  const lines = [];
7345
7646
  for (const element of this.bodyElements) {
7346
- if (element instanceof Paragraph_js_1.Paragraph) {
7347
- const mdLine = this.paragraphToMarkdown(element);
7348
- if (mdLine !== null) {
7349
- lines.push(mdLine);
7350
- lines.push('');
7351
- }
7647
+ this.bodyElementToMarkdown(element, ctx, lines);
7648
+ }
7649
+ while (lines.length > 0 && lines[lines.length - 1] === '') {
7650
+ lines.pop();
7651
+ }
7652
+ let out = lines.join('\n');
7653
+ if (ctx.opts.footnotes && ctx.notes.length > 0) {
7654
+ const defs = ctx.notes.map((n) => `[^${n.marker}]: ${n.text}`).join('\n');
7655
+ out = out ? `${out}\n\n${defs}` : defs;
7656
+ }
7657
+ return out;
7658
+ }
7659
+ bodyElementToMarkdown(element, ctx, lines) {
7660
+ if (element instanceof Paragraph_js_1.Paragraph) {
7661
+ const md = this.paragraphToMarkdown(element, ctx);
7662
+ if (md !== null) {
7663
+ lines.push(md);
7664
+ lines.push('');
7352
7665
  }
7353
- else if (element instanceof Table_js_1.Table) {
7354
- lines.push(...this.tableToMarkdown(element));
7666
+ }
7667
+ else if (element instanceof Table_js_1.Table) {
7668
+ const tableLines = this.tableToMarkdown(element, ctx);
7669
+ if (tableLines.length > 0) {
7670
+ lines.push(...tableLines);
7355
7671
  lines.push('');
7356
7672
  }
7357
7673
  }
7358
- while (lines.length > 0 && lines[lines.length - 1] === '') {
7359
- lines.pop();
7674
+ else if (element instanceof StructuredDocumentTag_js_1.StructuredDocumentTag) {
7675
+ for (const child of element.getContent()) {
7676
+ this.bodyElementToMarkdown(child, ctx, lines);
7677
+ }
7678
+ }
7679
+ else if (element instanceof PreservedElement_js_1.PreservedElement) {
7680
+ const text = this.extractTextFromRawXml(element.getRawXml());
7681
+ if (text) {
7682
+ lines.push(this.escapeMarkdown(text));
7683
+ lines.push('');
7684
+ }
7360
7685
  }
7361
- return lines.join('\n');
7362
7686
  }
7363
- paragraphToMarkdown(para) {
7364
- const text = this.paragraphContentToMarkdown(para);
7365
- if (!text && !para.hasNumbering())
7687
+ paragraphToMarkdown(para, ctx) {
7688
+ const inline = this.paragraphContentToMarkdown(para, ctx);
7689
+ const hasNumbering = para.hasNumbering();
7690
+ if (!inline && !hasNumbering)
7366
7691
  return null;
7367
7692
  const headingLevel = para.detectHeadingLevel();
7368
7693
  if (headingLevel !== null && headingLevel >= 1 && headingLevel <= 6) {
7369
- return '#'.repeat(headingLevel) + ' ' + text;
7370
- }
7371
- if (para.hasNumbering()) {
7372
- const style = para.getStyle();
7373
- const isBullet = style?.toLowerCase().includes('bullet') || style?.toLowerCase().includes('list bullet');
7374
- return isBullet ? `- ${text}` : `1. ${text}`;
7694
+ return '#'.repeat(headingLevel) + ' ' + this.toSingleLine(inline);
7695
+ }
7696
+ const style = (para.getStyle() ?? '').toLowerCase();
7697
+ const isListStyle = style.includes('listbullet') ||
7698
+ style.includes('list bullet') ||
7699
+ style.includes('listnumber') ||
7700
+ style.includes('list number');
7701
+ if (hasNumbering || isListStyle) {
7702
+ const level = para.getNumbering()?.level ?? 0;
7703
+ const indent = ' '.repeat(Math.max(0, level));
7704
+ const marker = this.isOrderedList(para) ? '1.' : '-';
7705
+ return `${indent}${marker} ${this.toSingleLine(inline)}`;
7706
+ }
7707
+ if (style.includes('quote')) {
7708
+ return this.toSingleLine(inline)
7709
+ .split('\n')
7710
+ .map((l) => `> ${l}`)
7711
+ .join('\n');
7712
+ }
7713
+ return inline;
7714
+ }
7715
+ isOrderedList(para) {
7716
+ const numbering = para.getNumbering();
7717
+ if (numbering) {
7718
+ const instance = this.numberingManager.getInstance(numbering.numId);
7719
+ if (instance) {
7720
+ const abstract = this.numberingManager.getAbstractNumbering(instance.getAbstractNumId());
7721
+ const levelDef = abstract?.getLevel(numbering.level);
7722
+ const format = levelDef?.getFormat();
7723
+ if (format)
7724
+ return format !== 'bullet';
7725
+ }
7375
7726
  }
7376
- return text;
7727
+ const style = (para.getStyle() ?? '').toLowerCase();
7728
+ if (style.includes('bullet'))
7729
+ return false;
7730
+ if (style.includes('number'))
7731
+ return true;
7732
+ return true;
7733
+ }
7734
+ paragraphContentToMarkdown(para, ctx) {
7735
+ return this.inlineContentToMarkdown(para.getContent(), ctx);
7377
7736
  }
7378
- paragraphContentToMarkdown(para) {
7737
+ inlineContentToMarkdown(items, ctx) {
7379
7738
  const parts = [];
7380
- for (const item of para.getContent()) {
7381
- if (item instanceof Run_js_1.Run) {
7382
- const runText = item.getText();
7383
- if (!runText)
7384
- continue;
7385
- const fmt = item.getFormatting();
7386
- let md = runText;
7387
- if (fmt.bold && fmt.italic) {
7388
- md = `***${md}***`;
7389
- }
7390
- else if (fmt.bold) {
7391
- md = `**${md}**`;
7392
- }
7393
- else if (fmt.italic) {
7394
- md = `*${md}*`;
7739
+ for (const item of items) {
7740
+ if (item instanceof ImageRun_js_1.ImageRun) {
7741
+ if (ctx.opts.images) {
7742
+ const image = item.getImageElement();
7743
+ const alt = this.escapeMarkdown(image.getAltText() || 'image');
7744
+ const src = image.getRelationshipId() ?? 'image';
7745
+ parts.push(`![${alt}](${src})`);
7395
7746
  }
7396
- if (fmt.strike) {
7397
- md = `~~${md}~~`;
7747
+ }
7748
+ else if (item instanceof Run_js_1.Run) {
7749
+ parts.push(this.runToMarkdown(item, ctx));
7750
+ }
7751
+ else if (item instanceof Hyperlink_js_1.Hyperlink) {
7752
+ const runs = item.getRuns();
7753
+ let label = runs.length > 0
7754
+ ? runs.map((r) => this.runToMarkdown(r, ctx, true)).join('')
7755
+ : this.escapeMarkdown(item.getText());
7756
+ if (!label)
7757
+ label = this.escapeMarkdown(item.getText());
7758
+ let url = item.getUrl() ?? '';
7759
+ const anchor = item.getAnchor();
7760
+ if (anchor)
7761
+ url = url ? `${url}#${anchor}` : `#${anchor}`;
7762
+ parts.push(`[${label}](${url})`);
7763
+ }
7764
+ else if (item instanceof Revision_js_1.Revision) {
7765
+ const inner = this.inlineContentToMarkdown(item.getContent(), ctx);
7766
+ if (!inner)
7767
+ continue;
7768
+ const type = item.getType();
7769
+ if (type === 'delete' || type === 'moveFrom') {
7770
+ parts.push(ctx.opts.htmlFallback ? `<del>${inner}</del>` : `~~${inner}~~`);
7398
7771
  }
7399
- if (fmt.font &&
7400
- /^(courier|consolas|monaco|menlo|source code|fira code|jetbrains mono)/i.test(fmt.font)) {
7401
- md = `\`${runText}\``;
7772
+ else {
7773
+ parts.push(inner);
7402
7774
  }
7403
- parts.push(md);
7404
7775
  }
7405
- else if (item instanceof Hyperlink_js_1.Hyperlink) {
7406
- const url = item.getUrl() || '';
7407
- const linkText = item.getText() || url;
7408
- parts.push(`[${linkText}](${url})`);
7776
+ else if (item instanceof Field_js_1.ComplexField) {
7777
+ const result = item.getResult();
7778
+ if (result)
7779
+ parts.push(this.escapeMarkdown(result));
7780
+ }
7781
+ else if (item instanceof Field_js_1.Field) {
7782
+ const result = item.getCachedResult();
7783
+ if (result)
7784
+ parts.push(this.escapeMarkdown(result));
7785
+ }
7786
+ else if (item instanceof TextBox_js_1.TextBox) {
7787
+ const text = item
7788
+ .getParagraphs()
7789
+ .map((p) => this.paragraphContentToMarkdown(p, ctx))
7790
+ .filter((s) => s !== '')
7791
+ .join(' ');
7792
+ if (text)
7793
+ parts.push(text);
7794
+ }
7795
+ else if (item instanceof Shape_js_1.Shape) {
7796
+ const text = item.getText();
7797
+ if (text)
7798
+ parts.push(this.escapeMarkdown(text));
7799
+ }
7800
+ else if (item instanceof PreservedElement_js_1.PreservedElement) {
7801
+ const type = item.getElementType();
7802
+ if (!type.startsWith('w:comment')) {
7803
+ const text = this.extractTextFromRawXml(item.getRawXml());
7804
+ if (text)
7805
+ parts.push(this.escapeMarkdown(text));
7806
+ }
7409
7807
  }
7410
7808
  }
7411
7809
  return parts.join('');
7412
7810
  }
7413
- tableToMarkdown(table) {
7414
- const data = table.toArray();
7415
- if (data.length === 0)
7811
+ runToMarkdown(run, ctx, inLink = false) {
7812
+ const fmt = run.getFormatting();
7813
+ const isMono = !!(fmt.font &&
7814
+ /^(courier|consolas|monaco|menlo|source code|fira code|jetbrains mono)/i.test(fmt.font));
7815
+ const escape = (s) => (isMono ? s : this.escapeMarkdown(s));
7816
+ const segments = [];
7817
+ const markers = [];
7818
+ for (const content of run.getContent()) {
7819
+ switch (content.type) {
7820
+ case 'text':
7821
+ case 'instructionText':
7822
+ segments.push(escape(content.value ?? ''));
7823
+ break;
7824
+ case 'tab':
7825
+ segments.push('\t');
7826
+ break;
7827
+ case 'carriageReturn':
7828
+ segments.push('\n');
7829
+ break;
7830
+ case 'break':
7831
+ if (content.breakType !== 'page' && content.breakType !== 'column') {
7832
+ segments.push(ctx.opts.htmlFallback ? '<br>' : '\n');
7833
+ }
7834
+ break;
7835
+ case 'noBreakHyphen':
7836
+ segments.push('‑');
7837
+ break;
7838
+ case 'symbol':
7839
+ if (content.symbolChar) {
7840
+ const code = parseInt(content.symbolChar, 16);
7841
+ if (!Number.isNaN(code))
7842
+ segments.push(escape(String.fromCharCode(code)));
7843
+ }
7844
+ break;
7845
+ case 'footnoteReference':
7846
+ if (ctx.opts.footnotes && content.footnoteId !== undefined) {
7847
+ markers.push(this.noteMarker(content.footnoteId, 'fn', ctx));
7848
+ }
7849
+ break;
7850
+ case 'endnoteReference':
7851
+ if (ctx.opts.footnotes && content.endnoteId !== undefined) {
7852
+ markers.push(this.noteMarker(content.endnoteId, 'en', ctx));
7853
+ }
7854
+ break;
7855
+ default:
7856
+ break;
7857
+ }
7858
+ }
7859
+ let text = segments.join('');
7860
+ if (text) {
7861
+ if (isMono) {
7862
+ text = `\`${text}\``;
7863
+ }
7864
+ if (fmt.bold && fmt.italic)
7865
+ text = `***${text}***`;
7866
+ else if (fmt.bold)
7867
+ text = `**${text}**`;
7868
+ else if (fmt.italic)
7869
+ text = `*${text}*`;
7870
+ if (fmt.strike || fmt.dstrike)
7871
+ text = `~~${text}~~`;
7872
+ if (ctx.opts.htmlFallback) {
7873
+ if (fmt.superscript)
7874
+ text = `<sup>${text}</sup>`;
7875
+ else if (fmt.subscript)
7876
+ text = `<sub>${text}</sub>`;
7877
+ if (fmt.highlight && fmt.highlight !== 'none')
7878
+ text = `<mark>${text}</mark>`;
7879
+ if (!inLink) {
7880
+ if (fmt.underline && fmt.underline !== 'none')
7881
+ text = `<u>${text}</u>`;
7882
+ if (fmt.color && fmt.color !== 'auto' && /^[0-9a-fA-F]{6}$/.test(fmt.color)) {
7883
+ text = `<span style="color:#${fmt.color}">${text}</span>`;
7884
+ }
7885
+ }
7886
+ }
7887
+ }
7888
+ return text + markers.join('');
7889
+ }
7890
+ noteMarker(id, kind, ctx) {
7891
+ const marker = `${kind}${id}`;
7892
+ if (!ctx.noteMarkers.has(marker)) {
7893
+ ctx.noteMarkers.add(marker);
7894
+ const note = kind === 'fn' ? this.footnoteManager.getFootnote(id) : this.endnoteManager.getEndnote(id);
7895
+ let text = '';
7896
+ if (note) {
7897
+ text = note
7898
+ .getParagraphs()
7899
+ .map((p) => this.paragraphContentToMarkdown(p, ctx))
7900
+ .filter((s) => s !== '')
7901
+ .join(' ')
7902
+ .replace(/\s*\n\s*/g, ' ')
7903
+ .trim();
7904
+ }
7905
+ ctx.notes.push({ marker, text });
7906
+ }
7907
+ return `[^${marker}]`;
7908
+ }
7909
+ tableToMarkdown(table, ctx) {
7910
+ const rows = table.getRows();
7911
+ if (rows.length === 0)
7416
7912
  return [];
7417
- const colCount = Math.max(...data.map((row) => row.length));
7913
+ const isComplex = rows.some((row) => row
7914
+ .getCells()
7915
+ .some((cell) => (cell.getColumnSpan() ?? 1) > 1 ||
7916
+ cell.getVerticalMerge() !== undefined ||
7917
+ cell.hasNestedTables()));
7918
+ if (isComplex && ctx.opts.htmlFallback) {
7919
+ return this.tableToHtmlBlock(table);
7920
+ }
7921
+ const matrix = rows.map((row) => row.getCells().map((cell) => this.cellToMarkdown(cell, ctx)));
7922
+ const colCount = Math.max(...matrix.map((row) => row.length));
7418
7923
  if (colCount === 0)
7419
7924
  return [];
7420
- const normalized = data.map((row) => {
7925
+ const normalized = matrix.map((row) => {
7421
7926
  const padded = [...row];
7422
7927
  while (padded.length < colCount)
7423
7928
  padded.push('');
7424
- return padded.map((cell) => cell.replace(/\|/g, '\\|').replace(/\n/g, ' ').trim());
7929
+ return padded;
7425
7930
  });
7426
7931
  const lines = [];
7427
7932
  lines.push('| ' + normalized[0].join(' | ') + ' |');
@@ -7431,6 +7936,88 @@ class Document {
7431
7936
  }
7432
7937
  return lines;
7433
7938
  }
7939
+ cellToMarkdown(cell, ctx) {
7940
+ const text = cell
7941
+ .getParagraphs()
7942
+ .map((p) => this.paragraphContentToMarkdown(p, ctx))
7943
+ .filter((s) => s !== '')
7944
+ .join(' ');
7945
+ return text.replace(/\|/g, '\\|').replace(/<br>/g, ' ').replace(/\n/g, ' ').trim();
7946
+ }
7947
+ tableToHtmlBlock(table) {
7948
+ const rows = table.getRows();
7949
+ const rowCells = rows.map((row) => {
7950
+ let gridStart = 0;
7951
+ return row.getCells().map((cell) => {
7952
+ const span = cell.getColumnSpan() ?? 1;
7953
+ const entry = { cell, gridStart, span };
7954
+ gridStart += span;
7955
+ return entry;
7956
+ });
7957
+ });
7958
+ const html = ['<table>'];
7959
+ for (let ri = 0; ri < rowCells.length; ri++) {
7960
+ html.push('<tr>');
7961
+ for (const { cell, gridStart, span } of rowCells[ri]) {
7962
+ if (cell.getVerticalMerge() === 'continue')
7963
+ continue;
7964
+ let rowspan = 1;
7965
+ if (cell.getVerticalMerge() === 'restart') {
7966
+ for (let rj = ri + 1; rj < rowCells.length; rj++) {
7967
+ const below = rowCells[rj].find((e) => e.gridStart === gridStart);
7968
+ if (below?.cell.getVerticalMerge() === 'continue')
7969
+ rowspan++;
7970
+ else
7971
+ break;
7972
+ }
7973
+ }
7974
+ const tag = ri === 0 ? 'th' : 'td';
7975
+ const attrs = (span > 1 ? ` colspan="${span}"` : '') + (rowspan > 1 ? ` rowspan="${rowspan}"` : '');
7976
+ let content = cell
7977
+ .getParagraphs()
7978
+ .map((p) => this.paragraphContentToHTML(p))
7979
+ .filter((s) => s !== '')
7980
+ .join('<br>') || this.escapeHTML(cell.getText());
7981
+ if (cell.hasNestedTables()) {
7982
+ const nestedText = cell
7983
+ .getRawNestedContent()
7984
+ .map((n) => this.extractTextFromRawXml(n.xml))
7985
+ .filter((s) => s)
7986
+ .join(' ');
7987
+ if (nestedText)
7988
+ content += `<br>${this.escapeHTML(nestedText)}`;
7989
+ }
7990
+ html.push(`<${tag}${attrs}>${content}</${tag}>`);
7991
+ }
7992
+ html.push('</tr>');
7993
+ }
7994
+ html.push('</table>');
7995
+ return html;
7996
+ }
7997
+ escapeMarkdown(text) {
7998
+ return text.replace(/([\\`*_[\]<>])/g, '\\$1');
7999
+ }
8000
+ toSingleLine(text) {
8001
+ return text.replace(/<br>/g, ' ').replace(/\s*\n\s*/g, ' ');
8002
+ }
8003
+ extractTextFromRawXml(xml) {
8004
+ if (!xml.includes('<w:t'))
8005
+ return '';
8006
+ const parts = [];
8007
+ const regex = /<w:t(?:\s[^>]*)?>([\s\S]*?)<\/w:t>/g;
8008
+ let match;
8009
+ while ((match = regex.exec(xml)) !== null) {
8010
+ parts.push(match[1] ?? '');
8011
+ }
8012
+ return parts
8013
+ .join('')
8014
+ .replace(/&lt;/g, '<')
8015
+ .replace(/&gt;/g, '>')
8016
+ .replace(/&quot;/g, '"')
8017
+ .replace(/&apos;/g, "'")
8018
+ .replace(/&amp;/g, '&')
8019
+ .trim();
8020
+ }
7434
8021
  toHTML(options) {
7435
8022
  const parts = [];
7436
8023
  let inList = null;
@@ -7521,8 +8108,12 @@ class Document {
7521
8108
  parts.push(html);
7522
8109
  }
7523
8110
  else if (item instanceof Hyperlink_js_1.Hyperlink) {
7524
- const url = this.escapeHTML(item.getUrl() || '');
7525
- const linkText = this.escapeHTML(item.getText() || url);
8111
+ let rawUrl = item.getUrl() ?? '';
8112
+ const anchor = item.getAnchor();
8113
+ if (anchor)
8114
+ rawUrl = rawUrl ? `${rawUrl}#${anchor}` : `#${anchor}`;
8115
+ const url = this.escapeHTML(rawUrl);
8116
+ const linkText = this.escapeHTML(item.getText() || rawUrl);
7526
8117
  parts.push(`<a href="${url}">${linkText}</a>`);
7527
8118
  }
7528
8119
  }
@@ -7670,7 +8261,10 @@ class Document {
7670
8261
  removeParagraph(paragraphOrIndex) {
7671
8262
  let index;
7672
8263
  if (typeof paragraphOrIndex === 'number') {
7673
- index = paragraphOrIndex;
8264
+ const para = this.getParagraphAt(paragraphOrIndex);
8265
+ if (!para)
8266
+ return false;
8267
+ index = this.bodyElements.indexOf(para);
7674
8268
  }
7675
8269
  else {
7676
8270
  index = this.bodyElements.indexOf(paragraphOrIndex);
@@ -7679,13 +8273,8 @@ class Document {
7679
8273
  const element = this.bodyElements[index];
7680
8274
  if (element instanceof Paragraph_js_1.Paragraph) {
7681
8275
  if (this.trackChangesEnabled && this.trackingContext.isEnabled()) {
7682
- const runs = element.getRuns();
7683
- if (runs.length > 0) {
7684
- const author = this.trackingContext.getAuthor();
7685
- const deletion = Revision_js_1.Revision.createDeletion(author, runs);
7686
- this.trackingContext.getRevisionManager().register(deletion);
7687
- element.addRevision(deletion);
7688
- }
8276
+ this.bindTrackingToElement(element);
8277
+ element.clearContent();
7689
8278
  return true;
7690
8279
  }
7691
8280
  this.bodyElements.splice(index, 1);
@@ -7939,16 +8528,6 @@ class Document {
7939
8528
  for (const paragraph of this.getAllParagraphs()) {
7940
8529
  extractHyperlinksFromParagraph(paragraph);
7941
8530
  }
7942
- for (const table of this.getTables()) {
7943
- for (const row of table.getRows()) {
7944
- for (const cell of row.getCells()) {
7945
- const cellParagraphs = cell instanceof TableCell_js_1.TableCell ? cell.getParagraphs() : [];
7946
- for (const para of cellParagraphs) {
7947
- extractHyperlinksFromParagraph(para);
7948
- }
7949
- }
7950
- }
7951
- }
7952
8531
  return hyperlinks;
7953
8532
  }
7954
8533
  collectAllReferencedHyperlinkIds() {
@@ -8073,17 +8652,6 @@ class Document {
8073
8652
  bookmarks.push({ bookmark, paragraph });
8074
8653
  }
8075
8654
  }
8076
- for (const table of this.getTables()) {
8077
- for (const row of table.getRows()) {
8078
- for (const cell of row.getCells()) {
8079
- for (const para of cell.getParagraphs()) {
8080
- for (const bookmark of para.getBookmarksStart()) {
8081
- bookmarks.push({ bookmark, paragraph: para });
8082
- }
8083
- }
8084
- }
8085
- }
8086
- }
8087
8655
  return bookmarks;
8088
8656
  }
8089
8657
  getFields() {
@@ -8093,18 +8661,6 @@ class Document {
8093
8661
  results.push({ field, paragraph });
8094
8662
  }
8095
8663
  }
8096
- for (const table of this.getTables()) {
8097
- for (const row of table.getRows()) {
8098
- for (const cell of row.getCells()) {
8099
- const cellParagraphs = cell instanceof TableCell_js_1.TableCell ? cell.getParagraphs() : [];
8100
- for (const para of cellParagraphs) {
8101
- for (const field of para.getFields()) {
8102
- results.push({ field, paragraph: para, table });
8103
- }
8104
- }
8105
- }
8106
- }
8107
- }
8108
8664
  return results;
8109
8665
  }
8110
8666
  getImages() {
@@ -8143,7 +8699,7 @@ class Document {
8143
8699
  await entry.image.updateImageData(result.data);
8144
8700
  }
8145
8701
  if (result.newExtension !== extension) {
8146
- const newFilename = filename.replace(/\.[^.]+$/, `.${result.newExtension}`);
8702
+ const newFilename = this.resolveUniqueMediaFilename(filename.replace(/\.[^.]+$/, `.${result.newExtension}`), filename);
8147
8703
  this.imageManager.updateEntryFilename(image, newFilename);
8148
8704
  for (const entry of entries) {
8149
8705
  this.updateImageRelationshipTarget(entry.relationshipId, filename, newFilename);
@@ -8154,6 +8710,20 @@ class Document {
8154
8710
  }
8155
8711
  return { optimizedCount, totalSavedBytes: totalSaved };
8156
8712
  }
8713
+ resolveUniqueMediaFilename(candidate, currentFilename) {
8714
+ const dotIndex = candidate.lastIndexOf('.');
8715
+ const base = dotIndex === -1 ? candidate : candidate.slice(0, dotIndex);
8716
+ const ext = dotIndex === -1 ? '' : candidate.slice(dotIndex);
8717
+ const isTaken = (name) => this.zipHandler.hasFile(`word/media/${name}`) ||
8718
+ this.imageManager.isFilenameOwnedByOther(name, currentFilename);
8719
+ let name = candidate;
8720
+ let counter = 1;
8721
+ while (isTaken(name)) {
8722
+ name = `${base}-${counter}${ext}`;
8723
+ counter++;
8724
+ }
8725
+ return name;
8726
+ }
8157
8727
  updateImageRelationshipTarget(relId, oldFilename, newFilename) {
8158
8728
  const rel = this.relationshipManager.getRelationship(relId);
8159
8729
  if (rel) {
@@ -8277,7 +8847,7 @@ class Document {
8277
8847
  const toRemove = [];
8278
8848
  this.bodyElements.forEach((element, index) => {
8279
8849
  if (element instanceof Paragraph_js_1.Paragraph) {
8280
- const isEmpty = element.getText().trim() === '';
8850
+ const isEmpty = this.isParagraphRemovableBlank(element);
8281
8851
  if (isEmpty && lastWasEmpty) {
8282
8852
  toRemove.push(index);
8283
8853
  }
@@ -8361,11 +8931,30 @@ class Document {
8361
8931
  }
8362
8932
  return { removed, normalized };
8363
8933
  }
8934
+ isParagraphRemovableBlank(para) {
8935
+ if (para.getText().trim() !== '')
8936
+ return false;
8937
+ if (para.formatting.sectPr !== undefined)
8938
+ return false;
8939
+ if (para.getBookmarksStart().length > 0 || para.getBookmarksEnd().length > 0) {
8940
+ return false;
8941
+ }
8942
+ if (para.getCommentsStart().length > 0 || para.getCommentsEnd().length > 0) {
8943
+ return false;
8944
+ }
8945
+ for (const item of para.getContent()) {
8946
+ if (item instanceof ImageRun_js_1.ImageRun || item instanceof Shape_js_1.Shape || item instanceof RangeMarker_js_1.RangeMarker) {
8947
+ return false;
8948
+ }
8949
+ }
8950
+ return true;
8951
+ }
8364
8952
  setLanguage(language) {
8365
8953
  if (!this.properties) {
8366
8954
  this.properties = {};
8367
8955
  }
8368
8956
  this.properties.language = language;
8957
+ this._corePropsModified = true;
8369
8958
  return this;
8370
8959
  }
8371
8960
  getLanguage() {
@@ -8481,32 +9070,6 @@ class Document {
8481
9070
  pattern.lastIndex = 0;
8482
9071
  }
8483
9072
  }
8484
- for (const table of this.getTables()) {
8485
- for (const row of table.getRows()) {
8486
- for (const cell of row.getCells()) {
8487
- for (const para of cell.getParagraphs()) {
8488
- for (const run of para.getRuns()) {
8489
- const text = run.getText();
8490
- if (!text)
8491
- continue;
8492
- const runFormatting = run.getFormatting();
8493
- if (matchBold && !runFormatting.bold)
8494
- continue;
8495
- if (matchItalic && !runFormatting.italic)
8496
- continue;
8497
- if (pattern.test(text)) {
8498
- const newText = text.replace(pattern, replace);
8499
- if (newText !== text) {
8500
- run.setText(newText);
8501
- replacedCount++;
8502
- }
8503
- }
8504
- pattern.lastIndex = 0;
8505
- }
8506
- }
8507
- }
8508
- }
8509
- }
8510
9073
  return replacedCount;
8511
9074
  }
8512
9075
  static createEmpty() {