@stll/folio-core 0.46.0 → 0.47.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (370) hide show
  1. package/dist/ai-edits/apply.d.ts +17 -1
  2. package/dist/ai-edits/apply.js +31 -27
  3. package/dist/ai-edits/headless.d.ts +9 -2
  4. package/dist/ai-edits/headless.js +5 -3
  5. package/dist/ai-edits/read.d.ts +1 -0
  6. package/dist/ai-edits/read.js +1 -0
  7. package/dist/ai-edits/snapshot.js +32 -27
  8. package/dist/ai-edits/table-cell-mutations.js +15 -7
  9. package/dist/ai-edits/table-geometry.js +21 -18
  10. package/dist/ai-edits/table-template.js +2 -2
  11. package/dist/compare/compare.js +2 -1
  12. package/dist/compare/content-alignment.js +192 -46
  13. package/dist/compare/content-types.d.ts +8 -2
  14. package/dist/compare/content.js +2 -11
  15. package/dist/compare/plan.js +7 -4
  16. package/dist/compare/section-boundary-properties.js +1 -2
  17. package/dist/content-controls/checkboxDisplay.d.ts +8 -2
  18. package/dist/content-controls/checkboxDisplay.js +11 -5
  19. package/dist/content-controls/mutateContentControls.js +41 -42
  20. package/dist/controller/layoutPipeline.js +8 -3
  21. package/dist/display-list/build/buildDisplayList.js +7 -7
  22. package/dist/display-list/build/imagePrimitives.d.ts +4 -4
  23. package/dist/display-list/build/imagePrimitives.js +38 -20
  24. package/dist/display-list/build/pageBorderPrimitives.js +2 -1
  25. package/dist/display-list/build/paragraphPrimitives.js +93 -13
  26. package/dist/display-list/build/previewPrimitives.d.ts +10 -0
  27. package/dist/display-list/build/previewPrimitives.js +89 -0
  28. package/dist/display-list/build/strokes.d.ts +177 -8
  29. package/dist/display-list/build/strokes.js +167 -47
  30. package/dist/display-list/build/tablePrimitives.js +4 -2
  31. package/dist/display-list/build/textBoxPrimitives.js +6 -4
  32. package/dist/display-list/build/textDecorations.d.ts +15 -1
  33. package/dist/display-list/build/textDecorations.js +15 -1
  34. package/dist/display-list/dom/renderDisplayListToDom.js +1 -19
  35. package/dist/display-list/primitives.d.ts +13 -2
  36. package/dist/display-list/primitives.js +36 -1
  37. package/dist/document-operations.d.ts +9 -2
  38. package/dist/document-operations.js +5 -3
  39. package/dist/docx/attributeRemainder.d.ts +34 -1
  40. package/dist/docx/attributeRemainder.js +49 -3
  41. package/dist/docx/blockContentParser.d.ts +2 -0
  42. package/dist/docx/blockContentParser.js +39 -67
  43. package/dist/docx/blockPlainText.js +3 -1
  44. package/dist/docx/borderParser.js +26 -11
  45. package/dist/docx/builtInStyles.d.ts +8 -16
  46. package/dist/docx/builtInStyles.js +54 -17
  47. package/dist/docx/commentAnchorIndex.js +1 -1
  48. package/dist/docx/commentParser.js +3 -3
  49. package/dist/docx/commentRangeIntegrity.js +1 -1
  50. package/dist/docx/commentRangeJoin.js +1 -1
  51. package/dist/docx/commentReferenceNormalization.js +3 -2
  52. package/dist/docx/commentReplyMarkers.js +1 -1
  53. package/dist/docx/compatibility.js +56 -42
  54. package/dist/docx/containerChildren.d.ts +110 -13
  55. package/dist/docx/containerChildren.gen.d.ts +16 -1
  56. package/dist/docx/containerChildren.gen.js +18 -1
  57. package/dist/docx/containerChildren.js +63 -13
  58. package/dist/docx/diagramPreview.d.ts +14 -2
  59. package/dist/docx/diagramPreview.js +81 -169
  60. package/dist/docx/documentParser.js +4 -1
  61. package/dist/docx/drawingAnchor.d.ts +87 -0
  62. package/dist/docx/drawingAnchor.js +201 -0
  63. package/dist/docx/drawingUtils.d.ts +43 -38
  64. package/dist/docx/drawingUtils.js +205 -118
  65. package/dist/docx/fontTableParser.js +102 -41
  66. package/dist/docx/footnoteParser.js +10 -6
  67. package/dist/docx/groupDrawingParser.js +4 -3
  68. package/dist/docx/headerFooterReferenceNormalization.js +1 -1
  69. package/dist/docx/hyperlinkParser.d.ts +45 -7
  70. package/dist/docx/hyperlinkParser.js +126 -57
  71. package/dist/docx/imageParser.js +127 -107
  72. package/dist/docx/index.d.ts +2 -1
  73. package/dist/docx/index.js +2 -1
  74. package/dist/docx/inlineContentRemovals.d.ts +28 -0
  75. package/dist/docx/inlineContentRemovals.js +46 -0
  76. package/dist/docx/inlineWrapperContent.d.ts +84 -3
  77. package/dist/docx/inlineWrapperContent.js +85 -4
  78. package/dist/docx/inlineWrapperParser.d.ts +11 -0
  79. package/dist/docx/inlineWrapperParser.js +60 -0
  80. package/dist/docx/nonVisualDrawingProps.d.ts +5 -13
  81. package/dist/docx/normalizeBaseDirection.js +4 -2
  82. package/dist/docx/numberingParser.d.ts +25 -2
  83. package/dist/docx/numberingParser.js +264 -361
  84. package/dist/docx/numberingReference.d.ts +9 -16
  85. package/dist/docx/numberingReference.js +17 -16
  86. package/dist/docx/numberingReferenceNormalization.js +7 -7
  87. package/dist/docx/ooxmlCounterFormatter.d.ts +1 -1
  88. package/dist/docx/ooxmlCounterFormatter.js +4 -1
  89. package/dist/docx/paraIdAttribute.d.ts +91 -1
  90. package/dist/docx/paraIdAttribute.js +79 -1
  91. package/dist/docx/paragraphParser.d.ts +9 -24
  92. package/dist/docx/paragraphParser.js +212 -396
  93. package/dist/docx/paragraphProperties.d.ts +23 -0
  94. package/dist/docx/paragraphProperties.js +279 -0
  95. package/dist/docx/paragraphPropertySource.js +2 -0
  96. package/dist/docx/paragraphTextBoxEnrichment.d.ts +2 -1
  97. package/dist/docx/paragraphTextBoxEnrichment.js +14 -7
  98. package/dist/docx/paragraphTraversal.d.ts +14 -10
  99. package/dist/docx/paragraphTraversal.js +47 -49
  100. package/dist/docx/parseWarningMessage.js +3 -0
  101. package/dist/docx/parserEnums.d.ts +6 -8
  102. package/dist/docx/parserEnums.js +4 -6
  103. package/dist/docx/preservedRunContent.js +16 -6
  104. package/dist/docx/previewBudget.d.ts +44 -23
  105. package/dist/docx/previewBudget.js +61 -30
  106. package/dist/docx/propertyElementAttributes.d.ts +178 -0
  107. package/dist/docx/propertyElementAttributes.js +114 -0
  108. package/dist/docx/renderedPageBreakNormalization.js +2 -2
  109. package/dist/docx/rezip.d.ts +28 -2
  110. package/dist/docx/rezip.js +78 -9
  111. package/dist/docx/runConsolidator.d.ts +42 -2
  112. package/dist/docx/runConsolidator.js +60 -6
  113. package/dist/docx/runParser.d.ts +54 -18
  114. package/dist/docx/runParser.js +379 -295
  115. package/dist/docx/runPayload.d.ts +5 -0
  116. package/dist/docx/runPayload.js +4 -0
  117. package/dist/docx/sdtProperties.d.ts +39 -5
  118. package/dist/docx/sdtProperties.js +205 -84
  119. package/dist/docx/sdtPropertiesPatch.d.ts +5 -9
  120. package/dist/docx/sdtPropertiesPatch.js +68 -112
  121. package/dist/docx/sectionParser.d.ts +1 -2
  122. package/dist/docx/sectionParser.js +236 -240
  123. package/dist/docx/selectiveSave.js +3 -2
  124. package/dist/docx/selectiveXmlPatch.d.ts +21 -2
  125. package/dist/docx/selectiveXmlPatch.js +195 -99
  126. package/dist/docx/serializer/blockSdtSerializer.js +2 -96
  127. package/dist/docx/serializer/borderSerializer.d.ts +5 -5
  128. package/dist/docx/serializer/borderSerializer.js +10 -8
  129. package/dist/docx/serializer/documentSerializer.js +3 -0
  130. package/dist/docx/serializer/fontTableSerializer.js +31 -3
  131. package/dist/docx/serializer/headerFooterSerializer.js +3 -0
  132. package/dist/docx/serializer/markupRangeAttributes.d.ts +9 -1
  133. package/dist/docx/serializer/markupRangeAttributes.js +9 -1
  134. package/dist/docx/serializer/noteSerializer.js +3 -0
  135. package/dist/docx/serializer/numberingSerializer.d.ts +1 -6
  136. package/dist/docx/serializer/numberingSerializer.js +81 -79
  137. package/dist/docx/serializer/paragraphSerializer.d.ts +1 -9
  138. package/dist/docx/serializer/paragraphSerializer.js +88 -188
  139. package/dist/docx/serializer/runSerializer.d.ts +1 -5
  140. package/dist/docx/serializer/runSerializer.js +109 -59
  141. package/dist/docx/serializer/sdtPropertiesSerializer.d.ts +26 -0
  142. package/dist/docx/serializer/sdtPropertiesSerializer.js +111 -0
  143. package/dist/docx/serializer/sectionPropertiesSerializer.js +34 -45
  144. package/dist/docx/serializer/settingsSerializer.js +6 -4
  145. package/dist/docx/serializer/stylesSerializer.js +8 -11
  146. package/dist/docx/serializer/tableSerializer.js +268 -100
  147. package/dist/docx/serializer/textFormattingSerializer.d.ts +28 -4
  148. package/dist/docx/serializer/textFormattingSerializer.js +111 -101
  149. package/dist/docx/serializer/xmlUtils.d.ts +1 -1
  150. package/dist/docx/serializer/xmlUtils.js +1 -1
  151. package/dist/docx/server/createBilingualDocument.js +18 -16
  152. package/dist/docx/server/migrateYjsAttrSchema.js +3 -3
  153. package/dist/docx/settingsParser.js +7 -4
  154. package/dist/docx/shadingParser.d.ts +2 -1
  155. package/dist/docx/shadingParser.js +43 -7
  156. package/dist/docx/shapeParser.js +8 -3
  157. package/dist/docx/strictNames.d.ts +11 -0
  158. package/dist/docx/strictNames.gen.d.ts +45 -0
  159. package/dist/docx/strictNames.gen.js +50 -0
  160. package/dist/docx/strictNames.js +43 -0
  161. package/dist/docx/strictValueEncodings.gen.js +133 -131
  162. package/dist/docx/styleParser.js +17 -349
  163. package/dist/docx/tableParser.d.ts +10 -1
  164. package/dist/docx/tableParser.js +505 -181
  165. package/dist/docx/textBoxParser.d.ts +3 -1
  166. package/dist/docx/textBoxParser.js +18 -8
  167. package/dist/docx/themeColorAttribute.d.ts +13 -0
  168. package/dist/docx/themeColorAttribute.js +24 -0
  169. package/dist/docx/trackedMoveRangeNormalization.js +2 -1
  170. package/dist/docx/vmlImageParser.d.ts +13 -4
  171. package/dist/docx/vmlImageParser.js +74 -31
  172. package/dist/docx/vmlPreview.js +2 -2
  173. package/dist/docx/wrapPolygon.d.ts +30 -0
  174. package/dist/docx/wrapPolygon.js +70 -0
  175. package/dist/docx/xmlParser.d.ts +14 -1
  176. package/dist/docx/xmlParser.js +18 -2
  177. package/dist/fonts/embeddedFonts.js +3 -3
  178. package/dist/headless-layout.js +2 -0
  179. package/dist/i18n/messages/catalogs.gen.d.ts +68 -0
  180. package/dist/i18n/messages/catalogs.gen.js +102 -34
  181. package/dist/i18n/messages/messages.gen.d.ts +4 -0
  182. package/dist/internal/headlessRevisionResolution.js +9 -0
  183. package/dist/internal/pageBreakRunSourceDescendantIndex.js +3 -1
  184. package/dist/internal/paragraphFormattingSerialization.d.ts +20 -9
  185. package/dist/internal/paragraphFormattingSerialization.js +118 -83
  186. package/dist/layout-bridge/convert/footnoteLayout.d.ts +1 -0
  187. package/dist/layout-bridge/convert/footnoteLayout.js +1 -0
  188. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +1 -0
  189. package/dist/layout-bridge/convert/headerFooterLayout.js +2 -0
  190. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +17 -12
  191. package/dist/layout-bridge/convert/toFlowBlocks.js +177 -101
  192. package/dist/layout-engine/index.d.ts +2 -2
  193. package/dist/layout-engine/index.js +53 -17
  194. package/dist/layout-engine/measure/measureBlocks.d.ts +3 -0
  195. package/dist/layout-engine/measure/measureBlocks.js +6 -10
  196. package/dist/layout-engine/measure/tableCellGrid.js +2 -1
  197. package/dist/layout-engine/measure/tableFragmentBorderGeometry.js +2 -1
  198. package/dist/layout-engine/measure/tableInlinePlacement.js +2 -5
  199. package/dist/layout-engine/paragraphSequence.js +3 -2
  200. package/dist/layout-engine/renderedBreakReconciliation.js +2 -1
  201. package/dist/layout-engine/section-breaks.d.ts +49 -2
  202. package/dist/layout-engine/section-breaks.js +55 -4
  203. package/dist/layout-engine/types.d.ts +47 -17
  204. package/dist/layout-engine/types.js +16 -1
  205. package/dist/layout-painter/borderStroke.d.ts +18 -4
  206. package/dist/layout-painter/renderPage.js +6 -4
  207. package/dist/layout-painter/renderParagraph.d.ts +2 -1
  208. package/dist/layout-painter/renderParagraph.js +13 -26
  209. package/dist/layout-painter/renderTable.d.ts +4 -1
  210. package/dist/layout-painter/renderTable.js +22 -22
  211. package/dist/layout-painter/renderTextBox.js +5 -3
  212. package/dist/markdown/renderBlock.js +3 -1
  213. package/dist/markdown/renderRuns.js +7 -2
  214. package/dist/markdown/renderTable.js +2 -1
  215. package/dist/model.d.ts +3 -3
  216. package/dist/model.js +2 -2
  217. package/dist/paged-layout/sectionBlockWidths.d.ts +3 -0
  218. package/dist/paged-layout/sectionBlockWidths.js +26 -4
  219. package/dist/prosemirror/attrs/index.d.ts +22 -4
  220. package/dist/prosemirror/attrs/index.js +498 -60
  221. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +9 -1
  222. package/dist/prosemirror/bookmarkBoundaryAttrs.js +22 -3
  223. package/dist/prosemirror/commands/comments.js +68 -53
  224. package/dist/prosemirror/commands/contentControls.js +24 -19
  225. package/dist/prosemirror/commands/image.d.ts +1 -1
  226. package/dist/prosemirror/commands/image.js +4 -1
  227. package/dist/prosemirror/commands/paragraph.d.ts +2 -1
  228. package/dist/prosemirror/commands/propertyChangeScope.d.ts +12 -4
  229. package/dist/prosemirror/commands/propertyChangeScope.js +22 -4
  230. package/dist/prosemirror/commands/sectionBreak.d.ts +33 -1
  231. package/dist/prosemirror/commands/sectionBreak.js +187 -11
  232. package/dist/prosemirror/conversion/fromProseDoc.d.ts +18 -2
  233. package/dist/prosemirror/conversion/fromProseDoc.js +330 -183
  234. package/dist/prosemirror/conversion/index.d.ts +2 -2
  235. package/dist/prosemirror/conversion/preservedSinkCarriers.d.ts +39 -0
  236. package/dist/prosemirror/conversion/preservedSinkCarriers.js +19 -0
  237. package/dist/prosemirror/conversion/runShadingMark.js +14 -1
  238. package/dist/prosemirror/conversion/sdtAttrs.d.ts +10 -1
  239. package/dist/prosemirror/conversion/sdtAttrs.js +19 -5
  240. package/dist/prosemirror/conversion/toProseDoc.js +371 -141
  241. package/dist/prosemirror/emptyRangeAnchor.d.ts +53 -0
  242. package/dist/prosemirror/emptyRangeAnchor.js +158 -0
  243. package/dist/prosemirror/extensions/StarterKit.js +8 -2
  244. package/dist/prosemirror/extensions/core/DocExtension.js +1 -1
  245. package/dist/prosemirror/extensions/core/ParagraphExtension.js +19 -15
  246. package/dist/prosemirror/extensions/features/BaseKeymapExtension.js +3 -2
  247. package/dist/prosemirror/extensions/features/ListExtension.js +43 -24
  248. package/dist/prosemirror/extensions/features/ParagraphChangeTrackerExtension.js +4 -3
  249. package/dist/prosemirror/extensions/features/PasteCleanupExtension.d.ts +3 -3
  250. package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +5 -5
  251. package/dist/prosemirror/extensions/features/pasteCleanup.d.ts +3 -1
  252. package/dist/prosemirror/extensions/features/pasteCleanup.js +56 -2
  253. package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +5 -4
  254. package/dist/prosemirror/extensions/markRegistry.d.ts +26 -2
  255. package/dist/prosemirror/extensions/markRegistry.js +73 -10
  256. package/dist/prosemirror/extensions/marks/InlineWrapperExtension.js +17 -3
  257. package/dist/prosemirror/extensions/marks/RunIdentityExtension.d.ts +26 -0
  258. package/dist/prosemirror/extensions/marks/RunIdentityExtension.js +134 -0
  259. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +2 -1
  260. package/dist/prosemirror/extensions/marks/UnderlineExtension.js +12 -18
  261. package/dist/prosemirror/extensions/marks/markUtils.js +2 -1
  262. package/dist/prosemirror/extensions/nodes/BlockBookmarkBoundaryExtension.d.ts +29 -0
  263. package/dist/prosemirror/extensions/nodes/BlockBookmarkBoundaryExtension.js +46 -0
  264. package/dist/prosemirror/extensions/nodes/BlockSdtExtension.d.ts +4 -3
  265. package/dist/prosemirror/extensions/nodes/BlockSdtExtension.js +18 -13
  266. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +28 -53
  267. package/dist/prosemirror/extensions/nodes/CommentReferenceExtension.js +10 -0
  268. package/dist/prosemirror/extensions/nodes/ImageExtension.js +8 -1
  269. package/dist/prosemirror/extensions/nodes/MoveRangeBoundaryExtension.d.ts +11 -0
  270. package/dist/prosemirror/extensions/nodes/MoveRangeBoundaryExtension.js +43 -0
  271. package/dist/prosemirror/extensions/nodes/RangeAnchorExtension.d.ts +13 -0
  272. package/dist/prosemirror/extensions/nodes/RangeAnchorExtension.js +65 -0
  273. package/dist/prosemirror/extensions/nodes/SdtExtension.d.ts +3 -1
  274. package/dist/prosemirror/extensions/nodes/SdtExtension.js +22 -16
  275. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +4 -0
  276. package/dist/prosemirror/extensions/nodes/TableExtension.js +141 -123
  277. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +4 -0
  278. package/dist/prosemirror/extensions/nodes/bookmarkBoundaryDom.d.ts +23 -0
  279. package/dist/prosemirror/extensions/nodes/bookmarkBoundaryDom.js +57 -0
  280. package/dist/prosemirror/extensions/types.d.ts +12 -3
  281. package/dist/prosemirror/index.d.ts +4 -2
  282. package/dist/prosemirror/index.js +2 -1
  283. package/dist/prosemirror/inlineWrapperStack.js +20 -3
  284. package/dist/prosemirror/listMarker.d.ts +2 -2
  285. package/dist/prosemirror/listMarker.js +7 -8
  286. package/dist/prosemirror/listRenderingAttrs.js +11 -1
  287. package/dist/prosemirror/listState.d.ts +62 -0
  288. package/dist/prosemirror/listState.js +49 -0
  289. package/dist/prosemirror/moveRangeBoundaryAttrs.d.ts +13 -0
  290. package/dist/prosemirror/moveRangeBoundaryAttrs.js +114 -0
  291. package/dist/prosemirror/numberedRefFields.js +4 -4
  292. package/dist/prosemirror/numberingAttr.d.ts +55 -0
  293. package/dist/prosemirror/numberingAttr.js +74 -0
  294. package/dist/prosemirror/outlineLevelAttr.d.ts +29 -0
  295. package/dist/prosemirror/outlineLevelAttr.js +42 -0
  296. package/dist/prosemirror/paragraphFormattingProvenance.d.ts +9 -0
  297. package/dist/prosemirror/paragraphFormattingProvenance.js +4 -1
  298. package/dist/prosemirror/plugins/selectionTracker.d.ts +3 -6
  299. package/dist/prosemirror/plugins/selectionTracker.js +3 -10
  300. package/dist/prosemirror/rangeAnchorAttrs.d.ts +14 -0
  301. package/dist/prosemirror/rangeAnchorAttrs.js +101 -0
  302. package/dist/prosemirror/replacedAnnotations.d.ts +1 -1
  303. package/dist/prosemirror/replacedAnnotations.js +24 -6
  304. package/dist/prosemirror/revisionCarriers.d.ts +86 -2
  305. package/dist/prosemirror/revisionCarriers.js +86 -60
  306. package/dist/prosemirror/runFormattingInlineCarriers.d.ts +2 -0
  307. package/dist/prosemirror/runFormattingInlineCarriers.js +2 -0
  308. package/dist/prosemirror/runIdentity.d.ts +28 -0
  309. package/dist/prosemirror/runIdentity.js +36 -0
  310. package/dist/prosemirror/runStyleFormatting.js +1 -1
  311. package/dist/prosemirror/schema/index.d.ts +2 -2
  312. package/dist/prosemirror/schema/marks.d.ts +23 -4
  313. package/dist/prosemirror/schema/nodes.d.ts +220 -24
  314. package/dist/prosemirror/sectionCarrier.d.ts +37 -0
  315. package/dist/prosemirror/sectionCarrier.js +40 -0
  316. package/dist/prosemirror/selectionState.d.ts +3 -0
  317. package/dist/prosemirror/selectionState.js +4 -1
  318. package/dist/prosemirror/styles/resolvedStyleAttrs.d.ts +5 -4
  319. package/dist/prosemirror/styles/resolvedStyleAttrs.js +15 -13
  320. package/dist/prosemirror/tableResize.js +5 -6
  321. package/dist/prosemirror/trackedRunInlineAtoms.d.ts +2 -0
  322. package/dist/prosemirror/trackedRunInlineAtoms.js +2 -0
  323. package/dist/prosemirror/utils/extractTrackedChanges.d.ts +10 -11
  324. package/dist/prosemirror/utils/extractTrackedChanges.js +109 -92
  325. package/dist/prosemirror/validation.js +17 -6
  326. package/dist/prosemirror/yjsDocumentMetadata.d.ts +2 -2
  327. package/dist/prosemirror/yjsDocumentMetadata.js +428 -7
  328. package/dist/prosemirror/zeroWidthAnchors.js +4 -0
  329. package/dist/style-sets/extract.js +4 -4
  330. package/dist/style-sets/stellaStyle.js +36 -23
  331. package/dist/types/colors.d.ts +2 -2
  332. package/dist/types/content.d.ts +2 -2
  333. package/dist/types/documentEnumValues.d.ts +53 -26
  334. package/dist/types/documentEnumValues.js +72 -174
  335. package/dist/types/formatting.d.ts +2 -2
  336. package/dist/types/index.d.ts +9 -2
  337. package/dist/utils/borderCss.d.ts +246 -0
  338. package/dist/utils/borderCss.js +325 -0
  339. package/dist/utils/colorResolver.d.ts +4 -3
  340. package/dist/utils/colorResolver.js +45 -76
  341. package/dist/utils/createDocument.js +24 -6
  342. package/dist/utils/findReplace.js +52 -10
  343. package/dist/utils/formatToStyle.d.ts +84 -2
  344. package/dist/utils/formatToStyle.js +133 -52
  345. package/dist/utils/headingCollector.js +3 -2
  346. package/dist/utils/mergeDocumentContent.js +5 -3
  347. package/dist/utils/paragraphFormattingMerge.js +27 -6
  348. package/dist/utils/replaceText.js +1 -1
  349. package/dist/utils/tableOperations.d.ts +5 -3
  350. package/dist/utils/tableOperations.js +14 -1
  351. package/dist/utils/tablePlacement.d.ts +7 -0
  352. package/dist/utils/tablePlacement.js +14 -0
  353. package/dist/utils/textDirectionFlow.d.ts +15 -0
  354. package/dist/utils/textDirectionFlow.js +38 -0
  355. package/dist/utils/textFormattingMerge.js +16 -4
  356. package/package.json +10 -10
  357. package/dist/ai-edits/__fixtures__/paragraphs.d.ts +0 -17
  358. package/dist/ai-edits/__fixtures__/paragraphs.js +0 -33
  359. package/dist/compare/__fixtures__/body-sequence.d.ts +0 -119
  360. package/dist/compare/__fixtures__/body-sequence.js +0 -225
  361. package/dist/compare/__fixtures__/nested-table.d.ts +0 -16
  362. package/dist/compare/__fixtures__/nested-table.js +0 -50
  363. package/dist/compare/__fixtures__/numbered-list.d.ts +0 -34
  364. package/dist/compare/__fixtures__/numbered-list.js +0 -85
  365. package/dist/docx/bookmarkPlacement.d.ts +0 -9
  366. package/dist/docx/bookmarkPlacement.js +0 -52
  367. package/dist/fonts/embeddedFontTable.d.ts +0 -45
  368. package/dist/fonts/embeddedFontTable.js +0 -80
  369. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.d.ts +0 -13
  370. package/dist/prosemirror/extensions/marks/PageBreakRunOwnerExtension.js +0 -39
@@ -2,7 +2,7 @@ import { serializeParagraphFormatting } from "./paragraphSerializer.js";
2
2
  import { serializePartElement } from "./partNamespaces.js";
3
3
  import { serializeTableCellFormatting, serializeTableFormatting, serializeTableRowFormatting } from "./tableSerializer.js";
4
4
  import { serializeTextFormatting } from "./textFormattingSerializer.js";
5
- import { escapeXmlAttribute } from "@stll/docx-core";
5
+ import { escapeXmlAttribute, pushOnOffElement } from "@stll/docx-core";
6
6
  //#region src/docx/serializer/stylesSerializer.ts
7
7
  const serializeStylesXml = (definitions) => {
8
8
  return "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" + serializePartElement({
@@ -14,7 +14,8 @@ const serializeStylesXml = (definitions) => {
14
14
  });
15
15
  };
16
16
  const serializeDocumentDefaults = (definitions) => {
17
- return `<w:docDefaults><w:rPrDefault>${serializeTextFormatting(definitions.docDefaults?.rPr) || "<w:rPr/>"}</w:rPrDefault><w:pPrDefault>${serializeParagraphFormatting(definitions.docDefaults?.pPr) || "<w:pPr/>"}</w:pPrDefault></w:docDefaults>`;
17
+ const rPr = serializeTextFormatting(definitions.docDefaults?.rPr);
18
+ return `<w:docDefaults>${rPr === "" ? "<w:rPrDefault/>" : `<w:rPrDefault>${rPr}</w:rPrDefault>`}<w:pPrDefault>${serializeParagraphFormatting(definitions.docDefaults?.pPr) || "<w:pPr/>"}</w:pPrDefault></w:docDefaults>`;
18
19
  };
19
20
  const serializeLatentStyles = (definitions) => {
20
21
  const latent = definitions.latentStyles;
@@ -35,11 +36,11 @@ const serializeStyle = (style) => {
35
36
  if (style.next) parts.push(`<w:next w:val="${escapeXmlAttribute(style.next)}"/>`);
36
37
  if (style.link) parts.push(`<w:link w:val="${escapeXmlAttribute(style.link)}"/>`);
37
38
  if (style.uiPriority !== void 0) parts.push(`<w:uiPriority w:val="${style.uiPriority}"/>`);
38
- pushBooleanElement(parts, "hidden", style.hidden);
39
- pushBooleanElement(parts, "semiHidden", style.semiHidden);
40
- pushBooleanElement(parts, "unhideWhenUsed", style.unhideWhenUsed);
41
- pushBooleanElement(parts, "qFormat", style.qFormat);
42
- pushBooleanElement(parts, "personal", style.personal);
39
+ pushOnOffElement(parts, style.hidden, "hidden");
40
+ pushOnOffElement(parts, style.semiHidden, "semiHidden");
41
+ pushOnOffElement(parts, style.unhideWhenUsed, "unhideWhenUsed");
42
+ pushOnOffElement(parts, style.qFormat, "qFormat");
43
+ pushOnOffElement(parts, style.personal, "personal");
43
44
  parts.push(serializeParagraphFormatting(style.pPr));
44
45
  parts.push(serializeTextFormatting(style.rPr));
45
46
  parts.push(serializeTableFormatting(style.tblPr));
@@ -48,10 +49,6 @@ const serializeStyle = (style) => {
48
49
  for (const conditional of style.tblStylePr ?? []) parts.push(`<w:tblStylePr w:type="${conditional.type}">${serializeParagraphFormatting(conditional.pPr)}${serializeTextFormatting(conditional.rPr)}${serializeTableFormatting(conditional.tblPr)}${serializeTableRowFormatting(conditional.trPr)}${serializeTableCellFormatting(conditional.tcPr)}</w:tblStylePr>`);
49
50
  return `<w:style ${attrs.join(" ")}>${parts.join("")}</w:style>`;
50
51
  };
51
- const pushBooleanElement = (parts, name, value) => {
52
- if (value === true) parts.push(`<w:${name}/>`);
53
- else if (value === false) parts.push(`<w:${name} w:val="0"/>`);
54
- };
55
52
  const pushBooleanAttr = (attrs, name, value) => {
56
53
  if (value !== void 0) attrs.push(`${name}="${value ? 1 : 0}"`);
57
54
  };
@@ -1,15 +1,19 @@
1
1
  import { canonicalJson } from "../../utils/canonicalJson.js";
2
2
  import { isValidHexColor } from "../../utils/colorResolver.js";
3
3
  import { serializePreservedAttributes } from "../attributeRemainder.js";
4
- import { serializeWithPreservedChildren } from "../containerChildren.js";
4
+ import { withPreservedChildren } from "../containerChildren.js";
5
+ import { TRANSITIONAL_NAME_BY_STRICT_NAME } from "../strictNames.gen.js";
5
6
  import { TABLE_LOOK_FLAGS } from "../tableLook.js";
6
- import { parseTableCellProperties, parseTableGrid, parseTableProperties, parseTableRowProperties } from "../tableParser.js";
7
- import { sanitizeCapturedXmlElement } from "../verbatimCapture.js";
8
- import { NAMESPACES, OOXML_NAMESPACE_SCOPE, parseXml } from "../xmlParser.js";
7
+ import { parseTableCellProperties, parseTableGrid, parseTableProperties, parseTablePropertyExceptions, parseTableRowProperties } from "../tableParser.js";
8
+ import { OOXML_NAMESPACE_SCOPE, parseXml } from "../xmlParser.js";
9
9
  import { serializeBorder } from "./borderSerializer.js";
10
+ import { serializeBookmarkMarker } from "./markupRangeAttributes.js";
11
+ import { serializeSdtWrapper } from "./sdtPropertiesSerializer.js";
10
12
  import { serializeTrackedChangeAttributes } from "./trackedChangeAttributes.js";
11
13
  import { intAttr } from "./xmlUtils.js";
12
- import { escapeXmlAttribute } from "@stll/docx-core";
14
+ import { escapeXmlAttribute, serializeOnOffElement } from "@stll/docx-core";
15
+ import { themeColorToken } from "@stll/docx-core/model";
16
+ import { serializeSequenceChildren } from "@stll/docx-core/schema";
13
17
  //#region src/docx/serializer/tableSerializer.ts
14
18
  /**
15
19
  * The captured element with the revision children written back into it.
@@ -30,20 +34,36 @@ const withRevisionChildren = (sourceXml, revisions) => {
30
34
  };
31
35
  /** `w:trPr/w:ins` | `w:trPr/w:del`, the row's own structural revision. */
32
36
  const rowStructuralChangeXml = (change) => {
33
- if (change?.type === "tableRowInsertion") return [`<w:ins ${serializeTrackedChangeAttributes(change.info)}/>`];
34
- if (change?.type === "tableRowDeletion") return [`<w:del ${serializeTrackedChangeAttributes(change.info)}/>`];
35
- return [];
37
+ if (change?.type === "tableRowInsertion") return {
38
+ name: "ins",
39
+ xml: `<w:ins ${serializeTrackedChangeAttributes(change.info)}/>`
40
+ };
41
+ if (change?.type === "tableRowDeletion") return {
42
+ name: "del",
43
+ xml: `<w:del ${serializeTrackedChangeAttributes(change.info)}/>`
44
+ };
36
45
  };
37
46
  /** `w:tcPr/w:cellIns` | `w:cellDel` | `w:cellMerge`, the cell's own. */
38
47
  const cellStructuralChangeXml = (change) => {
39
- if (change?.type === "tableCellInsertion") return [`<w:cellIns ${serializeTrackedChangeAttributes(change.info)}/>`];
40
- if (change?.type === "tableCellDeletion") return [`<w:cellDel ${serializeTrackedChangeAttributes(change.info)}/>`];
41
- if (change?.type !== "tableCellMerge") return [];
48
+ if (change?.type === "tableCellInsertion") return {
49
+ name: "cellIns",
50
+ xml: `<w:cellIns ${serializeTrackedChangeAttributes(change.info)}/>`
51
+ };
52
+ if (change?.type === "tableCellDeletion") return {
53
+ name: "cellDel",
54
+ xml: `<w:cellDel ${serializeTrackedChangeAttributes(change.info)}/>`
55
+ };
56
+ if (change?.type !== "tableCellMerge") return;
42
57
  const attrs = [serializeTrackedChangeAttributes(change.info)];
43
58
  if (change.verticalMerge) attrs.push(`w:vMerge="${change.verticalMerge === "continue" ? "cont" : "rest"}"`);
44
59
  if (change.verticalMergeOriginal) attrs.push(`w:vMergeOrig="${change.verticalMergeOriginal === "continue" ? "cont" : "rest"}"`);
45
- return [`<w:cellMerge ${attrs.join(" ")}/>`];
60
+ return {
61
+ name: "cellMerge",
62
+ xml: `<w:cellMerge ${attrs.join(" ")}/>`
63
+ };
46
64
  };
65
+ /** The one structural revision a property set carries, as a modelled entry. */
66
+ const structuralChangeEntry = (name, change) => [name, change?.name === name ? change.xml : ""];
47
67
  /**
48
68
  * A property set without the elements kept beside it. Only the typed values
49
69
  * decide whether a capture still describes the node; the captures themselves
@@ -82,6 +102,16 @@ function serializeMeasurement(measurement, elementName) {
82
102
  return `<w:${elementName} ${[`w:w="${intAttr(measurement.value)}"`, `w:type="${measurement.type}"`].join(" ")}/>`;
83
103
  }
84
104
  /**
105
+ * The side names folio writes, from the table the census reads.
106
+ *
107
+ * A Strict producer spells these `w:start` and `w:end`; folio rebuilds every
108
+ * package as Transitional and writes one spelling, and taking it from the
109
+ * generated table is what keeps the writer and the survival law's equivalence
110
+ * from drifting apart.
111
+ */
112
+ const BORDER_LEFT = TRANSITIONAL_NAME_BY_STRICT_NAME["CT_Border start"];
113
+ const BORDER_RIGHT = TRANSITIONAL_NAME_BY_STRICT_NAME["CT_Border end"];
114
+ /**
85
115
  * Serialize table borders (w:tblBorders or w:tcBorders)
86
116
  */
87
117
  function serializeTableBorderParts(borders) {
@@ -91,9 +121,9 @@ function serializeTableBorderParts(borders) {
91
121
  if (xml) parts.push(xml);
92
122
  };
93
123
  appendBorder(borders.top, "top");
94
- appendBorder(borders.left, "left");
124
+ appendBorder(borders.left, BORDER_LEFT);
95
125
  appendBorder(borders.bottom, "bottom");
96
- appendBorder(borders.right, "right");
126
+ appendBorder(borders.right, BORDER_RIGHT);
97
127
  appendBorder(borders.insideH, "insideH");
98
128
  appendBorder(borders.insideV, "insideV");
99
129
  return parts;
@@ -113,6 +143,9 @@ function serializeTableCellBorders(borders) {
113
143
  if (topRightToBottomLeft) parts.push(topRightToBottomLeft);
114
144
  return parts.length > 0 ? `<w:tcBorders>${parts.join("")}</w:tcBorders>` : "";
115
145
  }
146
+ /** The same rename one type over: a cell margin is a `CT_TblWidth`. */
147
+ const MARGIN_LEFT = TRANSITIONAL_NAME_BY_STRICT_NAME["CT_TblWidth start"];
148
+ const MARGIN_RIGHT = TRANSITIONAL_NAME_BY_STRICT_NAME["CT_TblWidth end"];
116
149
  /**
117
150
  * Serialize cell margins (w:tblCellMar or w:tcMar)
118
151
  */
@@ -120,9 +153,9 @@ function serializeCellMargins(margins, elementName) {
120
153
  if (!margins) return "";
121
154
  const parts = [];
122
155
  if (margins.top) parts.push(serializeMeasurement(margins.top, "top"));
123
- if (margins.left) parts.push(serializeMeasurement(margins.left, "left"));
156
+ if (margins.left) parts.push(serializeMeasurement(margins.left, MARGIN_LEFT));
124
157
  if (margins.bottom) parts.push(serializeMeasurement(margins.bottom, "bottom"));
125
- if (margins.right) parts.push(serializeMeasurement(margins.right, "right"));
158
+ if (margins.right) parts.push(serializeMeasurement(margins.right, MARGIN_RIGHT));
126
159
  if (parts.length === 0) return "";
127
160
  return `<w:${elementName}>${parts.join("")}</w:${elementName}>`;
128
161
  }
@@ -136,9 +169,12 @@ function serializeShading(shading) {
136
169
  else attrs.push("w:val=\"clear\"");
137
170
  if (shading.color?.rgb && isValidHexColor(shading.color.rgb)) attrs.push(`w:color="${escapeXmlAttribute(shading.color.rgb)}"`);
138
171
  else if (shading.color?.auto) attrs.push("w:color=\"auto\"");
172
+ if (shading.color?.themeColor) attrs.push(`w:themeColor="${escapeXmlAttribute(themeColorToken(shading.color.themeColor))}"`);
173
+ if (shading.color?.themeTint) attrs.push(`w:themeTint="${escapeXmlAttribute(shading.color.themeTint)}"`);
174
+ if (shading.color?.themeShade) attrs.push(`w:themeShade="${escapeXmlAttribute(shading.color.themeShade)}"`);
139
175
  if (shading.fill?.rgb && isValidHexColor(shading.fill.rgb)) attrs.push(`w:fill="${escapeXmlAttribute(shading.fill.rgb)}"`);
140
176
  else if (shading.fill?.auto) attrs.push("w:fill=\"auto\"");
141
- if (shading.fill?.themeColor) attrs.push(`w:themeFill="${escapeXmlAttribute(shading.fill.themeColor)}"`);
177
+ if (shading.fill?.themeColor) attrs.push(`w:themeFill="${escapeXmlAttribute(themeColorToken(shading.fill.themeColor))}"`);
142
178
  if (shading.fill?.themeTint) attrs.push(`w:themeFillTint="${escapeXmlAttribute(shading.fill.themeTint)}"`);
143
179
  if (shading.fill?.themeShade) attrs.push(`w:themeFillShade="${escapeXmlAttribute(shading.fill.themeShade)}"`);
144
180
  if (attrs.length === 0) return "";
@@ -183,37 +219,39 @@ function serializeFloatingTableProperties(floating) {
183
219
  if (attrs.length === 0) return "";
184
220
  return `<w:tblpPr ${attrs.join(" ")}/>`;
185
221
  }
222
+ /** `<w:name w:val="…"/>`, or nothing when the model holds no value. */
223
+ const tagWithVal = (name, value) => value === void 0 ? "" : `<w:${name} w:val="${escapeXmlAttribute(value)}"/>`;
224
+ const numberTag = (name, value) => value === void 0 ? "" : `<w:${name} w:val="${intAttr(value)}"/>`;
186
225
  /**
187
226
  * Serialize table formatting properties (w:tblPr)
188
227
  */
189
228
  function serializeTableFormatting(formatting, propertyChanges) {
190
229
  const tableSource = verifiedSourceXml(formatting, parseTableProperties);
191
230
  if (tableSource !== null) return withRevisionChildren(tableSource, (propertyChanges ?? []).map((change) => serializeTablePropertyChange(change)));
192
- const parts = [];
193
- if (formatting) {
194
- if (formatting.styleId) parts.push(`<w:tblStyle w:val="${escapeXmlAttribute(formatting.styleId)}"/>`);
195
- const floatingXml = serializeFloatingTableProperties(formatting.floating);
196
- if (floatingXml) parts.push(floatingXml);
197
- if (formatting.overlap) parts.push(`<w:tblOverlap w:val="${formatting.overlap}"/>`);
198
- if (formatting.bidi !== void 0) parts.push(formatting.bidi ? "<w:bidiVisual/>" : "<w:bidiVisual w:val=\"0\"/>");
199
- const widthXml = serializeMeasurement(formatting.width, "tblW");
200
- if (widthXml) parts.push(widthXml);
201
- if (formatting.justification) parts.push(`<w:jc w:val="${formatting.justification}"/>`);
202
- const cellSpacingXml = serializeMeasurement(formatting.cellSpacing, "tblCellSpacing");
203
- if (cellSpacingXml) parts.push(cellSpacingXml);
204
- const indentXml = serializeMeasurement(formatting.indent, "tblInd");
205
- if (indentXml) parts.push(indentXml);
206
- const bordersXml = serializeTableBorders(formatting.borders, "tblBorders");
207
- if (bordersXml) parts.push(bordersXml);
208
- const shadingXml = serializeShading(formatting.shading);
209
- if (shadingXml) parts.push(shadingXml);
210
- if (formatting.layout) parts.push(`<w:tblLayout w:type="${formatting.layout}"/>`);
211
- const marginsXml = serializeCellMargins(formatting.cellMargins, "tblCellMar");
212
- if (marginsXml) parts.push(marginsXml);
213
- const lookXml = serializeTableLook(formatting.look);
214
- if (lookXml) parts.push(lookXml);
215
- }
216
- if (propertyChanges && propertyChanges.length > 0) parts.push(...propertyChanges.map((change) => serializeTablePropertyChange(change)));
231
+ const parts = serializeSequenceChildren({
232
+ container: "table-properties",
233
+ modelled: [
234
+ ["tblStyle", formatting?.styleId ? tagWithVal("tblStyle", formatting.styleId) : ""],
235
+ ["tblpPr", serializeFloatingTableProperties(formatting?.floating)],
236
+ ["tblOverlap", formatting?.overlap ? `<w:tblOverlap w:val="${formatting.overlap}"/>` : ""],
237
+ ["bidiVisual", serializeOnOffElement(formatting?.bidi, "bidiVisual")],
238
+ ["tblStyleRowBandSize", numberTag("tblStyleRowBandSize", formatting?.rowBandSize)],
239
+ ["tblStyleColBandSize", numberTag("tblStyleColBandSize", formatting?.columnBandSize)],
240
+ ["tblW", serializeMeasurement(formatting?.width, "tblW")],
241
+ ["jc", formatting?.justification ? `<w:jc w:val="${formatting.justification}"/>` : ""],
242
+ ["tblCellSpacing", serializeMeasurement(formatting?.cellSpacing, "tblCellSpacing")],
243
+ ["tblInd", serializeMeasurement(formatting?.indent, "tblInd")],
244
+ ["tblBorders", serializeTableBorders(formatting?.borders, "tblBorders")],
245
+ ["shd", serializeShading(formatting?.shading)],
246
+ ["tblLayout", formatting?.layout ? `<w:tblLayout w:type="${formatting.layout}"/>` : ""],
247
+ ["tblCellMar", serializeCellMargins(formatting?.cellMargins, "tblCellMar")],
248
+ ["tblLook", serializeTableLook(formatting?.look)],
249
+ ["tblCaption", tagWithVal("tblCaption", formatting?.caption)],
250
+ ["tblDescription", tagWithVal("tblDescription", formatting?.description)],
251
+ ["tblPrChange", (propertyChanges ?? []).map((change) => serializeTablePropertyChange(change)).join("")]
252
+ ],
253
+ preserved: formatting?.preserved
254
+ });
217
255
  if (parts.length === 0) return "";
218
256
  return `<w:tblPr>${parts.join("")}</w:tblPr>`;
219
257
  }
@@ -227,32 +265,73 @@ function serializeTablePropertyChange(change) {
227
265
  return `<w:tblPrChange ${attrs}>${previousTblPrInner.length > 0 ? `<w:tblPr>${previousTblPrInner}</w:tblPr>` : "<w:tblPr/>"}</w:tblPrChange>`;
228
266
  }
229
267
  /**
268
+ * Serialize a row's table property exceptions (w:tblPrEx).
269
+ *
270
+ * `CT_TblPrEx` is a sequence like `CT_TblPr`, and the nine children it shares
271
+ * with it are written by the same statements: the modelled half is keyed by
272
+ * element name and `serializeSequenceChildren` puts it in the generated order,
273
+ * so the exception and the property it overrides cannot come out spelled two
274
+ * different ways.
275
+ */
276
+ function serializeTablePropertyExceptions(exceptions, propertyChanges) {
277
+ if (exceptions === void 0 && (propertyChanges ?? []).length === 0) return "";
278
+ const exceptionSource = verifiedSourceXml(exceptions, parseTablePropertyExceptions);
279
+ if (exceptionSource !== null) return withRevisionChildren(exceptionSource, (propertyChanges ?? []).map((change) => serializeTablePropertyExceptionChange(change)));
280
+ const parts = serializeSequenceChildren({
281
+ container: "table-property-exceptions",
282
+ modelled: [
283
+ ["tblW", serializeMeasurement(exceptions?.width, "tblW")],
284
+ ["jc", exceptions?.justification ? `<w:jc w:val="${exceptions.justification}"/>` : ""],
285
+ ["tblCellSpacing", serializeMeasurement(exceptions?.cellSpacing, "tblCellSpacing")],
286
+ ["tblInd", serializeMeasurement(exceptions?.indent, "tblInd")],
287
+ ["tblBorders", serializeTableBorders(exceptions?.borders, "tblBorders")],
288
+ ["shd", serializeShading(exceptions?.shading)],
289
+ ["tblLayout", exceptions?.layout ? `<w:tblLayout w:type="${exceptions.layout}"/>` : ""],
290
+ ["tblCellMar", serializeCellMargins(exceptions?.cellMargins, "tblCellMar")],
291
+ ["tblLook", serializeTableLook(exceptions?.look)],
292
+ ["tblPrExChange", (propertyChanges ?? []).map((change) => serializeTablePropertyExceptionChange(change)).join("")]
293
+ ],
294
+ preserved: exceptions?.preserved
295
+ });
296
+ return parts.length === 0 ? "<w:tblPrEx/>" : `<w:tblPrEx>${parts.join("")}</w:tblPrEx>`;
297
+ }
298
+ function serializeTablePropertyExceptionChange(change) {
299
+ return `<w:tblPrExChange ${serializeTrackedChangeAttributes(change.info)}>${serializeTablePropertyExceptions(change.previousFormatting) || "<w:tblPrEx/>"}</w:tblPrExChange>`;
300
+ }
301
+ /** `w:trHeight`, whose value rides `w:val` rather than `w:w`. */
302
+ const serializeRowHeight = (formatting) => {
303
+ if (!formatting?.height) return "";
304
+ const attrs = [`w:val="${intAttr(formatting.height.value)}"`];
305
+ if (formatting.heightRule) attrs.push(`w:hRule="${formatting.heightRule}"`);
306
+ return `<w:trHeight ${attrs.join(" ")}/>`;
307
+ };
308
+ /**
230
309
  * Serialize table row formatting properties (w:trPr)
231
310
  */
232
311
  function serializeTableRowFormatting(formatting, propertyChanges, structuralChange) {
312
+ const rowStructuralChange = rowStructuralChangeXml(structuralChange);
233
313
  const rowSource = verifiedSourceXml(formatting, parseTableRowProperties);
234
- if (rowSource !== null) return withRevisionChildren(rowSource, [...rowStructuralChangeXml(structuralChange), ...(propertyChanges ?? []).map((change) => serializeTableRowPropertyChange(change))]);
235
- const parts = [];
236
- if (formatting) {
237
- const cnfStyleXml = serializeConditionalFormatStyle(formatting.conditionalFormat);
238
- if (cnfStyleXml) parts.push(cnfStyleXml);
239
- if (formatting.gridBefore) parts.push(`<w:gridBefore w:val="${intAttr(formatting.gridBefore)}"/>`);
240
- if (formatting.widthBefore) parts.push(`<w:wBefore w:w="${intAttr(formatting.widthBefore.value)}" w:type="${formatting.widthBefore.type}"/>`);
241
- if (formatting.gridAfter) parts.push(`<w:gridAfter w:val="${intAttr(formatting.gridAfter)}"/>`);
242
- if (formatting.widthAfter) parts.push(`<w:wAfter w:w="${intAttr(formatting.widthAfter.value)}" w:type="${formatting.widthAfter.type}"/>`);
243
- if (formatting.cantSplit) parts.push("<w:cantSplit/>");
244
- if (formatting.header) parts.push("<w:tblHeader/>");
245
- if (formatting.height) {
246
- const attrs = [`w:val="${intAttr(formatting.height.value)}"`];
247
- if (formatting.heightRule) attrs.push(`w:hRule="${formatting.heightRule}"`);
248
- parts.push(`<w:trHeight ${attrs.join(" ")}/>`);
249
- }
250
- if (formatting.justification) parts.push(`<w:jc w:val="${formatting.justification}"/>`);
251
- if (formatting.hidden) parts.push("<w:hidden/>");
252
- }
253
- parts.push(...rowStructuralChangeXml(structuralChange));
254
- if (propertyChanges && propertyChanges.length > 0) parts.push(...propertyChanges.map((change) => serializeTableRowPropertyChange(change)));
255
- if (parts.length === 0) return "";
314
+ if (rowSource !== null) return withRevisionChildren(rowSource, [...rowStructuralChange ? [rowStructuralChange.xml] : [], ...(propertyChanges ?? []).map((change) => serializeTableRowPropertyChange(change))]);
315
+ const parts = serializeSequenceChildren({
316
+ container: "row-properties",
317
+ modelled: [
318
+ ["cnfStyle", serializeConditionalFormatStyle(formatting?.conditionalFormat)],
319
+ ["gridBefore", formatting?.gridBefore ? `<w:gridBefore w:val="${intAttr(formatting.gridBefore)}"/>` : ""],
320
+ ["gridAfter", formatting?.gridAfter ? `<w:gridAfter w:val="${intAttr(formatting.gridAfter)}"/>` : ""],
321
+ ["wBefore", serializeMeasurement(formatting?.widthBefore, "wBefore")],
322
+ ["wAfter", serializeMeasurement(formatting?.widthAfter, "wAfter")],
323
+ ["cantSplit", serializeOnOffElement(formatting?.cantSplit, "cantSplit")],
324
+ ["trHeight", serializeRowHeight(formatting)],
325
+ ["tblHeader", serializeOnOffElement(formatting?.header, "tblHeader")],
326
+ ["jc", formatting?.justification ? `<w:jc w:val="${formatting.justification}"/>` : ""],
327
+ ["hidden", serializeOnOffElement(formatting?.hidden, "hidden")],
328
+ structuralChangeEntry("ins", rowStructuralChange),
329
+ structuralChangeEntry("del", rowStructuralChange),
330
+ ["trPrChange", (propertyChanges ?? []).map((change) => serializeTableRowPropertyChange(change)).join("")]
331
+ ],
332
+ preserved: formatting?.preserved
333
+ });
334
+ if (parts.length === 0) return formatting === void 0 ? "" : "<w:trPr/>";
256
335
  return `<w:trPr>${parts.join("")}</w:trPr>`;
257
336
  }
258
337
  function extractTrPrInner(trPrXml) {
@@ -286,37 +365,41 @@ function serializeConditionalFormatStyle(style) {
286
365
  if (val === "000000000000") return "";
287
366
  return `<w:cnfStyle w:val="${val}"/>`;
288
367
  }
368
+ /** `w:vMerge`: no `w:val` is the continuation, so only a restart states one. */
369
+ const serializeVerticalMerge = (vMerge) => {
370
+ if (vMerge === void 0) return "";
371
+ return vMerge === "restart" ? "<w:vMerge w:val=\"restart\"/>" : "<w:vMerge/>";
372
+ };
289
373
  /**
290
374
  * Serialize table cell formatting properties (w:tcPr)
291
375
  */
292
376
  function serializeTableCellFormatting(formatting, propertyChanges, structuralChange) {
377
+ const cellStructuralChange = cellStructuralChangeXml(structuralChange);
293
378
  const cellSource = verifiedSourceXml(formatting, parseTableCellProperties);
294
- if (cellSource !== null) return withRevisionChildren(cellSource, [...cellStructuralChangeXml(structuralChange), ...(propertyChanges ?? []).map((change) => serializeTableCellPropertyChange(change))]);
295
- const parts = [];
296
- if (formatting) {
297
- const cnfStyleXml = serializeConditionalFormatStyle(formatting.conditionalFormat);
298
- if (cnfStyleXml) parts.push(cnfStyleXml);
299
- const widthXml = serializeMeasurement(formatting.width, "tcW");
300
- if (widthXml) parts.push(widthXml);
301
- if (formatting.gridSpan && formatting.gridSpan > 1) parts.push(`<w:gridSpan w:val="${intAttr(formatting.gridSpan)}"/>`);
302
- if (formatting.vMerge) if (formatting.vMerge === "restart") parts.push("<w:vMerge w:val=\"restart\"/>");
303
- else parts.push("<w:vMerge/>");
304
- const bordersXml = serializeTableCellBorders(formatting.borders);
305
- if (bordersXml) parts.push(bordersXml);
306
- const shadingXml = serializeShading(formatting.shading);
307
- if (shadingXml) parts.push(shadingXml);
308
- if (formatting.noWrap) parts.push("<w:noWrap/>");
309
- const marginsXml = serializeCellMargins(formatting.margins, "tcMar");
310
- if (marginsXml) parts.push(marginsXml);
311
- if (formatting.textDirection) parts.push(`<w:textDirection w:val="${formatting.textDirection}"/>`);
312
- if (formatting.fitText) parts.push("<w:tcFitText/>");
313
- if (formatting.verticalAlign) parts.push(`<w:vAlign w:val="${formatting.verticalAlign}"/>`);
314
- if (formatting.hideMark === true) parts.push("<w:hideMark/>");
315
- else if (formatting.hideMark === false) parts.push("<w:hideMark w:val=\"off\"/>");
316
- }
317
- parts.push(...cellStructuralChangeXml(structuralChange));
318
- if (propertyChanges && propertyChanges.length > 0) parts.push(...propertyChanges.map((change) => serializeTableCellPropertyChange(change)));
319
- if (parts.length === 0) return "";
379
+ if (cellSource !== null) return withRevisionChildren(cellSource, [...cellStructuralChange ? [cellStructuralChange.xml] : [], ...(propertyChanges ?? []).map((change) => serializeTableCellPropertyChange(change))]);
380
+ const parts = serializeSequenceChildren({
381
+ container: "cell-properties",
382
+ modelled: [
383
+ ["cnfStyle", serializeConditionalFormatStyle(formatting?.conditionalFormat)],
384
+ ["tcW", serializeMeasurement(formatting?.width, "tcW")],
385
+ ["gridSpan", formatting?.gridSpan && formatting.gridSpan > 1 ? `<w:gridSpan w:val="${intAttr(formatting.gridSpan)}"/>` : ""],
386
+ ["vMerge", serializeVerticalMerge(formatting?.vMerge)],
387
+ ["tcBorders", serializeTableCellBorders(formatting?.borders)],
388
+ ["shd", serializeShading(formatting?.shading)],
389
+ ["noWrap", serializeOnOffElement(formatting?.noWrap, "noWrap")],
390
+ ["tcMar", serializeCellMargins(formatting?.margins, "tcMar")],
391
+ ["textDirection", formatting?.textDirection ? `<w:textDirection w:val="${formatting.textDirection}"/>` : ""],
392
+ ["tcFitText", serializeOnOffElement(formatting?.fitText, "tcFitText")],
393
+ ["vAlign", formatting?.verticalAlign ? `<w:vAlign w:val="${formatting.verticalAlign}"/>` : ""],
394
+ ["hideMark", serializeOnOffElement(formatting?.hideMark, "hideMark")],
395
+ structuralChangeEntry("cellIns", cellStructuralChange),
396
+ structuralChangeEntry("cellDel", cellStructuralChange),
397
+ structuralChangeEntry("cellMerge", cellStructuralChange),
398
+ ["tcPrChange", (propertyChanges ?? []).map((change) => serializeTableCellPropertyChange(change)).join("")]
399
+ ],
400
+ preserved: formatting?.preserved
401
+ });
402
+ if (parts.length === 0) return formatting === void 0 ? "" : "<w:tcPr/>";
320
403
  return `<w:tcPr>${parts.join("")}</w:tcPr>`;
321
404
  }
322
405
  function extractTcPrInner(tcPrXml) {
@@ -325,7 +408,7 @@ function extractTcPrInner(tcPrXml) {
325
408
  }
326
409
  function serializeTableCellPropertyChange(change) {
327
410
  const attrs = serializeTrackedChangeAttributes(change.info);
328
- const previousTcPrInner = extractTcPrInner(serializeTableCellFormatting(change.previousFormatting) || "<w:tcPr/>");
411
+ const previousTcPrInner = extractTcPrInner(serializeTableCellFormatting(change.previousFormatting, void 0, change.previousStructuralChange) || "<w:tcPr/>");
329
412
  return `<w:tcPrChange ${attrs}>${previousTcPrInner.length > 0 ? `<w:tcPr>${previousTcPrInner}</w:tcPr>` : "<w:tcPr/>"}</w:tcPrChange>`;
330
413
  }
331
414
  /**
@@ -354,17 +437,75 @@ function serializeTableGrid(table) {
354
437
  if (gridSourceXml !== void 0) {
355
438
  if (canonicalJson(parseTableGrid(parseXml(gridSourceXml, OOXML_NAMESPACE_SCOPE).elements?.[0] ?? null)) === canonicalJson(columnWidths)) return gridSourceXml;
356
439
  }
357
- const gridChange = replayableGridChangeXml(table.formatting?.gridChangeXml) ?? "";
440
+ const change = table.formatting?.gridChange;
441
+ const gridChange = change === void 0 ? "" : serializeTableGridChange(change);
358
442
  if (columnWidths && columnWidths.length > 0) return `<w:tblGrid>${columnWidths.map((w) => `<w:gridCol w:w="${intAttr(w)}"/>`).join("")}${gridChange}</w:tblGrid>`;
359
443
  const columns = gridColumnCount(table);
360
444
  return columns === 0 && gridChange === "" ? "<w:tblGrid/>" : `<w:tblGrid>${"<w:gridCol/>".repeat(columns)}${gridChange}</w:tblGrid>`;
361
445
  }
362
- const GRID_CHANGE_ROOT_NAME = /* @__PURE__ */ new Set(["tblGridChange"]);
363
- const WORDPROCESSINGML_NAMESPACE = /* @__PURE__ */ new Set([NAMESPACES.w]);
364
- const replayableGridChangeXml = (gridChangeXml) => sanitizeCapturedXmlElement(gridChangeXml, {
365
- allowedLocalNames: GRID_CHANGE_ROOT_NAME,
366
- allowedNamespaceUris: WORDPROCESSINGML_NAMESPACE,
367
- inheritedNamespaceScope: OOXML_NAMESPACE_SCOPE
446
+ /**
447
+ * Serialize `w:tblGridChange`: the grid a reviewer replaced, from the change's
448
+ * own record rather than from the bytes it arrived as.
449
+ *
450
+ * `w:w` is optional on a `w:gridCol`, so a column the snapshot recorded no
451
+ * measure for is written back without one; spelling it as a zero would claim a
452
+ * width the source never stated.
453
+ */
454
+ const serializeTableGridChange = ({ id, columnWidths }) => {
455
+ const columns = columnWidths.map((width) => width === void 0 ? "<w:gridCol/>" : `<w:gridCol w:w="${intAttr(width)}"/>`).join("");
456
+ return `<w:tblGridChange w:id="${intAttr(id)}"><w:tblGrid>${columns}</w:tblGrid></w:tblGridChange>`;
457
+ };
458
+ /**
459
+ * What makes two rows members of the same control.
460
+ *
461
+ * The control's record is on every child it held, so the wrapper is rebuilt
462
+ * by grouping consecutive children that name the same control. Equality is
463
+ * the record's canonical spelling rather than object identity, because the
464
+ * editor carries these records through JSON — a Yjs sync, a snapshot, a
465
+ * structured clone — and hands back an equal record rather than the same one.
466
+ * A wrapper that split in two there would mint a second `w:id` for one
467
+ * control, which is the defect, not the fix.
468
+ *
469
+ * The cost is the other direction: two adjacent rows the author put in two
470
+ * separate but identically spelled controls come back as one. Word mints a
471
+ * distinct `w:id` per control, so that needs a producer that writes none; the
472
+ * inline wrapper stack makes the same trade for the same reason.
473
+ */
474
+ const contentControlKey = (properties) => canonicalJson(properties);
475
+ /**
476
+ * Re-open each control around the run of children that named it, outermost
477
+ * first.
478
+ *
479
+ * @param depth which layer of the stack this call is opening
480
+ */
481
+ const serializeControlledChildren = (children, depth) => {
482
+ const parts = [];
483
+ let index = 0;
484
+ while (index < children.length) {
485
+ const child = children[index];
486
+ const control = child.controls[depth];
487
+ if (control === void 0) {
488
+ parts.push(child.xml);
489
+ index += 1;
490
+ continue;
491
+ }
492
+ const key = contentControlKey(control);
493
+ let end = index + 1;
494
+ while (end < children.length) {
495
+ const next = children[end]?.controls[depth];
496
+ if (next === void 0 || contentControlKey(next) !== key) break;
497
+ end += 1;
498
+ }
499
+ const inner = serializeControlledChildren(children.slice(index, end), depth + 1);
500
+ parts.push(serializeSdtWrapper(control, inner));
501
+ index = end;
502
+ }
503
+ return parts.join("");
504
+ };
505
+ /** A capture from the sink, with the controls it sat inside when parsed. */
506
+ const preservedChild = (xml, child) => ({
507
+ controls: child.contentControls ?? [],
508
+ xml
368
509
  });
369
510
  /**
370
511
  * Serialize cell content (paragraphs, nested tables)
@@ -375,6 +516,8 @@ function serializeCellContent(content, serializeParagraph) {
375
516
  case "paragraph": return serializeParagraph(block);
376
517
  case "table": return serializeTable(block, serializeParagraph);
377
518
  case "preservedBlock": return block.xml;
519
+ case "bookmarkStart":
520
+ case "bookmarkEnd": return serializeBookmarkMarker(block);
378
521
  default: return block;
379
522
  }
380
523
  });
@@ -392,13 +535,35 @@ function serializeTableCell(cell, serializeParagraph) {
392
535
  return `<w:tc>${parts.join("")}</w:tc>`;
393
536
  }
394
537
  /**
538
+ * A container's verbatim sink and its bookmark markers, as one positioned list.
539
+ *
540
+ * Both stand between the same two modelled children and both record where by
541
+ * counting the ones before them, so one writer puts both back. Two entries
542
+ * recorded at the same index keep their group's order, with the sink's first;
543
+ * the source order between a capture and a bookmark sharing a slot is the one
544
+ * thing an index cannot say, and it changes nothing a reader can see.
545
+ */
546
+ const positionedChildren = (preserved, bookmarks) => {
547
+ if (bookmarks === void 0 || bookmarks.length === 0) return preserved;
548
+ return { children: [...preserved?.children ?? [], ...bookmarks.map(({ index, marker, contentControls }) => ({
549
+ index,
550
+ xml: serializeBookmarkMarker(marker),
551
+ ...contentControls === void 0 ? {} : { contentControls }
552
+ }))] };
553
+ };
554
+ /**
395
555
  * Serialize a table row (w:tr)
396
556
  */
397
557
  function serializeTableRow(row, serializeParagraph) {
398
558
  const parts = [];
559
+ const tblPrExXml = serializeTablePropertyExceptions(row.tablePropertyExceptions, row.tablePropertyExceptionChanges);
560
+ if (tblPrExXml) parts.push(tblPrExXml);
399
561
  const trPrXml = serializeTableRowFormatting(row.formatting, row.propertyChanges, row.structuralChange);
400
562
  if (trPrXml) parts.push(trPrXml);
401
- parts.push(serializeWithPreservedChildren(row.cells.map((cell) => serializeTableCell(cell, serializeParagraph)), row.preserved));
563
+ parts.push(serializeControlledChildren(withPreservedChildren(row.cells.map((cell) => ({
564
+ controls: cell.contentControls ?? [],
565
+ xml: serializeTableCell(cell, serializeParagraph)
566
+ })), positionedChildren(row.preserved, row.bookmarks), preservedChild), 0));
402
567
  const attrs = serializePreservedAttributes([], row.preservedAttributes);
403
568
  return `<w:tr${attrs.length > 0 ? ` ${attrs.join(" ")}` : ""}>${parts.join("")}</w:tr>`;
404
569
  }
@@ -412,7 +577,10 @@ function serializeTable(table, serializeParagraph) {
412
577
  return `<w:tbl>${[
413
578
  serializeTableFormatting(table.formatting, table.propertyChanges) || "<w:tblPr/>",
414
579
  serializeTableGrid(table),
415
- serializeWithPreservedChildren(table.rows.map((row) => serializeTableRow(row, serializeParagraph)), table.preserved)
580
+ serializeControlledChildren(withPreservedChildren(table.rows.map((row) => ({
581
+ controls: row.contentControls ?? [],
582
+ xml: serializeTableRow(row, serializeParagraph)
583
+ })), positionedChildren(table.preserved, table.bookmarks), preservedChild), 0)
416
584
  ].join("")}</w:tbl>`;
417
585
  }
418
586
  /**
@@ -1,16 +1,40 @@
1
1
  import { document_d_exports } from "../../types/document.js";
2
+ import { DeclaredChild } from "../containerChildren.gen.js";
2
3
  //#region src/docx/serializer/textFormattingSerializer.d.ts
3
- type ClassifiedShadingField = "color" | "fill" | "pattern";
4
+ type ClassifiedShadingField = "color" | "fill" | "pattern" | "preservedAttributes";
4
5
  type ExhaustiveShadingProperties = document_d_exports.ExhaustiveFields<document_d_exports.ShadingProperties, ClassifiedShadingField>;
5
- type ClassifiedTextFormattingField = "bold" | "boldCs" | "italic" | "italicCs" | "underline" | "strike" | "doubleStrike" | "vertAlign" | "smallCaps" | "allCaps" | "hidden" | "noProof" | "color" | "highlight" | "shading" | "fontSize" | "fontSizeCs" | "fontFamily" | "language" | "spacing" | "position" | "scale" | "kerning" | "effect" | "emphasisMark" | "emboss" | "imprint" | "outline" | "shadow" | "rtl" | "cs" | "styleId";
6
+ type ClassifiedTextFormattingField = "bold" | "boldCs" | "italic" | "italicCs" | "underline" | "strike" | "doubleStrike" | "vertAlign" | "smallCaps" | "allCaps" | "hidden" | "noProof" | "color" | "highlight" | "shading" | "fontSize" | "fontSizeCs" | "fontFamily" | "language" | "spacing" | "position" | "scale" | "kerning" | "effect" | "emphasisMark" | "emboss" | "imprint" | "outline" | "shadow" | "rtl" | "cs" | "styleId" | "preserved";
6
7
  type ExhaustiveTextFormatting = document_d_exports.ExhaustiveFields<document_d_exports.TextFormatting, ClassifiedTextFormattingField>;
8
+ /**
9
+ * A child of this `w:rPr` that another record owns, named by its declared
10
+ * child so the sequence places it.
11
+ *
12
+ * A run's `w:rPrChange` and the paragraph mark's revision and `w:specVanish`
13
+ * are read by the run's and the paragraph's own records, so they arrive here
14
+ * as markup rather than as a field. Naming each one means the schema decides
15
+ * where it goes, exactly as it does for the modelled children.
16
+ */
17
+ type OwnedRunPropertyChild = readonly [name: DeclaredChild<"run-properties">, xml: string];
7
18
  /**
8
19
  * Serialize shading properties (w:shd)
9
20
  */
10
21
  declare function serializeShading(shading: ExhaustiveShadingProperties | undefined): string;
11
22
  /**
12
- * Serialize text formatting properties to w:rPr XML
23
+ * The single `w:rPr` writer.
24
+ *
25
+ * A run, the paragraph mark, a style, a numbering level and the snapshot
26
+ * inside either kind of `w:rPrChange` all write their run properties through
27
+ * here, so none of them can grow its own order or its own idea of which
28
+ * children exist. `EG_RPrBase` is an `xsd:choice` referenced
29
+ * `maxOccurs="unbounded"`, so a `w:rPr` in any order is valid and the order
30
+ * below is a canonical form rather than a validity rule: it is the one Word
31
+ * writes, and writing it from the generated declared-child list is what stops
32
+ * two of folio's serializers from disagreeing. The restatement is what
33
+ * drifted, and it is why folio wrote `w:vanish` before `w:noProof` while the
34
+ * schema declares the reverse.
35
+ *
36
+ * @param owned children a sibling record holds; see {@link OwnedRunPropertyChild}
13
37
  */
14
- declare function serializeTextFormatting(input: ExhaustiveTextFormatting | undefined): string;
38
+ declare function serializeTextFormatting(input: ExhaustiveTextFormatting | undefined, owned?: readonly OwnedRunPropertyChild[]): string;
15
39
  //#endregion
16
40
  export { serializeShading, serializeTextFormatting };