docxmlater 10.0.1 → 10.0.3

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 (395) hide show
  1. package/README.md +3 -2
  2. package/dist/constants/legacyCompatFlags.d.ts.map +1 -1
  3. package/dist/constants/legacyCompatFlags.js.map +1 -1
  4. package/dist/constants/limits.d.ts +0 -27
  5. package/dist/constants/limits.d.ts.map +1 -1
  6. package/dist/constants/limits.js +13 -13
  7. package/dist/constants/limits.js.map +1 -1
  8. package/dist/core/Document.d.ts +24 -19
  9. package/dist/core/Document.d.ts.map +1 -1
  10. package/dist/core/Document.js +272 -71
  11. package/dist/core/Document.js.map +1 -1
  12. package/dist/core/DocumentContent.d.ts.map +1 -1
  13. package/dist/core/DocumentContent.js.map +1 -1
  14. package/dist/core/DocumentGenerator.d.ts.map +1 -1
  15. package/dist/core/DocumentGenerator.js +59 -24
  16. package/dist/core/DocumentGenerator.js.map +1 -1
  17. package/dist/core/DocumentIdManager.d.ts.map +1 -1
  18. package/dist/core/DocumentIdManager.js.map +1 -1
  19. package/dist/core/DocumentParser.d.ts +6 -6
  20. package/dist/core/DocumentParser.d.ts.map +1 -1
  21. package/dist/core/DocumentParser.js +60 -54
  22. package/dist/core/DocumentParser.js.map +1 -1
  23. package/dist/core/DocumentValidator.d.ts.map +1 -1
  24. package/dist/core/DocumentValidator.js.map +1 -1
  25. package/dist/core/Relationship.d.ts.map +1 -1
  26. package/dist/core/Relationship.js +1 -1
  27. package/dist/core/Relationship.js.map +1 -1
  28. package/dist/core/RelationshipManager.js +3 -3
  29. package/dist/core/RelationshipManager.js.map +1 -1
  30. package/dist/elements/AlternateContent.js.map +1 -1
  31. package/dist/elements/Bookmark.d.ts.map +1 -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.js +1 -1
  36. package/dist/elements/Comment.js.map +1 -1
  37. package/dist/elements/CommentManager.d.ts.map +1 -1
  38. package/dist/elements/CommentManager.js +8 -2
  39. package/dist/elements/CommentManager.js.map +1 -1
  40. package/dist/elements/CommonTypes.d.ts.map +1 -1
  41. package/dist/elements/CommonTypes.js +1 -2
  42. package/dist/elements/CommonTypes.js.map +1 -1
  43. package/dist/elements/CustomXml.js.map +1 -1
  44. package/dist/elements/Endnote.d.ts.map +1 -1
  45. package/dist/elements/Endnote.js.map +1 -1
  46. package/dist/elements/EndnoteManager.d.ts.map +1 -1
  47. package/dist/elements/EndnoteManager.js.map +1 -1
  48. package/dist/elements/Field.d.ts.map +1 -1
  49. package/dist/elements/Field.js +31 -28
  50. package/dist/elements/Field.js.map +1 -1
  51. package/dist/elements/FieldHelpers.d.ts.map +1 -1
  52. package/dist/elements/FieldHelpers.js +6 -6
  53. package/dist/elements/FieldHelpers.js.map +1 -1
  54. package/dist/elements/FontManager.d.ts.map +1 -1
  55. package/dist/elements/FontManager.js.map +1 -1
  56. package/dist/elements/Footer.js.map +1 -1
  57. package/dist/elements/Footnote.d.ts.map +1 -1
  58. package/dist/elements/Footnote.js.map +1 -1
  59. package/dist/elements/FootnoteManager.d.ts.map +1 -1
  60. package/dist/elements/FootnoteManager.js.map +1 -1
  61. package/dist/elements/Header.js.map +1 -1
  62. package/dist/elements/HeaderFooterManager.js.map +1 -1
  63. package/dist/elements/Hyperlink.d.ts.map +1 -1
  64. package/dist/elements/Hyperlink.js +5 -5
  65. package/dist/elements/Hyperlink.js.map +1 -1
  66. package/dist/elements/Image.d.ts +2 -2
  67. package/dist/elements/Image.d.ts.map +1 -1
  68. package/dist/elements/Image.js +21 -5
  69. package/dist/elements/Image.js.map +1 -1
  70. package/dist/elements/ImageManager.d.ts.map +1 -1
  71. package/dist/elements/ImageManager.js +2 -2
  72. package/dist/elements/ImageManager.js.map +1 -1
  73. package/dist/elements/ImageRun.js.map +1 -1
  74. package/dist/elements/MathElement.js.map +1 -1
  75. package/dist/elements/Paragraph.d.ts.map +1 -1
  76. package/dist/elements/Paragraph.js +128 -117
  77. package/dist/elements/Paragraph.js.map +1 -1
  78. package/dist/elements/PreservedElement.js.map +1 -1
  79. package/dist/elements/PropertyChangeTypes.js.map +1 -1
  80. package/dist/elements/RangeMarker.js.map +1 -1
  81. package/dist/elements/Revision.d.ts +1 -0
  82. package/dist/elements/Revision.d.ts.map +1 -1
  83. package/dist/elements/Revision.js +44 -5
  84. package/dist/elements/Revision.js.map +1 -1
  85. package/dist/elements/RevisionContent.js.map +1 -1
  86. package/dist/elements/RevisionManager.d.ts.map +1 -1
  87. package/dist/elements/RevisionManager.js.map +1 -1
  88. package/dist/elements/Run.d.ts.map +1 -1
  89. package/dist/elements/Run.js +1 -3
  90. package/dist/elements/Run.js.map +1 -1
  91. package/dist/elements/Section.d.ts.map +1 -1
  92. package/dist/elements/Section.js +127 -118
  93. package/dist/elements/Section.js.map +1 -1
  94. package/dist/elements/Shape.d.ts.map +1 -1
  95. package/dist/elements/Shape.js +21 -0
  96. package/dist/elements/Shape.js.map +1 -1
  97. package/dist/elements/StructuredDocumentTag.d.ts.map +1 -1
  98. package/dist/elements/StructuredDocumentTag.js +20 -8
  99. package/dist/elements/StructuredDocumentTag.js.map +1 -1
  100. package/dist/elements/Table.d.ts +2 -2
  101. package/dist/elements/Table.d.ts.map +1 -1
  102. package/dist/elements/Table.js +29 -35
  103. package/dist/elements/Table.js.map +1 -1
  104. package/dist/elements/TableCell.d.ts +2 -2
  105. package/dist/elements/TableCell.d.ts.map +1 -1
  106. package/dist/elements/TableCell.js +63 -67
  107. package/dist/elements/TableCell.js.map +1 -1
  108. package/dist/elements/TableGridChange.js.map +1 -1
  109. package/dist/elements/TableOfContents.d.ts +6 -6
  110. package/dist/elements/TableOfContents.d.ts.map +1 -1
  111. package/dist/elements/TableOfContents.js.map +1 -1
  112. package/dist/elements/TableOfContentsElement.js.map +1 -1
  113. package/dist/elements/TableRow.d.ts.map +1 -1
  114. package/dist/elements/TableRow.js +65 -47
  115. package/dist/elements/TableRow.js.map +1 -1
  116. package/dist/elements/TextBox.d.ts.map +1 -1
  117. package/dist/elements/TextBox.js +1 -1
  118. package/dist/elements/TextBox.js.map +1 -1
  119. package/dist/formatting/AbstractNumbering.d.ts +1 -1
  120. package/dist/formatting/AbstractNumbering.d.ts.map +1 -1
  121. package/dist/formatting/AbstractNumbering.js +11 -11
  122. package/dist/formatting/AbstractNumbering.js.map +1 -1
  123. package/dist/formatting/NumberingInstance.d.ts.map +1 -1
  124. package/dist/formatting/NumberingInstance.js +4 -4
  125. package/dist/formatting/NumberingInstance.js.map +1 -1
  126. package/dist/formatting/NumberingLevel.d.ts.map +1 -1
  127. package/dist/formatting/NumberingLevel.js +26 -26
  128. package/dist/formatting/NumberingLevel.js.map +1 -1
  129. package/dist/formatting/NumberingManager.d.ts +1 -1
  130. package/dist/formatting/NumberingManager.d.ts.map +1 -1
  131. package/dist/formatting/NumberingManager.js.map +1 -1
  132. package/dist/formatting/Style.d.ts.map +1 -1
  133. package/dist/formatting/Style.js +87 -95
  134. package/dist/formatting/Style.js.map +1 -1
  135. package/dist/formatting/StylesManager.d.ts +3 -3
  136. package/dist/formatting/StylesManager.d.ts.map +1 -1
  137. package/dist/formatting/StylesManager.js.map +1 -1
  138. package/dist/helpers/CleanupHelper.d.ts.map +1 -1
  139. package/dist/helpers/CleanupHelper.js +1 -7
  140. package/dist/helpers/CleanupHelper.js.map +1 -1
  141. package/dist/images/ImageOptimizer.js.map +1 -1
  142. package/dist/index.js.map +1 -1
  143. package/dist/managers/DrawingManager.d.ts.map +1 -1
  144. package/dist/managers/DrawingManager.js.map +1 -1
  145. package/dist/tracking/DocumentTrackingContext.js.map +1 -1
  146. package/dist/tracking/TrackingContext.js.map +1 -1
  147. package/dist/types/compatibility-types.js.map +1 -1
  148. package/dist/types/formatting.js.map +1 -1
  149. package/dist/types/list-types.d.ts +4 -4
  150. package/dist/types/list-types.d.ts.map +1 -1
  151. package/dist/types/list-types.js.map +1 -1
  152. package/dist/types/settings-types.js.map +1 -1
  153. package/dist/types/styleConfig.js.map +1 -1
  154. package/dist/utils/ChangelogGenerator.d.ts.map +1 -1
  155. package/dist/utils/ChangelogGenerator.js.map +1 -1
  156. package/dist/utils/CompatibilityUpgrader.d.ts.map +1 -1
  157. package/dist/utils/CompatibilityUpgrader.js +7 -7
  158. package/dist/utils/CompatibilityUpgrader.js.map +1 -1
  159. package/dist/utils/InMemoryRevisionAcceptor.js +1 -1
  160. package/dist/utils/InMemoryRevisionAcceptor.js.map +1 -1
  161. package/dist/utils/MoveOperationHelper.js.map +1 -1
  162. package/dist/utils/RevisionAwareProcessor.js.map +1 -1
  163. package/dist/utils/RevisionWalker.js.map +1 -1
  164. package/dist/utils/SelectiveRevisionAcceptor.js.map +1 -1
  165. package/dist/utils/ShadingResolver.js +1 -1
  166. package/dist/utils/ShadingResolver.js.map +1 -1
  167. package/dist/utils/acceptRevisions.d.ts +0 -28
  168. package/dist/utils/acceptRevisions.d.ts.map +1 -1
  169. package/dist/utils/acceptRevisions.js +5 -7
  170. package/dist/utils/acceptRevisions.js.map +1 -1
  171. package/dist/utils/cnfStyleDecoder.js +1 -1
  172. package/dist/utils/cnfStyleDecoder.js.map +1 -1
  173. package/dist/utils/corruptionDetection.js.map +1 -1
  174. package/dist/utils/dateFormatting.js.map +1 -1
  175. package/dist/utils/deepClone.d.ts +0 -1
  176. package/dist/utils/deepClone.d.ts.map +1 -1
  177. package/dist/utils/deepClone.js +0 -7
  178. package/dist/utils/deepClone.js.map +1 -1
  179. package/dist/utils/diagnostics.d.ts +2 -2
  180. package/dist/utils/diagnostics.d.ts.map +1 -1
  181. package/dist/utils/diagnostics.js.map +1 -1
  182. package/dist/utils/errorHandling.js.map +1 -1
  183. package/dist/utils/formatting.js.map +1 -1
  184. package/dist/utils/list-detection.d.ts +2 -2
  185. package/dist/utils/list-detection.d.ts.map +1 -1
  186. package/dist/utils/list-detection.js +3 -3
  187. package/dist/utils/list-detection.js.map +1 -1
  188. package/dist/utils/logger.d.ts +2 -4
  189. package/dist/utils/logger.d.ts.map +1 -1
  190. package/dist/utils/logger.js +0 -2
  191. package/dist/utils/logger.js.map +1 -1
  192. package/dist/utils/parsingHelpers.js.map +1 -1
  193. package/dist/utils/stripTrackedChanges.d.ts +0 -19
  194. package/dist/utils/stripTrackedChanges.d.ts.map +1 -1
  195. package/dist/utils/stripTrackedChanges.js +0 -2
  196. package/dist/utils/stripTrackedChanges.js.map +1 -1
  197. package/dist/utils/textDiff.js.map +1 -1
  198. package/dist/utils/units.js.map +1 -1
  199. package/dist/utils/validation.d.ts.map +1 -1
  200. package/dist/utils/validation.js.map +1 -1
  201. package/dist/utils/xmlSanitization.js.map +1 -1
  202. package/dist/validation/RevisionAutoFixer.js.map +1 -1
  203. package/dist/validation/RevisionValidator.js.map +1 -1
  204. package/dist/validation/ValidationRules.js.map +1 -1
  205. package/dist/validation/index.js.map +1 -1
  206. package/dist/xml/XMLBuilder.d.ts.map +1 -1
  207. package/dist/xml/XMLBuilder.js +10 -0
  208. package/dist/xml/XMLBuilder.js.map +1 -1
  209. package/dist/xml/XMLParser.d.ts.map +1 -1
  210. package/dist/xml/XMLParser.js +4 -5
  211. package/dist/xml/XMLParser.js.map +1 -1
  212. package/dist/zip/ZipHandler.js.map +1 -1
  213. package/dist/zip/ZipReader.js.map +1 -1
  214. package/dist/zip/ZipWriter.js.map +1 -1
  215. package/dist/zip/errors.js.map +1 -1
  216. package/dist/zip/types.js.map +1 -1
  217. package/package.json +34 -4
  218. package/src/__tests__/helper-methods.test.ts +512 -0
  219. package/src/constants/legacyCompatFlags.ts +138 -0
  220. package/src/constants/limits.ts +50 -0
  221. package/src/core/CLAUDE.md +109 -0
  222. package/src/core/Document.ts +15569 -0
  223. package/src/core/DocumentContent.ts +467 -0
  224. package/src/core/DocumentGenerator.ts +1104 -0
  225. package/src/core/DocumentIdManager.ts +158 -0
  226. package/src/core/DocumentParser.ts +10107 -0
  227. package/src/core/DocumentValidator.ts +372 -0
  228. package/src/core/Relationship.ts +367 -0
  229. package/src/core/RelationshipManager.ts +428 -0
  230. package/src/elements/AlternateContent.ts +42 -0
  231. package/src/elements/Bookmark.ts +210 -0
  232. package/src/elements/BookmarkManager.ts +250 -0
  233. package/src/elements/CLAUDE.md +126 -0
  234. package/src/elements/Comment.ts +359 -0
  235. package/src/elements/CommentManager.ts +502 -0
  236. package/src/elements/CommonTypes.ts +549 -0
  237. package/src/elements/CustomXml.ts +36 -0
  238. package/src/elements/Endnote.ts +217 -0
  239. package/src/elements/EndnoteManager.ts +249 -0
  240. package/src/elements/Field.ts +1233 -0
  241. package/src/elements/FieldHelpers.ts +333 -0
  242. package/src/elements/FontManager.ts +339 -0
  243. package/src/elements/Footer.ts +269 -0
  244. package/src/elements/Footnote.ts +217 -0
  245. package/src/elements/FootnoteManager.ts +249 -0
  246. package/src/elements/Header.ts +269 -0
  247. package/src/elements/HeaderFooterManager.ts +219 -0
  248. package/src/elements/Hyperlink.ts +1146 -0
  249. package/src/elements/Image.ts +1756 -0
  250. package/src/elements/ImageManager.ts +432 -0
  251. package/src/elements/ImageRun.ts +59 -0
  252. package/src/elements/MathElement.ts +65 -0
  253. package/src/elements/Paragraph.ts +4227 -0
  254. package/src/elements/PreservedElement.ts +53 -0
  255. package/src/elements/PropertyChangeTypes.ts +442 -0
  256. package/src/elements/RangeMarker.ts +400 -0
  257. package/src/elements/Revision.ts +1217 -0
  258. package/src/elements/RevisionContent.ts +73 -0
  259. package/src/elements/RevisionManager.ts +1070 -0
  260. package/src/elements/Run.ts +3068 -0
  261. package/src/elements/Section.ts +1421 -0
  262. package/src/elements/Shape.ts +873 -0
  263. package/src/elements/StructuredDocumentTag.ts +978 -0
  264. package/src/elements/Table.ts +2524 -0
  265. package/src/elements/TableCell.ts +1586 -0
  266. package/src/elements/TableGridChange.ts +151 -0
  267. package/src/elements/TableOfContents.ts +691 -0
  268. package/src/elements/TableOfContentsElement.ts +89 -0
  269. package/src/elements/TableRow.ts +906 -0
  270. package/src/elements/TextBox.ts +768 -0
  271. package/src/formatting/AbstractNumbering.ts +548 -0
  272. package/src/formatting/CLAUDE.md +74 -0
  273. package/src/formatting/NumberingInstance.ts +212 -0
  274. package/src/formatting/NumberingLevel.ts +1006 -0
  275. package/src/formatting/NumberingManager.ts +827 -0
  276. package/src/formatting/Style.ts +1833 -0
  277. package/src/formatting/StylesManager.ts +1005 -0
  278. package/src/helpers/CleanupHelper.ts +524 -0
  279. package/src/images/ImageOptimizer.ts +274 -0
  280. package/src/index.ts +554 -0
  281. package/src/managers/CLAUDE.md +47 -0
  282. package/src/managers/DrawingManager.ts +319 -0
  283. package/src/tracking/DocumentTrackingContext.ts +643 -0
  284. package/src/tracking/TrackingContext.ts +173 -0
  285. package/src/types/compatibility-types.ts +49 -0
  286. package/src/types/formatting.ts +210 -0
  287. package/src/types/list-types.ts +152 -0
  288. package/src/types/settings-types.ts +59 -0
  289. package/src/types/styleConfig.ts +189 -0
  290. package/src/utils/CLAUDE.md +153 -0
  291. package/src/utils/ChangelogGenerator.ts +1581 -0
  292. package/src/utils/CompatibilityUpgrader.ts +237 -0
  293. package/src/utils/InMemoryRevisionAcceptor.ts +668 -0
  294. package/src/utils/MoveOperationHelper.ts +238 -0
  295. package/src/utils/RevisionAwareProcessor.ts +526 -0
  296. package/src/utils/RevisionWalker.ts +457 -0
  297. package/src/utils/SelectiveRevisionAcceptor.ts +613 -0
  298. package/src/utils/ShadingResolver.ts +107 -0
  299. package/src/utils/acceptRevisions.ts +714 -0
  300. package/src/utils/cnfStyleDecoder.ts +217 -0
  301. package/src/utils/corruptionDetection.ts +345 -0
  302. package/src/utils/dateFormatting.ts +20 -0
  303. package/src/utils/deepClone.ts +78 -0
  304. package/src/utils/diagnostics.ts +129 -0
  305. package/src/utils/errorHandling.ts +80 -0
  306. package/src/utils/formatting.ts +213 -0
  307. package/src/utils/list-detection.ts +274 -0
  308. package/src/utils/logger.ts +404 -0
  309. package/src/utils/parsingHelpers.ts +190 -0
  310. package/src/utils/stripTrackedChanges.ts +353 -0
  311. package/src/utils/textDiff.ts +100 -0
  312. package/src/utils/units.ts +421 -0
  313. package/src/utils/validation.ts +542 -0
  314. package/src/utils/xmlSanitization.ts +182 -0
  315. package/src/validation/RevisionAutoFixer.ts +542 -0
  316. package/src/validation/RevisionValidator.ts +460 -0
  317. package/src/validation/ValidationRules.ts +338 -0
  318. package/src/validation/index.ts +30 -0
  319. package/src/xml/CLAUDE.md +65 -0
  320. package/src/xml/XMLBuilder.ts +871 -0
  321. package/src/xml/XMLParser.ts +919 -0
  322. package/src/zip/CLAUDE.md +55 -0
  323. package/src/zip/ZipHandler.ts +637 -0
  324. package/src/zip/ZipReader.ts +299 -0
  325. package/src/zip/ZipWriter.ts +390 -0
  326. package/src/zip/errors.ts +69 -0
  327. package/src/zip/types.ts +116 -0
  328. package/dist/core/ListNormalizer.d.ts +0 -23
  329. package/dist/core/ListNormalizer.d.ts.map +0 -1
  330. package/dist/core/ListNormalizer.js +0 -624
  331. package/dist/core/ListNormalizer.js.map +0 -1
  332. package/dist/images/index.d.ts +0 -2
  333. package/dist/images/index.d.ts.map +0 -1
  334. package/dist/images/index.js +0 -8
  335. package/dist/images/index.js.map +0 -1
  336. package/dist/ms-doc/cfb/CFBReader.d.ts +0 -35
  337. package/dist/ms-doc/cfb/CFBReader.d.ts.map +0 -1
  338. package/dist/ms-doc/cfb/CFBReader.js +0 -360
  339. package/dist/ms-doc/cfb/CFBReader.js.map +0 -1
  340. package/dist/ms-doc/converter/DocToDocxConverter.d.ts +0 -55
  341. package/dist/ms-doc/converter/DocToDocxConverter.d.ts.map +0 -1
  342. package/dist/ms-doc/converter/DocToDocxConverter.js +0 -324
  343. package/dist/ms-doc/converter/DocToDocxConverter.js.map +0 -1
  344. package/dist/ms-doc/fib/FIB.d.ts +0 -18
  345. package/dist/ms-doc/fib/FIB.d.ts.map +0 -1
  346. package/dist/ms-doc/fib/FIB.js +0 -342
  347. package/dist/ms-doc/fib/FIB.js.map +0 -1
  348. package/dist/ms-doc/fields/FieldParser.d.ts +0 -31
  349. package/dist/ms-doc/fields/FieldParser.d.ts.map +0 -1
  350. package/dist/ms-doc/fields/FieldParser.js +0 -266
  351. package/dist/ms-doc/fields/FieldParser.js.map +0 -1
  352. package/dist/ms-doc/images/PictureExtractor.d.ts +0 -22
  353. package/dist/ms-doc/images/PictureExtractor.d.ts.map +0 -1
  354. package/dist/ms-doc/images/PictureExtractor.js +0 -233
  355. package/dist/ms-doc/images/PictureExtractor.js.map +0 -1
  356. package/dist/ms-doc/index.d.ts +0 -20
  357. package/dist/ms-doc/index.d.ts.map +0 -1
  358. package/dist/ms-doc/index.js +0 -59
  359. package/dist/ms-doc/index.js.map +0 -1
  360. package/dist/ms-doc/properties/SPRM.d.ts +0 -210
  361. package/dist/ms-doc/properties/SPRM.d.ts.map +0 -1
  362. package/dist/ms-doc/properties/SPRM.js +0 -633
  363. package/dist/ms-doc/properties/SPRM.js.map +0 -1
  364. package/dist/ms-doc/sections/SectionParser.d.ts +0 -25
  365. package/dist/ms-doc/sections/SectionParser.d.ts.map +0 -1
  366. package/dist/ms-doc/sections/SectionParser.js +0 -214
  367. package/dist/ms-doc/sections/SectionParser.js.map +0 -1
  368. package/dist/ms-doc/styles/StyleSheet.d.ts +0 -23
  369. package/dist/ms-doc/styles/StyleSheet.d.ts.map +0 -1
  370. package/dist/ms-doc/styles/StyleSheet.js +0 -268
  371. package/dist/ms-doc/styles/StyleSheet.js.map +0 -1
  372. package/dist/ms-doc/subdocuments/SubdocumentParser.d.ts +0 -61
  373. package/dist/ms-doc/subdocuments/SubdocumentParser.d.ts.map +0 -1
  374. package/dist/ms-doc/subdocuments/SubdocumentParser.js +0 -208
  375. package/dist/ms-doc/subdocuments/SubdocumentParser.js.map +0 -1
  376. package/dist/ms-doc/tables/TableParser.d.ts +0 -29
  377. package/dist/ms-doc/tables/TableParser.d.ts.map +0 -1
  378. package/dist/ms-doc/tables/TableParser.js +0 -176
  379. package/dist/ms-doc/tables/TableParser.js.map +0 -1
  380. package/dist/ms-doc/text/PieceTable.d.ts +0 -21
  381. package/dist/ms-doc/text/PieceTable.d.ts.map +0 -1
  382. package/dist/ms-doc/text/PieceTable.js +0 -171
  383. package/dist/ms-doc/text/PieceTable.js.map +0 -1
  384. package/dist/ms-doc/types/Constants.d.ts +0 -99
  385. package/dist/ms-doc/types/Constants.d.ts.map +0 -1
  386. package/dist/ms-doc/types/Constants.js +0 -102
  387. package/dist/ms-doc/types/Constants.js.map +0 -1
  388. package/dist/ms-doc/types/DocTypes.d.ts +0 -368
  389. package/dist/ms-doc/types/DocTypes.d.ts.map +0 -1
  390. package/dist/ms-doc/types/DocTypes.js +0 -3
  391. package/dist/ms-doc/types/DocTypes.js.map +0 -1
  392. package/dist/tracking/index.d.ts +0 -3
  393. package/dist/tracking/index.d.ts.map +0 -1
  394. package/dist/tracking/index.js +0 -6
  395. package/dist/tracking/index.js.map +0 -1
@@ -0,0 +1,1006 @@
1
+ /**
2
+ * NumberingLevel - Defines formatting for a single level in a list
3
+ *
4
+ * A numbering level specifies how a particular list level (0-8) should be formatted,
5
+ * including the numbering format (bullet, decimal, roman, etc.), text template,
6
+ * alignment, and indentation.
7
+ */
8
+
9
+ import { XMLBuilder, XMLElement } from "../xml/XMLBuilder";
10
+
11
+ /**
12
+ * Word-native bullet character mappings
13
+ *
14
+ * Microsoft Word uses specific fonts with Private Use Area (PUA) characters
15
+ * for bullet points. These mappings ensure 100% compatibility with Word's
16
+ * native bullet rendering.
17
+ *
18
+ * Pattern: Levels 0,3,6 = filled bullet; 1,4,7 = open circle; 2,5,8 = filled square
19
+ */
20
+ export const WORD_NATIVE_BULLETS = {
21
+ /** Filled bullet (levels 0, 3, 6) - Symbol font U+F0B7 */
22
+ FILLED_BULLET: { char: "\uF0B7", font: "Symbol" },
23
+ /** Open circle (levels 1, 4, 7) - Courier New U+006F (lowercase 'o') */
24
+ OPEN_CIRCLE: { char: "\u006F", font: "Courier New" },
25
+ /** Filled square (levels 2, 5, 8) - Wingdings U+F0A7 */
26
+ FILLED_SQUARE: { char: "\uF0A7", font: "Wingdings" },
27
+ } as const;
28
+
29
+ /**
30
+ * Type for Word-native bullet definition
31
+ */
32
+ export type WordNativeBullet =
33
+ (typeof WORD_NATIVE_BULLETS)[keyof typeof WORD_NATIVE_BULLETS];
34
+
35
+ /**
36
+ * Numbering format types supported by Word
37
+ */
38
+ export type NumberFormat =
39
+ | "bullet" // Bullet character
40
+ | "decimal" // 1, 2, 3, ...
41
+ | "lowerRoman" // i, ii, iii, ...
42
+ | "upperRoman" // I, II, III, ...
43
+ | "lowerLetter" // a, b, c, ...
44
+ | "upperLetter" // A, B, C, ...
45
+ | "ordinal" // 1st, 2nd, 3rd, ...
46
+ | "cardinalText" // One, Two, Three, ...
47
+ | "ordinalText" // First, Second, Third, ...
48
+ | "hex" // 0x01, 0x02, ...
49
+ | "chicago" // *, †, ‡, §, ...
50
+ | "decimal zero"; // 01, 02, 03, ...
51
+
52
+ /**
53
+ * Alignment for the numbering text
54
+ */
55
+ export type NumberAlignment = "left" | "center" | "right" | "start" | "end";
56
+
57
+ /**
58
+ * Properties for creating a numbering level
59
+ */
60
+ export interface NumberingLevelProperties {
61
+ /** The level index (0-8, where 0 is the outermost level) */
62
+ level: number;
63
+
64
+ /** The numbering format */
65
+ format: NumberFormat;
66
+
67
+ /** The text template (e.g., "%1." for decimal, "•" for bullet) */
68
+ text: string;
69
+
70
+ /** Alignment of the numbering text */
71
+ alignment?: NumberAlignment;
72
+
73
+ /** Starting value (for numeric formats, default: 1) */
74
+ start?: number;
75
+
76
+ /** Left indentation in twips (can be negative for outdents into margin) */
77
+ leftIndent?: number;
78
+
79
+ /** Hanging indentation in twips (for the text after the number) */
80
+ hangingIndent?: number;
81
+
82
+ /** Font family for the numbering character (useful for bullets) */
83
+ font?: string;
84
+
85
+ /** Font size in half-points (e.g., 22 = 11pt) */
86
+ fontSize?: number;
87
+
88
+ /** Whether to show text after the number (default: true) */
89
+ isLegalNumberingStyle?: boolean;
90
+
91
+ /** Suffix after the number (tab, space, or nothing) */
92
+ suffix?: "tab" | "space" | "nothing";
93
+
94
+ /** Text color in hex (without #) */
95
+ color?: string;
96
+
97
+ /** Whether the numbering text is bold */
98
+ bold?: boolean;
99
+
100
+ /** Whether the numbering text is italic */
101
+ italic?: boolean;
102
+
103
+ /** Underline style for numbering text ('single', 'double', 'wave', 'dotted', 'dash', etc.) */
104
+ underline?: string;
105
+
106
+ /**
107
+ * Level at which numbering should restart (w:lvlRestart per ECMA-376 Part 1 §17.9.11)
108
+ * Specifies when to restart this level's numbering based on a higher-level change:
109
+ * - 0: Never restart (continues throughout document)
110
+ * - 1-8: Restart when the specified level changes
111
+ * - undefined (default): Restart when level-1 changes (standard behavior)
112
+ */
113
+ lvlRestart?: number;
114
+ }
115
+
116
+ /**
117
+ * Represents a single level in a numbering definition
118
+ */
119
+ export class NumberingLevel {
120
+ private properties: Required<Omit<NumberingLevelProperties, 'lvlRestart' | 'underline'>> & Pick<NumberingLevelProperties, 'lvlRestart' | 'underline'>;
121
+
122
+ /**
123
+ * Creates a new numbering level
124
+ * @param properties The level properties
125
+ */
126
+ constructor(properties: NumberingLevelProperties) {
127
+ // Set defaults
128
+ this.properties = {
129
+ level: properties.level,
130
+ format: properties.format,
131
+ text: properties.text,
132
+ alignment: properties.alignment || "left",
133
+ start: properties.start !== undefined ? properties.start : 1,
134
+ leftIndent:
135
+ properties.leftIndent !== undefined
136
+ ? properties.leftIndent
137
+ : 720 + properties.level * 360,
138
+ hangingIndent:
139
+ properties.hangingIndent !== undefined ? properties.hangingIndent : 360,
140
+ font: properties.font || "Calibri",
141
+ fontSize: properties.fontSize || 22, // 11pt default
142
+ isLegalNumberingStyle:
143
+ properties.isLegalNumberingStyle !== undefined
144
+ ? properties.isLegalNumberingStyle
145
+ : false,
146
+ suffix: properties.suffix || "tab",
147
+ color: properties.color || "000000",
148
+ bold: properties.bold !== undefined ? properties.bold : false,
149
+ italic: properties.italic !== undefined ? properties.italic : false,
150
+ underline: properties.underline,
151
+ lvlRestart: properties.lvlRestart, // undefined means default behavior (restart on level-1 change)
152
+ };
153
+
154
+ this.validate();
155
+ }
156
+
157
+ /**
158
+ * Validates the level properties
159
+ */
160
+ private validate(): void {
161
+ if (this.properties.level < 0 || this.properties.level > 8) {
162
+ throw new Error(
163
+ `Level must be between 0 and 8, got ${this.properties.level}`
164
+ );
165
+ }
166
+
167
+ // Note: leftIndent CAN be negative (outdent into margin) per ECMA-376
168
+ // This is valid and used for hanging indents where bullets appear in margin
169
+
170
+ if (this.properties.hangingIndent < 0) {
171
+ throw new Error("Hanging indent must be non-negative");
172
+ }
173
+
174
+ if (this.properties.start < 0) {
175
+ throw new Error("Start value must be non-negative");
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Calculates safe indentation values for a given level based on page constraints.
181
+ *
182
+ * Use this instead of default indentation when working with narrow pages or
183
+ * deep nesting levels to ensure content stays within page margins.
184
+ *
185
+ * @param level The level index (0-8)
186
+ * @param pageWidthTwips Page width in twips (default: 12240 = 8.5 inches)
187
+ * @param leftMarginTwips Left margin in twips (default: 1440 = 1 inch)
188
+ * @param rightMarginTwips Right margin in twips (default: 1440 = 1 inch)
189
+ * @param minContentWidth Minimum content width in twips (default: 2880 = 2 inches)
190
+ * @returns Safe indentation values that won't exceed available space
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * // For a narrow page (6" wide with 0.5" margins)
195
+ * const indent = NumberingLevel.calculateSafeIndentation(
196
+ * 5, // level 5
197
+ * 8640, // 6 inches page width
198
+ * 720, // 0.5 inch left margin
199
+ * 720 // 0.5 inch right margin
200
+ * );
201
+ * ```
202
+ */
203
+ static calculateSafeIndentation(
204
+ level: number,
205
+ pageWidthTwips = 12240,
206
+ leftMarginTwips = 1440,
207
+ rightMarginTwips = 1440,
208
+ minContentWidth = 2880
209
+ ): { leftIndent: number; hangingIndent: number } {
210
+ if (level < 0 || level > 8) {
211
+ throw new Error(`Invalid level ${level}. Level must be between 0 and 8.`);
212
+ }
213
+
214
+ // Calculate available content width
215
+ const availableWidth = pageWidthTwips - leftMarginTwips - rightMarginTwips;
216
+
217
+ // Calculate max safe indent (leave space for content)
218
+ const maxSafeIndent = Math.max(0, availableWidth - minContentWidth);
219
+
220
+ // Standard indentation
221
+ const standardLeftIndent = 720 + level * 360;
222
+ const hangingIndent = 360;
223
+
224
+ // Cap at safe maximum
225
+ const safeLeftIndent = Math.min(standardLeftIndent, maxSafeIndent);
226
+
227
+ return {
228
+ leftIndent: safeLeftIndent,
229
+ hangingIndent,
230
+ };
231
+ }
232
+
233
+ /**
234
+ * Gets the level index
235
+ */
236
+ getLevel(): number {
237
+ return this.properties.level;
238
+ }
239
+
240
+ /**
241
+ * Gets the numbering format
242
+ */
243
+ getFormat(): NumberFormat {
244
+ return this.properties.format;
245
+ }
246
+
247
+ /**
248
+ * Gets the level properties
249
+ */
250
+ getProperties(): Required<Omit<NumberingLevelProperties, 'lvlRestart' | 'underline'>> & Pick<NumberingLevelProperties, 'lvlRestart' | 'underline'> {
251
+ return { ...this.properties };
252
+ }
253
+
254
+ /**
255
+ * Sets the left indentation
256
+ * @param twips Indentation in twips
257
+ */
258
+ setLeftIndent(twips: number): this {
259
+ // Note: Negative values are valid (outdent into margin) per ECMA-376
260
+ this.properties.leftIndent = twips;
261
+ return this;
262
+ }
263
+
264
+ /**
265
+ * Sets the hanging indentation
266
+ * @param twips Indentation in twips
267
+ */
268
+ setHangingIndent(twips: number): this {
269
+ if (twips < 0) {
270
+ throw new Error("Hanging indent must be non-negative");
271
+ }
272
+ this.properties.hangingIndent = twips;
273
+ return this;
274
+ }
275
+
276
+ /**
277
+ * Sets the font for the numbering character
278
+ * @param font Font family name
279
+ */
280
+ setFont(font: string): this {
281
+ this.properties.font = font;
282
+ return this;
283
+ }
284
+
285
+ /**
286
+ * Sets the alignment
287
+ * @param alignment Alignment type
288
+ */
289
+ setAlignment(alignment: NumberAlignment): this {
290
+ this.properties.alignment = alignment;
291
+ return this;
292
+ }
293
+
294
+ /**
295
+ * Sets the font size in half-points
296
+ * @param halfPoints Font size in half-points (e.g., 24 = 12pt)
297
+ */
298
+ setFontSize(halfPoints: number): this {
299
+ this.properties.fontSize = halfPoints;
300
+ return this;
301
+ }
302
+
303
+ /**
304
+ * Sets the level text (bullet character or number template)
305
+ * @param text The text template (e.g., '•' for bullets, '%1.' for numbered)
306
+ */
307
+ setText(text: string): this {
308
+ this.properties.text = text;
309
+ return this;
310
+ }
311
+
312
+ /**
313
+ * Sets the text color
314
+ * @param color Hex color without # (e.g., '000000' for black)
315
+ */
316
+ setColor(color: string): this {
317
+ this.properties.color = color;
318
+ return this;
319
+ }
320
+
321
+ /**
322
+ * Sets whether the numbering text is bold
323
+ * @param bold Whether to make bold
324
+ */
325
+ setBold(bold: boolean): this {
326
+ this.properties.bold = bold;
327
+ return this;
328
+ }
329
+
330
+ /**
331
+ * Sets whether the numbering text is italic
332
+ * @param italic Whether to make italic
333
+ */
334
+ setItalic(italic: boolean): this {
335
+ this.properties.italic = italic;
336
+ return this;
337
+ }
338
+
339
+ /**
340
+ * Gets whether the numbering text is italic
341
+ */
342
+ getItalic(): boolean {
343
+ return this.properties.italic ?? false;
344
+ }
345
+
346
+ /**
347
+ * Sets the underline style for numbering text
348
+ * @param style Underline style ('single', 'double', 'wave', 'dotted', 'dash', etc.)
349
+ */
350
+ setUnderline(style: string | undefined): this {
351
+ this.properties.underline = style;
352
+ return this;
353
+ }
354
+
355
+ /**
356
+ * Gets the underline style
357
+ */
358
+ getUnderline(): string | undefined {
359
+ return this.properties.underline;
360
+ }
361
+
362
+ /**
363
+ * Clears the underline style
364
+ */
365
+ clearUnderline(): this {
366
+ this.properties.underline = undefined;
367
+ return this;
368
+ }
369
+
370
+ /**
371
+ * Sets the level restart behavior (w:lvlRestart per ECMA-376 Part 1 §17.9.11)
372
+ *
373
+ * Controls when this level's numbering restarts based on higher-level changes:
374
+ * - 0: Never restart (continues throughout document)
375
+ * - 1-8: Restart when the specified level changes
376
+ * - undefined: Restart when level-1 changes (standard/default behavior)
377
+ *
378
+ * @param level The level that triggers restart (0-8), or undefined for default
379
+ * @example
380
+ * // Level 1 that never restarts (continuous across document)
381
+ * level1.setLvlRestart(0);
382
+ *
383
+ * // Level 2 that restarts when level 0 changes (not level 1)
384
+ * level2.setLvlRestart(0);
385
+ */
386
+ setLvlRestart(level: number | undefined): this {
387
+ if (level !== undefined && (level < 0 || level > 8)) {
388
+ throw new Error(`lvlRestart must be between 0 and 8, got ${level}`);
389
+ }
390
+ this.properties.lvlRestart = level;
391
+ return this;
392
+ }
393
+
394
+ /**
395
+ * Gets the level restart value
396
+ * @returns The level that triggers restart, or undefined for default behavior
397
+ */
398
+ getLvlRestart(): number | undefined {
399
+ return this.properties.lvlRestart;
400
+ }
401
+
402
+ /**
403
+ * Sets the numbering format (decimal, lowerLetter, bullet, etc.)
404
+ * @param format The numbering format
405
+ */
406
+ setFormat(format: NumberFormat): this {
407
+ this.properties.format = NumberingLevel.normalizeFormat(format);
408
+ return this;
409
+ }
410
+
411
+ /**
412
+ * Normalizes display-string format values to ECMA-376 ST_NumberFormat names.
413
+ * Accepts both standard format names and common display shortcuts.
414
+ */
415
+ static normalizeFormat(format: string): NumberFormat {
416
+ const corrections: Record<string, NumberFormat> = {
417
+ "a.": "lowerLetter",
418
+ "A.": "upperLetter",
419
+ "i.": "lowerRoman",
420
+ "I.": "upperRoman",
421
+ "1.": "decimal",
422
+ };
423
+ return (corrections[format] ?? format) as NumberFormat;
424
+ }
425
+
426
+ /**
427
+ * Generates the WordprocessingML XML for this level
428
+ */
429
+ toXML(): XMLElement {
430
+ // ECMA-376 CT_Lvl element order: start, numFmt, lvlRestart, pStyle, isLgl, suff, lvlText, lvlJc, pPr, rPr
431
+ const children: XMLElement[] = [];
432
+
433
+ // 1. Start value
434
+ children.push(
435
+ XMLBuilder.wSelf("start", { "w:val": this.properties.start.toString() })
436
+ );
437
+
438
+ // 2. Number format
439
+ children.push(
440
+ XMLBuilder.wSelf("numFmt", { "w:val": this.properties.format })
441
+ );
442
+
443
+ // 3. Level restart (w:lvlRestart per ECMA-376 Part 1 §17.9.11)
444
+ if (this.properties.lvlRestart !== undefined) {
445
+ children.push(
446
+ XMLBuilder.wSelf("lvlRestart", { "w:val": this.properties.lvlRestart.toString() })
447
+ );
448
+ }
449
+
450
+ // 4. pStyle — not modeled, skipped
451
+
452
+ // 5. Legal numbering style
453
+ if (this.properties.isLegalNumberingStyle) {
454
+ children.push(XMLBuilder.wSelf("isLgl"));
455
+ }
456
+
457
+ // 6. Suffix (what comes after the number)
458
+ if (this.properties.suffix) {
459
+ children.push(
460
+ XMLBuilder.wSelf("suff", { "w:val": this.properties.suffix })
461
+ );
462
+ }
463
+
464
+ // 7. Level text (e.g., "%1." or "•")
465
+ children.push(
466
+ XMLBuilder.wSelf("lvlText", { "w:val": this.properties.text })
467
+ );
468
+
469
+ // 8. Alignment
470
+ children.push(
471
+ XMLBuilder.wSelf("lvlJc", { "w:val": this.properties.alignment })
472
+ );
473
+
474
+ // 9. Paragraph properties (indentation)
475
+ const ind = XMLBuilder.wSelf("ind", {
476
+ "w:left": this.properties.leftIndent.toString(),
477
+ "w:hanging": this.properties.hangingIndent.toString(),
478
+ });
479
+ const pPr = XMLBuilder.w("pPr", undefined, [ind]);
480
+ children.push(pPr);
481
+
482
+ // 10. Run properties (font)
483
+ const rPrChildren: XMLElement[] = [];
484
+
485
+ // Font
486
+ rPrChildren.push(
487
+ XMLBuilder.wSelf("rFonts", {
488
+ "w:ascii": this.properties.font,
489
+ "w:hAnsi": this.properties.font,
490
+ "w:cs": this.properties.font,
491
+ "w:hint": "default",
492
+ })
493
+ );
494
+
495
+ // Bold
496
+ if (this.properties.bold) {
497
+ rPrChildren.push(XMLBuilder.wSelf("b"));
498
+ rPrChildren.push(XMLBuilder.wSelf("bCs"));
499
+ }
500
+
501
+ // Italic
502
+ if (this.properties.italic) {
503
+ rPrChildren.push(XMLBuilder.wSelf("i"));
504
+ rPrChildren.push(XMLBuilder.wSelf("iCs"));
505
+ }
506
+
507
+ // Underline
508
+ if (this.properties.underline) {
509
+ rPrChildren.push(
510
+ XMLBuilder.wSelf("u", { "w:val": this.properties.underline })
511
+ );
512
+ }
513
+
514
+ // Color
515
+ if (this.properties.color) {
516
+ rPrChildren.push(
517
+ XMLBuilder.wSelf("color", { "w:val": this.properties.color })
518
+ );
519
+ }
520
+
521
+ // Font size
522
+ rPrChildren.push(
523
+ XMLBuilder.wSelf("sz", { "w:val": this.properties.fontSize.toString() })
524
+ );
525
+ rPrChildren.push(
526
+ XMLBuilder.wSelf("szCs", { "w:val": this.properties.fontSize.toString() })
527
+ );
528
+
529
+ const rPr = XMLBuilder.w("rPr", undefined, rPrChildren);
530
+ children.push(rPr);
531
+
532
+ return XMLBuilder.w(
533
+ "lvl",
534
+ { "w:ilvl": this.properties.level.toString() },
535
+ children
536
+ );
537
+ }
538
+
539
+ /**
540
+ * Gets the recommended bullet symbol and font for a given level
541
+ * @param level The level index (0-8)
542
+ * @param style Optional bullet style ('standard', 'circle', 'square', 'arrow', 'check', 'word-native')
543
+ * @returns Object with symbol and font properties
544
+ */
545
+ static getBulletSymbolWithFont(
546
+ level: number,
547
+ style:
548
+ | "standard"
549
+ | "circle"
550
+ | "square"
551
+ | "arrow"
552
+ | "check"
553
+ | "word-native" = "standard"
554
+ ): { symbol: string; font: string } {
555
+ const bulletSets = {
556
+ // Standard style now uses Word-native encoding for maximum compatibility
557
+ standard: [
558
+ {
559
+ symbol: WORD_NATIVE_BULLETS.FILLED_BULLET.char,
560
+ font: WORD_NATIVE_BULLETS.FILLED_BULLET.font,
561
+ }, // Level 0: Filled bullet (Symbol U+F0B7)
562
+ {
563
+ symbol: WORD_NATIVE_BULLETS.OPEN_CIRCLE.char,
564
+ font: WORD_NATIVE_BULLETS.OPEN_CIRCLE.font,
565
+ }, // Level 1: Open circle (Courier New U+006F)
566
+ {
567
+ symbol: WORD_NATIVE_BULLETS.FILLED_SQUARE.char,
568
+ font: WORD_NATIVE_BULLETS.FILLED_SQUARE.font,
569
+ }, // Level 2: Filled square (Wingdings U+F0A7)
570
+ {
571
+ symbol: WORD_NATIVE_BULLETS.FILLED_BULLET.char,
572
+ font: WORD_NATIVE_BULLETS.FILLED_BULLET.font,
573
+ }, // Level 3: Filled bullet
574
+ {
575
+ symbol: WORD_NATIVE_BULLETS.OPEN_CIRCLE.char,
576
+ font: WORD_NATIVE_BULLETS.OPEN_CIRCLE.font,
577
+ }, // Level 4: Open circle
578
+ {
579
+ symbol: WORD_NATIVE_BULLETS.FILLED_SQUARE.char,
580
+ font: WORD_NATIVE_BULLETS.FILLED_SQUARE.font,
581
+ }, // Level 5: Filled square
582
+ {
583
+ symbol: WORD_NATIVE_BULLETS.FILLED_BULLET.char,
584
+ font: WORD_NATIVE_BULLETS.FILLED_BULLET.font,
585
+ }, // Level 6: Filled bullet
586
+ {
587
+ symbol: WORD_NATIVE_BULLETS.OPEN_CIRCLE.char,
588
+ font: WORD_NATIVE_BULLETS.OPEN_CIRCLE.font,
589
+ }, // Level 7: Open circle
590
+ {
591
+ symbol: WORD_NATIVE_BULLETS.FILLED_SQUARE.char,
592
+ font: WORD_NATIVE_BULLETS.FILLED_SQUARE.font,
593
+ }, // Level 8: Filled square
594
+ ],
595
+ circle: [
596
+ { symbol: "●", font: "Calibri" }, // Level 0: Filled circle (bold)
597
+ { symbol: "○", font: "Calibri" }, // Level 1: Empty circle
598
+ { symbol: "◉", font: "Calibri" }, // Level 2: Fisheye
599
+ { symbol: "◯", font: "Calibri" }, // Level 3: Large circle
600
+ { symbol: "⦿", font: "Calibri" }, // Level 4: Circled bullet
601
+ { symbol: "○", font: "Calibri" }, // Level 5: Empty circle
602
+ { symbol: "●", font: "Calibri" }, // Level 6: Filled circle
603
+ { symbol: "○", font: "Calibri" }, // Level 7: Empty circle
604
+ { symbol: "◉", font: "Calibri" }, // Level 8: Fisheye
605
+ ],
606
+ square: [
607
+ { symbol: "■", font: "Calibri" }, // Level 0: Filled square
608
+ { symbol: "□", font: "Calibri" }, // Level 1: Empty square
609
+ { symbol: "▪", font: "Calibri" }, // Level 2: Small filled square
610
+ { symbol: "▫", font: "Calibri" }, // Level 3: Small empty square
611
+ { symbol: "◼", font: "Calibri" }, // Level 4: Medium filled square
612
+ { symbol: "◻", font: "Calibri" }, // Level 5: Medium empty square
613
+ { symbol: "■", font: "Calibri" }, // Level 6: Filled square
614
+ { symbol: "□", font: "Calibri" }, // Level 7: Empty square
615
+ { symbol: "▪", font: "Calibri" }, // Level 8: Small filled square
616
+ ],
617
+ arrow: [
618
+ { symbol: "➢", font: "Calibri" }, // Level 0: Right arrow
619
+ { symbol: "➣", font: "Calibri" }, // Level 1: Right arrow filled
620
+ { symbol: "➤", font: "Calibri" }, // Level 2: Right arrow bold
621
+ { symbol: "➔", font: "Calibri" }, // Level 3: Right arrow simple
622
+ { symbol: "➜", font: "Calibri" }, // Level 4: Right arrow outline
623
+ { symbol: "➢", font: "Calibri" }, // Level 5: Right arrow
624
+ { symbol: "➣", font: "Calibri" }, // Level 6: Right arrow filled
625
+ { symbol: "➤", font: "Calibri" }, // Level 7: Right arrow bold
626
+ { symbol: "➔", font: "Calibri" }, // Level 8: Right arrow simple
627
+ ],
628
+ check: [
629
+ { symbol: "✓", font: "Calibri" }, // Level 0: Check mark
630
+ { symbol: "✔", font: "Calibri" }, // Level 1: Heavy check mark
631
+ { symbol: "☑", font: "Calibri" }, // Level 2: Checked box
632
+ { symbol: "✓", font: "Calibri" }, // Level 3: Check mark
633
+ { symbol: "✔", font: "Calibri" }, // Level 4: Heavy check mark
634
+ { symbol: "☑", font: "Calibri" }, // Level 5: Checked box
635
+ { symbol: "✓", font: "Calibri" }, // Level 6: Check mark
636
+ { symbol: "✔", font: "Calibri" }, // Level 7: Heavy check mark
637
+ { symbol: "☑", font: "Calibri" }, // Level 8: Checked box
638
+ ],
639
+ "word-native": [
640
+ // Word-native bullets using PUA characters with Symbol/Wingdings fonts
641
+ {
642
+ symbol: WORD_NATIVE_BULLETS.FILLED_BULLET.char,
643
+ font: WORD_NATIVE_BULLETS.FILLED_BULLET.font,
644
+ }, // Level 0: Filled bullet (Symbol U+F0B7)
645
+ {
646
+ symbol: WORD_NATIVE_BULLETS.OPEN_CIRCLE.char,
647
+ font: WORD_NATIVE_BULLETS.OPEN_CIRCLE.font,
648
+ }, // Level 1: Open circle (Courier New U+006F)
649
+ {
650
+ symbol: WORD_NATIVE_BULLETS.FILLED_SQUARE.char,
651
+ font: WORD_NATIVE_BULLETS.FILLED_SQUARE.font,
652
+ }, // Level 2: Filled square (Wingdings U+F0A7)
653
+ {
654
+ symbol: WORD_NATIVE_BULLETS.FILLED_BULLET.char,
655
+ font: WORD_NATIVE_BULLETS.FILLED_BULLET.font,
656
+ }, // Level 3: Filled bullet
657
+ {
658
+ symbol: WORD_NATIVE_BULLETS.OPEN_CIRCLE.char,
659
+ font: WORD_NATIVE_BULLETS.OPEN_CIRCLE.font,
660
+ }, // Level 4: Open circle
661
+ {
662
+ symbol: WORD_NATIVE_BULLETS.FILLED_SQUARE.char,
663
+ font: WORD_NATIVE_BULLETS.FILLED_SQUARE.font,
664
+ }, // Level 5: Filled square
665
+ {
666
+ symbol: WORD_NATIVE_BULLETS.FILLED_BULLET.char,
667
+ font: WORD_NATIVE_BULLETS.FILLED_BULLET.font,
668
+ }, // Level 6: Filled bullet
669
+ {
670
+ symbol: WORD_NATIVE_BULLETS.OPEN_CIRCLE.char,
671
+ font: WORD_NATIVE_BULLETS.OPEN_CIRCLE.font,
672
+ }, // Level 7: Open circle
673
+ {
674
+ symbol: WORD_NATIVE_BULLETS.FILLED_SQUARE.char,
675
+ font: WORD_NATIVE_BULLETS.FILLED_SQUARE.font,
676
+ }, // Level 8: Filled square
677
+ ],
678
+ };
679
+
680
+ const selectedSet = bulletSets[style];
681
+ const levelIndex = level % selectedSet.length;
682
+ const result = selectedSet[levelIndex];
683
+
684
+ // Fallback to standard bullet if somehow undefined
685
+ return result || { symbol: "•", font: "Calibri" };
686
+ }
687
+
688
+ /**
689
+ * Calculates the standard indentation values for a given level
690
+ * @param level The level index (0-8)
691
+ * @returns Object with leftIndent and hangingIndent in twips
692
+ * @example
693
+ * const indent = NumberingLevel.calculateStandardIndentation(0);
694
+ * // Returns: { leftIndent: 720, hangingIndent: 360 } (0.5" left, 0.25" hanging)
695
+ *
696
+ * const indent2 = NumberingLevel.calculateStandardIndentation(2);
697
+ * // Returns: { leftIndent: 1440, hangingIndent: 360 } (1.0" left, 0.25" hanging)
698
+ */
699
+ static calculateStandardIndentation(level: number): {
700
+ leftIndent: number;
701
+ hangingIndent: number;
702
+ } {
703
+ if (level < 0 || level > 8) {
704
+ throw new Error(`Invalid level ${level}. Level must be between 0 and 8.`);
705
+ }
706
+
707
+ return {
708
+ leftIndent: 720 + level * 360,
709
+ hangingIndent: 360,
710
+ };
711
+ }
712
+
713
+ /**
714
+ * Gets the standard number format for a given level
715
+ * @param level The level index (0-8)
716
+ * @returns The recommended number format for this level
717
+ * @example
718
+ * NumberingLevel.getStandardNumberFormat(0); // 'decimal' (1., 2., 3.)
719
+ * NumberingLevel.getStandardNumberFormat(1); // 'lowerLetter' (a., b., c.)
720
+ * NumberingLevel.getStandardNumberFormat(2); // 'lowerRoman' (i., ii., iii.)
721
+ * NumberingLevel.getStandardNumberFormat(3); // 'upperLetter' (A., B., C.)
722
+ * NumberingLevel.getStandardNumberFormat(4); // 'upperRoman' (I., II., III.)
723
+ */
724
+ static getStandardNumberFormat(level: number): NumberFormat {
725
+ if (level < 0 || level > 8) {
726
+ throw new Error(`Invalid level ${level}. Level must be between 0 and 8.`);
727
+ }
728
+
729
+ const formats: NumberFormat[] = [
730
+ "decimal", // Level 0: 1., 2., 3.
731
+ "lowerLetter", // Level 1: a., b., c.
732
+ "lowerRoman", // Level 2: i., ii., iii.
733
+ "upperLetter", // Level 3: A., B., C.
734
+ "upperRoman", // Level 4: I., II., III.
735
+ ];
736
+
737
+ const result = formats[level % formats.length];
738
+ return result || "decimal"; // Fallback to decimal (should never happen)
739
+ }
740
+
741
+ /**
742
+ * Creates a bullet list level
743
+ *
744
+ * When called without parameters, uses Word-native encoding for the level:
745
+ * - Levels 0, 3, 6: Filled bullet (Symbol font, U+F0B7)
746
+ * - Levels 1, 4, 7: Open circle (Courier New, U+006F)
747
+ * - Levels 2, 5, 8: Filled square (Wingdings, U+F0A7)
748
+ *
749
+ * @param level The level index (0-8)
750
+ * @param bullet Optional bullet character (defaults to Word-native for level)
751
+ * @param font Optional font to use for the bullet (defaults to Word-native for level)
752
+ */
753
+ static createBulletLevel(
754
+ level: number,
755
+ bullet?: string,
756
+ font?: string
757
+ ): NumberingLevel {
758
+ // Use Word-native defaults when not specified
759
+ const defaults = NumberingLevel.getBulletSymbolWithFont(level, "standard");
760
+ const actualBullet = bullet ?? defaults.symbol;
761
+ const actualFont = font ?? defaults.font;
762
+
763
+ return new NumberingLevel({
764
+ level,
765
+ format: "bullet",
766
+ text: actualBullet,
767
+ alignment: "left",
768
+ font: actualFont,
769
+ fontSize: 24, // 12pt
770
+ bold: false,
771
+ color: "000000",
772
+ leftIndent: 720 + level * 360,
773
+ hangingIndent: 360,
774
+ });
775
+ }
776
+
777
+ /**
778
+ * Creates a decimal list level (1, 2, 3, ...)
779
+ * @param level The level index (0-8)
780
+ * @param template The text template (default: '%1.')
781
+ */
782
+ static createDecimalLevel(
783
+ level: number,
784
+ template = `%${level + 1}.`
785
+ ): NumberingLevel {
786
+ return new NumberingLevel({
787
+ level,
788
+ format: "decimal",
789
+ text: template,
790
+ alignment: "left",
791
+ font: "Verdana",
792
+ fontSize: 24, // 12pt
793
+ bold: false,
794
+ color: "000000",
795
+ leftIndent: 720 + level * 360,
796
+ hangingIndent: 360,
797
+ });
798
+ }
799
+
800
+ /**
801
+ * Creates a lower roman list level (i, ii, iii, ...)
802
+ * @param level The level index (0-8)
803
+ * @param template The text template (default: '%1.')
804
+ */
805
+ static createLowerRomanLevel(
806
+ level: number,
807
+ template = `%${level + 1}.`
808
+ ): NumberingLevel {
809
+ return new NumberingLevel({
810
+ level,
811
+ format: "lowerRoman",
812
+ text: template,
813
+ alignment: "left",
814
+ font: "Verdana",
815
+ fontSize: 24, // 12pt
816
+ bold: false,
817
+ color: "000000",
818
+ leftIndent: 720 + level * 360,
819
+ hangingIndent: 360,
820
+ });
821
+ }
822
+
823
+ /**
824
+ * Creates an upper roman list level (I, II, III, ...)
825
+ * @param level The level index (0-8)
826
+ * @param template The text template (default: '%1.')
827
+ */
828
+ static createUpperRomanLevel(
829
+ level: number,
830
+ template = `%${level + 1}.`
831
+ ): NumberingLevel {
832
+ return new NumberingLevel({
833
+ level,
834
+ format: "upperRoman",
835
+ text: template,
836
+ alignment: "left",
837
+ font: "Verdana",
838
+ fontSize: 24, // 12pt
839
+ bold: false,
840
+ color: "000000",
841
+ leftIndent: 720 + level * 360,
842
+ hangingIndent: 360,
843
+ });
844
+ }
845
+
846
+ /**
847
+ * Creates a lower letter list level (a, b, c, ...)
848
+ * @param level The level index (0-8)
849
+ * @param template The text template (default: '%1.')
850
+ */
851
+ static createLowerLetterLevel(
852
+ level: number,
853
+ template = `%${level + 1}.`
854
+ ): NumberingLevel {
855
+ return new NumberingLevel({
856
+ level,
857
+ format: "lowerLetter",
858
+ text: template,
859
+ alignment: "left",
860
+ font: "Verdana",
861
+ fontSize: 24, // 12pt
862
+ bold: false,
863
+ color: "000000",
864
+ leftIndent: 720 + level * 360,
865
+ hangingIndent: 360,
866
+ });
867
+ }
868
+
869
+ /**
870
+ * Creates an upper letter list level (A, B, C, ...)
871
+ * @param level The level index (0-8)
872
+ * @param template The text template (default: '%1.')
873
+ */
874
+ static createUpperLetterLevel(
875
+ level: number,
876
+ template = `%${level + 1}.`
877
+ ): NumberingLevel {
878
+ return new NumberingLevel({
879
+ level,
880
+ format: "upperLetter",
881
+ text: template,
882
+ alignment: "left",
883
+ font: "Verdana",
884
+ fontSize: 24, // 12pt
885
+ bold: false,
886
+ color: "000000",
887
+ leftIndent: 720 + level * 360,
888
+ hangingIndent: 360,
889
+ });
890
+ }
891
+
892
+ /**
893
+ * Factory method for creating a numbering level
894
+ * @param properties The level properties
895
+ */
896
+ static create(properties: NumberingLevelProperties): NumberingLevel {
897
+ return new NumberingLevel(properties);
898
+ }
899
+
900
+ /**
901
+ * Creates a NumberingLevel from XML element
902
+ * @param xml The XML string of the <w:lvl> element
903
+ * @returns NumberingLevel instance
904
+ */
905
+ static fromXML(xml: string): NumberingLevel {
906
+ // Extract level index (required)
907
+ const ilvlMatch = /<w:lvl[^>]*w:ilvl="([^"]+)"/.exec(xml);
908
+ if (!ilvlMatch?.[1]) {
909
+ throw new Error("Missing required w:ilvl attribute");
910
+ }
911
+ const level = parseInt(ilvlMatch[1], 10);
912
+
913
+ // Extract number format (required)
914
+ const numFmtMatch = /<w:numFmt[^>]*w:val="([^"]+)"/.exec(xml);
915
+ if (!numFmtMatch?.[1]) {
916
+ throw new Error("Missing required w:numFmt element");
917
+ }
918
+ const format = NumberingLevel.normalizeFormat(numFmtMatch[1]);
919
+
920
+ // Extract level text (optional - can be empty for placeholder levels)
921
+ const lvlTextMatch = /<w:lvlText[^>]*w:val="([^"]*)"/.exec(xml);
922
+ const text = lvlTextMatch?.[1] !== undefined ? lvlTextMatch[1] : "";
923
+
924
+ // Extract alignment (optional, default: left)
925
+ const lvlJcMatch = /<w:lvlJc[^>]*w:val="([^"]+)"/.exec(xml);
926
+ const alignment = (
927
+ lvlJcMatch?.[1] ? lvlJcMatch[1] : "left"
928
+ ) as NumberAlignment;
929
+
930
+ // Extract start value (optional, default: 1)
931
+ const startMatch = /<w:start[^>]*w:val="([^"]+)"/.exec(xml);
932
+ const start = startMatch?.[1] ? parseInt(startMatch[1], 10) : 1;
933
+
934
+ // Extract suffix (optional, default: tab)
935
+ const suffixMatch = /<w:suff[^>]*w:val="([^"]+)"/.exec(xml);
936
+ const suffix =
937
+ suffixMatch?.[1]
938
+ ? (suffixMatch[1] as "tab" | "space" | "nothing")
939
+ : "tab";
940
+
941
+ // Extract level restart (w:lvlRestart per ECMA-376 Part 1 §17.9.11)
942
+ let lvlRestart: number | undefined;
943
+ const lvlRestartMatch = /<w:lvlRestart[^>]*w:val="([^"]+)"/.exec(xml);
944
+ if (lvlRestartMatch?.[1]) {
945
+ lvlRestart = parseInt(lvlRestartMatch[1], 10);
946
+ }
947
+
948
+ // Extract indentation from <w:pPr><w:ind>
949
+ let leftIndent = 720 + level * 360; // default
950
+ let hangingIndent = 360; // default
951
+ const indMatch = /<w:ind[^>]*\/>/.exec(xml);
952
+ if (indMatch) {
953
+ const indElement = indMatch[0];
954
+ const leftMatch = /w:left="([^"]+)"/.exec(indElement);
955
+ const hangingMatch = /w:hanging="([^"]+)"/.exec(indElement);
956
+
957
+ if (leftMatch?.[1]) leftIndent = parseInt(leftMatch[1], 10);
958
+ if (hangingMatch?.[1])
959
+ hangingIndent = parseInt(hangingMatch[1], 10);
960
+ }
961
+
962
+ // Extract font and size from <w:rPr>
963
+ let font = "Calibri";
964
+ let fontSize = 22;
965
+
966
+ const rFontsMatch = /<w:rFonts[^>]*\/>/.exec(xml);
967
+ if (rFontsMatch) {
968
+ const rFontsElement = rFontsMatch[0];
969
+ const asciiMatch = /w:ascii="([^"]+)"/.exec(rFontsElement);
970
+ if (asciiMatch?.[1]) font = asciiMatch[1];
971
+ }
972
+
973
+ const szMatch = /<w:sz[^>]*w:val="([^"]+)"/.exec(xml);
974
+ if (szMatch?.[1]) fontSize = parseInt(szMatch[1], 10);
975
+
976
+ // List prefixes should never have bold, italic, or underline - ignore source XML formatting
977
+ const bold = false;
978
+ const italic = false;
979
+ const underline: string | undefined = undefined;
980
+
981
+ // Extract color from <w:rPr>
982
+ let color: string | undefined;
983
+ const colorMatch = /<w:color[^>]*w:val="([^"]+)"/.exec(xml);
984
+ if (colorMatch?.[1]) {
985
+ color = colorMatch[1];
986
+ }
987
+
988
+ return new NumberingLevel({
989
+ level,
990
+ format,
991
+ text,
992
+ alignment,
993
+ start,
994
+ leftIndent,
995
+ hangingIndent,
996
+ font,
997
+ fontSize,
998
+ suffix,
999
+ bold,
1000
+ italic,
1001
+ underline,
1002
+ color,
1003
+ lvlRestart,
1004
+ });
1005
+ }
1006
+ }