docxmlater 11.0.9 → 12.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (354) hide show
  1. package/README.md +51 -13
  2. package/dist/core/Document.d.ts +28 -2
  3. package/dist/core/Document.d.ts.map +1 -1
  4. package/dist/core/Document.js +725 -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 +431 -85
  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 +726 -171
  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 +431 -85
  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 +58 -8
  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/cnfStyleDecoder.js +7 -7
  179. package/dist/esm/processors/cnfStyleDecoder.js.map +1 -1
  180. package/dist/esm/processors/stripTrackedChanges.js +16 -5
  181. package/dist/esm/processors/stripTrackedChanges.js.map +1 -1
  182. package/dist/esm/utils/deepClone.js +24 -11
  183. package/dist/esm/utils/deepClone.js.map +1 -1
  184. package/dist/esm/utils/units.js +1 -1
  185. package/dist/esm/utils/units.js.map +1 -1
  186. package/dist/esm/utils/validation.js +11 -23
  187. package/dist/esm/utils/validation.js.map +1 -1
  188. package/dist/esm/utils/xmlSanitization.js +131 -7
  189. package/dist/esm/utils/xmlSanitization.js.map +1 -1
  190. package/dist/esm/validation/RevisionAutoFixer.js +69 -55
  191. package/dist/esm/validation/RevisionAutoFixer.js.map +1 -1
  192. package/dist/esm/validation/RevisionValidator.js +24 -20
  193. package/dist/esm/validation/RevisionValidator.js.map +1 -1
  194. package/dist/esm/xml/XMLBuilder.js +52 -20
  195. package/dist/esm/xml/XMLBuilder.js.map +1 -1
  196. package/dist/esm/xml/XMLParser.js +55 -13
  197. package/dist/esm/xml/XMLParser.js.map +1 -1
  198. package/dist/esm/zip/ZipHandler.js +37 -13
  199. package/dist/esm/zip/ZipHandler.js.map +1 -1
  200. package/dist/esm/zip/ZipReader.js +53 -6
  201. package/dist/esm/zip/ZipReader.js.map +1 -1
  202. package/dist/esm/zip/errors.js +7 -0
  203. package/dist/esm/zip/errors.js.map +1 -1
  204. package/dist/esm/zip/types.js +4 -0
  205. package/dist/esm/zip/types.js.map +1 -1
  206. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  207. package/dist/formatting/AbstractNumbering.js +1 -1
  208. package/dist/formatting/AbstractNumbering.js.map +1 -1
  209. package/dist/formatting/NumberingLevel.d.ts +1 -1
  210. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  211. package/dist/formatting/NumberingLevel.js +8 -6
  212. package/dist/formatting/NumberingLevel.js.map +1 -1
  213. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  214. package/dist/formatting/NumberingManager.js +16 -1
  215. package/dist/formatting/NumberingManager.js.map +1 -1
  216. package/dist/formatting/Style.d.ts.map +1 -1
  217. package/dist/formatting/Style.js +14 -0
  218. package/dist/formatting/Style.js.map +1 -1
  219. package/dist/formatting/StylesManager.d.ts +2 -0
  220. package/dist/formatting/StylesManager.d.ts.map +1 -1
  221. package/dist/formatting/StylesManager.js +14 -2
  222. package/dist/formatting/StylesManager.js.map +1 -1
  223. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  224. package/dist/helpers/CleanupHelper.js +103 -26
  225. package/dist/helpers/CleanupHelper.js.map +1 -1
  226. package/dist/images/ImageOptimizer.d.ts.map +1 -1
  227. package/dist/images/ImageOptimizer.js +52 -4
  228. package/dist/images/ImageOptimizer.js.map +1 -1
  229. package/dist/index.d.ts +3 -1
  230. package/dist/index.d.ts.map +1 -1
  231. package/dist/index.js +4 -2
  232. package/dist/index.js.map +1 -1
  233. package/dist/internal.d.ts +1 -1
  234. package/dist/internal.d.ts.map +1 -1
  235. package/dist/internal.js +2 -1
  236. package/dist/internal.js.map +1 -1
  237. package/dist/processors/CompatibilityUpgrader.d.ts.map +1 -1
  238. package/dist/processors/CompatibilityUpgrader.js +7 -1
  239. package/dist/processors/CompatibilityUpgrader.js.map +1 -1
  240. package/dist/processors/InMemoryRevisionAcceptor.d.ts +1 -0
  241. package/dist/processors/InMemoryRevisionAcceptor.d.ts.map +1 -1
  242. package/dist/processors/InMemoryRevisionAcceptor.js +135 -13
  243. package/dist/processors/InMemoryRevisionAcceptor.js.map +1 -1
  244. package/dist/processors/RevisionWalker.d.ts +2 -0
  245. package/dist/processors/RevisionWalker.d.ts.map +1 -1
  246. package/dist/processors/RevisionWalker.js +58 -8
  247. package/dist/processors/RevisionWalker.js.map +1 -1
  248. package/dist/processors/SelectiveRevisionAcceptor.d.ts.map +1 -1
  249. package/dist/processors/SelectiveRevisionAcceptor.js +116 -17
  250. package/dist/processors/SelectiveRevisionAcceptor.js.map +1 -1
  251. package/dist/processors/cnfStyleDecoder.d.ts.map +1 -1
  252. package/dist/processors/cnfStyleDecoder.js +7 -7
  253. package/dist/processors/cnfStyleDecoder.js.map +1 -1
  254. package/dist/processors/stripTrackedChanges.d.ts.map +1 -1
  255. package/dist/processors/stripTrackedChanges.js +16 -5
  256. package/dist/processors/stripTrackedChanges.js.map +1 -1
  257. package/dist/utils/deepClone.d.ts.map +1 -1
  258. package/dist/utils/deepClone.js +24 -11
  259. package/dist/utils/deepClone.js.map +1 -1
  260. package/dist/utils/units.d.ts.map +1 -1
  261. package/dist/utils/units.js +1 -1
  262. package/dist/utils/units.js.map +1 -1
  263. package/dist/utils/validation.d.ts.map +1 -1
  264. package/dist/utils/validation.js +11 -23
  265. package/dist/utils/validation.js.map +1 -1
  266. package/dist/utils/xmlSanitization.d.ts +2 -0
  267. package/dist/utils/xmlSanitization.d.ts.map +1 -1
  268. package/dist/utils/xmlSanitization.js +133 -7
  269. package/dist/utils/xmlSanitization.js.map +1 -1
  270. package/dist/validation/RevisionAutoFixer.d.ts +6 -2
  271. package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
  272. package/dist/validation/RevisionAutoFixer.js +68 -54
  273. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  274. package/dist/validation/RevisionValidator.d.ts +2 -0
  275. package/dist/validation/RevisionValidator.d.ts.map +1 -1
  276. package/dist/validation/RevisionValidator.js +26 -21
  277. package/dist/validation/RevisionValidator.js.map +1 -1
  278. package/dist/xml/XMLBuilder.d.ts +1 -0
  279. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  280. package/dist/xml/XMLBuilder.js +52 -20
  281. package/dist/xml/XMLBuilder.js.map +1 -1
  282. package/dist/xml/XMLParser.d.ts +1 -0
  283. package/dist/xml/XMLParser.d.ts.map +1 -1
  284. package/dist/xml/XMLParser.js +55 -13
  285. package/dist/xml/XMLParser.js.map +1 -1
  286. package/dist/zip/ZipHandler.d.ts.map +1 -1
  287. package/dist/zip/ZipHandler.js +37 -13
  288. package/dist/zip/ZipHandler.js.map +1 -1
  289. package/dist/zip/ZipReader.d.ts.map +1 -1
  290. package/dist/zip/ZipReader.js +52 -5
  291. package/dist/zip/ZipReader.js.map +1 -1
  292. package/dist/zip/errors.d.ts +3 -0
  293. package/dist/zip/errors.d.ts.map +1 -1
  294. package/dist/zip/errors.js +9 -1
  295. package/dist/zip/errors.js.map +1 -1
  296. package/dist/zip/types.d.ts +4 -0
  297. package/dist/zip/types.d.ts.map +1 -1
  298. package/dist/zip/types.js +4 -0
  299. package/dist/zip/types.js.map +1 -1
  300. package/package.json +2 -2
  301. package/src/core/Document.ts +1159 -240
  302. package/src/core/DocumentGenerator.ts +106 -26
  303. package/src/core/DocumentParser.ts +692 -120
  304. package/src/core/RelationshipManager.ts +446 -442
  305. package/src/elements/Comment.ts +123 -18
  306. package/src/elements/CommentManager.ts +121 -22
  307. package/src/elements/EndnoteManager.ts +4 -1
  308. package/src/elements/Field.ts +134 -43
  309. package/src/elements/FieldHelpers.ts +20 -4
  310. package/src/elements/Footer.ts +62 -67
  311. package/src/elements/FootnoteManager.ts +4 -1
  312. package/src/elements/Header.ts +62 -67
  313. package/src/elements/HeaderFooterManager.ts +56 -8
  314. package/src/elements/Hyperlink.ts +150 -55
  315. package/src/elements/Image.ts +51 -7
  316. package/src/elements/ImageManager.ts +24 -0
  317. package/src/elements/Paragraph.ts +161 -40
  318. package/src/elements/Revision.ts +446 -47
  319. package/src/elements/Run.ts +44 -6
  320. package/src/elements/Section.ts +25 -9
  321. package/src/elements/Shape.ts +52 -44
  322. package/src/elements/StructuredDocumentTag.ts +83 -8
  323. package/src/elements/Table.ts +151 -50
  324. package/src/elements/TableCell.ts +57 -17
  325. package/src/elements/TableOfContents.ts +10 -9
  326. package/src/elements/TableRow.ts +35 -3
  327. package/src/elements/TextBox.ts +58 -43
  328. package/src/formatting/AbstractNumbering.ts +4 -2
  329. package/src/formatting/NumberingLevel.ts +50 -12
  330. package/src/formatting/NumberingManager.ts +32 -3
  331. package/src/formatting/Style.ts +14 -0
  332. package/src/formatting/StylesManager.ts +29 -2
  333. package/src/helpers/CleanupHelper.ts +122 -30
  334. package/src/images/ImageOptimizer.ts +64 -5
  335. package/src/index.ts +7 -0
  336. package/src/internal.ts +1 -0
  337. package/src/processors/CompatibilityUpgrader.ts +15 -2
  338. package/src/processors/InMemoryRevisionAcceptor.ts +276 -17
  339. package/src/processors/RevisionWalker.ts +83 -7
  340. package/src/processors/SelectiveRevisionAcceptor.ts +164 -28
  341. package/src/processors/cnfStyleDecoder.ts +18 -12
  342. package/src/processors/stripTrackedChanges.ts +47 -10
  343. package/src/utils/deepClone.ts +48 -14
  344. package/src/utils/units.ts +3 -1
  345. package/src/utils/validation.ts +30 -32
  346. package/src/utils/xmlSanitization.ts +218 -22
  347. package/src/validation/RevisionAutoFixer.ts +109 -65
  348. package/src/validation/RevisionValidator.ts +48 -23
  349. package/src/xml/XMLBuilder.ts +82 -22
  350. package/src/xml/XMLParser.ts +87 -20
  351. package/src/zip/ZipHandler.ts +61 -21
  352. package/src/zip/ZipReader.ts +135 -13
  353. package/src/zip/errors.ts +15 -0
  354. 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;
@@ -422,7 +428,7 @@ class Document {
422
428
  }
423
429
  const numberingXml = zipHandler.getFileAsString(types_js_1.DOCX_PATHS.NUMBERING);
424
430
  if (numberingXml) {
425
- doc._originalNumberingXml = numberingXml;
431
+ doc._originalNumberingXml = (0, xmlSanitization_js_1.reorderRunPropertyChildren)(numberingXml);
426
432
  }
427
433
  const settingsXml = zipHandler.getFileAsString(types_js_1.DOCX_PATHS.SETTINGS);
428
434
  if (settingsXml) {
@@ -433,6 +439,10 @@ class Document {
433
439
  if (appPropsXml) {
434
440
  doc._originalAppPropsXml = appPropsXml;
435
441
  }
442
+ const corePropsXml = zipHandler.getFileAsString(types_js_1.DOCX_PATHS.CORE_PROPS);
443
+ if (corePropsXml) {
444
+ doc._originalCorePropsXml = corePropsXml;
445
+ }
436
446
  const webSettingsXml = zipHandler.getFileAsString(types_js_1.DOCX_PATHS.WEB_SETTINGS);
437
447
  if (webSettingsXml) {
438
448
  doc._originalWebSettingsXml = webSettingsXml;
@@ -695,17 +705,17 @@ class Document {
695
705
  try {
696
706
  const headersFooters = await this.parser.parseHeadersAndFooters(this.zipHandler, result.section, this.relationshipManager, this.imageManager);
697
707
  const registeredHeaderRIds = new Set();
698
- for (const { header, relationshipId } of headersFooters.headers) {
708
+ for (const { header, relationshipId, filename } of headersFooters.headers) {
699
709
  if (registeredHeaderRIds.has(relationshipId))
700
710
  continue;
701
- this.headerFooterManager.registerHeader(header, relationshipId);
711
+ this.headerFooterManager.registerHeader(header, relationshipId, filename);
702
712
  registeredHeaderRIds.add(relationshipId);
703
713
  }
704
714
  const registeredFooterRIds = new Set();
705
- for (const { footer, relationshipId } of headersFooters.footers) {
715
+ for (const { footer, relationshipId, filename } of headersFooters.footers) {
706
716
  if (registeredFooterRIds.has(relationshipId))
707
717
  continue;
708
- this.headerFooterManager.registerFooter(footer, relationshipId);
718
+ this.headerFooterManager.registerFooter(footer, relationshipId, filename);
709
719
  registeredFooterRIds.add(relationshipId);
710
720
  }
711
721
  }
@@ -748,7 +758,7 @@ class Document {
748
758
  }
749
759
  }
750
760
  const parser = new DocumentParser_js_1.DocumentParser();
751
- const comments = parser.parseCommentsXml(commentsXml);
761
+ const comments = parser.parseCommentsXml(commentsXml, this._originalCommentCompanionFiles.get(types_js_1.DOCX_PATHS.COMMENTS_EXTENDED));
752
762
  for (const comment of comments) {
753
763
  this.commentManager.registerExisting(comment);
754
764
  }
@@ -762,7 +772,9 @@ class Document {
762
772
  this._originalFootnotesXml = footnotesXml;
763
773
  try {
764
774
  const parser = new DocumentParser_js_1.DocumentParser();
765
- const footnotes = parser.parseFootnotesXml(footnotesXml);
775
+ const relsXml = this.zipHandler.getFileAsString('word/_rels/footnotes.xml.rels');
776
+ const partRels = relsXml ? RelationshipManager_js_1.RelationshipManager.fromXml(relsXml) : undefined;
777
+ const footnotes = parser.parseFootnotesXml(footnotesXml, partRels);
766
778
  for (const footnote of footnotes) {
767
779
  const id = footnote.getId();
768
780
  if (!this.footnoteManager.hasFootnote(id)) {
@@ -784,7 +796,9 @@ class Document {
784
796
  this._originalEndnotesXml = endnotesXml;
785
797
  try {
786
798
  const parser = new DocumentParser_js_1.DocumentParser();
787
- const endnotes = parser.parseEndnotesXml(endnotesXml);
799
+ const relsXml = this.zipHandler.getFileAsString('word/_rels/endnotes.xml.rels');
800
+ const partRels = relsXml ? RelationshipManager_js_1.RelationshipManager.fromXml(relsXml) : undefined;
801
+ const endnotes = parser.parseEndnotesXml(endnotesXml, partRels);
788
802
  for (const endnote of endnotes) {
789
803
  const id = endnote.getId();
790
804
  if (!this.endnoteManager.hasEndnote(id)) {
@@ -876,12 +890,13 @@ class Document {
876
890
  paragraph._setStylesManager(this.stylesManager);
877
891
  if (this.trackChangesEnabled && this.trackingContext.isEnabled()) {
878
892
  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);
893
+ const author = this.trackingContext.getAuthor();
894
+ for (const item of paragraph.getContent()) {
895
+ if (item instanceof Run_js_1.Run || item instanceof Hyperlink_js_1.Hyperlink) {
896
+ const insertion = Revision_js_1.Revision.createInsertion(author, item);
897
+ this.trackingContext.getRevisionManager().register(insertion);
898
+ paragraph.replaceContent(item, [insertion]);
899
+ }
885
900
  }
886
901
  }
887
902
  this.bodyElements.push(paragraph);
@@ -1097,14 +1112,17 @@ class Document {
1097
1112
  }
1098
1113
  setTitle(title) {
1099
1114
  this.properties.title = title;
1115
+ this._corePropsModified = true;
1100
1116
  return this;
1101
1117
  }
1102
1118
  setSubject(subject) {
1103
1119
  this.properties.subject = subject;
1120
+ this._corePropsModified = true;
1104
1121
  return this;
1105
1122
  }
1106
1123
  setCreator(creator) {
1107
1124
  this.properties.creator = creator;
1125
+ this._corePropsModified = true;
1108
1126
  return this;
1109
1127
  }
1110
1128
  setAuthor(author) {
@@ -1112,18 +1130,22 @@ class Document {
1112
1130
  }
1113
1131
  setKeywords(keywords) {
1114
1132
  this.properties.keywords = keywords;
1133
+ this._corePropsModified = true;
1115
1134
  return this;
1116
1135
  }
1117
1136
  setDescription(description) {
1118
1137
  this.properties.description = description;
1138
+ this._corePropsModified = true;
1119
1139
  return this;
1120
1140
  }
1121
1141
  setCategory(category) {
1122
1142
  this.properties.category = category;
1143
+ this._corePropsModified = true;
1123
1144
  return this;
1124
1145
  }
1125
1146
  setContentStatus(status) {
1126
1147
  this.properties.contentStatus = status;
1148
+ this._corePropsModified = true;
1127
1149
  return this;
1128
1150
  }
1129
1151
  setApplication(application) {
@@ -1570,8 +1592,48 @@ class Document {
1570
1592
  if (this._removedParts.has(types_js_1.DOCX_PATHS.CORE_PROPS) ||
1571
1593
  this._removedParts.has('docProps/core.xml'))
1572
1594
  return;
1573
- const xml = this.generator.generateCoreProps(this.properties);
1574
- this.zipHandler.updateFile(types_js_1.DOCX_PATHS.CORE_PROPS, xml);
1595
+ if (this._originalCorePropsXml && !this._corePropsModified) {
1596
+ return;
1597
+ }
1598
+ if (this._originalCorePropsXml && this._corePropsModified) {
1599
+ const mergedXml = this.mergeCorePropsWithOriginal();
1600
+ this.zipHandler.updateFile(types_js_1.DOCX_PATHS.CORE_PROPS, mergedXml);
1601
+ }
1602
+ else {
1603
+ const xml = this.generator.generateCoreProps(this.properties);
1604
+ this.zipHandler.updateFile(types_js_1.DOCX_PATHS.CORE_PROPS, xml);
1605
+ }
1606
+ }
1607
+ mergeCorePropsWithOriginal() {
1608
+ if (!this._originalCorePropsXml) {
1609
+ return this.generator.generateCoreProps(this.properties);
1610
+ }
1611
+ let xml = this._originalCorePropsXml;
1612
+ const mergeField = (tag, value) => {
1613
+ if (value === undefined)
1614
+ return;
1615
+ const escaped = XMLBuilder_js_1.XMLBuilder.sanitizeXmlContent(value);
1616
+ const openClose = new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?</${tag}>`);
1617
+ const selfClosing = new RegExp(`<${tag}\\b[^>]*/>`);
1618
+ if (openClose.test(xml)) {
1619
+ xml = xml.replace(openClose, `<${tag}>${escaped}</${tag}>`);
1620
+ }
1621
+ else if (selfClosing.test(xml)) {
1622
+ xml = xml.replace(selfClosing, `<${tag}>${escaped}</${tag}>`);
1623
+ }
1624
+ else {
1625
+ xml = xml.replace(/<\/cp:coreProperties>/, ` <${tag}>${escaped}</${tag}>\n</cp:coreProperties>`);
1626
+ }
1627
+ };
1628
+ mergeField('dc:title', this.properties.title);
1629
+ mergeField('dc:subject', this.properties.subject);
1630
+ mergeField('dc:creator', this.properties.creator);
1631
+ mergeField('cp:keywords', this.properties.keywords);
1632
+ mergeField('dc:description', this.properties.description);
1633
+ mergeField('cp:category', this.properties.category);
1634
+ mergeField('cp:contentStatus', this.properties.contentStatus);
1635
+ mergeField('dc:language', this.properties.language);
1636
+ return xml;
1575
1637
  }
1576
1638
  updateAppProps() {
1577
1639
  if (this._removedParts.has(types_js_1.DOCX_PATHS.APP_PROPS) || this._removedParts.has('docProps/app.xml'))
@@ -1601,24 +1663,36 @@ class Document {
1601
1663
  else if (xml.includes('<Company/>')) {
1602
1664
  xml = xml.replace(/<Company\/>/, `<Company>${escaped}</Company>`);
1603
1665
  }
1666
+ else {
1667
+ xml = xml.replace(/<\/Properties>/, ` <Company>${escaped}</Company>\n</Properties>`);
1668
+ }
1604
1669
  }
1605
1670
  if (this.properties.application !== undefined) {
1606
1671
  const escaped = XMLBuilder_js_1.XMLBuilder.sanitizeXmlContent(this.properties.application);
1607
1672
  if (xml.includes('<Application>')) {
1608
1673
  xml = xml.replace(/<Application>[^<]*<\/Application>/, `<Application>${escaped}</Application>`);
1609
1674
  }
1675
+ else {
1676
+ xml = xml.replace(/<\/Properties>/, ` <Application>${escaped}</Application>\n</Properties>`);
1677
+ }
1610
1678
  }
1611
1679
  if (this.properties.appVersion !== undefined) {
1612
1680
  const escaped = XMLBuilder_js_1.XMLBuilder.sanitizeXmlContent(this.properties.appVersion);
1613
1681
  if (xml.includes('<AppVersion>')) {
1614
1682
  xml = xml.replace(/<AppVersion>[^<]*<\/AppVersion>/, `<AppVersion>${escaped}</AppVersion>`);
1615
1683
  }
1684
+ else {
1685
+ xml = xml.replace(/<\/Properties>/, ` <AppVersion>${escaped}</AppVersion>\n</Properties>`);
1686
+ }
1616
1687
  }
1617
1688
  if (this.properties.manager !== undefined) {
1618
1689
  const escaped = XMLBuilder_js_1.XMLBuilder.sanitizeXmlContent(this.properties.manager);
1619
1690
  if (xml.includes('<Manager>')) {
1620
1691
  xml = xml.replace(/<Manager>[^<]*<\/Manager>/, `<Manager>${escaped}</Manager>`);
1621
1692
  }
1693
+ else {
1694
+ xml = xml.replace(/<\/Properties>/, ` <Manager>${escaped}</Manager>\n</Properties>`);
1695
+ }
1622
1696
  }
1623
1697
  return xml;
1624
1698
  }
@@ -1744,7 +1818,8 @@ class Document {
1744
1818
  return this.stylesManager.generateStylesXml();
1745
1819
  }
1746
1820
  const modifiedStyleIds = this.stylesManager.getModifiedStyleIds();
1747
- if (modifiedStyleIds.size === 0) {
1821
+ const removedStyleIds = this.stylesManager.getRemovedStyleIds();
1822
+ if (modifiedStyleIds.size === 0 && removedStyleIds.size === 0) {
1748
1823
  return this._originalStylesXml;
1749
1824
  }
1750
1825
  const modifiedStyles = new Map();
@@ -1766,6 +1841,11 @@ class Document {
1766
1841
  resultXml = resultXml.replace('</w:styles>', `${newStyleXml}\n</w:styles>`);
1767
1842
  }
1768
1843
  }
1844
+ for (const styleId of removedStyleIds) {
1845
+ const escapedStyleId = styleId.replace(/[.*+?^${}()|[\]\\"]/g, '\\$&');
1846
+ const removedPattern = new RegExp(`\\s*<w:style[^>]*\\sw:styleId="${escapedStyleId}"[^>]*>[\\s\\S]*?</w:style>`);
1847
+ resultXml = resultXml.replace(removedPattern, '');
1848
+ }
1769
1849
  return resultXml;
1770
1850
  }
1771
1851
  updateNumberingXml() {
@@ -1964,8 +2044,14 @@ class Document {
1964
2044
  xml = xml.replace(/<w:revisionView\b[^>]*>[\s\S]*?<\/w:revisionView>/g, '');
1965
2045
  let trackBlock = '';
1966
2046
  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'}"/>`;
2047
+ if (!view.showInsertionsAndDeletions ||
2048
+ !view.showFormatting ||
2049
+ !view.showInkAnnotations ||
2050
+ view.showMarkup === false ||
2051
+ view.showComments === false) {
2052
+ const markupAttr = view.showMarkup === false ? ' w:markup="0"' : '';
2053
+ const commentsAttr = view.showComments === false ? ' w:comments="0"' : '';
2054
+ 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
2055
  }
1970
2056
  if (this.trackChangesEnabled) {
1971
2057
  trackBlock += '\n <w:trackRevisions/>';
@@ -2001,6 +2087,8 @@ class Document {
2001
2087
  const prot = this.documentProtection;
2002
2088
  const esc = XMLBuilder_js_1.XMLBuilder.escapeXmlAttribute;
2003
2089
  let protXml = `\n <w:documentProtection w:edit="${esc(prot.edit)}" w:enforcement="${prot.enforcement ? '1' : '0'}"`;
2090
+ if (prot.formatting !== undefined)
2091
+ protXml += ` w:formatting="${prot.formatting ? '1' : '0'}"`;
2004
2092
  if (prot.cryptProviderType)
2005
2093
  protXml += ` w:cryptProviderType="${esc(prot.cryptProviderType)}"`;
2006
2094
  if (prot.cryptAlgorithmClass)
@@ -2015,6 +2103,12 @@ class Document {
2015
2103
  protXml += ` w:hash="${esc(prot.hash)}"`;
2016
2104
  if (prot.salt)
2017
2105
  protXml += ` w:salt="${esc(prot.salt)}"`;
2106
+ if (prot.algorithmName)
2107
+ protXml += ` w:algorithmName="${esc(prot.algorithmName)}"`;
2108
+ if (prot.hashValue)
2109
+ protXml += ` w:hashValue="${esc(prot.hashValue)}"`;
2110
+ if (prot.saltValue)
2111
+ protXml += ` w:saltValue="${esc(prot.saltValue)}"`;
2018
2112
  protXml += '/>';
2019
2113
  if (/<w:autoFormatOverride\b/.test(xml)) {
2020
2114
  xml = xml.replace(/<w:autoFormatOverride\b/, protXml + '\n <w:autoFormatOverride');
@@ -2768,6 +2862,18 @@ class Document {
2768
2862
  }
2769
2863
  }
2770
2864
  }
2865
+ for (const style of this.stylesManager.getAllStyles()) {
2866
+ const styleNumId = style.getProperties().numPr?.numId;
2867
+ if (styleNumId !== undefined) {
2868
+ usedNumIds.add(styleNumId);
2869
+ }
2870
+ }
2871
+ for (const filePath of [types_js_1.DOCX_PATHS.STYLES, 'word/comments.xml']) {
2872
+ const xml = this.zipHandler.getFileAsString(filePath);
2873
+ if (xml) {
2874
+ this.collectNumIdsFromXml(xml, usedNumIds);
2875
+ }
2876
+ }
2771
2877
  this.numberingManager.cleanupUnusedNumbering(usedNumIds);
2772
2878
  }
2773
2879
  validateNumberingReferences() {
@@ -2869,7 +2975,67 @@ class Document {
2869
2975
  maxRevId = rev.getId();
2870
2976
  }
2871
2977
  const registeredSet = new Set(existingRevisions);
2872
- let docPrId = 1;
2978
+ let maxPreservedDocPrId = 0;
2979
+ const collectPreservedDocPrIds = (rawXml) => {
2980
+ if (!rawXml || !rawXml.includes('wp:docPr'))
2981
+ return;
2982
+ const docPrPattern = /<wp:docPr\b[^>]*\bid="(\d+)"/g;
2983
+ let match;
2984
+ while ((match = docPrPattern.exec(rawXml)) !== null) {
2985
+ const id = parseInt(match[1], 10);
2986
+ if (id > maxPreservedDocPrId)
2987
+ maxPreservedDocPrId = id;
2988
+ }
2989
+ };
2990
+ const collectFromRun = (run) => {
2991
+ if (run instanceof ImageRun_js_1.ImageRun) {
2992
+ collectPreservedDocPrIds(run.getRawRunXml());
2993
+ return;
2994
+ }
2995
+ for (const contentItem of run.getContent()) {
2996
+ collectPreservedDocPrIds(contentItem.rawXml);
2997
+ }
2998
+ };
2999
+ const collectFromParagraph = (para) => {
3000
+ for (const item of para.getContent()) {
3001
+ if (item instanceof Revision_js_1.Revision) {
3002
+ for (const revItem of item.getContent()) {
3003
+ if (revItem instanceof Run_js_1.Run)
3004
+ collectFromRun(revItem);
3005
+ }
3006
+ }
3007
+ else if (item instanceof Run_js_1.Run) {
3008
+ collectFromRun(item);
3009
+ }
3010
+ else if (item instanceof PreservedElement_js_1.PreservedElement) {
3011
+ collectPreservedDocPrIds(item.getRawXml());
3012
+ }
3013
+ }
3014
+ };
3015
+ for (const element of this.bodyElements) {
3016
+ if (element instanceof Paragraph_js_1.Paragraph) {
3017
+ collectFromParagraph(element);
3018
+ }
3019
+ else if (element instanceof Table_js_1.Table) {
3020
+ for (const row of element.getRows()) {
3021
+ for (const cell of row.getCells()) {
3022
+ for (const para of cell.getParagraphs()) {
3023
+ collectFromParagraph(para);
3024
+ }
3025
+ for (const nested of cell.getRawNestedContent()) {
3026
+ collectPreservedDocPrIds(nested.xml);
3027
+ }
3028
+ }
3029
+ }
3030
+ }
3031
+ else {
3032
+ const passthrough = element;
3033
+ if (typeof passthrough.getRawXml === 'function') {
3034
+ collectPreservedDocPrIds(passthrough.getRawXml());
3035
+ }
3036
+ }
3037
+ }
3038
+ let docPrId = maxPreservedDocPrId + 1;
2873
3039
  const existingParaIds = new Set();
2874
3040
  const paragraphsNeedingIds = [];
2875
3041
  const generateUniqueParaId = () => {
@@ -2901,6 +3067,13 @@ class Document {
2901
3067
  else if (item instanceof ImageRun_js_1.ImageRun) {
2902
3068
  item.getImageElement().setDocPrId(docPrId++);
2903
3069
  }
3070
+ else if (item instanceof Revision_js_1.Revision) {
3071
+ for (const revItem of item.getContent()) {
3072
+ if (revItem instanceof ImageRun_js_1.ImageRun) {
3073
+ revItem.getImageElement().setDocPrId(docPrId++);
3074
+ }
3075
+ }
3076
+ }
2904
3077
  }
2905
3078
  if (para.formatting.paraId) {
2906
3079
  existingParaIds.add(para.formatting.paraId);
@@ -3190,6 +3363,7 @@ class Document {
3190
3363
  numLevel.setLeftIndent(720 * (levelIndex + 1));
3191
3364
  numLevel.setHangingIndent(360);
3192
3365
  }
3366
+ this.numberingManager.markAbstractNumberingModified(abstractNumId);
3193
3367
  this.applyFormattingToListParagraphs(instance.getNumId());
3194
3368
  count++;
3195
3369
  }
@@ -3216,6 +3390,7 @@ class Document {
3216
3390
  numLevel.setHangingIndent(360);
3217
3391
  numLevel.setAlignment('left');
3218
3392
  }
3393
+ this.numberingManager.markAbstractNumberingModified(abstractNumId);
3219
3394
  this.applyFormattingToListParagraphs(instance.getNumId());
3220
3395
  count++;
3221
3396
  }
@@ -5038,39 +5213,39 @@ class Document {
5038
5213
  return this;
5039
5214
  }
5040
5215
  setHeader(header) {
5041
- const relationship = this.relationshipManager.addHeader(`${header.getFilename(1)}`);
5216
+ const relationship = this.relationshipManager.addHeader(this.headerFooterManager.peekHeaderFilename(header));
5042
5217
  this.headerFooterManager.registerHeader(header, relationship.getId());
5043
5218
  this.section.setHeaderReference('default', relationship.getId());
5044
5219
  return this;
5045
5220
  }
5046
5221
  setFirstPageHeader(header) {
5047
5222
  this.section.setTitlePage(true);
5048
- const relationship = this.relationshipManager.addHeader(`${header.getFilename(this.headerFooterManager.getHeaderCount() + 1)}`);
5223
+ const relationship = this.relationshipManager.addHeader(this.headerFooterManager.peekHeaderFilename(header));
5049
5224
  this.headerFooterManager.registerHeader(header, relationship.getId());
5050
5225
  this.section.setHeaderReference('first', relationship.getId());
5051
5226
  return this;
5052
5227
  }
5053
5228
  setEvenPageHeader(header) {
5054
- const relationship = this.relationshipManager.addHeader(`${header.getFilename(this.headerFooterManager.getHeaderCount() + 1)}`);
5229
+ const relationship = this.relationshipManager.addHeader(this.headerFooterManager.peekHeaderFilename(header));
5055
5230
  this.headerFooterManager.registerHeader(header, relationship.getId());
5056
5231
  this.section.setHeaderReference('even', relationship.getId());
5057
5232
  return this;
5058
5233
  }
5059
5234
  setFooter(footer) {
5060
- const relationship = this.relationshipManager.addFooter(`${footer.getFilename(1)}`);
5235
+ const relationship = this.relationshipManager.addFooter(this.headerFooterManager.peekFooterFilename(footer));
5061
5236
  this.headerFooterManager.registerFooter(footer, relationship.getId());
5062
5237
  this.section.setFooterReference('default', relationship.getId());
5063
5238
  return this;
5064
5239
  }
5065
5240
  setFirstPageFooter(footer) {
5066
5241
  this.section.setTitlePage(true);
5067
- const relationship = this.relationshipManager.addFooter(`${footer.getFilename(this.headerFooterManager.getFooterCount() + 1)}`);
5242
+ const relationship = this.relationshipManager.addFooter(this.headerFooterManager.peekFooterFilename(footer));
5068
5243
  this.headerFooterManager.registerFooter(footer, relationship.getId());
5069
5244
  this.section.setFooterReference('first', relationship.getId());
5070
5245
  return this;
5071
5246
  }
5072
5247
  setEvenPageFooter(footer) {
5073
- const relationship = this.relationshipManager.addFooter(`${footer.getFilename(this.headerFooterManager.getFooterCount() + 1)}`);
5248
+ const relationship = this.relationshipManager.addFooter(this.headerFooterManager.peekFooterFilename(footer));
5074
5249
  this.headerFooterManager.registerFooter(footer, relationship.getId());
5075
5250
  this.section.setFooterReference('even', relationship.getId());
5076
5251
  return this;
@@ -5216,6 +5391,20 @@ class Document {
5216
5391
  }
5217
5392
  }
5218
5393
  this.removeCommentCompanionFiles();
5394
+ const extendedXml = this.commentManager.generateCommentsExtendedXml();
5395
+ if (extendedXml) {
5396
+ this.zipHandler.addFile(types_js_1.DOCX_PATHS.COMMENTS_EXTENDED, extendedXml);
5397
+ const hasExtendedRel = this.relationshipManager
5398
+ .getAllRelationships()
5399
+ .some((rel) => rel.getTarget() === 'commentsExtended.xml');
5400
+ if (!hasExtendedRel) {
5401
+ this.relationshipManager.addRelationship(Relationship_js_1.Relationship.create({
5402
+ id: this.relationshipManager.generateId(),
5403
+ type: 'http://schemas.microsoft.com/office/2011/relationships/commentsExtended',
5404
+ target: 'commentsExtended.xml',
5405
+ }));
5406
+ }
5407
+ }
5219
5408
  }
5220
5409
  else if (this._originalCommentsXml) {
5221
5410
  this.zipHandler.addFile('word/comments.xml', this._originalCommentsXml);
@@ -5253,7 +5442,8 @@ class Document {
5253
5442
  }
5254
5443
  }
5255
5444
  saveFootnotes() {
5256
- if (this._footnotesModified || this.footnoteManager.getCount() > 0) {
5445
+ if (this._footnotesModified ||
5446
+ (!this._originalFootnotesXml && this.footnoteManager.getCount() > 0)) {
5257
5447
  const xml = this.footnoteManager.generateFootnotesXml();
5258
5448
  this.zipHandler.addFile(types_js_1.DOCX_PATHS.FOOTNOTES, xml);
5259
5449
  const existingRels = this.relationshipManager.getRelationshipsByType(Relationship_js_1.RelationshipType.FOOTNOTES);
@@ -5271,7 +5461,8 @@ class Document {
5271
5461
  }
5272
5462
  }
5273
5463
  saveEndnotes() {
5274
- if (this._endnotesModified || this.endnoteManager.getCount() > 0) {
5464
+ if (this._endnotesModified ||
5465
+ (!this._originalEndnotesXml && this.endnoteManager.getCount() > 0)) {
5275
5466
  const xml = this.endnoteManager.generateEndnotesXml();
5276
5467
  this.zipHandler.addFile(types_js_1.DOCX_PATHS.ENDNOTES, xml);
5277
5468
  const existingRels = this.relationshipManager.getRelationshipsByType(Relationship_js_1.RelationshipType.ENDNOTES);
@@ -5340,7 +5531,12 @@ class Document {
5340
5531
  xml += '</Relationships>';
5341
5532
  this.zipHandler.addFile(relsPath, xml);
5342
5533
  for (const rel of hyperlinkRels) {
5343
- this.relationshipManager.removeRelationship(rel.id);
5534
+ const mainRel = this.relationshipManager.getRelationship(rel.id);
5535
+ if (mainRel &&
5536
+ mainRel.getType() === Relationship_js_1.RelationshipType.HYPERLINK &&
5537
+ mainRel.getTarget() === rel.url) {
5538
+ this.relationshipManager.removeRelationship(rel.id);
5539
+ }
5344
5540
  }
5345
5541
  }
5346
5542
  }
@@ -5458,13 +5654,25 @@ class Document {
5458
5654
  parseContentTypes(xml) {
5459
5655
  const defaults = new Set();
5460
5656
  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]}`);
5657
+ const readAttr = (tag, name) => {
5658
+ const match = tag.match(new RegExp(`(?:^|\\s)${name}\\s*=\\s*("([^"]*)"|'([^']*)')`));
5659
+ if (!match)
5660
+ return undefined;
5661
+ return XMLBuilder_js_1.XMLBuilder.unescapeXml(match[2] ?? match[3] ?? '');
5662
+ };
5663
+ for (const tagMatch of xml.matchAll(/<Default\b[^>]*>/g)) {
5664
+ const ext = readAttr(tagMatch[0], 'Extension');
5665
+ const contentType = readAttr(tagMatch[0], 'ContentType');
5666
+ if (ext && contentType) {
5667
+ defaults.add(`${ext}|${contentType}`);
5668
+ }
5464
5669
  }
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]}`);
5670
+ for (const tagMatch of xml.matchAll(/<Override\b[^>]*>/g)) {
5671
+ const partName = readAttr(tagMatch[0], 'PartName');
5672
+ const contentType = readAttr(tagMatch[0], 'ContentType');
5673
+ if (partName && contentType) {
5674
+ overrides.add(`${partName}|${contentType}`);
5675
+ }
5468
5676
  }
5469
5677
  return { defaults, overrides };
5470
5678
  }
@@ -5784,9 +5992,7 @@ class Document {
5784
5992
  }
5785
5993
  if (element && typeof element.getContent === 'function') {
5786
5994
  for (const item of element.getContent()) {
5787
- if (item &&
5788
- typeof item._setTrackingContext === 'function' &&
5789
- typeof item.getInstruction === 'function') {
5995
+ if (item && typeof item._setTrackingContext === 'function') {
5790
5996
  item._setTrackingContext(this.trackingContext);
5791
5997
  }
5792
5998
  }
@@ -5953,6 +6159,7 @@ class Document {
5953
6159
  updated.size = sizeInPoints;
5954
6160
  }
5955
6161
  normalStyle.setRunFormatting(updated);
6162
+ this.stylesManager.addStyle(normalStyle);
5956
6163
  return this;
5957
6164
  }
5958
6165
  setDefaultFontSize(sizeInPoints) {
@@ -5968,6 +6175,7 @@ class Document {
5968
6175
  }
5969
6176
  const existing = normalStyle.getRunFormatting() ?? {};
5970
6177
  normalStyle.setRunFormatting({ ...existing, size: sizeInPoints });
6178
+ this.stylesManager.addStyle(normalStyle);
5971
6179
  return this;
5972
6180
  }
5973
6181
  getUpdateFields() {
@@ -6159,6 +6367,40 @@ class Document {
6159
6367
  this.endnoteManager.clear();
6160
6368
  this._endnotesModified = true;
6161
6369
  }
6370
+ removeFootnote(id) {
6371
+ const removed = this.footnoteManager.removeFootnote(id);
6372
+ if (removed) {
6373
+ this._footnotesModified = true;
6374
+ this.removeNoteReferenceRuns('footnoteReference', id);
6375
+ }
6376
+ return removed;
6377
+ }
6378
+ removeEndnote(id) {
6379
+ const removed = this.endnoteManager.removeEndnote(id);
6380
+ if (removed) {
6381
+ this._endnotesModified = true;
6382
+ this.removeNoteReferenceRuns('endnoteReference', id);
6383
+ }
6384
+ return removed;
6385
+ }
6386
+ removeNoteReferenceRuns(refType, id) {
6387
+ for (const para of this.getAllParagraphs()) {
6388
+ const content = para.getContent();
6389
+ for (let i = content.length - 1; i >= 0; i--) {
6390
+ const item = content[i];
6391
+ if (!(item instanceof Run_js_1.Run)) {
6392
+ continue;
6393
+ }
6394
+ const matches = item
6395
+ .getContent()
6396
+ .some((c) => c.type === refType &&
6397
+ (refType === 'footnoteReference' ? c.footnoteId === id : c.endnoteId === id));
6398
+ if (matches) {
6399
+ para.removeContentAt(i);
6400
+ }
6401
+ }
6402
+ }
6403
+ }
6162
6404
  addCommentToParagraph(paragraph, commentOrAuthor, content, initials) {
6163
6405
  const comment = typeof commentOrAuthor === 'string'
6164
6406
  ? this.createComment(commentOrAuthor, content, initials)
@@ -6209,12 +6451,52 @@ class Document {
6209
6451
  return this.commentManager.hasReplies(commentId);
6210
6452
  }
6211
6453
  removeComment(id) {
6454
+ const replyIds = this.commentManager.getReplies(id).map((reply) => reply.getId());
6212
6455
  const removed = this.commentManager.removeComment(id);
6213
6456
  if (removed) {
6457
+ this.removeCommentAnchors([id, ...replyIds]);
6214
6458
  this._commentsModified = true;
6215
6459
  }
6216
6460
  return removed;
6217
6461
  }
6462
+ removeCommentAnchors(commentIds) {
6463
+ const strip = (paragraphs) => {
6464
+ let removed = false;
6465
+ for (const paragraph of paragraphs) {
6466
+ for (const commentId of commentIds) {
6467
+ if (paragraph.removeCommentAnchor(commentId)) {
6468
+ removed = true;
6469
+ }
6470
+ }
6471
+ }
6472
+ return removed;
6473
+ };
6474
+ strip(this.getAllParagraphs());
6475
+ for (const entry of this.headerFooterManager.getAllHeaders()) {
6476
+ strip(this.extractParagraphsFromElements(entry.header.getElements()));
6477
+ }
6478
+ for (const entry of this.headerFooterManager.getAllFooters()) {
6479
+ strip(this.extractParagraphsFromElements(entry.footer.getElements()));
6480
+ }
6481
+ let footnotesChanged = false;
6482
+ for (const footnote of this.footnoteManager.getAllFootnotes()) {
6483
+ if (strip(footnote.getParagraphs())) {
6484
+ footnotesChanged = true;
6485
+ }
6486
+ }
6487
+ if (footnotesChanged) {
6488
+ this._footnotesModified = true;
6489
+ }
6490
+ let endnotesChanged = false;
6491
+ for (const endnote of this.endnoteManager.getAllEndnotes()) {
6492
+ if (strip(endnote.getParagraphs())) {
6493
+ endnotesChanged = true;
6494
+ }
6495
+ }
6496
+ if (endnotesChanged) {
6497
+ this._endnotesModified = true;
6498
+ }
6499
+ }
6218
6500
  hasNoRevisions() {
6219
6501
  return this.revisionManager.isEmpty();
6220
6502
  }
@@ -6470,8 +6752,8 @@ class Document {
6470
6752
  this.parser.clearParseErrors();
6471
6753
  this.stylesManager.clear();
6472
6754
  this.numberingManager.clear();
6473
- this.imageManager.clear();
6474
6755
  this.imageManager.releaseAllImageData();
6756
+ this.imageManager.clear();
6475
6757
  this.relationshipManager.clear();
6476
6758
  this.headerFooterManager.clear();
6477
6759
  this.bookmarkManager.clear();
@@ -6485,6 +6767,7 @@ class Document {
6485
6767
  this._originalNumberingXml = undefined;
6486
6768
  this._originalSettingsXml = undefined;
6487
6769
  this._originalAppPropsXml = undefined;
6770
+ this._originalCorePropsXml = undefined;
6488
6771
  this._originalFootnotesXml = undefined;
6489
6772
  this._originalEndnotesXml = undefined;
6490
6773
  this._originalCommentsXml = undefined;
@@ -6493,6 +6776,7 @@ class Document {
6493
6776
  this._originalContentTypes = undefined;
6494
6777
  this._settingsModified = false;
6495
6778
  this._appPropsModified = false;
6779
+ this._corePropsModified = false;
6496
6780
  this._footnotesModified = false;
6497
6781
  this._endnotesModified = false;
6498
6782
  this._originalWebSettingsXml = undefined;
@@ -7050,7 +7334,7 @@ class Document {
7050
7334
  const matches = originalText.match(wordPattern);
7051
7335
  if (matches) {
7052
7336
  replacementCount += matches.length;
7053
- newText = originalText.replace(wordPattern, replace);
7337
+ newText = originalText.replace(wordPattern, () => replace);
7054
7338
  }
7055
7339
  }
7056
7340
  else {
@@ -7058,7 +7342,7 @@ class Document {
7058
7342
  const matches = originalText.match(searchPattern);
7059
7343
  if (matches) {
7060
7344
  replacementCount += matches.length;
7061
- newText = originalText.replace(searchPattern, replace);
7345
+ newText = originalText.replace(searchPattern, () => replace);
7062
7346
  }
7063
7347
  }
7064
7348
  if (newText !== originalText) {
@@ -7338,90 +7622,303 @@ class Document {
7338
7622
  }
7339
7623
  toPlainText(separator = '\n') {
7340
7624
  const paragraphs = this.getAllParagraphs();
7341
- return paragraphs.map((p) => p.getText()).join(separator);
7342
- }
7343
- toMarkdown() {
7625
+ return paragraphs.map((p) => p.getTextIncludingRevisions()).join(separator);
7626
+ }
7627
+ toMarkdown(options) {
7628
+ const ctx = {
7629
+ opts: {
7630
+ htmlFallback: options?.htmlFallback ?? true,
7631
+ footnotes: options?.footnotes ?? true,
7632
+ images: options?.images ?? true,
7633
+ },
7634
+ notes: [],
7635
+ noteMarkers: new Set(),
7636
+ };
7344
7637
  const lines = [];
7345
7638
  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
- }
7639
+ this.bodyElementToMarkdown(element, ctx, lines);
7640
+ }
7641
+ while (lines.length > 0 && lines[lines.length - 1] === '') {
7642
+ lines.pop();
7643
+ }
7644
+ let out = lines.join('\n');
7645
+ if (ctx.opts.footnotes && ctx.notes.length > 0) {
7646
+ const defs = ctx.notes.map((n) => `[^${n.marker}]: ${n.text}`).join('\n');
7647
+ out = out ? `${out}\n\n${defs}` : defs;
7648
+ }
7649
+ return out;
7650
+ }
7651
+ bodyElementToMarkdown(element, ctx, lines) {
7652
+ if (element instanceof Paragraph_js_1.Paragraph) {
7653
+ const md = this.paragraphToMarkdown(element, ctx);
7654
+ if (md !== null) {
7655
+ lines.push(md);
7656
+ lines.push('');
7352
7657
  }
7353
- else if (element instanceof Table_js_1.Table) {
7354
- lines.push(...this.tableToMarkdown(element));
7658
+ }
7659
+ else if (element instanceof Table_js_1.Table) {
7660
+ const tableLines = this.tableToMarkdown(element, ctx);
7661
+ if (tableLines.length > 0) {
7662
+ lines.push(...tableLines);
7355
7663
  lines.push('');
7356
7664
  }
7357
7665
  }
7358
- while (lines.length > 0 && lines[lines.length - 1] === '') {
7359
- lines.pop();
7666
+ else if (element instanceof StructuredDocumentTag_js_1.StructuredDocumentTag) {
7667
+ for (const child of element.getContent()) {
7668
+ this.bodyElementToMarkdown(child, ctx, lines);
7669
+ }
7670
+ }
7671
+ else if (element instanceof PreservedElement_js_1.PreservedElement) {
7672
+ const text = this.extractTextFromRawXml(element.getRawXml());
7673
+ if (text) {
7674
+ lines.push(this.escapeMarkdown(text));
7675
+ lines.push('');
7676
+ }
7360
7677
  }
7361
- return lines.join('\n');
7362
7678
  }
7363
- paragraphToMarkdown(para) {
7364
- const text = this.paragraphContentToMarkdown(para);
7365
- if (!text && !para.hasNumbering())
7679
+ paragraphToMarkdown(para, ctx) {
7680
+ const inline = this.paragraphContentToMarkdown(para, ctx);
7681
+ const hasNumbering = para.hasNumbering();
7682
+ if (!inline && !hasNumbering)
7366
7683
  return null;
7367
7684
  const headingLevel = para.detectHeadingLevel();
7368
7685
  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}`;
7686
+ return '#'.repeat(headingLevel) + ' ' + this.toSingleLine(inline);
7687
+ }
7688
+ const style = (para.getStyle() ?? '').toLowerCase();
7689
+ const isListStyle = style.includes('listbullet') ||
7690
+ style.includes('list bullet') ||
7691
+ style.includes('listnumber') ||
7692
+ style.includes('list number');
7693
+ if (hasNumbering || isListStyle) {
7694
+ const level = para.getNumbering()?.level ?? 0;
7695
+ const indent = ' '.repeat(Math.max(0, level));
7696
+ const marker = this.isOrderedList(para) ? '1.' : '-';
7697
+ return `${indent}${marker} ${this.toSingleLine(inline)}`;
7698
+ }
7699
+ if (style.includes('quote')) {
7700
+ return this.toSingleLine(inline)
7701
+ .split('\n')
7702
+ .map((l) => `> ${l}`)
7703
+ .join('\n');
7704
+ }
7705
+ return inline;
7706
+ }
7707
+ isOrderedList(para) {
7708
+ const numbering = para.getNumbering();
7709
+ if (numbering) {
7710
+ const instance = this.numberingManager.getInstance(numbering.numId);
7711
+ if (instance) {
7712
+ const abstract = this.numberingManager.getAbstractNumbering(instance.getAbstractNumId());
7713
+ const levelDef = abstract?.getLevel(numbering.level);
7714
+ const format = levelDef?.getFormat();
7715
+ if (format)
7716
+ return format !== 'bullet';
7717
+ }
7375
7718
  }
7376
- return text;
7719
+ const style = (para.getStyle() ?? '').toLowerCase();
7720
+ if (style.includes('bullet'))
7721
+ return false;
7722
+ if (style.includes('number'))
7723
+ return true;
7724
+ return true;
7377
7725
  }
7378
- paragraphContentToMarkdown(para) {
7726
+ paragraphContentToMarkdown(para, ctx) {
7727
+ return this.inlineContentToMarkdown(para.getContent(), ctx);
7728
+ }
7729
+ inlineContentToMarkdown(items, ctx) {
7379
7730
  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}*`;
7731
+ for (const item of items) {
7732
+ if (item instanceof ImageRun_js_1.ImageRun) {
7733
+ if (ctx.opts.images) {
7734
+ const image = item.getImageElement();
7735
+ const alt = this.escapeMarkdown(image.getAltText() || 'image');
7736
+ const src = image.getRelationshipId() ?? 'image';
7737
+ parts.push(`![${alt}](${src})`);
7395
7738
  }
7396
- if (fmt.strike) {
7397
- md = `~~${md}~~`;
7739
+ }
7740
+ else if (item instanceof Run_js_1.Run) {
7741
+ parts.push(this.runToMarkdown(item, ctx));
7742
+ }
7743
+ else if (item instanceof Hyperlink_js_1.Hyperlink) {
7744
+ const runs = item.getRuns();
7745
+ let label = runs.length > 0
7746
+ ? runs.map((r) => this.runToMarkdown(r, ctx, true)).join('')
7747
+ : this.escapeMarkdown(item.getText());
7748
+ if (!label)
7749
+ label = this.escapeMarkdown(item.getText());
7750
+ let url = item.getUrl() ?? '';
7751
+ const anchor = item.getAnchor();
7752
+ if (anchor)
7753
+ url = url ? `${url}#${anchor}` : `#${anchor}`;
7754
+ parts.push(`[${label}](${url})`);
7755
+ }
7756
+ else if (item instanceof Revision_js_1.Revision) {
7757
+ const inner = this.inlineContentToMarkdown(item.getContent(), ctx);
7758
+ if (!inner)
7759
+ continue;
7760
+ const type = item.getType();
7761
+ if (type === 'delete' || type === 'moveFrom') {
7762
+ parts.push(ctx.opts.htmlFallback ? `<del>${inner}</del>` : `~~${inner}~~`);
7398
7763
  }
7399
- if (fmt.font &&
7400
- /^(courier|consolas|monaco|menlo|source code|fira code|jetbrains mono)/i.test(fmt.font)) {
7401
- md = `\`${runText}\``;
7764
+ else {
7765
+ parts.push(inner);
7402
7766
  }
7403
- parts.push(md);
7404
7767
  }
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})`);
7768
+ else if (item instanceof Field_js_1.ComplexField) {
7769
+ const result = item.getResult();
7770
+ if (result)
7771
+ parts.push(this.escapeMarkdown(result));
7772
+ }
7773
+ else if (item instanceof Field_js_1.Field) {
7774
+ const result = item.getCachedResult();
7775
+ if (result)
7776
+ parts.push(this.escapeMarkdown(result));
7777
+ }
7778
+ else if (item instanceof TextBox_js_1.TextBox) {
7779
+ const text = item
7780
+ .getParagraphs()
7781
+ .map((p) => this.paragraphContentToMarkdown(p, ctx))
7782
+ .filter((s) => s !== '')
7783
+ .join(' ');
7784
+ if (text)
7785
+ parts.push(text);
7786
+ }
7787
+ else if (item instanceof Shape_js_1.Shape) {
7788
+ const text = item.getText();
7789
+ if (text)
7790
+ parts.push(this.escapeMarkdown(text));
7791
+ }
7792
+ else if (item instanceof PreservedElement_js_1.PreservedElement) {
7793
+ const type = item.getElementType();
7794
+ if (!type.startsWith('w:comment')) {
7795
+ const text = this.extractTextFromRawXml(item.getRawXml());
7796
+ if (text)
7797
+ parts.push(this.escapeMarkdown(text));
7798
+ }
7409
7799
  }
7410
7800
  }
7411
7801
  return parts.join('');
7412
7802
  }
7413
- tableToMarkdown(table) {
7414
- const data = table.toArray();
7415
- if (data.length === 0)
7803
+ runToMarkdown(run, ctx, inLink = false) {
7804
+ const fmt = run.getFormatting();
7805
+ const isMono = !!(fmt.font &&
7806
+ /^(courier|consolas|monaco|menlo|source code|fira code|jetbrains mono)/i.test(fmt.font));
7807
+ const escape = (s) => (isMono ? s : this.escapeMarkdown(s));
7808
+ const segments = [];
7809
+ const markers = [];
7810
+ for (const content of run.getContent()) {
7811
+ switch (content.type) {
7812
+ case 'text':
7813
+ case 'instructionText':
7814
+ segments.push(escape(content.value ?? ''));
7815
+ break;
7816
+ case 'tab':
7817
+ segments.push('\t');
7818
+ break;
7819
+ case 'carriageReturn':
7820
+ segments.push('\n');
7821
+ break;
7822
+ case 'break':
7823
+ if (content.breakType !== 'page' && content.breakType !== 'column') {
7824
+ segments.push(ctx.opts.htmlFallback ? '<br>' : '\n');
7825
+ }
7826
+ break;
7827
+ case 'noBreakHyphen':
7828
+ segments.push('‑');
7829
+ break;
7830
+ case 'symbol':
7831
+ if (content.symbolChar) {
7832
+ const code = parseInt(content.symbolChar, 16);
7833
+ if (!Number.isNaN(code))
7834
+ segments.push(escape(String.fromCharCode(code)));
7835
+ }
7836
+ break;
7837
+ case 'footnoteReference':
7838
+ if (ctx.opts.footnotes && content.footnoteId !== undefined) {
7839
+ markers.push(this.noteMarker(content.footnoteId, 'fn', ctx));
7840
+ }
7841
+ break;
7842
+ case 'endnoteReference':
7843
+ if (ctx.opts.footnotes && content.endnoteId !== undefined) {
7844
+ markers.push(this.noteMarker(content.endnoteId, 'en', ctx));
7845
+ }
7846
+ break;
7847
+ default:
7848
+ break;
7849
+ }
7850
+ }
7851
+ let text = segments.join('');
7852
+ if (text) {
7853
+ if (isMono) {
7854
+ text = `\`${text}\``;
7855
+ }
7856
+ if (fmt.bold && fmt.italic)
7857
+ text = `***${text}***`;
7858
+ else if (fmt.bold)
7859
+ text = `**${text}**`;
7860
+ else if (fmt.italic)
7861
+ text = `*${text}*`;
7862
+ if (fmt.strike || fmt.dstrike)
7863
+ text = `~~${text}~~`;
7864
+ if (ctx.opts.htmlFallback) {
7865
+ if (fmt.superscript)
7866
+ text = `<sup>${text}</sup>`;
7867
+ else if (fmt.subscript)
7868
+ text = `<sub>${text}</sub>`;
7869
+ if (fmt.highlight && fmt.highlight !== 'none')
7870
+ text = `<mark>${text}</mark>`;
7871
+ if (!inLink) {
7872
+ if (fmt.underline && fmt.underline !== 'none')
7873
+ text = `<u>${text}</u>`;
7874
+ if (fmt.color && fmt.color !== 'auto' && /^[0-9a-fA-F]{6}$/.test(fmt.color)) {
7875
+ text = `<span style="color:#${fmt.color}">${text}</span>`;
7876
+ }
7877
+ }
7878
+ }
7879
+ }
7880
+ return text + markers.join('');
7881
+ }
7882
+ noteMarker(id, kind, ctx) {
7883
+ const marker = `${kind}${id}`;
7884
+ if (!ctx.noteMarkers.has(marker)) {
7885
+ ctx.noteMarkers.add(marker);
7886
+ const note = kind === 'fn' ? this.footnoteManager.getFootnote(id) : this.endnoteManager.getEndnote(id);
7887
+ let text = '';
7888
+ if (note) {
7889
+ text = note
7890
+ .getParagraphs()
7891
+ .map((p) => this.paragraphContentToMarkdown(p, ctx))
7892
+ .filter((s) => s !== '')
7893
+ .join(' ')
7894
+ .replace(/\s*\n\s*/g, ' ')
7895
+ .trim();
7896
+ }
7897
+ ctx.notes.push({ marker, text });
7898
+ }
7899
+ return `[^${marker}]`;
7900
+ }
7901
+ tableToMarkdown(table, ctx) {
7902
+ const rows = table.getRows();
7903
+ if (rows.length === 0)
7416
7904
  return [];
7417
- const colCount = Math.max(...data.map((row) => row.length));
7905
+ const isComplex = rows.some((row) => row
7906
+ .getCells()
7907
+ .some((cell) => (cell.getColumnSpan() ?? 1) > 1 ||
7908
+ cell.getVerticalMerge() !== undefined ||
7909
+ cell.hasNestedTables()));
7910
+ if (isComplex && ctx.opts.htmlFallback) {
7911
+ return this.tableToHtmlBlock(table);
7912
+ }
7913
+ const matrix = rows.map((row) => row.getCells().map((cell) => this.cellToMarkdown(cell, ctx)));
7914
+ const colCount = Math.max(...matrix.map((row) => row.length));
7418
7915
  if (colCount === 0)
7419
7916
  return [];
7420
- const normalized = data.map((row) => {
7917
+ const normalized = matrix.map((row) => {
7421
7918
  const padded = [...row];
7422
7919
  while (padded.length < colCount)
7423
7920
  padded.push('');
7424
- return padded.map((cell) => cell.replace(/\|/g, '\\|').replace(/\n/g, ' ').trim());
7921
+ return padded;
7425
7922
  });
7426
7923
  const lines = [];
7427
7924
  lines.push('| ' + normalized[0].join(' | ') + ' |');
@@ -7431,6 +7928,88 @@ class Document {
7431
7928
  }
7432
7929
  return lines;
7433
7930
  }
7931
+ cellToMarkdown(cell, ctx) {
7932
+ const text = cell
7933
+ .getParagraphs()
7934
+ .map((p) => this.paragraphContentToMarkdown(p, ctx))
7935
+ .filter((s) => s !== '')
7936
+ .join(' ');
7937
+ return text.replace(/\|/g, '\\|').replace(/<br>/g, ' ').replace(/\n/g, ' ').trim();
7938
+ }
7939
+ tableToHtmlBlock(table) {
7940
+ const rows = table.getRows();
7941
+ const rowCells = rows.map((row) => {
7942
+ let gridStart = 0;
7943
+ return row.getCells().map((cell) => {
7944
+ const span = cell.getColumnSpan() ?? 1;
7945
+ const entry = { cell, gridStart, span };
7946
+ gridStart += span;
7947
+ return entry;
7948
+ });
7949
+ });
7950
+ const html = ['<table>'];
7951
+ for (let ri = 0; ri < rowCells.length; ri++) {
7952
+ html.push('<tr>');
7953
+ for (const { cell, gridStart, span } of rowCells[ri]) {
7954
+ if (cell.getVerticalMerge() === 'continue')
7955
+ continue;
7956
+ let rowspan = 1;
7957
+ if (cell.getVerticalMerge() === 'restart') {
7958
+ for (let rj = ri + 1; rj < rowCells.length; rj++) {
7959
+ const below = rowCells[rj].find((e) => e.gridStart === gridStart);
7960
+ if (below?.cell.getVerticalMerge() === 'continue')
7961
+ rowspan++;
7962
+ else
7963
+ break;
7964
+ }
7965
+ }
7966
+ const tag = ri === 0 ? 'th' : 'td';
7967
+ const attrs = (span > 1 ? ` colspan="${span}"` : '') + (rowspan > 1 ? ` rowspan="${rowspan}"` : '');
7968
+ let content = cell
7969
+ .getParagraphs()
7970
+ .map((p) => this.paragraphContentToHTML(p))
7971
+ .filter((s) => s !== '')
7972
+ .join('<br>') || this.escapeHTML(cell.getText());
7973
+ if (cell.hasNestedTables()) {
7974
+ const nestedText = cell
7975
+ .getRawNestedContent()
7976
+ .map((n) => this.extractTextFromRawXml(n.xml))
7977
+ .filter((s) => s)
7978
+ .join(' ');
7979
+ if (nestedText)
7980
+ content += `<br>${this.escapeHTML(nestedText)}`;
7981
+ }
7982
+ html.push(`<${tag}${attrs}>${content}</${tag}>`);
7983
+ }
7984
+ html.push('</tr>');
7985
+ }
7986
+ html.push('</table>');
7987
+ return html;
7988
+ }
7989
+ escapeMarkdown(text) {
7990
+ return text.replace(/([\\`*_[\]<>])/g, '\\$1');
7991
+ }
7992
+ toSingleLine(text) {
7993
+ return text.replace(/<br>/g, ' ').replace(/\s*\n\s*/g, ' ');
7994
+ }
7995
+ extractTextFromRawXml(xml) {
7996
+ if (!xml.includes('<w:t'))
7997
+ return '';
7998
+ const parts = [];
7999
+ const regex = /<w:t(?:\s[^>]*)?>([\s\S]*?)<\/w:t>/g;
8000
+ let match;
8001
+ while ((match = regex.exec(xml)) !== null) {
8002
+ parts.push(match[1] ?? '');
8003
+ }
8004
+ return parts
8005
+ .join('')
8006
+ .replace(/&lt;/g, '<')
8007
+ .replace(/&gt;/g, '>')
8008
+ .replace(/&quot;/g, '"')
8009
+ .replace(/&apos;/g, "'")
8010
+ .replace(/&amp;/g, '&')
8011
+ .trim();
8012
+ }
7434
8013
  toHTML(options) {
7435
8014
  const parts = [];
7436
8015
  let inList = null;
@@ -7521,8 +8100,12 @@ class Document {
7521
8100
  parts.push(html);
7522
8101
  }
7523
8102
  else if (item instanceof Hyperlink_js_1.Hyperlink) {
7524
- const url = this.escapeHTML(item.getUrl() || '');
7525
- const linkText = this.escapeHTML(item.getText() || url);
8103
+ let rawUrl = item.getUrl() ?? '';
8104
+ const anchor = item.getAnchor();
8105
+ if (anchor)
8106
+ rawUrl = rawUrl ? `${rawUrl}#${anchor}` : `#${anchor}`;
8107
+ const url = this.escapeHTML(rawUrl);
8108
+ const linkText = this.escapeHTML(item.getText() || rawUrl);
7526
8109
  parts.push(`<a href="${url}">${linkText}</a>`);
7527
8110
  }
7528
8111
  }
@@ -7670,7 +8253,10 @@ class Document {
7670
8253
  removeParagraph(paragraphOrIndex) {
7671
8254
  let index;
7672
8255
  if (typeof paragraphOrIndex === 'number') {
7673
- index = paragraphOrIndex;
8256
+ const para = this.getParagraphAt(paragraphOrIndex);
8257
+ if (!para)
8258
+ return false;
8259
+ index = this.bodyElements.indexOf(para);
7674
8260
  }
7675
8261
  else {
7676
8262
  index = this.bodyElements.indexOf(paragraphOrIndex);
@@ -7679,13 +8265,8 @@ class Document {
7679
8265
  const element = this.bodyElements[index];
7680
8266
  if (element instanceof Paragraph_js_1.Paragraph) {
7681
8267
  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
- }
8268
+ this.bindTrackingToElement(element);
8269
+ element.clearContent();
7689
8270
  return true;
7690
8271
  }
7691
8272
  this.bodyElements.splice(index, 1);
@@ -7939,16 +8520,6 @@ class Document {
7939
8520
  for (const paragraph of this.getAllParagraphs()) {
7940
8521
  extractHyperlinksFromParagraph(paragraph);
7941
8522
  }
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
8523
  return hyperlinks;
7953
8524
  }
7954
8525
  collectAllReferencedHyperlinkIds() {
@@ -8073,17 +8644,6 @@ class Document {
8073
8644
  bookmarks.push({ bookmark, paragraph });
8074
8645
  }
8075
8646
  }
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
8647
  return bookmarks;
8088
8648
  }
8089
8649
  getFields() {
@@ -8093,18 +8653,6 @@ class Document {
8093
8653
  results.push({ field, paragraph });
8094
8654
  }
8095
8655
  }
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
8656
  return results;
8109
8657
  }
8110
8658
  getImages() {
@@ -8143,7 +8691,7 @@ class Document {
8143
8691
  await entry.image.updateImageData(result.data);
8144
8692
  }
8145
8693
  if (result.newExtension !== extension) {
8146
- const newFilename = filename.replace(/\.[^.]+$/, `.${result.newExtension}`);
8694
+ const newFilename = this.resolveUniqueMediaFilename(filename.replace(/\.[^.]+$/, `.${result.newExtension}`), filename);
8147
8695
  this.imageManager.updateEntryFilename(image, newFilename);
8148
8696
  for (const entry of entries) {
8149
8697
  this.updateImageRelationshipTarget(entry.relationshipId, filename, newFilename);
@@ -8154,6 +8702,20 @@ class Document {
8154
8702
  }
8155
8703
  return { optimizedCount, totalSavedBytes: totalSaved };
8156
8704
  }
8705
+ resolveUniqueMediaFilename(candidate, currentFilename) {
8706
+ const dotIndex = candidate.lastIndexOf('.');
8707
+ const base = dotIndex === -1 ? candidate : candidate.slice(0, dotIndex);
8708
+ const ext = dotIndex === -1 ? '' : candidate.slice(dotIndex);
8709
+ const isTaken = (name) => this.zipHandler.hasFile(`word/media/${name}`) ||
8710
+ this.imageManager.isFilenameOwnedByOther(name, currentFilename);
8711
+ let name = candidate;
8712
+ let counter = 1;
8713
+ while (isTaken(name)) {
8714
+ name = `${base}-${counter}${ext}`;
8715
+ counter++;
8716
+ }
8717
+ return name;
8718
+ }
8157
8719
  updateImageRelationshipTarget(relId, oldFilename, newFilename) {
8158
8720
  const rel = this.relationshipManager.getRelationship(relId);
8159
8721
  if (rel) {
@@ -8277,7 +8839,7 @@ class Document {
8277
8839
  const toRemove = [];
8278
8840
  this.bodyElements.forEach((element, index) => {
8279
8841
  if (element instanceof Paragraph_js_1.Paragraph) {
8280
- const isEmpty = element.getText().trim() === '';
8842
+ const isEmpty = this.isParagraphRemovableBlank(element);
8281
8843
  if (isEmpty && lastWasEmpty) {
8282
8844
  toRemove.push(index);
8283
8845
  }
@@ -8361,11 +8923,30 @@ class Document {
8361
8923
  }
8362
8924
  return { removed, normalized };
8363
8925
  }
8926
+ isParagraphRemovableBlank(para) {
8927
+ if (para.getText().trim() !== '')
8928
+ return false;
8929
+ if (para.formatting.sectPr !== undefined)
8930
+ return false;
8931
+ if (para.getBookmarksStart().length > 0 || para.getBookmarksEnd().length > 0) {
8932
+ return false;
8933
+ }
8934
+ if (para.getCommentsStart().length > 0 || para.getCommentsEnd().length > 0) {
8935
+ return false;
8936
+ }
8937
+ for (const item of para.getContent()) {
8938
+ if (item instanceof ImageRun_js_1.ImageRun || item instanceof Shape_js_1.Shape || item instanceof RangeMarker_js_1.RangeMarker) {
8939
+ return false;
8940
+ }
8941
+ }
8942
+ return true;
8943
+ }
8364
8944
  setLanguage(language) {
8365
8945
  if (!this.properties) {
8366
8946
  this.properties = {};
8367
8947
  }
8368
8948
  this.properties.language = language;
8949
+ this._corePropsModified = true;
8369
8950
  return this;
8370
8951
  }
8371
8952
  getLanguage() {
@@ -8481,32 +9062,6 @@ class Document {
8481
9062
  pattern.lastIndex = 0;
8482
9063
  }
8483
9064
  }
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
9065
  return replacedCount;
8511
9066
  }
8512
9067
  static createEmpty() {