docxmlater 10.1.3 → 10.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (371) hide show
  1. package/README.md +759 -754
  2. package/dist/constants/legacyCompatFlags.js +1 -1
  3. package/dist/constants/legacyCompatFlags.js.map +1 -1
  4. package/dist/constants/limits.js.map +1 -1
  5. package/dist/core/Document.d.ts +50 -50
  6. package/dist/core/Document.d.ts.map +1 -1
  7. package/dist/core/Document.js +483 -471
  8. package/dist/core/Document.js.map +1 -1
  9. package/dist/core/DocumentContent.d.ts +9 -9
  10. package/dist/core/DocumentContent.d.ts.map +1 -1
  11. package/dist/core/DocumentContent.js +1 -1
  12. package/dist/core/DocumentContent.js.map +1 -1
  13. package/dist/core/DocumentGenerator.d.ts +11 -11
  14. package/dist/core/DocumentGenerator.d.ts.map +1 -1
  15. package/dist/core/DocumentGenerator.js +251 -251
  16. package/dist/core/DocumentGenerator.js.map +1 -1
  17. package/dist/core/DocumentIdManager.js.map +1 -1
  18. package/dist/core/DocumentParser.d.ts +15 -15
  19. package/dist/core/DocumentParser.d.ts.map +1 -1
  20. package/dist/core/DocumentParser.js +2123 -2155
  21. package/dist/core/DocumentParser.js.map +1 -1
  22. package/dist/core/DocumentValidator.d.ts.map +1 -1
  23. package/dist/core/DocumentValidator.js +2 -5
  24. package/dist/core/DocumentValidator.js.map +1 -1
  25. package/dist/core/Relationship.js.map +1 -1
  26. package/dist/core/RelationshipManager.d.ts.map +1 -1
  27. package/dist/core/RelationshipManager.js +3 -3
  28. package/dist/core/RelationshipManager.js.map +1 -1
  29. package/dist/elements/AlternateContent.js.map +1 -1
  30. package/dist/elements/Bookmark.d.ts.map +1 -1
  31. package/dist/elements/Bookmark.js +3 -1
  32. package/dist/elements/Bookmark.js.map +1 -1
  33. package/dist/elements/BookmarkManager.d.ts.map +1 -1
  34. package/dist/elements/BookmarkManager.js.map +1 -1
  35. package/dist/elements/Comment.d.ts.map +1 -1
  36. package/dist/elements/Comment.js +9 -6
  37. package/dist/elements/Comment.js.map +1 -1
  38. package/dist/elements/CommentManager.d.ts.map +1 -1
  39. package/dist/elements/CommentManager.js +18 -17
  40. package/dist/elements/CommentManager.js.map +1 -1
  41. package/dist/elements/CommonTypes.d.ts +21 -21
  42. package/dist/elements/CommonTypes.d.ts.map +1 -1
  43. package/dist/elements/CommonTypes.js +56 -56
  44. package/dist/elements/CommonTypes.js.map +1 -1
  45. package/dist/elements/CustomXml.js.map +1 -1
  46. package/dist/elements/Endnote.d.ts.map +1 -1
  47. package/dist/elements/Endnote.js +6 -6
  48. package/dist/elements/Endnote.js.map +1 -1
  49. package/dist/elements/EndnoteManager.d.ts.map +1 -1
  50. package/dist/elements/EndnoteManager.js +6 -7
  51. package/dist/elements/EndnoteManager.js.map +1 -1
  52. package/dist/elements/Field.d.ts.map +1 -1
  53. package/dist/elements/Field.js +82 -25
  54. package/dist/elements/Field.js.map +1 -1
  55. package/dist/elements/FieldHelpers.d.ts.map +1 -1
  56. package/dist/elements/FieldHelpers.js.map +1 -1
  57. package/dist/elements/FontManager.d.ts.map +1 -1
  58. package/dist/elements/FontManager.js +1 -1
  59. package/dist/elements/FontManager.js.map +1 -1
  60. package/dist/elements/Footer.js +2 -2
  61. package/dist/elements/Footer.js.map +1 -1
  62. package/dist/elements/Footnote.d.ts.map +1 -1
  63. package/dist/elements/Footnote.js +6 -6
  64. package/dist/elements/Footnote.js.map +1 -1
  65. package/dist/elements/FootnoteManager.d.ts.map +1 -1
  66. package/dist/elements/FootnoteManager.js +6 -7
  67. package/dist/elements/FootnoteManager.js.map +1 -1
  68. package/dist/elements/Header.js +2 -2
  69. package/dist/elements/Header.js.map +1 -1
  70. package/dist/elements/HeaderFooterManager.js.map +1 -1
  71. package/dist/elements/Hyperlink.d.ts +5 -3
  72. package/dist/elements/Hyperlink.d.ts.map +1 -1
  73. package/dist/elements/Hyperlink.js +134 -76
  74. package/dist/elements/Hyperlink.js.map +1 -1
  75. package/dist/elements/Image.d.ts.map +1 -1
  76. package/dist/elements/Image.js +238 -106
  77. package/dist/elements/Image.js.map +1 -1
  78. package/dist/elements/ImageManager.d.ts.map +1 -1
  79. package/dist/elements/ImageManager.js +1 -1
  80. package/dist/elements/ImageManager.js.map +1 -1
  81. package/dist/elements/ImageRun.js +1 -1
  82. package/dist/elements/ImageRun.js.map +1 -1
  83. package/dist/elements/MathElement.js.map +1 -1
  84. package/dist/elements/Paragraph.d.ts +24 -24
  85. package/dist/elements/Paragraph.d.ts.map +1 -1
  86. package/dist/elements/Paragraph.js +181 -188
  87. package/dist/elements/Paragraph.js.map +1 -1
  88. package/dist/elements/PreservedElement.js.map +1 -1
  89. package/dist/elements/PropertyChangeTypes.d.ts.map +1 -1
  90. package/dist/elements/PropertyChangeTypes.js +6 -6
  91. package/dist/elements/PropertyChangeTypes.js.map +1 -1
  92. package/dist/elements/RangeMarker.d.ts.map +1 -1
  93. package/dist/elements/RangeMarker.js.map +1 -1
  94. package/dist/elements/Revision.d.ts.map +1 -1
  95. package/dist/elements/Revision.js +4 -5
  96. package/dist/elements/Revision.js.map +1 -1
  97. package/dist/elements/RevisionContent.js.map +1 -1
  98. package/dist/elements/RevisionManager.d.ts.map +1 -1
  99. package/dist/elements/RevisionManager.js +40 -48
  100. package/dist/elements/RevisionManager.js.map +1 -1
  101. package/dist/elements/Run.d.ts +16 -16
  102. package/dist/elements/Run.d.ts.map +1 -1
  103. package/dist/elements/Run.js +256 -238
  104. package/dist/elements/Run.js.map +1 -1
  105. package/dist/elements/Section.d.ts.map +1 -1
  106. package/dist/elements/Section.js +36 -11
  107. package/dist/elements/Section.js.map +1 -1
  108. package/dist/elements/Shape.d.ts.map +1 -1
  109. package/dist/elements/Shape.js.map +1 -1
  110. package/dist/elements/StructuredDocumentTag.d.ts +6 -6
  111. package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
  112. package/dist/elements/StructuredDocumentTag.js +99 -104
  113. package/dist/elements/StructuredDocumentTag.js.map +1 -1
  114. package/dist/elements/Table.d.ts +11 -11
  115. package/dist/elements/Table.d.ts.map +1 -1
  116. package/dist/elements/Table.js +102 -107
  117. package/dist/elements/Table.js.map +1 -1
  118. package/dist/elements/TableCell.d.ts +10 -10
  119. package/dist/elements/TableCell.d.ts.map +1 -1
  120. package/dist/elements/TableCell.js +105 -106
  121. package/dist/elements/TableCell.js.map +1 -1
  122. package/dist/elements/TableGridChange.d.ts.map +1 -1
  123. package/dist/elements/TableGridChange.js.map +1 -1
  124. package/dist/elements/TableOfContents.d.ts.map +1 -1
  125. package/dist/elements/TableOfContents.js +4 -4
  126. package/dist/elements/TableOfContents.js.map +1 -1
  127. package/dist/elements/TableOfContentsElement.js.map +1 -1
  128. package/dist/elements/TableRow.d.ts.map +1 -1
  129. package/dist/elements/TableRow.js +13 -6
  130. package/dist/elements/TableRow.js.map +1 -1
  131. package/dist/elements/TextBox.d.ts.map +1 -1
  132. package/dist/elements/TextBox.js +3 -5
  133. package/dist/elements/TextBox.js.map +1 -1
  134. package/dist/formatting/AbstractNumbering.d.ts +4 -4
  135. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  136. package/dist/formatting/AbstractNumbering.js +54 -49
  137. package/dist/formatting/AbstractNumbering.js.map +1 -1
  138. package/dist/formatting/NumberingInstance.d.ts.map +1 -1
  139. package/dist/formatting/NumberingInstance.js +1 -3
  140. package/dist/formatting/NumberingInstance.js.map +1 -1
  141. package/dist/formatting/NumberingLevel.d.ts +5 -5
  142. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  143. package/dist/formatting/NumberingLevel.js +119 -125
  144. package/dist/formatting/NumberingLevel.js.map +1 -1
  145. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  146. package/dist/formatting/NumberingManager.js +9 -9
  147. package/dist/formatting/NumberingManager.js.map +1 -1
  148. package/dist/formatting/Style.d.ts +11 -11
  149. package/dist/formatting/Style.d.ts.map +1 -1
  150. package/dist/formatting/Style.js +219 -247
  151. package/dist/formatting/Style.js.map +1 -1
  152. package/dist/formatting/StylesManager.d.ts +2 -2
  153. package/dist/formatting/StylesManager.d.ts.map +1 -1
  154. package/dist/formatting/StylesManager.js +96 -102
  155. package/dist/formatting/StylesManager.js.map +1 -1
  156. package/dist/helpers/CleanupHelper.d.ts +1 -1
  157. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  158. package/dist/helpers/CleanupHelper.js +6 -6
  159. package/dist/helpers/CleanupHelper.js.map +1 -1
  160. package/dist/images/ImageOptimizer.js +7 -7
  161. package/dist/images/ImageOptimizer.js.map +1 -1
  162. package/dist/index.d.ts +9 -9
  163. package/dist/index.d.ts.map +1 -1
  164. package/dist/index.js.map +1 -1
  165. package/dist/managers/DrawingManager.js.map +1 -1
  166. package/dist/tracking/DocumentTrackingContext.d.ts.map +1 -1
  167. package/dist/tracking/DocumentTrackingContext.js +23 -7
  168. package/dist/tracking/DocumentTrackingContext.js.map +1 -1
  169. package/dist/tracking/TrackingContext.d.ts.map +1 -1
  170. package/dist/tracking/TrackingContext.js.map +1 -1
  171. package/dist/types/compatibility-types.js.map +1 -1
  172. package/dist/types/formatting.js.map +1 -1
  173. package/dist/types/list-types.d.ts +6 -6
  174. package/dist/types/list-types.js.map +1 -1
  175. package/dist/types/settings-types.js.map +1 -1
  176. package/dist/types/styleConfig.d.ts +2 -2
  177. package/dist/types/styleConfig.js.map +1 -1
  178. package/dist/utils/ChangelogGenerator.d.ts.map +1 -1
  179. package/dist/utils/ChangelogGenerator.js +97 -101
  180. package/dist/utils/ChangelogGenerator.js.map +1 -1
  181. package/dist/utils/CompatibilityUpgrader.d.ts.map +1 -1
  182. package/dist/utils/CompatibilityUpgrader.js +1 -1
  183. package/dist/utils/CompatibilityUpgrader.js.map +1 -1
  184. package/dist/utils/InMemoryRevisionAcceptor.d.ts.map +1 -1
  185. package/dist/utils/InMemoryRevisionAcceptor.js +1 -6
  186. package/dist/utils/InMemoryRevisionAcceptor.js.map +1 -1
  187. package/dist/utils/MoveOperationHelper.d.ts.map +1 -1
  188. package/dist/utils/MoveOperationHelper.js +1 -1
  189. package/dist/utils/MoveOperationHelper.js.map +1 -1
  190. package/dist/utils/RevisionAwareProcessor.d.ts.map +1 -1
  191. package/dist/utils/RevisionAwareProcessor.js +2 -4
  192. package/dist/utils/RevisionAwareProcessor.js.map +1 -1
  193. package/dist/utils/RevisionWalker.d.ts.map +1 -1
  194. package/dist/utils/RevisionWalker.js +4 -12
  195. package/dist/utils/RevisionWalker.js.map +1 -1
  196. package/dist/utils/SelectiveRevisionAcceptor.d.ts.map +1 -1
  197. package/dist/utils/SelectiveRevisionAcceptor.js +2 -6
  198. package/dist/utils/SelectiveRevisionAcceptor.js.map +1 -1
  199. package/dist/utils/ShadingResolver.d.ts.map +1 -1
  200. package/dist/utils/ShadingResolver.js +1 -1
  201. package/dist/utils/ShadingResolver.js.map +1 -1
  202. package/dist/utils/acceptRevisions.d.ts.map +1 -1
  203. package/dist/utils/acceptRevisions.js +23 -12
  204. package/dist/utils/acceptRevisions.js.map +1 -1
  205. package/dist/utils/cnfStyleDecoder.d.ts +1 -1
  206. package/dist/utils/cnfStyleDecoder.d.ts.map +1 -1
  207. package/dist/utils/cnfStyleDecoder.js +40 -40
  208. package/dist/utils/cnfStyleDecoder.js.map +1 -1
  209. package/dist/utils/corruptionDetection.d.ts.map +1 -1
  210. package/dist/utils/corruptionDetection.js.map +1 -1
  211. package/dist/utils/dateFormatting.js.map +1 -1
  212. package/dist/utils/deepClone.js +1 -1
  213. package/dist/utils/deepClone.js.map +1 -1
  214. package/dist/utils/diagnostics.d.ts.map +1 -1
  215. package/dist/utils/diagnostics.js +1 -1
  216. package/dist/utils/diagnostics.js.map +1 -1
  217. package/dist/utils/errorHandling.js.map +1 -1
  218. package/dist/utils/formatting.d.ts.map +1 -1
  219. package/dist/utils/formatting.js +10 -2
  220. package/dist/utils/formatting.js.map +1 -1
  221. package/dist/utils/list-detection.d.ts +2 -2
  222. package/dist/utils/list-detection.d.ts.map +1 -1
  223. package/dist/utils/list-detection.js +21 -23
  224. package/dist/utils/list-detection.js.map +1 -1
  225. package/dist/utils/logger.d.ts.map +1 -1
  226. package/dist/utils/logger.js +12 -7
  227. package/dist/utils/logger.js.map +1 -1
  228. package/dist/utils/parsingHelpers.js.map +1 -1
  229. package/dist/utils/stripTrackedChanges.d.ts.map +1 -1
  230. package/dist/utils/stripTrackedChanges.js +3 -3
  231. package/dist/utils/stripTrackedChanges.js.map +1 -1
  232. package/dist/utils/textDiff.d.ts +1 -1
  233. package/dist/utils/textDiff.js +8 -8
  234. package/dist/utils/textDiff.js.map +1 -1
  235. package/dist/utils/units.js.map +1 -1
  236. package/dist/utils/validation.d.ts.map +1 -1
  237. package/dist/utils/validation.js +24 -7
  238. package/dist/utils/validation.js.map +1 -1
  239. package/dist/utils/xmlSanitization.d.ts.map +1 -1
  240. package/dist/utils/xmlSanitization.js +3 -3
  241. package/dist/utils/xmlSanitization.js.map +1 -1
  242. package/dist/validation/RevisionAutoFixer.d.ts.map +1 -1
  243. package/dist/validation/RevisionAutoFixer.js +5 -5
  244. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  245. package/dist/validation/RevisionValidator.d.ts.map +1 -1
  246. package/dist/validation/RevisionValidator.js +7 -9
  247. package/dist/validation/RevisionValidator.js.map +1 -1
  248. package/dist/validation/ValidationRules.js +3 -3
  249. package/dist/validation/ValidationRules.js.map +1 -1
  250. package/dist/validation/index.js.map +1 -1
  251. package/dist/xml/XMLBuilder.d.ts +1 -1
  252. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  253. package/dist/xml/XMLBuilder.js +98 -100
  254. package/dist/xml/XMLBuilder.js.map +1 -1
  255. package/dist/xml/XMLParser.d.ts.map +1 -1
  256. package/dist/xml/XMLParser.js +61 -66
  257. package/dist/xml/XMLParser.js.map +1 -1
  258. package/dist/zip/ZipHandler.d.ts.map +1 -1
  259. package/dist/zip/ZipHandler.js.map +1 -1
  260. package/dist/zip/ZipReader.d.ts.map +1 -1
  261. package/dist/zip/ZipReader.js +1 -3
  262. package/dist/zip/ZipReader.js.map +1 -1
  263. package/dist/zip/ZipWriter.d.ts +1 -1
  264. package/dist/zip/ZipWriter.d.ts.map +1 -1
  265. package/dist/zip/ZipWriter.js +28 -36
  266. package/dist/zip/ZipWriter.js.map +1 -1
  267. package/dist/zip/types.js +1 -1
  268. package/dist/zip/types.js.map +1 -1
  269. package/package.json +92 -92
  270. package/src/__tests__/helper-methods.test.ts +512 -512
  271. package/src/constants/legacyCompatFlags.ts +138 -138
  272. package/src/constants/limits.ts +50 -50
  273. package/src/core/Document.ts +985 -1145
  274. package/src/core/DocumentContent.ts +461 -467
  275. package/src/core/DocumentGenerator.ts +1133 -1104
  276. package/src/core/DocumentIdManager.ts +158 -158
  277. package/src/core/DocumentParser.ts +2347 -2716
  278. package/src/core/DocumentValidator.ts +363 -372
  279. package/src/core/Relationship.ts +367 -367
  280. package/src/core/RelationshipManager.ts +429 -428
  281. package/src/elements/AlternateContent.ts +42 -42
  282. package/src/elements/Bookmark.ts +212 -210
  283. package/src/elements/BookmarkManager.ts +247 -250
  284. package/src/elements/Comment.ts +356 -359
  285. package/src/elements/CommentManager.ts +499 -502
  286. package/src/elements/CommonTypes.ts +524 -549
  287. package/src/elements/CustomXml.ts +36 -36
  288. package/src/elements/Endnote.ts +221 -217
  289. package/src/elements/EndnoteManager.ts +246 -249
  290. package/src/elements/Field.ts +1292 -1233
  291. package/src/elements/FieldHelpers.ts +329 -333
  292. package/src/elements/FontManager.ts +336 -339
  293. package/src/elements/Footer.ts +269 -269
  294. package/src/elements/Footnote.ts +221 -217
  295. package/src/elements/FootnoteManager.ts +246 -249
  296. package/src/elements/Header.ts +269 -269
  297. package/src/elements/HeaderFooterManager.ts +219 -219
  298. package/src/elements/Hyperlink.ts +1288 -1193
  299. package/src/elements/Image.ts +1982 -1756
  300. package/src/elements/ImageManager.ts +437 -432
  301. package/src/elements/ImageRun.ts +59 -59
  302. package/src/elements/MathElement.ts +65 -65
  303. package/src/elements/Paragraph.ts +4347 -4287
  304. package/src/elements/PreservedElement.ts +53 -53
  305. package/src/elements/PropertyChangeTypes.ts +458 -442
  306. package/src/elements/RangeMarker.ts +382 -400
  307. package/src/elements/Revision.ts +1198 -1217
  308. package/src/elements/RevisionContent.ts +73 -73
  309. package/src/elements/RevisionManager.ts +1070 -1070
  310. package/src/elements/Run.ts +3103 -3073
  311. package/src/elements/Section.ts +1521 -1421
  312. package/src/elements/Shape.ts +884 -873
  313. package/src/elements/StructuredDocumentTag.ts +1176 -1207
  314. package/src/elements/Table.ts +2468 -2524
  315. package/src/elements/TableCell.ts +1617 -1621
  316. package/src/elements/TableGridChange.ts +149 -151
  317. package/src/elements/TableOfContents.ts +701 -691
  318. package/src/elements/TableOfContentsElement.ts +89 -89
  319. package/src/elements/TableRow.ts +960 -929
  320. package/src/elements/TextBox.ts +766 -768
  321. package/src/formatting/AbstractNumbering.ts +580 -579
  322. package/src/formatting/NumberingInstance.ts +295 -299
  323. package/src/formatting/NumberingLevel.ts +981 -1040
  324. package/src/formatting/NumberingManager.ts +833 -827
  325. package/src/formatting/Style.ts +1785 -1879
  326. package/src/formatting/StylesManager.ts +1090 -1130
  327. package/src/helpers/CleanupHelper.ts +524 -524
  328. package/src/images/ImageOptimizer.ts +274 -274
  329. package/src/index.ts +559 -554
  330. package/src/managers/DrawingManager.ts +319 -319
  331. package/src/tracking/DocumentTrackingContext.ts +687 -674
  332. package/src/tracking/TrackingContext.ts +175 -173
  333. package/src/types/compatibility-types.ts +49 -49
  334. package/src/types/formatting.ts +210 -210
  335. package/src/types/list-types.ts +14 -14
  336. package/src/types/settings-types.ts +59 -59
  337. package/src/types/styleConfig.ts +189 -189
  338. package/src/utils/ChangelogGenerator.ts +1583 -1581
  339. package/src/utils/CompatibilityUpgrader.ts +235 -237
  340. package/src/utils/InMemoryRevisionAcceptor.ts +691 -696
  341. package/src/utils/MoveOperationHelper.ts +233 -238
  342. package/src/utils/RevisionAwareProcessor.ts +518 -526
  343. package/src/utils/RevisionWalker.ts +427 -457
  344. package/src/utils/SelectiveRevisionAcceptor.ts +662 -683
  345. package/src/utils/ShadingResolver.ts +105 -107
  346. package/src/utils/acceptRevisions.ts +723 -714
  347. package/src/utils/cnfStyleDecoder.ts +212 -217
  348. package/src/utils/corruptionDetection.ts +346 -345
  349. package/src/utils/dateFormatting.ts +20 -20
  350. package/src/utils/deepClone.ts +77 -78
  351. package/src/utils/diagnostics.ts +125 -129
  352. package/src/utils/errorHandling.ts +80 -80
  353. package/src/utils/formatting.ts +220 -213
  354. package/src/utils/list-detection.ts +32 -42
  355. package/src/utils/logger.ts +412 -404
  356. package/src/utils/parsingHelpers.ts +190 -190
  357. package/src/utils/stripTrackedChanges.ts +356 -353
  358. package/src/utils/textDiff.ts +100 -100
  359. package/src/utils/units.ts +421 -421
  360. package/src/utils/validation.ts +553 -542
  361. package/src/utils/xmlSanitization.ts +179 -182
  362. package/src/validation/RevisionAutoFixer.ts +541 -542
  363. package/src/validation/RevisionValidator.ts +470 -460
  364. package/src/validation/ValidationRules.ts +338 -338
  365. package/src/validation/index.ts +30 -30
  366. package/src/xml/XMLBuilder.ts +857 -871
  367. package/src/xml/XMLParser.ts +877 -919
  368. package/src/zip/ZipHandler.ts +629 -637
  369. package/src/zip/ZipReader.ts +295 -299
  370. package/src/zip/ZipWriter.ts +374 -390
  371. package/src/zip/types.ts +116 -116
@@ -1,333 +1,329 @@
1
- /**
2
- * Helper functions for creating complex and nested fields
3
- */
4
-
5
- import { ComplexField } from './Field';
6
- import { defaultLogger } from '../utils/logger';
7
-
8
- /**
9
- * Parsed components of a HYPERLINK field instruction
10
- */
11
- export interface ParsedHyperlinkInstruction {
12
- /** Base URL (with encoded characters decoded) */
13
- url: string;
14
- /** Anchor/fragment from \l switch (decoded) */
15
- anchor?: string;
16
- /** Tooltip text from \o switch */
17
- tooltip?: string;
18
- /** Whether \h switch is present (creates hyperlink) */
19
- hasHSwitch: boolean;
20
- /** Combined full URL (url + "#" + anchor if both present) */
21
- fullUrl: string;
22
- /** Original raw instruction string */
23
- rawInstruction: string;
24
- }
25
-
26
- /**
27
- * Parses a HYPERLINK field instruction string into its components
28
- *
29
- * HYPERLINK field syntax per ECMA-376:
30
- * - HYPERLINK "url" - basic external hyperlink
31
- * - HYPERLINK \l "anchor" - anchor-only internal hyperlink (no URL)
32
- * - \l "anchor" - specifies a location (anchor/fragment) within the target
33
- * - \o "tooltip" - specifies the tooltip/screentip text
34
- * - \h - creates a hyperlink (always present for clickable links)
35
- * - \n - opens link in new window
36
- * - \t "target" - specifies target frame
37
- *
38
- * @param instruction The raw field instruction string (e.g., 'HYPERLINK "url" \l "anchor" \h')
39
- * @returns Parsed components or null if not a valid HYPERLINK instruction
40
- *
41
- * @example
42
- * ```typescript
43
- * // External hyperlink with anchor
44
- * const result = parseHyperlinkInstruction('HYPERLINK "https://example.com/" \\l "section1" \\h');
45
- * // result.url = "https://example.com/"
46
- * // result.anchor = "section1"
47
- * // result.fullUrl = "https://example.com/#section1"
48
- *
49
- * // Anchor-only internal hyperlink (e.g., "Top of the Document")
50
- * const result2 = parseHyperlinkInstruction('HYPERLINK \\l "_top" \\h');
51
- * // result2.url = ""
52
- * // result2.anchor = "_top"
53
- * // result2.fullUrl = "#_top"
54
- * ```
55
- */
56
- export function parseHyperlinkInstruction(instruction: string): ParsedHyperlinkInstruction | null {
57
- if (!instruction) {
58
- return null;
59
- }
60
-
61
- // Normalize whitespace and trim
62
- const normalized = instruction.trim();
63
-
64
- // Check if this is a HYPERLINK instruction
65
- if (!normalized.toUpperCase().startsWith('HYPERLINK')) {
66
- return null;
67
- }
68
-
69
- // Extract the URL (first quoted string after HYPERLINK, before any switches)
70
- // URL is optional - anchor-only hyperlinks like 'HYPERLINK \l "_top"' are valid
71
- let url = '';
72
- const urlMatch = /HYPERLINK\s+"([^"]*)"/i.exec(normalized);
73
- if (urlMatch?.[1] !== undefined) {
74
- url = urlMatch[1];
75
- // Decode URL-encoded characters
76
- try {
77
- url = decodeURIComponent(url);
78
- } catch (e) {
79
- defaultLogger.debug(`[FieldHelpers] Failed to decode URL: ${url}`);
80
- }
81
- }
82
-
83
- // Extract \l switch (anchor/fragment)
84
- let anchor: string | undefined;
85
- const anchorMatch = /\\l\s+"([^"]*)"/i.exec(normalized);
86
- if (anchorMatch?.[1] !== undefined) {
87
- anchor = anchorMatch[1];
88
- // Decode anchor as well
89
- try {
90
- anchor = decodeURIComponent(anchor);
91
- } catch (e) {
92
- defaultLogger.debug(`[FieldHelpers] Failed to decode anchor: ${anchor}`);
93
- }
94
- }
95
-
96
- // Must have either URL or anchor to be valid
97
- if (!url && !anchor) {
98
- return null;
99
- }
100
-
101
- // Extract \o switch (tooltip)
102
- let tooltip: string | undefined;
103
- const tooltipMatch = /\\o\s+"([^"]*)"/i.exec(normalized);
104
- if (tooltipMatch?.[1] !== undefined) {
105
- tooltip = tooltipMatch[1];
106
- }
107
-
108
- // Check for \h switch
109
- const hasHSwitch = /\\h(?:\s|$)/i.test(normalized);
110
-
111
- // Build full URL by combining base URL and anchor
112
- let fullUrl: string = url;
113
- if (anchor) {
114
- // If URL already has a fragment, replace it; otherwise append
115
- const hashIndex = url.indexOf('#');
116
- if (hashIndex >= 0) {
117
- fullUrl = url.substring(0, hashIndex) + '#' + anchor;
118
- } else if (url) {
119
- fullUrl = url + '#' + anchor;
120
- } else {
121
- // Anchor-only: just use #anchor
122
- fullUrl = '#' + anchor;
123
- }
124
- }
125
-
126
- return {
127
- url,
128
- anchor,
129
- tooltip,
130
- hasHSwitch,
131
- fullUrl,
132
- rawInstruction: instruction,
133
- };
134
- }
135
-
136
- /**
137
- * Creates a HYPERLINK field instruction string from components
138
- *
139
- * @param url The target URL
140
- * @param anchor Optional anchor/fragment (will use \l switch)
141
- * @param tooltip Optional tooltip text (will use \o switch)
142
- * @returns Properly formatted HYPERLINK instruction string
143
- *
144
- * @example
145
- * ```typescript
146
- * const instr = buildHyperlinkInstruction('https://example.com/', 'section1', 'Click here');
147
- * // Returns: 'HYPERLINK "https://example.com/" \\l "section1" \\o "Click here" \\h'
148
- * ```
149
- */
150
- export function buildHyperlinkInstruction(
151
- url: string,
152
- anchor?: string,
153
- tooltip?: string
154
- ): string {
155
- let instruction = `HYPERLINK "${url}"`;
156
-
157
- if (anchor) {
158
- instruction += ` \\l "${anchor}"`;
159
- }
160
-
161
- if (tooltip) {
162
- instruction += ` \\o "${tooltip}"`;
163
- }
164
-
165
- // Always add \h switch for clickable hyperlinks
166
- instruction += ' \\h';
167
-
168
- return instruction;
169
- }
170
-
171
- /**
172
- * Checks if a field instruction is a HYPERLINK field
173
- *
174
- * @param instruction The field instruction to check
175
- * @returns True if the instruction is a HYPERLINK field
176
- */
177
- export function isHyperlinkInstruction(instruction: string): boolean {
178
- if (!instruction) {
179
- return false;
180
- }
181
- return instruction.trim().toUpperCase().startsWith('HYPERLINK');
182
- }
183
-
184
- /**
185
- * Creates a nested IF field containing a MERGEFIELD
186
- * This is a common pattern for conditional mail merge
187
- *
188
- * @param condition The IF condition (e.g., 'Status = "Active"')
189
- * @param mergeFieldName The merge field name to include
190
- * @param trueText Text to show when condition is true
191
- * @param falseText Text to show when condition is false
192
- * @returns ComplexField with nested MERGEFIELD
193
- *
194
- * @example
195
- * ```typescript
196
- * const field = createNestedIFMergeField('Status = "Active"', 'Name', 'Active: ', 'Inactive');
197
- * // Result: IF field that shows "Active: [Name]" if Status is Active, otherwise "Inactive"
198
- * ```
199
- */
200
- export function createNestedIFMergeField(
201
- condition: string,
202
- mergeFieldName: string,
203
- trueText = '',
204
- falseText = ''
205
- ): ComplexField {
206
- // Create the nested MERGEFIELD
207
- const mergeField = new ComplexField({
208
- instruction: ` MERGEFIELD ${mergeFieldName} `,
209
- result: `[${mergeFieldName}]`,
210
- });
211
-
212
- // Create the IF field with nested MERGEFIELD
213
- const ifField = new ComplexField({
214
- instruction: ` IF ${condition} "${trueText}" "${falseText}" `,
215
- result: trueText || falseText,
216
- });
217
-
218
- ifField.addNestedField(mergeField);
219
-
220
- return ifField;
221
- }
222
-
223
- /**
224
- * Creates a MERGEFIELD with custom formatting
225
- *
226
- * @param fieldName The merge field name
227
- * @param format Optional format switches
228
- * @returns ComplexField for MERGEFIELD
229
- *
230
- * @example
231
- * ```typescript
232
- * const field = createMergeField('Date', '\\@ "MMMM d, yyyy"');
233
- * ```
234
- */
235
- export function createMergeField(fieldName: string, format?: string): ComplexField {
236
- let instruction = ` MERGEFIELD ${fieldName}`;
237
-
238
- if (format) {
239
- instruction += ` ${format}`;
240
- }
241
-
242
- instruction += ' \\* MERGEFORMAT ';
243
-
244
- return new ComplexField({
245
- instruction,
246
- result: `[${fieldName}]`,
247
- });
248
- }
249
-
250
- /**
251
- * Creates a REF field with a nested field in the bookmark reference
252
- * Used for complex cross-references
253
- *
254
- * @param bookmarkName The bookmark to reference
255
- * @param format Optional format switches
256
- * @returns ComplexField for REF
257
- *
258
- * @example
259
- * ```typescript
260
- * const field = createRefField('Chapter1', '\\h');
261
- * ```
262
- */
263
- export function createRefField(bookmarkName: string, format?: string): ComplexField {
264
- let instruction = ` REF ${bookmarkName}`;
265
-
266
- if (format) {
267
- instruction += ` ${format}`;
268
- } else {
269
- instruction += ' \\h'; // Hyperlink by default
270
- }
271
-
272
- instruction += ' \\* MERGEFORMAT ';
273
-
274
- return new ComplexField({
275
- instruction,
276
- result: `[${bookmarkName}]`,
277
- });
278
- }
279
-
280
- /**
281
- * Creates an IF field with custom true/false branches
282
- *
283
- * @param condition The condition to evaluate
284
- * @param trueContent Content to show when true
285
- * @param falseContent Content to show when false
286
- * @returns ComplexField for IF
287
- *
288
- * @example
289
- * ```typescript
290
- * const field = createIFField('Amount > 1000', 'High Value', 'Normal');
291
- * ```
292
- */
293
- export function createIFField(
294
- condition: string,
295
- trueContent: string,
296
- falseContent = ''
297
- ): ComplexField {
298
- const instruction = ` IF ${condition} "${trueContent}" "${falseContent}" `;
299
-
300
- return new ComplexField({
301
- instruction,
302
- result: trueContent,
303
- });
304
- }
305
-
306
- /**
307
- * Creates a complex nested field structure with multiple levels
308
- * Useful for advanced scenarios like nested IF statements
309
- *
310
- * @param outerInstruction The outer field instruction
311
- * @param nestedFields Array of nested fields to include
312
- * @returns ComplexField with nested structure
313
- *
314
- * @example
315
- * ```typescript
316
- * const innerField = createMergeField('Amount');
317
- * const field = createNestedField('IF Amount > 0', [innerField]);
318
- * ```
319
- */
320
- export function createNestedField(
321
- outerInstruction: string,
322
- nestedFields: ComplexField[]
323
- ): ComplexField {
324
- const field = new ComplexField({
325
- instruction: outerInstruction,
326
- });
327
-
328
- for (const nested of nestedFields) {
329
- field.addNestedField(nested);
330
- }
331
-
332
- return field;
333
- }
1
+ /**
2
+ * Helper functions for creating complex and nested fields
3
+ */
4
+
5
+ import { ComplexField } from './Field';
6
+ import { defaultLogger } from '../utils/logger';
7
+
8
+ /**
9
+ * Parsed components of a HYPERLINK field instruction
10
+ */
11
+ export interface ParsedHyperlinkInstruction {
12
+ /** Base URL (with encoded characters decoded) */
13
+ url: string;
14
+ /** Anchor/fragment from \l switch (decoded) */
15
+ anchor?: string;
16
+ /** Tooltip text from \o switch */
17
+ tooltip?: string;
18
+ /** Whether \h switch is present (creates hyperlink) */
19
+ hasHSwitch: boolean;
20
+ /** Combined full URL (url + "#" + anchor if both present) */
21
+ fullUrl: string;
22
+ /** Original raw instruction string */
23
+ rawInstruction: string;
24
+ }
25
+
26
+ /**
27
+ * Parses a HYPERLINK field instruction string into its components
28
+ *
29
+ * HYPERLINK field syntax per ECMA-376:
30
+ * - HYPERLINK "url" - basic external hyperlink
31
+ * - HYPERLINK \l "anchor" - anchor-only internal hyperlink (no URL)
32
+ * - \l "anchor" - specifies a location (anchor/fragment) within the target
33
+ * - \o "tooltip" - specifies the tooltip/screentip text
34
+ * - \h - creates a hyperlink (always present for clickable links)
35
+ * - \n - opens link in new window
36
+ * - \t "target" - specifies target frame
37
+ *
38
+ * @param instruction The raw field instruction string (e.g., 'HYPERLINK "url" \l "anchor" \h')
39
+ * @returns Parsed components or null if not a valid HYPERLINK instruction
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * // External hyperlink with anchor
44
+ * const result = parseHyperlinkInstruction('HYPERLINK "https://example.com/" \\l "section1" \\h');
45
+ * // result.url = "https://example.com/"
46
+ * // result.anchor = "section1"
47
+ * // result.fullUrl = "https://example.com/#section1"
48
+ *
49
+ * // Anchor-only internal hyperlink (e.g., "Top of the Document")
50
+ * const result2 = parseHyperlinkInstruction('HYPERLINK \\l "_top" \\h');
51
+ * // result2.url = ""
52
+ * // result2.anchor = "_top"
53
+ * // result2.fullUrl = "#_top"
54
+ * ```
55
+ */
56
+ export function parseHyperlinkInstruction(instruction: string): ParsedHyperlinkInstruction | null {
57
+ if (!instruction) {
58
+ return null;
59
+ }
60
+
61
+ // Normalize whitespace and trim
62
+ const normalized = instruction.trim();
63
+
64
+ // Check if this is a HYPERLINK instruction
65
+ if (!normalized.toUpperCase().startsWith('HYPERLINK')) {
66
+ return null;
67
+ }
68
+
69
+ // Extract the URL (first quoted string after HYPERLINK, before any switches)
70
+ // URL is optional - anchor-only hyperlinks like 'HYPERLINK \l "_top"' are valid
71
+ let url = '';
72
+ const urlMatch = /HYPERLINK\s+"([^"]*)"/i.exec(normalized);
73
+ if (urlMatch?.[1] !== undefined) {
74
+ url = urlMatch[1];
75
+ // Decode URL-encoded characters
76
+ try {
77
+ url = decodeURIComponent(url);
78
+ } catch (e) {
79
+ defaultLogger.debug(`[FieldHelpers] Failed to decode URL: ${url}`);
80
+ }
81
+ }
82
+
83
+ // Extract \l switch (anchor/fragment)
84
+ let anchor: string | undefined;
85
+ const anchorMatch = /\\l\s+"([^"]*)"/i.exec(normalized);
86
+ if (anchorMatch?.[1] !== undefined) {
87
+ anchor = anchorMatch[1];
88
+ // Decode anchor as well
89
+ try {
90
+ anchor = decodeURIComponent(anchor);
91
+ } catch (e) {
92
+ defaultLogger.debug(`[FieldHelpers] Failed to decode anchor: ${anchor}`);
93
+ }
94
+ }
95
+
96
+ // Must have either URL or anchor to be valid
97
+ if (!url && !anchor) {
98
+ return null;
99
+ }
100
+
101
+ // Extract \o switch (tooltip)
102
+ let tooltip: string | undefined;
103
+ const tooltipMatch = /\\o\s+"([^"]*)"/i.exec(normalized);
104
+ if (tooltipMatch?.[1] !== undefined) {
105
+ tooltip = tooltipMatch[1];
106
+ }
107
+
108
+ // Check for \h switch
109
+ const hasHSwitch = /\\h(?:\s|$)/i.test(normalized);
110
+
111
+ // Build full URL by combining base URL and anchor
112
+ let fullUrl: string = url;
113
+ if (anchor) {
114
+ // If URL already has a fragment, replace it; otherwise append
115
+ const hashIndex = url.indexOf('#');
116
+ if (hashIndex >= 0) {
117
+ fullUrl = url.substring(0, hashIndex) + '#' + anchor;
118
+ } else if (url) {
119
+ fullUrl = url + '#' + anchor;
120
+ } else {
121
+ // Anchor-only: just use #anchor
122
+ fullUrl = '#' + anchor;
123
+ }
124
+ }
125
+
126
+ return {
127
+ url,
128
+ anchor,
129
+ tooltip,
130
+ hasHSwitch,
131
+ fullUrl,
132
+ rawInstruction: instruction,
133
+ };
134
+ }
135
+
136
+ /**
137
+ * Creates a HYPERLINK field instruction string from components
138
+ *
139
+ * @param url The target URL
140
+ * @param anchor Optional anchor/fragment (will use \l switch)
141
+ * @param tooltip Optional tooltip text (will use \o switch)
142
+ * @returns Properly formatted HYPERLINK instruction string
143
+ *
144
+ * @example
145
+ * ```typescript
146
+ * const instr = buildHyperlinkInstruction('https://example.com/', 'section1', 'Click here');
147
+ * // Returns: 'HYPERLINK "https://example.com/" \\l "section1" \\o "Click here" \\h'
148
+ * ```
149
+ */
150
+ export function buildHyperlinkInstruction(url: string, anchor?: string, tooltip?: string): string {
151
+ let instruction = `HYPERLINK "${url}"`;
152
+
153
+ if (anchor) {
154
+ instruction += ` \\l "${anchor}"`;
155
+ }
156
+
157
+ if (tooltip) {
158
+ instruction += ` \\o "${tooltip}"`;
159
+ }
160
+
161
+ // Always add \h switch for clickable hyperlinks
162
+ instruction += ' \\h';
163
+
164
+ return instruction;
165
+ }
166
+
167
+ /**
168
+ * Checks if a field instruction is a HYPERLINK field
169
+ *
170
+ * @param instruction The field instruction to check
171
+ * @returns True if the instruction is a HYPERLINK field
172
+ */
173
+ export function isHyperlinkInstruction(instruction: string): boolean {
174
+ if (!instruction) {
175
+ return false;
176
+ }
177
+ return instruction.trim().toUpperCase().startsWith('HYPERLINK');
178
+ }
179
+
180
+ /**
181
+ * Creates a nested IF field containing a MERGEFIELD
182
+ * This is a common pattern for conditional mail merge
183
+ *
184
+ * @param condition The IF condition (e.g., 'Status = "Active"')
185
+ * @param mergeFieldName The merge field name to include
186
+ * @param trueText Text to show when condition is true
187
+ * @param falseText Text to show when condition is false
188
+ * @returns ComplexField with nested MERGEFIELD
189
+ *
190
+ * @example
191
+ * ```typescript
192
+ * const field = createNestedIFMergeField('Status = "Active"', 'Name', 'Active: ', 'Inactive');
193
+ * // Result: IF field that shows "Active: [Name]" if Status is Active, otherwise "Inactive"
194
+ * ```
195
+ */
196
+ export function createNestedIFMergeField(
197
+ condition: string,
198
+ mergeFieldName: string,
199
+ trueText = '',
200
+ falseText = ''
201
+ ): ComplexField {
202
+ // Create the nested MERGEFIELD
203
+ const mergeField = new ComplexField({
204
+ instruction: ` MERGEFIELD ${mergeFieldName} `,
205
+ result: `[${mergeFieldName}]`,
206
+ });
207
+
208
+ // Create the IF field with nested MERGEFIELD
209
+ const ifField = new ComplexField({
210
+ instruction: ` IF ${condition} "${trueText}" "${falseText}" `,
211
+ result: trueText || falseText,
212
+ });
213
+
214
+ ifField.addNestedField(mergeField);
215
+
216
+ return ifField;
217
+ }
218
+
219
+ /**
220
+ * Creates a MERGEFIELD with custom formatting
221
+ *
222
+ * @param fieldName The merge field name
223
+ * @param format Optional format switches
224
+ * @returns ComplexField for MERGEFIELD
225
+ *
226
+ * @example
227
+ * ```typescript
228
+ * const field = createMergeField('Date', '\\@ "MMMM d, yyyy"');
229
+ * ```
230
+ */
231
+ export function createMergeField(fieldName: string, format?: string): ComplexField {
232
+ let instruction = ` MERGEFIELD ${fieldName}`;
233
+
234
+ if (format) {
235
+ instruction += ` ${format}`;
236
+ }
237
+
238
+ instruction += ' \\* MERGEFORMAT ';
239
+
240
+ return new ComplexField({
241
+ instruction,
242
+ result: `[${fieldName}]`,
243
+ });
244
+ }
245
+
246
+ /**
247
+ * Creates a REF field with a nested field in the bookmark reference
248
+ * Used for complex cross-references
249
+ *
250
+ * @param bookmarkName The bookmark to reference
251
+ * @param format Optional format switches
252
+ * @returns ComplexField for REF
253
+ *
254
+ * @example
255
+ * ```typescript
256
+ * const field = createRefField('Chapter1', '\\h');
257
+ * ```
258
+ */
259
+ export function createRefField(bookmarkName: string, format?: string): ComplexField {
260
+ let instruction = ` REF ${bookmarkName}`;
261
+
262
+ if (format) {
263
+ instruction += ` ${format}`;
264
+ } else {
265
+ instruction += ' \\h'; // Hyperlink by default
266
+ }
267
+
268
+ instruction += ' \\* MERGEFORMAT ';
269
+
270
+ return new ComplexField({
271
+ instruction,
272
+ result: `[${bookmarkName}]`,
273
+ });
274
+ }
275
+
276
+ /**
277
+ * Creates an IF field with custom true/false branches
278
+ *
279
+ * @param condition The condition to evaluate
280
+ * @param trueContent Content to show when true
281
+ * @param falseContent Content to show when false
282
+ * @returns ComplexField for IF
283
+ *
284
+ * @example
285
+ * ```typescript
286
+ * const field = createIFField('Amount > 1000', 'High Value', 'Normal');
287
+ * ```
288
+ */
289
+ export function createIFField(
290
+ condition: string,
291
+ trueContent: string,
292
+ falseContent = ''
293
+ ): ComplexField {
294
+ const instruction = ` IF ${condition} "${trueContent}" "${falseContent}" `;
295
+
296
+ return new ComplexField({
297
+ instruction,
298
+ result: trueContent,
299
+ });
300
+ }
301
+
302
+ /**
303
+ * Creates a complex nested field structure with multiple levels
304
+ * Useful for advanced scenarios like nested IF statements
305
+ *
306
+ * @param outerInstruction The outer field instruction
307
+ * @param nestedFields Array of nested fields to include
308
+ * @returns ComplexField with nested structure
309
+ *
310
+ * @example
311
+ * ```typescript
312
+ * const innerField = createMergeField('Amount');
313
+ * const field = createNestedField('IF Amount > 0', [innerField]);
314
+ * ```
315
+ */
316
+ export function createNestedField(
317
+ outerInstruction: string,
318
+ nestedFields: ComplexField[]
319
+ ): ComplexField {
320
+ const field = new ComplexField({
321
+ instruction: outerInstruction,
322
+ });
323
+
324
+ for (const nested of nestedFields) {
325
+ field.addNestedField(nested);
326
+ }
327
+
328
+ return field;
329
+ }