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,129 @@
1
+ /**
2
+ * Diagnostic logging utilities for debugging document processing
3
+ * @module diagnostics
4
+ */
5
+
6
+ export interface DiagnosticConfig {
7
+ enabled: boolean;
8
+ logParsing: boolean;
9
+ logSerialization: boolean;
10
+ logTextDirection: boolean;
11
+ verbose: boolean;
12
+ }
13
+
14
+ const defaultConfig: DiagnosticConfig = {
15
+ enabled: false,
16
+ logParsing: false,
17
+ logSerialization: false,
18
+ logTextDirection: false,
19
+ verbose: false,
20
+ };
21
+
22
+ let config: DiagnosticConfig = { ...defaultConfig };
23
+
24
+ /**
25
+ * Enable diagnostic logging
26
+ */
27
+ export function enableDiagnostics(options: Partial<DiagnosticConfig> = {}): void {
28
+ config = {
29
+ ...defaultConfig,
30
+ enabled: true,
31
+ ...options,
32
+ };
33
+ }
34
+
35
+ /**
36
+ * Disable diagnostic logging
37
+ */
38
+ export function disableDiagnostics(): void {
39
+ config = { ...defaultConfig };
40
+ }
41
+
42
+ /**
43
+ * Get current diagnostic configuration
44
+ */
45
+ export function getDiagnosticConfig(): DiagnosticConfig {
46
+ return { ...config };
47
+ }
48
+
49
+ /**
50
+ * Log parsing activity
51
+ */
52
+ export function logParsing(message: string, data?: unknown): void {
53
+ if (config.enabled && config.logParsing) {
54
+ console.log(`[PARSE] ${message}`, data !== undefined ? data : '');
55
+ }
56
+ }
57
+
58
+ /**
59
+ * Log serialization activity
60
+ */
61
+ export function logSerialization(message: string, data?: unknown): void {
62
+ if (config.enabled && config.logSerialization) {
63
+ console.log(`[SERIALIZE] ${message}`, data !== undefined ? data : '');
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Log text direction properties
69
+ */
70
+ export function logTextDirection(message: string, data?: unknown): void {
71
+ if (config.enabled && config.logTextDirection) {
72
+ console.log(`[TEXT-DIR] ${message}`, data !== undefined ? data : '');
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Log verbose details
78
+ */
79
+ export function logVerbose(message: string, data?: unknown): void {
80
+ if (config.enabled && config.verbose) {
81
+ console.log(`[VERBOSE] ${message}`, data !== undefined ? data : '');
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Log paragraph content summary
87
+ */
88
+ export function logParagraphContent(
89
+ source: 'parsing' | 'serialization',
90
+ paraIndex: number,
91
+ runs: { text: string; rtl?: boolean }[],
92
+ bidi?: boolean
93
+ ): void {
94
+ if (!config.enabled) return;
95
+
96
+ const logger = source === 'parsing' ? logParsing : logSerialization;
97
+
98
+ logger(`Paragraph ${paraIndex}:`);
99
+ logger(` BiDi: ${bidi !== undefined ? bidi : 'not set'}`);
100
+ logger(` Runs (${runs.length}):`);
101
+
102
+ runs.forEach((run, idx) => {
103
+ const rtlStatus = run.rtl ? ' [RTL]' : '';
104
+ logger(` ${idx + 1}. "${run.text}"${rtlStatus}`);
105
+ });
106
+
107
+ const fullText = runs.map(r => r.text).join('');
108
+ logger(` Combined text: "${fullText}"`);
109
+ }
110
+
111
+ /**
112
+ * Compare text before and after processing
113
+ */
114
+ export function logTextComparison(
115
+ label: string,
116
+ before: string,
117
+ after: string
118
+ ): void {
119
+ if (!config.enabled) return;
120
+
121
+ if (before !== after) {
122
+ console.log(`[TEXT-CHANGE] ${label}:`);
123
+ console.log(` Before: "${before}"`);
124
+ console.log(` After: "${after}"`);
125
+ console.log(` MISMATCH DETECTED!`);
126
+ } else if (config.verbose) {
127
+ logVerbose(`${label}: Text preserved correctly`);
128
+ }
129
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Error handling utilities for consistent error processing
3
+ * Ensures all caught errors are properly typed and handled
4
+ */
5
+
6
+ /**
7
+ * Type guard to check if a value is an Error object
8
+ * @param error - The value to check
9
+ * @returns True if the value is an Error instance
10
+ */
11
+ export function isError(error: unknown): error is Error {
12
+ return error instanceof Error;
13
+ }
14
+
15
+ /**
16
+ * Converts unknown error to Error object
17
+ * Ensures we always have a proper Error with message property
18
+ * @param error - The error to normalize (can be anything)
19
+ * @returns Normalized Error object
20
+ */
21
+ export function toError(error: unknown): Error {
22
+ if (isError(error)) {
23
+ return error;
24
+ }
25
+
26
+ // Handle string errors
27
+ if (typeof error === 'string') {
28
+ return new Error(error);
29
+ }
30
+
31
+ // Handle objects with message property
32
+ if (error && typeof error === 'object' && 'message' in error) {
33
+ return new Error(String(error.message));
34
+ }
35
+
36
+ // Fallback for any other type
37
+ return new Error(String(error));
38
+ }
39
+
40
+ /**
41
+ * Wraps an error with additional context
42
+ * Useful for adding file paths, operation names, etc.
43
+ * @param error - The original error
44
+ * @param context - Additional context to prepend to error message
45
+ * @returns New Error with combined message and original stack
46
+ */
47
+ export function wrapError(error: unknown, context: string): Error {
48
+ const originalError = toError(error);
49
+ const wrappedError = new Error(`${context}: ${originalError.message}`);
50
+
51
+ // Preserve original stack trace if available
52
+ if (originalError.stack) {
53
+ wrappedError.stack = `${wrappedError.message}\nCaused by: ${originalError.stack}`;
54
+ }
55
+
56
+ return wrappedError;
57
+ }
58
+
59
+ /**
60
+ * Safe error message extraction
61
+ * Returns error message or generic fallback
62
+ * @param error - The error to extract message from
63
+ * @param fallback - Fallback message if extraction fails
64
+ * @returns Error message string
65
+ */
66
+ export function getErrorMessage(error: unknown, fallback = 'Unknown error occurred'): string {
67
+ if (isError(error)) {
68
+ return error.message;
69
+ }
70
+
71
+ if (typeof error === 'string') {
72
+ return error;
73
+ }
74
+
75
+ if (error && typeof error === 'object' && 'message' in error) {
76
+ return String(error.message);
77
+ }
78
+
79
+ return fallback;
80
+ }
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Formatting utilities for deep merging and cloning formatting objects
3
+ * Used for style inheritance and applying formatting
4
+ */
5
+
6
+ /**
7
+ * Deep merges two formatting objects, with override taking precedence
8
+ * Used for style inheritance and applying formatting
9
+ *
10
+ * @param base - Base formatting object
11
+ * @param override - Override formatting object (takes precedence)
12
+ * @returns Merged formatting object
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const baseFormat = { bold: true, fontSize: 24 };
17
+ * const overrideFormat = { fontSize: 28, italic: true };
18
+ * const result = mergeFormatting(baseFormat, overrideFormat);
19
+ * // Result: { bold: true, fontSize: 28, italic: true }
20
+ * ```
21
+ */
22
+ export function mergeFormatting<T extends Record<string, any>>(
23
+ base: T,
24
+ override: Partial<T>
25
+ ): T {
26
+ const result = { ...base };
27
+
28
+ for (const [key, value] of Object.entries(override)) {
29
+ if (value === undefined) continue;
30
+
31
+ if (typeof value === 'object' && !Array.isArray(value) && value !== null) {
32
+ // Deep merge nested objects
33
+ result[key as keyof T] = mergeFormatting(
34
+ result[key as keyof T] || ({} as any),
35
+ value
36
+ );
37
+ } else {
38
+ // Direct assignment for primitives
39
+ result[key as keyof T] = value;
40
+ }
41
+ }
42
+
43
+ return result;
44
+ }
45
+
46
+ /**
47
+ * Deep clones a formatting object
48
+ * Creates a completely independent copy with no shared references
49
+ *
50
+ * @param formatting - Formatting object to clone
51
+ * @returns Cloned formatting object
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const original = { bold: true, indentation: { left: 100 } };
56
+ * const cloned = cloneFormatting(original);
57
+ * cloned.indentation.left = 200; // Doesn't affect original
58
+ * ```
59
+ */
60
+ export function cloneFormatting<T>(formatting: T): T {
61
+ return JSON.parse(JSON.stringify(formatting));
62
+ }
63
+
64
+ /**
65
+ * Checks if a formatting object has any defined properties
66
+ *
67
+ * @param formatting - Formatting object to check
68
+ * @returns True if the object has at least one defined property
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * hasFormatting({}) // false
73
+ * hasFormatting({ bold: true }) // true
74
+ * hasFormatting({ bold: undefined }) // false
75
+ * ```
76
+ */
77
+ export function hasFormatting(formatting: Record<string, unknown>): boolean {
78
+ for (const value of Object.values(formatting)) {
79
+ if (value !== undefined && value !== null) {
80
+ return true;
81
+ }
82
+ }
83
+ return false;
84
+ }
85
+
86
+ /**
87
+ * Removes undefined and null properties from a formatting object
88
+ * Useful for cleaning up formatting before comparison or serialization
89
+ *
90
+ * @param formatting - Formatting object to clean
91
+ * @returns Cleaned formatting object with no undefined/null values
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * const dirty = { bold: true, italic: undefined, fontSize: null, underline: false };
96
+ * const clean = cleanFormatting(dirty);
97
+ * // Result: { bold: true, underline: false }
98
+ * ```
99
+ */
100
+ export function cleanFormatting<T extends Record<string, any>>(formatting: T): Partial<T> {
101
+ const cleaned: Partial<T> = {};
102
+
103
+ for (const [key, value] of Object.entries(formatting)) {
104
+ if (value !== undefined && value !== null) {
105
+ if (typeof value === 'object' && !Array.isArray(value)) {
106
+ // Recursively clean nested objects
107
+ const cleanedNested = cleanFormatting(value);
108
+ if (Object.keys(cleanedNested).length > 0) {
109
+ cleaned[key as keyof T] = cleanedNested as any;
110
+ }
111
+ } else {
112
+ cleaned[key as keyof T] = value;
113
+ }
114
+ }
115
+ }
116
+
117
+ return cleaned;
118
+ }
119
+
120
+ /**
121
+ * Compares two formatting objects for equality
122
+ * Performs deep comparison of all properties
123
+ *
124
+ * @param format1 - First formatting object
125
+ * @param format2 - Second formatting object
126
+ * @returns True if the formatting objects are equal
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * const a = { bold: true, fontSize: 24 };
131
+ * const b = { bold: true, fontSize: 24 };
132
+ * const c = { bold: true, fontSize: 28 };
133
+ * isEqualFormatting(a, b) // true
134
+ * isEqualFormatting(a, c) // false
135
+ * ```
136
+ */
137
+ export function isEqualFormatting(
138
+ format1: Record<string, unknown>,
139
+ format2: Record<string, unknown>
140
+ ): boolean {
141
+ // Quick reference check
142
+ if (format1 === format2) return true;
143
+
144
+ // Null/undefined checks
145
+ if (!format1 || !format2) return false;
146
+
147
+ // Get all keys from both objects
148
+ const keys1 = Object.keys(format1);
149
+ const keys2 = Object.keys(format2);
150
+
151
+ // Check if they have the same number of properties
152
+ if (keys1.length !== keys2.length) return false;
153
+
154
+ // Check all properties
155
+ for (const key of keys1) {
156
+ const val1 = format1[key];
157
+ const val2 = format2[key];
158
+
159
+ // Both undefined/null - considered equal
160
+ if ((val1 === undefined || val1 === null) && (val2 === undefined || val2 === null)) {
161
+ continue;
162
+ }
163
+
164
+ // One is undefined/null and the other isn't
165
+ if ((val1 === undefined || val1 === null) !== (val2 === undefined || val2 === null)) {
166
+ return false;
167
+ }
168
+
169
+ // Check nested objects
170
+ if (typeof val1 === 'object' && val1 !== null && typeof val2 === 'object' && val2 !== null && !Array.isArray(val1) && !Array.isArray(val2)) {
171
+ if (!isEqualFormatting(val1 as Record<string, unknown>, val2 as Record<string, unknown>)) return false;
172
+ } else if (val1 !== val2) {
173
+ return false;
174
+ }
175
+ }
176
+
177
+ return true;
178
+ }
179
+
180
+ /**
181
+ * Applies default values to a formatting object for any undefined properties
182
+ *
183
+ * @param formatting - Formatting object to apply defaults to
184
+ * @param defaults - Default values
185
+ * @returns Formatting object with defaults applied
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * const format = { bold: true };
190
+ * const defaults = { bold: false, italic: false, fontSize: 24 };
191
+ * const result = applyDefaults(format, defaults);
192
+ * // Result: { bold: true, italic: false, fontSize: 24 }
193
+ * ```
194
+ */
195
+ export function applyDefaults<T extends Record<string, any>>(
196
+ formatting: Partial<T>,
197
+ defaults: T
198
+ ): T {
199
+ const result = { ...defaults };
200
+
201
+ for (const [key, value] of Object.entries(formatting)) {
202
+ if (value !== undefined) {
203
+ if (typeof value === 'object' && !Array.isArray(value) && value !== null && typeof defaults[key] === 'object') {
204
+ // Deep merge nested objects
205
+ result[key as keyof T] = applyDefaults(value, defaults[key]);
206
+ } else {
207
+ result[key as keyof T] = value;
208
+ }
209
+ }
210
+ }
211
+
212
+ return result;
213
+ }
@@ -0,0 +1,274 @@
1
+ /**
2
+ * List Detection Utilities for docxmlater
3
+ *
4
+ * Provides functions to detect typed list prefixes and analyze
5
+ * paragraph list properties.
6
+ */
7
+
8
+ import type { Paragraph } from "../elements/Paragraph";
9
+ import type {
10
+ ListCategory,
11
+ ListDetectionResult,
12
+ NumberFormat,
13
+ BulletFormat,
14
+ } from "../types/list-types";
15
+
16
+ // =============================================================================
17
+ // CONSTANTS
18
+ // =============================================================================
19
+
20
+ /**
21
+ * Regex patterns for typed list prefixes.
22
+ * Order matters: more specific patterns first.
23
+ */
24
+ export const TYPED_LIST_PATTERNS: Record<string, RegExp> = {
25
+ // Numbered patterns (capture the marker for validation)
26
+ decimal: /^(\d+)[.)]\s+/,
27
+ lowerLetter: /^([a-z])[.)]\s+/,
28
+ upperLetter: /^([A-Z])[.)]\s+/,
29
+ lowerRoman: /^((?:i{1,3}|iv|vi{0,3}|ix|x{1,3}))[.)]\s+/i,
30
+
31
+ // Bullet patterns
32
+ bullet: /^[•●○◦▪■□]\s+/,
33
+ dash: /^[-–—]\s+/,
34
+ arrow: /^[►▸▶→]\s+/,
35
+ };
36
+
37
+ /** Map pattern names to categories */
38
+ export const PATTERN_TO_CATEGORY: Record<string, ListCategory> = {
39
+ decimal: "numbered",
40
+ lowerLetter: "numbered",
41
+ upperLetter: "numbered",
42
+ lowerRoman: "numbered",
43
+ bullet: "bullet",
44
+ dash: "bullet",
45
+ arrow: "bullet",
46
+ };
47
+
48
+ /**
49
+ * Map typed prefix format to Word numbering level.
50
+ * Word's default multilevel list uses:
51
+ * Level 0: 1., 2., 3. (decimal)
52
+ * Level 1: a., b., c. (lowerLetter)
53
+ * Level 2: i., ii., iii. (lowerRoman)
54
+ */
55
+ export const FORMAT_TO_LEVEL: Record<string, number> = {
56
+ decimal: 0, // 1., 2., 3.
57
+ lowerLetter: 1, // a., b., c.
58
+ upperLetter: 1, // A., B., C.
59
+ lowerRoman: 2, // i., ii., iii.
60
+ upperRoman: 2, // I., II., III.
61
+ bullet: 0, // Top-level bullet (filled circle)
62
+ dash: 0, // Top-level dash marker
63
+ arrow: 0, // Top-level arrow marker
64
+ };
65
+
66
+ /**
67
+ * Get the Word numbering level for a given format.
68
+ * Returns 0 (top level) for decimal or unknown formats.
69
+ */
70
+ export function getLevelFromFormat(format: string | null): number {
71
+ if (!format) return 0;
72
+ return FORMAT_TO_LEVEL[format] ?? 0;
73
+ }
74
+
75
+ /**
76
+ * Word standard indentation values in twips.
77
+ * Level 0: 720 twips (0.5 inch) left indent
78
+ * Level 1: 1080 twips (0.75 inch) left indent
79
+ * Level 2: 1440 twips (1 inch) left indent
80
+ * Each subsequent level adds 360 twips.
81
+ */
82
+ const WORD_BASE_INDENT = 720;
83
+ const INDENT_PER_LEVEL = 360;
84
+
85
+ // =============================================================================
86
+ // CORE DETECTION FUNCTIONS
87
+ // =============================================================================
88
+
89
+ /**
90
+ * Infer list level from indentation.
91
+ * Uses standard Word indentation: 720 twips for level 0, +360 per level.
92
+ */
93
+ export function inferLevelFromIndentation(indentTwips: number): number {
94
+ if (indentTwips < WORD_BASE_INDENT) return 0;
95
+ return Math.floor((indentTwips - WORD_BASE_INDENT) / INDENT_PER_LEVEL);
96
+ }
97
+
98
+ /**
99
+ * Infer list level from relative indentation (baseline already subtracted).
100
+ * Used when normalizing lists within a table cell where the baseline
101
+ * indentation varies per cell.
102
+ */
103
+ export function inferLevelFromRelativeIndentation(relativeIndentTwips: number): number {
104
+ if (relativeIndentTwips <= 0) return 0;
105
+ return Math.min(8, Math.floor(relativeIndentTwips / INDENT_PER_LEVEL));
106
+ }
107
+
108
+ /**
109
+ * Detect typed list prefix in text.
110
+ * Returns the matched prefix and format type.
111
+ *
112
+ * Special handling for abbreviations:
113
+ * - Single letter prefixes (A., B., P.) are NOT treated as list markers
114
+ * if the remaining text also starts with a letter+period pattern,
115
+ * indicating an abbreviation like "P.O. Box", "U.S. Army", etc.
116
+ */
117
+ export function detectTypedPrefix(text: string): {
118
+ prefix: string | null;
119
+ format: NumberFormat | BulletFormat | null;
120
+ category: ListCategory;
121
+ } {
122
+ for (const [format, regex] of Object.entries(TYPED_LIST_PATTERNS)) {
123
+ const match = text.match(regex);
124
+ if (match) {
125
+ // Special check for single-letter patterns (lowerLetter, upperLetter)
126
+ // to avoid false positives on abbreviations like "P.O. Box", "U.S.", "A.M."
127
+ if (format === "lowerLetter" || format === "upperLetter") {
128
+ const remaining = text.substring(match[0].length);
129
+ // If remaining text starts with another letter followed by period,
130
+ // this is likely an abbreviation, not a list marker
131
+ if (/^[A-Za-z]\./.test(remaining)) {
132
+ continue; // Skip this pattern, try others
133
+ }
134
+ }
135
+
136
+ return {
137
+ prefix: match[0],
138
+ format: format as NumberFormat | BulletFormat,
139
+ category: PATTERN_TO_CATEGORY[format] ?? "none",
140
+ };
141
+ }
142
+ }
143
+
144
+ return { prefix: null, format: null, category: "none" };
145
+ }
146
+
147
+ /**
148
+ * Get the left indentation from a paragraph in twips.
149
+ */
150
+ export function getParagraphIndentation(paragraph: Paragraph): number {
151
+ const formatting = paragraph.getFormatting();
152
+ return formatting?.indentation?.left ?? 0;
153
+ }
154
+
155
+ /**
156
+ * Main detection function: analyze a single paragraph for list properties.
157
+ */
158
+ export function detectListType(paragraph: Paragraph): ListDetectionResult {
159
+ const text = paragraph.getText();
160
+ const indentation = getParagraphIndentation(paragraph);
161
+ const numbering = paragraph.getNumbering();
162
+
163
+ // Priority 1: Real Word list with <w:numPr>
164
+ if (numbering?.numId !== undefined && numbering.numId !== 0) {
165
+ return {
166
+ category: "numbered", // Default, caller can refine with NumberingManager lookup
167
+ isWordList: true,
168
+ typedPrefix: null,
169
+ inferredLevel: numbering.level ?? 0,
170
+ format: null, // Would need numbering.xml lookup
171
+ numId: numbering.numId,
172
+ ilvl: numbering.level ?? 0,
173
+ indentationTwips: indentation,
174
+ };
175
+ }
176
+
177
+ // Priority 2: Typed prefix detection
178
+ const typed = detectTypedPrefix(text);
179
+ if (typed.prefix) {
180
+ return {
181
+ category: typed.category,
182
+ isWordList: false,
183
+ typedPrefix: typed.prefix,
184
+ // Use FORMAT to determine level, not indentation!
185
+ // decimal=0, lowerLetter=1, lowerRoman=2
186
+ inferredLevel: getLevelFromFormat(typed.format),
187
+ format: typed.format,
188
+ numId: null,
189
+ ilvl: null,
190
+ indentationTwips: indentation,
191
+ };
192
+ }
193
+
194
+ // Priority 3: Not a list
195
+ return {
196
+ category: "none",
197
+ isWordList: false,
198
+ typedPrefix: null,
199
+ inferredLevel: 0,
200
+ format: null,
201
+ numId: null,
202
+ ilvl: null,
203
+ indentationTwips: indentation,
204
+ };
205
+ }
206
+
207
+ /**
208
+ * Validate that a typed prefix sequence is reasonable.
209
+ * E.g., "1. 2. 3." is valid, "1. 5. 2." is suspicious.
210
+ */
211
+ export function validateListSequence(
212
+ paragraphs: { detection: ListDetectionResult; text: string }[]
213
+ ): { valid: boolean; warnings: string[] } {
214
+ const warnings: string[] = [];
215
+ let lastDecimal = 0;
216
+ let lastLetter = "";
217
+
218
+ for (const { detection } of paragraphs) {
219
+ if (!detection.typedPrefix || detection.category !== "numbered") continue;
220
+
221
+ const match = /^(\d+|[a-zA-Z]+)/.exec(detection.typedPrefix);
222
+ if (!match?.[1]) continue;
223
+
224
+ const marker = match[1];
225
+
226
+ // Check decimal sequence
227
+ if (/^\d+$/.test(marker)) {
228
+ const num = parseInt(marker, 10);
229
+ if (lastDecimal > 0 && num !== lastDecimal + 1 && num !== 1) {
230
+ warnings.push(`Unexpected number sequence: ${lastDecimal} → ${num}`);
231
+ }
232
+ lastDecimal = num;
233
+ }
234
+
235
+ // Check letter sequence
236
+ if (/^[a-z]$/i.test(marker)) {
237
+ const letter = marker.toLowerCase();
238
+ if (
239
+ lastLetter &&
240
+ letter.charCodeAt(0) !== lastLetter.charCodeAt(0) + 1 &&
241
+ letter !== "a"
242
+ ) {
243
+ warnings.push(`Unexpected letter sequence: ${lastLetter} → ${letter}`);
244
+ }
245
+ lastLetter = letter;
246
+ }
247
+ }
248
+
249
+ return { valid: warnings.length === 0, warnings };
250
+ }
251
+
252
+ /**
253
+ * Determine the list category for a given numId by checking the abstractNum.
254
+ * This requires access to the NumberingManager.
255
+ */
256
+ export function getListCategoryFromFormat(
257
+ format: string | undefined
258
+ ): ListCategory {
259
+ if (!format) return "none";
260
+
261
+ if (["bullet", "dash", "arrow"].includes(format)) {
262
+ return "bullet";
263
+ }
264
+
265
+ if (
266
+ ["decimal", "lowerLetter", "upperLetter", "lowerRoman", "upperRoman"].includes(
267
+ format
268
+ )
269
+ ) {
270
+ return "numbered";
271
+ }
272
+
273
+ return "none";
274
+ }