@stll/folio-core 0.43.0 → 0.45.0

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 (237) hide show
  1. package/dist/ai-edits/__fixtures__/paragraphs.js +2 -2
  2. package/dist/ai-edits/headless.js +7 -5
  3. package/dist/ai-edits/index.d.ts +2 -2
  4. package/dist/ai-edits/index.js +2 -2
  5. package/dist/ai-edits/snapshot.js +13 -9
  6. package/dist/compare/content-alignment.js +94 -54
  7. package/dist/compare/inline-atoms.js +34 -20
  8. package/dist/compare/style-resources.js +6 -0
  9. package/dist/content-controls/mutateContentControls.js +4 -2
  10. package/dist/display-list/dom/renderDisplayListToDom.js +8 -8
  11. package/dist/document-operations.js +14 -3
  12. package/dist/docx/appVersionNormalization.d.ts +0 -18
  13. package/dist/docx/blockContentParser.js +8 -0
  14. package/dist/docx/blockRangeMarkers.d.ts +36 -0
  15. package/dist/docx/blockRangeMarkers.js +59 -0
  16. package/dist/docx/bookmarkParser.d.ts +2 -20
  17. package/dist/docx/bookmarkParser.js +6 -30
  18. package/dist/docx/borderParser.d.ts +13 -0
  19. package/dist/docx/borderParser.js +71 -0
  20. package/dist/docx/builtInStyles.d.ts +165 -0
  21. package/dist/docx/builtInStyles.js +239 -0
  22. package/dist/docx/commentIdNormalization.d.ts +3 -1
  23. package/dist/docx/commentIdNormalization.js +18 -1
  24. package/dist/docx/commentParser.d.ts +2 -1
  25. package/dist/docx/commentParser.js +80 -42
  26. package/dist/docx/commentReferenceNormalization.d.ts +4 -1
  27. package/dist/docx/commentReferenceNormalization.js +23 -14
  28. package/dist/docx/commentThreadKey.d.ts +18 -0
  29. package/dist/docx/commentThreadKey.js +22 -0
  30. package/dist/docx/danglingRelationshipReferences.d.ts +15 -0
  31. package/dist/docx/danglingRelationshipReferences.js +30 -0
  32. package/dist/docx/defaultParagraphStyle.d.ts +18 -1
  33. package/dist/docx/defaultParagraphStyle.js +23 -1
  34. package/dist/docx/diagramPreview.js +87 -27
  35. package/dist/docx/documentParser.d.ts +2 -1
  36. package/dist/docx/documentParser.js +2 -2
  37. package/dist/docx/drawingUtils.d.ts +8 -1
  38. package/dist/docx/drawingUtils.js +12 -3
  39. package/dist/docx/fieldParser.js +3 -5
  40. package/dist/docx/footnoteParser.d.ts +3 -2
  41. package/dist/docx/footnoteParser.js +19 -4
  42. package/dist/docx/groupDrawingParser.js +4 -4
  43. package/dist/docx/headerFooterRefParser.d.ts +4 -3
  44. package/dist/docx/headerFooterRefParser.js +42 -12
  45. package/dist/docx/headerFooterReferenceNormalization.d.ts +4 -1
  46. package/dist/docx/headerFooterReferenceNormalization.js +5 -1
  47. package/dist/docx/hyperlinkParser.js +13 -17
  48. package/dist/docx/imageParser.d.ts +10 -2
  49. package/dist/docx/imageParser.js +80 -30
  50. package/dist/docx/imageRawXml.d.ts +14 -1
  51. package/dist/docx/imageRawXml.js +35 -11
  52. package/dist/docx/markupRangeMarker.d.ts +15 -0
  53. package/dist/docx/markupRangeMarker.js +44 -0
  54. package/dist/docx/mathToMathml.js +12 -14
  55. package/dist/docx/nonVisualDrawingProps.d.ts +34 -0
  56. package/dist/docx/nonVisualDrawingProps.js +46 -0
  57. package/dist/docx/noteReferenceStyles.d.ts +29 -0
  58. package/dist/docx/noteReferenceStyles.js +70 -0
  59. package/dist/docx/numberingReferenceNormalization.d.ts +4 -1
  60. package/dist/docx/numberingReferenceNormalization.js +20 -1
  61. package/dist/docx/paraIdRangeNormalization.d.ts +0 -19
  62. package/dist/docx/paragraphParser.js +66 -99
  63. package/dist/docx/paragraphPropertySource.js +1 -0
  64. package/dist/docx/paragraphTextBoxEnrichment.js +3 -0
  65. package/dist/docx/paragraphTraversal.d.ts +37 -1
  66. package/dist/docx/paragraphTraversal.js +84 -1
  67. package/dist/docx/parseContext.d.ts +37 -0
  68. package/dist/docx/parseContext.js +67 -0
  69. package/dist/docx/parseWarningMessage.d.ts +6 -0
  70. package/dist/docx/parseWarningMessage.js +44 -0
  71. package/dist/docx/parser.js +83 -29
  72. package/dist/docx/previewBudget.d.ts +64 -0
  73. package/dist/docx/previewBudget.js +88 -0
  74. package/dist/docx/relsParser.d.ts +28 -11
  75. package/dist/docx/relsParser.js +26 -13
  76. package/dist/docx/revisionIdNormalization.js +96 -10
  77. package/dist/docx/rezip.js +80 -40
  78. package/dist/docx/runConsolidator.js +1 -2
  79. package/dist/docx/runParser.d.ts +8 -1
  80. package/dist/docx/runParser.js +30 -48
  81. package/dist/docx/sdtPropertiesPatch.js +24 -18
  82. package/dist/docx/sectionParser.d.ts +2 -1
  83. package/dist/docx/sectionParser.js +21 -65
  84. package/dist/docx/sectionReferenceHistory.js +2 -2
  85. package/dist/docx/selectiveSave.js +6 -6
  86. package/dist/docx/serializer/blockSdtSerializer.js +38 -26
  87. package/dist/docx/serializer/borderSerializer.d.ts +2 -3
  88. package/dist/docx/serializer/borderSerializer.js +13 -12
  89. package/dist/docx/serializer/commentSerializer.d.ts +41 -16
  90. package/dist/docx/serializer/commentSerializer.js +82 -72
  91. package/dist/docx/serializer/documentSerializer.d.ts +1 -5
  92. package/dist/docx/serializer/documentSerializer.js +6 -16
  93. package/dist/docx/serializer/fontTableSerializer.js +6 -6
  94. package/dist/docx/serializer/headerFooterSerializer.js +10 -5
  95. package/dist/docx/serializer/markupRangeAttributes.d.ts +8 -0
  96. package/dist/docx/serializer/markupRangeAttributes.js +24 -0
  97. package/dist/docx/serializer/noteSerializer.js +5 -0
  98. package/dist/docx/serializer/numberingSerializer.js +7 -6
  99. package/dist/docx/serializer/paragraphSerializer.d.ts +1 -5
  100. package/dist/docx/serializer/paragraphSerializer.js +47 -52
  101. package/dist/docx/serializer/partNamespaces.js +2 -2
  102. package/dist/docx/serializer/runSerializer.js +57 -31
  103. package/dist/docx/serializer/sectionPropertiesSerializer.js +11 -10
  104. package/dist/docx/serializer/settingsSerializer.js +4 -3
  105. package/dist/docx/serializer/stylesSerializer.js +6 -6
  106. package/dist/docx/serializer/tableSerializer.js +37 -21
  107. package/dist/docx/serializer/textFormattingSerializer.d.ts +2 -3
  108. package/dist/docx/serializer/textFormattingSerializer.js +29 -28
  109. package/dist/docx/serializer/themeSerializer.js +6 -6
  110. package/dist/docx/serializer/trackedChangeAttributes.js +2 -2
  111. package/dist/docx/serializer/xmlUtils.d.ts +1 -2
  112. package/dist/docx/serializer/xmlUtils.js +1 -13
  113. package/dist/docx/server/boundedArchive.d.ts +12 -0
  114. package/dist/docx/server/boundedArchive.js +20 -1
  115. package/dist/docx/server/build.js +8 -1
  116. package/dist/docx/server/createBilingualDocument.js +10 -18
  117. package/dist/docx/server/extractDocxText.js +3 -4
  118. package/dist/docx/server/validateDocxConformance.js +22 -1
  119. package/dist/docx/shadingParser.d.ts +6 -0
  120. package/dist/docx/shadingParser.js +32 -0
  121. package/dist/docx/shapeParser.js +10 -8
  122. package/dist/docx/styleParser.js +13 -87
  123. package/dist/docx/styleReferenceResolution.d.ts +36 -0
  124. package/dist/docx/styleReferenceResolution.js +51 -0
  125. package/dist/docx/tableLook.d.ts +57 -0
  126. package/dist/docx/tableLook.js +63 -0
  127. package/dist/docx/tableParser.d.ts +7 -9
  128. package/dist/docx/tableParser.js +64 -110
  129. package/dist/docx/textBoxParser.js +11 -6
  130. package/dist/docx/trackedMoveRangeNormalization.d.ts +3 -1
  131. package/dist/docx/trackedMoveRangeNormalization.js +11 -21
  132. package/dist/docx/transitionalSpelling.d.ts +13 -2
  133. package/dist/docx/transitionalSpelling.js +23 -1
  134. package/dist/docx/unzip.d.ts +23 -0
  135. package/dist/docx/unzip.js +32 -22
  136. package/dist/docx/verbatimCapture.js +5 -12
  137. package/dist/docx/vmlImageParser.js +5 -4
  138. package/dist/docx/vmlPreview.d.ts +1 -3
  139. package/dist/docx/vmlPreview.js +2 -30
  140. package/dist/docx/watermarkParser.js +2 -2
  141. package/dist/docx/xmlParser.d.ts +38 -33
  142. package/dist/docx/xmlParser.js +92 -47
  143. package/dist/docx/xmlResourceLimits.d.ts +89 -9
  144. package/dist/docx/xmlResourceLimits.js +105 -24
  145. package/dist/internal/pageBreakRunSourceDescendantIndex.js +2 -1
  146. package/dist/internal/paragraphFormattingSerialization.d.ts +2 -3
  147. package/dist/internal/paragraphFormattingSerialization.js +29 -8
  148. package/dist/layout-bridge/convert/footnoteLayout.js +2 -7
  149. package/dist/layout-engine/index.d.ts +2 -2
  150. package/dist/layout-engine/index.js +2 -2
  151. package/dist/layout-engine/measure/measureBlocks.js +1 -6
  152. package/dist/layout-engine/types.d.ts +8 -2
  153. package/dist/layout-engine/types.js +35 -2
  154. package/dist/layout-painter/renderImage.js +4 -3
  155. package/dist/layout-painter/renderParagraph.js +4 -3
  156. package/dist/managers/autoSaveCodec.js +2 -8
  157. package/dist/markdown/images.js +1 -4
  158. package/dist/markdown/index.js +1 -1
  159. package/dist/markdown/internals.d.ts +6 -1
  160. package/dist/markdown/internals.js +14 -1
  161. package/dist/markdown/renderBlock.js +35 -21
  162. package/dist/markdown/renderParagraph.js +14 -5
  163. package/dist/markdown/renderRuns.js +4 -3
  164. package/dist/markdown/renderTable.js +4 -3
  165. package/dist/markdown/trailers.js +41 -7
  166. package/dist/markdown/types.d.ts +3 -7
  167. package/dist/prosemirror/attrs/index.js +71 -5
  168. package/dist/prosemirror/bookmarkBoundaryAttrs.d.ts +11 -1
  169. package/dist/prosemirror/bookmarkBoundaryAttrs.js +18 -3
  170. package/dist/prosemirror/commands/image.js +1 -0
  171. package/dist/prosemirror/commands/index.d.ts +3 -3
  172. package/dist/prosemirror/commands/index.js +2 -2
  173. package/dist/prosemirror/commands/paragraph.d.ts +3 -3
  174. package/dist/prosemirror/commands/paragraph.js +2 -2
  175. package/dist/prosemirror/commentIdAllocator.js +2 -7
  176. package/dist/prosemirror/conversion/fromProseDoc.js +197 -68
  177. package/dist/prosemirror/conversion/toProseDoc.d.ts +1 -14
  178. package/dist/prosemirror/conversion/toProseDoc.js +458 -335
  179. package/dist/prosemirror/extensions/core/ParagraphExtension.d.ts +14 -1
  180. package/dist/prosemirror/extensions/core/ParagraphExtension.js +11 -6
  181. package/dist/prosemirror/extensions/features/EmptyParagraphFormatExtension.js +3 -3
  182. package/dist/prosemirror/extensions/features/PasteCleanupExtension.d.ts +4 -1
  183. package/dist/prosemirror/extensions/features/PasteCleanupExtension.js +6 -2
  184. package/dist/prosemirror/extensions/features/pastedHeadingStyles.d.ts +7 -0
  185. package/dist/prosemirror/extensions/features/pastedHeadingStyles.js +74 -0
  186. package/dist/prosemirror/extensions/marks/HyperlinkExtension.js +2 -3
  187. package/dist/prosemirror/extensions/marks/markUtils.d.ts +11 -3
  188. package/dist/prosemirror/extensions/marks/markUtils.js +98 -19
  189. package/dist/prosemirror/extensions/nodes/BookmarkBoundaryExtension.js +7 -3
  190. package/dist/prosemirror/extensions/nodes/ImageExtension.js +6 -1
  191. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +8 -2
  192. package/dist/prosemirror/extensions/nodes/TableExtension.js +15 -1
  193. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +8 -4
  194. package/dist/prosemirror/extensions/types.d.ts +2 -2
  195. package/dist/prosemirror/index.d.ts +3 -3
  196. package/dist/prosemirror/index.js +3 -3
  197. package/dist/prosemirror/insertOperations.d.ts +9 -2
  198. package/dist/prosemirror/insertOperations.js +9 -4
  199. package/dist/prosemirror/paragraphFormattingProvenance.d.ts +162 -0
  200. package/dist/prosemirror/paragraphFormattingProvenance.js +115 -0
  201. package/dist/prosemirror/plugins/documentStyles.d.ts +9 -1
  202. package/dist/prosemirror/plugins/documentStyles.js +11 -1
  203. package/dist/prosemirror/plugins/index.d.ts +2 -2
  204. package/dist/prosemirror/plugins/index.js +2 -2
  205. package/dist/prosemirror/plugins/revisionIds.d.ts +11 -2
  206. package/dist/prosemirror/plugins/revisionIds.js +21 -6
  207. package/dist/prosemirror/runFormattingReconciliation.js +3 -2
  208. package/dist/prosemirror/runStyleFormatting.d.ts +1 -1
  209. package/dist/prosemirror/schema/nodes.d.ts +81 -1
  210. package/dist/prosemirror/styles/resolvedStyleAttrs.js +2 -0
  211. package/dist/prosemirror/styles/styleResolver.d.ts +9 -0
  212. package/dist/prosemirror/styles/styleResolver.js +12 -0
  213. package/dist/style-engine/styleEngine.d.ts +3 -0
  214. package/dist/style-engine/styleEngine.js +3 -0
  215. package/dist/style-sets/extract.js +1 -23
  216. package/dist/style-sets/stellaStyle.js +46 -39
  217. package/dist/style-sets/styleSetNormalization.d.ts +19 -0
  218. package/dist/style-sets/styleSetNormalization.js +99 -0
  219. package/dist/types/content.d.ts +2 -2
  220. package/dist/utils/base64.d.ts +36 -0
  221. package/dist/utils/base64.js +40 -0
  222. package/dist/utils/clipboard.js +2 -1
  223. package/dist/utils/createDocument.js +145 -20
  224. package/dist/utils/headingCollector.d.ts +8 -5
  225. package/dist/utils/headingCollector.js +23 -25
  226. package/dist/utils/tableOfContentsStyle.js +9 -2
  227. package/dist/utils/units.d.ts +10 -1
  228. package/dist/utils/units.js +12 -1
  229. package/dist/utils/urlSecurity.d.ts +8 -2
  230. package/dist/utils/urlSecurity.js +21 -3
  231. package/package.json +2 -2
  232. package/dist/docx/textWhitespace.d.ts +0 -4
  233. package/dist/docx/textWhitespace.js +0 -4
  234. package/dist/layout-bridge/engine/tableWidthUtils.d.ts +0 -6
  235. package/dist/layout-bridge/engine/tableWidthUtils.js +0 -25
  236. package/dist/markdown/headings.d.ts +0 -13
  237. package/dist/markdown/headings.js +0 -20
@@ -27,9 +27,11 @@ type BookmarkBoundaryAttrs = {
27
27
  name: string;
28
28
  colFirst?: number;
29
29
  colLast?: number;
30
+ displacedByCustomXml?: document_d_exports.DisplacedByCustomXml;
30
31
  } | {
31
32
  type: "end";
32
33
  id: number;
34
+ displacedByCustomXml?: document_d_exports.DisplacedByCustomXml;
33
35
  };
34
36
  /**
35
37
  * Paragraph node attributes - maps to ParagraphFormatting
@@ -189,6 +191,19 @@ type ParagraphAttrs = {
189
191
  /** Original inline paragraph formatting from DOCX (pre-style-resolution).
190
192
  * Used by fromProseDoc for lossless round-trip serialization. */
191
193
  _originalFormatting?: document_d_exports.ParagraphFormatting;
194
+ /**
195
+ * The `w:pPr` the style cascade resolves to for this paragraph: document
196
+ * defaults, the enclosing table style, then the `w:pStyle` chain. PM-only;
197
+ * never serialized.
198
+ *
199
+ * The formatting attrs above hold the EFFECTIVE value, because that is what
200
+ * the editor renders with. A save must write only what the paragraph states
201
+ * itself, so it needs this companion to tell an inherited value from an
202
+ * authored one — writing an inherited value back as direct `w:pPr` outranks
203
+ * the style it came from, and a later edit to that style stops reaching the
204
+ * paragraph. `TableCellAttrs._resolvedBorders` is the same device.
205
+ */
206
+ _resolvedFormatting?: document_d_exports.ParagraphFormatting;
192
207
  /** Import-effective spacing baseline for HTML auto-spacing detection.
193
208
  * PM-only; never serialized back into DOCX formatting. */
194
209
  _autospacingBase?: {
@@ -249,6 +264,25 @@ type ImagePositionAttrs = {
249
264
  align?: NonNullable<document_d_exports.ImagePosition["vertical"]["alignment"]>;
250
265
  };
251
266
  };
267
+ /**
268
+ * The EMUs a drawing's pixel attributes were projected from, keyed by the
269
+ * pixel attribute each one became.
270
+ *
271
+ * EMU → px → EMU does not land back on the same number: a size rounds to whole
272
+ * pixels, a stroke or an inset to two. Without the authored value beside the
273
+ * projected one, opening a document and saving it again moved every drawing
274
+ * off the number its author wrote. `fromProseDoc` writes the authored EMU back
275
+ * while the pixel attribute still projects from it, and converts the pixel
276
+ * attribute once an editor command has moved it.
277
+ *
278
+ * A key carries `undefined` when the source authored no such value, so an
279
+ * absent value stays absent rather than acquiring one the document never had.
280
+ */
281
+ type AuthoredEmuAttrs<Key extends string> = { readonly [K in Key]?: number | undefined; };
282
+ /** The pixel attributes a drawing's `wp:wrap*` insets are projected into. */
283
+ type WrapDistanceAttr = "distTop" | "distBottom" | "distLeft" | "distRight";
284
+ /** The pixel attributes a text box's internal margins are projected into. */
285
+ type TextBoxMarginAttr = "marginTop" | "marginBottom" | "marginLeft" | "marginRight";
252
286
  /**
253
287
  * Image node attributes
254
288
  */
@@ -305,6 +339,16 @@ type ImageAttrs = {
305
339
  position?: ImagePositionAttrs;
306
340
  /** Use the containing table cell as the anchor's positioning scope (the OOXML default). */
307
341
  layoutInCell?: boolean;
342
+ /**
343
+ * The image carries no information, so assistive technology skips it
344
+ * (`wp:docPr`'s decorative extension). Not {@link hidden}: a decorative
345
+ * image is still displayed.
346
+ */
347
+ decorative?: boolean;
348
+ /** `wp:docPr @hidden`: the drawing is not displayed. */
349
+ hidden?: boolean;
350
+ /** `wp:docPr` extensions folio does not model, carried through verbatim. */
351
+ docPrExtensions?: string[];
308
352
  /**
309
353
  * Authored `a:graphicFrameLocks`. Carried through the editor so a resize,
310
354
  * which forces the serializer to regenerate DrawingML, cannot silently
@@ -313,6 +357,8 @@ type ImageAttrs = {
313
357
  frameLocks?: document_d_exports.ImageFrameLocks;
314
358
  /** Border width in pixels */
315
359
  borderWidth?: number;
360
+ /** The EMUs behind `width`, `height`, `borderWidth` and the wrap insets. */
361
+ _docxAuthoredEmu?: AuthoredEmuAttrs<"width" | "height" | "borderWidth" | WrapDistanceAttr>;
316
362
  /** Border color as CSS color string */
317
363
  borderColor?: string;
318
364
  /** Border style (CSS border-style value) */
@@ -334,6 +380,14 @@ type ImageAttrs = {
334
380
  _docxRawImageFingerprint?: string;
335
381
  /** Embedded-object previews use their authored box as the exact line height. */
336
382
  _docxObjectPreview?: boolean;
383
+ /**
384
+ * The `w:rPr` of the run this atom came from. Inline atoms do not carry the
385
+ * run's formatting marks (see `withRunBoundaryMarks`), so without this the
386
+ * run properties of an embedded object, picture or shape are lost on save
387
+ * (`content[].content[].formatting: object became absent` in the corpus
388
+ * census).
389
+ */
390
+ _docxRunFormatting?: document_d_exports.TextFormatting;
337
391
  };
338
392
  /**
339
393
  * Field node attributes
@@ -445,6 +499,12 @@ type ShapeAttrs = {
445
499
  geometryAdjustments?: string;
446
500
  /** Unique identifier */
447
501
  shapeId?: string;
502
+ /** Authored non-visual drawing name (`wp:docPr@name` / `wps:cNvPr@name`) */
503
+ shapeName?: string;
504
+ /** Alt text for accessibility (`wp:docPr@descr`) */
505
+ alt?: string;
506
+ /** Authored non-visual drawing title (`wp:docPr@title`) */
507
+ title?: string;
448
508
  /** Width in pixels */
449
509
  width?: number;
450
510
  /** Height in pixels */
@@ -471,6 +531,8 @@ type ShapeAttrs = {
471
531
  outlineStyle?: OutlineStyleAttr;
472
532
  /** Line cap */
473
533
  outlineCap?: NonNullable<document_d_exports.ShapeOutline["cap"]>;
534
+ /** Line join */
535
+ outlineJoin?: NonNullable<document_d_exports.ShapeOutline["join"]>;
474
536
  /** Head arrow/end marker */
475
537
  outlineHeadEnd?: NonNullable<document_d_exports.ShapeOutline["headEnd"]>;
476
538
  /** Tail arrow/end marker */
@@ -507,6 +569,16 @@ type ShapeAttrs = {
507
569
  glowColor?: string;
508
570
  /** Glow radius in pixels */
509
571
  glowRadius?: number;
572
+ /**
573
+ * The `w:rPr` of the run this atom came from. Inline atoms do not carry the
574
+ * run's formatting marks (see `withRunBoundaryMarks`), so without this the
575
+ * run properties of an embedded object, picture or shape are lost on save
576
+ * (`content[].content[].formatting: object became absent` in the corpus
577
+ * census).
578
+ */
579
+ _docxRunFormatting?: document_d_exports.TextFormatting;
580
+ /** The EMUs behind `width`, `height`, `outlineWidth` and the wrap insets. */
581
+ _docxAuthoredEmu?: AuthoredEmuAttrs<"width" | "height" | "outlineWidth" | WrapDistanceAttr>;
510
582
  };
511
583
  /**
512
584
  * Text box node attributes
@@ -520,6 +592,8 @@ type TextBoxAttrs = {
520
592
  width?: number;
521
593
  /** Height in pixels */
522
594
  height?: number;
595
+ /** The EMUs behind the size, `outlineWidth`, the wrap insets and the margins. */
596
+ _docxAuthoredEmu?: AuthoredEmuAttrs<"width" | "height" | "outlineWidth" | WrapDistanceAttr | TextBoxMarginAttr>;
523
597
  /** Text fitting behavior */
524
598
  autoFit?: document_d_exports.ShapeTextBody["autoFit"];
525
599
  /** Authored DrawingML WordArt metadata. */
@@ -528,6 +602,12 @@ type TextBoxAttrs = {
528
602
  textWrap?: document_d_exports.ShapeTextBody["textWrap"];
529
603
  /** Unique identifier */
530
604
  textBoxId?: string;
605
+ /** Authored non-visual drawing name (`wp:docPr@name` / `wps:cNvPr@name`) */
606
+ textBoxName?: string;
607
+ /** Alt text for accessibility (`wp:docPr@descr`) */
608
+ alt?: string;
609
+ /** Authored non-visual drawing title (`wp:docPr@title`) */
610
+ title?: string;
531
611
  /** Fill color as CSS color */
532
612
  fillColor?: string;
533
613
  /** Outline width in pixels */
@@ -805,4 +885,4 @@ type TableCellAttrs = {
805
885
  _docxVMergeContinuationCells?: unknown;
806
886
  };
807
887
  //#endregion
808
- export { BlockSdtAttrs, BookmarkBoundaryAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, ImagePositionAttrs, MathAttrs, PageBreakRunAttrs, ParagraphAttrs, ParagraphPropertyChangeAttrs, SdtAttrs, ShapeAttrs, SuggestedStructuralMarker, SymbolAttrs, TEXT_BOX_TEXT_BODY_CONTENT_STATE_TYPES, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAnchorAttrs, TextBoxAttrs, TextBoxTextBodyContentState };
888
+ export { AuthoredEmuAttrs, BlockSdtAttrs, BookmarkBoundaryAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, ImagePositionAttrs, MathAttrs, PageBreakRunAttrs, ParagraphAttrs, ParagraphPropertyChangeAttrs, SdtAttrs, ShapeAttrs, SuggestedStructuralMarker, SymbolAttrs, TEXT_BOX_TEXT_BODY_CONTENT_STATE_TYPES, TabAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAnchorAttrs, TextBoxAttrs, TextBoxTextBodyContentState };
@@ -4,6 +4,7 @@ import { tableOfContentsStyleLevel } from "../../utils/tableOfContentsStyle.js";
4
4
  import { setAutospacingBaseValue } from "../autospacingBase.js";
5
5
  import { CLEARED_LIST_RENDERING_ATTRS } from "../listMarker.js";
6
6
  import { listRenderingAttrPatch } from "../listRenderingAttrs.js";
7
+ import { styleResolvedParagraphFormatting } from "../paragraphFormattingProvenance.js";
7
8
  //#region src/prosemirror/styles/resolvedStyleAttrs.ts
8
9
  /**
9
10
  * Shared helper for projecting a resolved paragraph style onto ProseMirror
@@ -45,6 +46,7 @@ function paragraphAttrsFromResolvedStyle(resolved, identity) {
45
46
  outlineLevel: ppr?.outlineLevel ?? null,
46
47
  borders: ppr?.borders ?? null,
47
48
  defaultTextFormatting: hasRunFormatting ? runFormatting : null,
49
+ _resolvedFormatting: styleResolvedParagraphFormatting(ppr),
48
50
  _autospacingBase: autospacingBaseFromResolvedParagraphFormatting(ppr),
49
51
  _tableOfContentsLevel: tableOfContentsStyleLevel(identity) ?? null
50
52
  };
@@ -1,4 +1,5 @@
1
1
  import { document_d_exports } from "../../types/document.js";
2
+ import { BuiltInStyleIndex } from "../../docx/builtInStyles.js";
2
3
  //#region src/prosemirror/styles/styleResolver.d.ts
3
4
  /**
4
5
  * Resolved style properties ready for rendering
@@ -27,6 +28,7 @@ type TableCellParagraphSpacingOverlay = Pick<document_d_exports.ParagraphFormatt
27
28
  */
28
29
  declare class StyleResolver {
29
30
  private readonly stylesById;
31
+ private builtInStyleIndex;
30
32
  private readonly docDefaults;
31
33
  private readonly defaultParagraphStyle;
32
34
  private readonly defaultCharacterStyle;
@@ -36,6 +38,13 @@ declare class StyleResolver {
36
38
  * Get a style by ID
37
39
  */
38
40
  getStyle(styleId: string): document_d_exports.Style | undefined;
41
+ /**
42
+ * This document's styles indexed by the built-in they are, so a consumer can
43
+ * ask whether a paragraph is a heading without matching an English style id.
44
+ * Built on first use and kept: the resolver outlives a single query, and the
45
+ * outline sidebar rebuilds its heading list on every transaction.
46
+ */
47
+ get builtInStyles(): BuiltInStyleIndex;
39
48
  /**
40
49
  * Get all available paragraph styles (for toolbar dropdown)
41
50
  */
@@ -1,3 +1,4 @@
1
+ import { createBuiltInStyleIndex } from "../../docx/builtInStyles.js";
1
2
  import { BUILT_IN_DEFAULT_PARAGRAPH_FORMATTING, resolveDefaultParagraphStyle } from "../../docx/defaultParagraphStyle.js";
2
3
  import { mergeParagraphFormatting } from "../../utils/paragraphFormattingMerge.js";
3
4
  import { cascadeStyleTextFormatting } from "./styleToggleCascade.js";
@@ -27,6 +28,7 @@ const BUILTIN_NORMAL_STYLE = {
27
28
  */
28
29
  var StyleResolver = class {
29
30
  stylesById;
31
+ builtInStyleIndex;
30
32
  docDefaults;
31
33
  defaultParagraphStyle;
32
34
  defaultCharacterStyle;
@@ -48,6 +50,16 @@ var StyleResolver = class {
48
50
  return this.stylesById.get(styleId);
49
51
  }
50
52
  /**
53
+ * This document's styles indexed by the built-in they are, so a consumer can
54
+ * ask whether a paragraph is a heading without matching an English style id.
55
+ * Built on first use and kept: the resolver outlives a single query, and the
56
+ * outline sidebar rebuilds its heading list on every transaction.
57
+ */
58
+ get builtInStyles() {
59
+ this.builtInStyleIndex ??= createBuiltInStyleIndex(this.stylesById.values(), this.docDefaults);
60
+ return this.builtInStyleIndex;
61
+ }
62
+ /**
51
63
  * Get all available paragraph styles (for toolbar dropdown)
52
64
  */
53
65
  getParagraphStyles() {
@@ -1,4 +1,5 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
+ import { BuiltInStyleIndex } from "../docx/builtInStyles.js";
2
3
  import { ResolvedParagraphStyle, TableCellParagraphSpacingOverlay } from "../prosemirror/styles/styleResolver.js";
3
4
  //#region src/style-engine/styleEngine.d.ts
4
5
  /** Engine construction options. */
@@ -44,6 +45,8 @@ type StyleEngine = {
44
45
  getParagraphStyles: () => document_d_exports.Style[];
45
46
  /** All visible table styles, sorted for the table-style gallery. */
46
47
  getTableStyles: () => document_d_exports.Style[];
48
+ /** The document's styles indexed by the built-in they are — see {@link StyleResolver.builtInStyles}. */
49
+ builtInStyles: BuiltInStyleIndex;
47
50
  /**
48
51
  * Resolve the full paragraph cascade for a given styleId.
49
52
  * Returned object is cached and must not be mutated.
@@ -62,6 +62,9 @@ function createStyleEngine(styleDefinitions, options) {
62
62
  getDefaultTableStyle: () => resolver.getDefaultTableStyle(),
63
63
  getParagraphStyles: () => resolver.getParagraphStyles(),
64
64
  getTableStyles: () => resolver.getTableStyles(),
65
+ get builtInStyles() {
66
+ return resolver.builtInStyles;
67
+ },
65
68
  resolveParagraphStyle: (styleId) => memoize(paragraphCache, cacheKey(styleId), () => resolver.resolveParagraphStyle(styleId)),
66
69
  resolveParagraphStyleInTable: (styleId, tableParagraphOverlay) => tableParagraphOverlay === void 0 ? memoize(paragraphCache, cacheKey(styleId), () => resolver.resolveParagraphStyleInTable(styleId, void 0)) : memoizeInTable(styleId, tableParagraphOverlay),
67
70
  resolveRunStyle: (styleId) => memoize(runCache, cacheKey(styleId), () => resolver.resolveRunStyle(styleId)),
@@ -1,4 +1,4 @@
1
- import { BUILT_IN_DEFAULT_PARAGRAPH_FORMATTING, BUILT_IN_DEFAULT_PARAGRAPH_STYLE_ID, BUILT_IN_DEFAULT_PARAGRAPH_STYLE_NAME, resolveDefaultParagraphStyle } from "../docx/defaultParagraphStyle.js";
1
+ import { mintDefaultParagraphStyle, resolveDefaultParagraphStyle } from "../docx/defaultParagraphStyle.js";
2
2
  import { getCachedNumberingMap } from "../docx/numberingParser.js";
3
3
  import { isNumberingReference } from "../docx/numberingReference.js";
4
4
  import { normalizeStyleNumberingReferences } from "../docx/numberingReferenceNormalization.js";
@@ -83,28 +83,6 @@ const ensureInitialParagraphStyle = ({ styles, requested, hasDocDefaults }) => {
83
83
  styles.push(minted);
84
84
  return minted.styleId;
85
85
  };
86
- /**
87
- * The default paragraph style a set needs when its source declared none.
88
- *
89
- * The id only has to be free, because the set is what defines it. The
90
- * formatting has to be the built-in template's whenever the source had no
91
- * `w:docDefaults`, because that is what the source itself rendered as: a
92
- * consumer applies its built-in Normal only where no default paragraph style
93
- * exists, and this minted style is one. Where the source did declare
94
- * `w:docDefaults`, the set carries them and they remain authoritative, so the
95
- * minted style states nothing.
96
- */
97
- const mintDefaultParagraphStyle = ({ takenStyleIds, hasDocDefaults }) => {
98
- let styleId = BUILT_IN_DEFAULT_PARAGRAPH_STYLE_ID;
99
- for (let suffix = 1; takenStyleIds.has(styleId); suffix += 1) styleId = `${BUILT_IN_DEFAULT_PARAGRAPH_STYLE_ID}${suffix}`;
100
- return {
101
- styleId,
102
- type: "paragraph",
103
- name: BUILT_IN_DEFAULT_PARAGRAPH_STYLE_NAME,
104
- default: true,
105
- ...hasDocDefaults ? {} : { pPr: { ...BUILT_IN_DEFAULT_PARAGRAPH_FORMATTING } }
106
- };
107
- };
108
86
  const collectStyleDependencyClosure = (stylesById, requestedStyleIds) => {
109
87
  const selected = /* @__PURE__ */ new Set();
110
88
  const pending = [...requestedStyleIds];
@@ -1,3 +1,4 @@
1
+ import { BUILT_IN_STYLE_NAME, builtInHeadingStyleName, builtInTableOfContentsStyleName } from "../docx/builtInStyles.js";
1
2
  import "./types.js";
2
3
  //#region src/style-sets/stellaStyle.ts
3
4
  const CLAUSE_NUMBERING_ID = 1;
@@ -43,7 +44,7 @@ const createStellaStyleSet = () => ({
43
44
  {
44
45
  styleId: "Normal",
45
46
  type: "paragraph",
46
- name: "Normal",
47
+ name: BUILT_IN_STYLE_NAME.normal,
47
48
  default: true,
48
49
  qFormat: true,
49
50
  uiPriority: 0,
@@ -64,7 +65,7 @@ const createStellaStyleSet = () => ({
64
65
  {
65
66
  styleId: "DefaultParagraphFont",
66
67
  type: "character",
67
- name: "Default Paragraph Font",
68
+ name: BUILT_IN_STYLE_NAME.defaultParagraphFont,
68
69
  default: true,
69
70
  semiHidden: true,
70
71
  unhideWhenUsed: true
@@ -72,7 +73,7 @@ const createStellaStyleSet = () => ({
72
73
  {
73
74
  styleId: "BodyText",
74
75
  type: "paragraph",
75
- name: "Body Text",
76
+ name: BUILT_IN_STYLE_NAME.bodyText,
76
77
  basedOn: "Normal",
77
78
  qFormat: true,
78
79
  uiPriority: 1
@@ -80,7 +81,7 @@ const createStellaStyleSet = () => ({
80
81
  {
81
82
  styleId: "Title",
82
83
  type: "paragraph",
83
- name: "Title",
84
+ name: BUILT_IN_STYLE_NAME.title,
84
85
  basedOn: "BodyText",
85
86
  next: "BodyText",
86
87
  qFormat: true,
@@ -109,7 +110,7 @@ const createStellaStyleSet = () => ({
109
110
  {
110
111
  styleId: "Subtitle",
111
112
  type: "paragraph",
112
- name: "Subtitle",
113
+ name: BUILT_IN_STYLE_NAME.subtitle,
113
114
  basedOn: "Title",
114
115
  next: "BodyText",
115
116
  qFormat: true,
@@ -131,7 +132,10 @@ const createStellaStyleSet = () => ({
131
132
  next: "Recital",
132
133
  qFormat: true,
133
134
  uiPriority: 5,
134
- pPr: { keepNext: true },
135
+ pPr: {
136
+ keepNext: true,
137
+ outlineLevel: 0
138
+ },
135
139
  rPr: { bold: true }
136
140
  },
137
141
  {
@@ -179,7 +183,7 @@ const createStellaStyleSet = () => ({
179
183
  {
180
184
  styleId: "ListParagraph",
181
185
  type: "paragraph",
182
- name: "List Paragraph",
186
+ name: BUILT_IN_STYLE_NAME.listParagraph,
183
187
  basedOn: "BodyText",
184
188
  qFormat: true,
185
189
  uiPriority: 31,
@@ -208,13 +212,14 @@ const createStellaStyleSet = () => ({
208
212
  pPr: {
209
213
  pageBreakBefore: true,
210
214
  keepNext: true,
211
- spaceAfter: 240
215
+ spaceAfter: 240,
216
+ outlineLevel: 0
212
217
  }
213
218
  },
214
219
  {
215
220
  styleId: "FootnoteText",
216
221
  type: "paragraph",
217
- name: "Footnote Text",
222
+ name: BUILT_IN_STYLE_NAME.footnoteText,
218
223
  basedOn: "Normal",
219
224
  link: "FootnoteTextChar",
220
225
  semiHidden: true,
@@ -229,7 +234,7 @@ const createStellaStyleSet = () => ({
229
234
  {
230
235
  styleId: "FootnoteTextChar",
231
236
  type: "character",
232
- name: "Footnote Text Char",
237
+ name: BUILT_IN_STYLE_NAME.footnoteTextChar,
233
238
  basedOn: "DefaultParagraphFont",
234
239
  link: "FootnoteText",
235
240
  semiHidden: true,
@@ -243,7 +248,7 @@ const createStellaStyleSet = () => ({
243
248
  {
244
249
  styleId: "FootnoteReference",
245
250
  type: "character",
246
- name: "Footnote Reference",
251
+ name: BUILT_IN_STYLE_NAME.footnoteReference,
247
252
  basedOn: "DefaultParagraphFont",
248
253
  semiHidden: true,
249
254
  unhideWhenUsed: true,
@@ -253,7 +258,7 @@ const createStellaStyleSet = () => ({
253
258
  {
254
259
  styleId: "EndnoteText",
255
260
  type: "paragraph",
256
- name: "Endnote Text",
261
+ name: BUILT_IN_STYLE_NAME.endnoteText,
257
262
  basedOn: "Normal",
258
263
  link: "EndnoteTextChar",
259
264
  semiHidden: true,
@@ -268,7 +273,7 @@ const createStellaStyleSet = () => ({
268
273
  {
269
274
  styleId: "EndnoteTextChar",
270
275
  type: "character",
271
- name: "Endnote Text Char",
276
+ name: BUILT_IN_STYLE_NAME.endnoteTextChar,
272
277
  basedOn: "DefaultParagraphFont",
273
278
  link: "EndnoteText",
274
279
  semiHidden: true,
@@ -282,7 +287,7 @@ const createStellaStyleSet = () => ({
282
287
  {
283
288
  styleId: "EndnoteReference",
284
289
  type: "character",
285
- name: "Endnote Reference",
290
+ name: BUILT_IN_STYLE_NAME.endnoteReference,
286
291
  basedOn: "DefaultParagraphFont",
287
292
  semiHidden: true,
288
293
  unhideWhenUsed: true,
@@ -292,7 +297,7 @@ const createStellaStyleSet = () => ({
292
297
  {
293
298
  styleId: "Footer",
294
299
  type: "paragraph",
295
- name: "Footer",
300
+ name: BUILT_IN_STYLE_NAME.footer,
296
301
  basedOn: "Normal",
297
302
  pPr: {
298
303
  alignment: "right",
@@ -307,7 +312,7 @@ const createStellaStyleSet = () => ({
307
312
  {
308
313
  styleId: "Hyperlink",
309
314
  type: "character",
310
- name: "Hyperlink",
315
+ name: BUILT_IN_STYLE_NAME.hyperlink,
311
316
  basedOn: "DefaultParagraphFont",
312
317
  unhideWhenUsed: true,
313
318
  uiPriority: 99,
@@ -319,7 +324,7 @@ const createStellaStyleSet = () => ({
319
324
  {
320
325
  styleId: "TableNormal",
321
326
  type: "table",
322
- name: "Normal Table",
327
+ name: BUILT_IN_STYLE_NAME.normalTable,
323
328
  default: true,
324
329
  semiHidden: true,
325
330
  unhideWhenUsed: true,
@@ -328,7 +333,7 @@ const createStellaStyleSet = () => ({
328
333
  {
329
334
  styleId: "TableGrid",
330
335
  type: "table",
331
- name: "Table Grid",
336
+ name: BUILT_IN_STYLE_NAME.tableGrid,
332
337
  basedOn: "TableNormal",
333
338
  qFormat: true,
334
339
  uiPriority: 59,
@@ -399,37 +404,37 @@ const createHeadingStyles = () => {
399
404
  return [
400
405
  {
401
406
  styleId: "Heading1",
402
- name: "heading 1",
407
+ name: builtInHeadingStyleName(0),
403
408
  fontSize: 28,
404
409
  spaceBefore: 360
405
410
  },
406
411
  {
407
412
  styleId: "Heading2",
408
- name: "heading 2",
413
+ name: builtInHeadingStyleName(1),
409
414
  fontSize: 24,
410
415
  spaceBefore: 240
411
416
  },
412
417
  {
413
418
  styleId: "Heading3",
414
- name: "heading 3",
419
+ name: builtInHeadingStyleName(2),
415
420
  fontSize: 22,
416
421
  spaceBefore: 240
417
422
  },
418
423
  {
419
424
  styleId: "Heading4",
420
- name: "heading 4",
425
+ name: builtInHeadingStyleName(3),
421
426
  fontSize: 20,
422
427
  spaceBefore: 120
423
428
  },
424
429
  {
425
430
  styleId: "Heading5",
426
- name: "heading 5",
431
+ name: builtInHeadingStyleName(4),
427
432
  fontSize: 20,
428
433
  spaceBefore: 120
429
434
  },
430
435
  {
431
436
  styleId: "Heading6",
432
- name: "heading 6",
437
+ name: builtInHeadingStyleName(5),
433
438
  fontSize: 20,
434
439
  spaceBefore: 120
435
440
  }
@@ -457,32 +462,33 @@ const createHeadingStyles = () => {
457
462
  };
458
463
  /** `TOCHeading` plus `TOC1`..`TOC3`, the styles a `TOC \o "1-3"` field fills. */
459
464
  const createTableOfContentsStyles = () => {
460
- return [{
461
- styleId: "TOCHeading",
462
- type: "paragraph",
463
- name: "TOC Heading",
464
- basedOn: "Heading1",
465
- next: "BodyText",
466
- unhideWhenUsed: true,
467
- uiPriority: 39,
468
- pPr: { outlineLevel: 9 }
469
- }, ...[
465
+ const levels = [
470
466
  {
471
467
  styleId: "TOC1",
472
- name: "toc 1",
468
+ name: builtInTableOfContentsStyleName(1),
473
469
  indent: 0
474
470
  },
475
471
  {
476
472
  styleId: "TOC2",
477
- name: "toc 2",
473
+ name: builtInTableOfContentsStyleName(2),
478
474
  indent: 220
479
475
  },
480
476
  {
481
477
  styleId: "TOC3",
482
- name: "toc 3",
478
+ name: builtInTableOfContentsStyleName(3),
483
479
  indent: 440
484
480
  }
485
- ].map(({ styleId, name, indent }) => ({
481
+ ];
482
+ return [{
483
+ styleId: "TOCHeading",
484
+ type: "paragraph",
485
+ name: BUILT_IN_STYLE_NAME.tocHeading,
486
+ basedOn: "Heading1",
487
+ next: "BodyText",
488
+ unhideWhenUsed: true,
489
+ uiPriority: 39,
490
+ pPr: { outlineLevel: 9 }
491
+ }, ...levels.map(({ styleId, name, indent }) => ({
486
492
  styleId,
487
493
  type: "paragraph",
488
494
  name,
@@ -548,7 +554,8 @@ const createClauseStyles = () => {
548
554
  ilvl: level
549
555
  },
550
556
  keepNext: level < 2,
551
- spaceBefore: clauseSpaceBefore(level)
557
+ spaceBefore: clauseSpaceBefore(level),
558
+ outlineLevel: level === 0 ? 0 : 9
552
559
  }
553
560
  };
554
561
  if (bold) return Object.assign(style, { rPr: { bold: true } });
@@ -0,0 +1,19 @@
1
+ import { DocumentStyleSet } from "./types.js";
2
+ import { ParseContext } from "../docx/parseContext.js";
3
+ //#region src/style-sets/styleSetNormalization.d.ts
4
+ /** The codes this normalisation is reported under, owned here, not at the caller. */
5
+ declare const DUPLICATE_STYLE_ID_WARNING: "style-set-duplicate-style-id";
6
+ declare const INITIAL_PARAGRAPH_STYLE_WARNING: "style-set-initial-style-missing";
7
+ declare const UNNUMBERED_STYLE_SET_STYLE_WARNING: "unnumbered-style";
8
+ /** The part a style-set normalisation names: the set itself, not a package. */
9
+ declare const STYLE_SET_PART = "style-set";
10
+ /**
11
+ * A normalised copy of the set, leaving the caller's value untouched.
12
+ *
13
+ * The version is the one thing still refused rather than repaired: a value
14
+ * folio has no reader for is programmer misuse, not a document defect, and
15
+ * guessing at its meaning would be worse than saying so.
16
+ */
17
+ declare const normalizeDocumentStyleSet: (styleSet: DocumentStyleSet, context?: ParseContext) => DocumentStyleSet;
18
+ //#endregion
19
+ export { DUPLICATE_STYLE_ID_WARNING, INITIAL_PARAGRAPH_STYLE_WARNING, STYLE_SET_PART, UNNUMBERED_STYLE_SET_STYLE_WARNING, normalizeDocumentStyleSet };
@@ -0,0 +1,99 @@
1
+ import { mintDefaultParagraphStyle, resolveDefaultParagraphStyle } from "../docx/defaultParagraphStyle.js";
2
+ import { getCachedNumberingMap } from "../docx/numberingParser.js";
3
+ import { normalizeStyleNumberingReferences } from "../docx/numberingReferenceNormalization.js";
4
+ import "./types.js";
5
+ import { panic } from "better-result";
6
+ import { PARSE_WARNING_CODES } from "@stll/docx-core/model";
7
+ //#region src/style-sets/styleSetNormalization.ts
8
+ /**
9
+ * The boundary an external `DocumentStyleSet` crosses to become a document.
10
+ *
11
+ * A style set is portable by design: hosts persist one as JSON, ship it
12
+ * between workspaces, and hand it back months later. That makes it untrusted
13
+ * input on the same footing as a `.docx`, and it can carry the same defects a
14
+ * package can: a style numbering the set never defines, two styles under one
15
+ * id, an initial paragraph style that is not in the set. A set written before
16
+ * folio learned to normalise those still carries them.
17
+ *
18
+ * So it is normalised here, once, on the way in, through the same owners the
19
+ * parser and the extractor use, rather than at a third call site with its own
20
+ * rules. `createEmptyDocument` is the only door, so this is the only place
21
+ * that has to run.
22
+ *
23
+ * `DOCUMENT_STYLE_SET_VERSION` does not move: the shape is unchanged and a v1
24
+ * value is still a v1 value. What changed is that folio repairs one instead of
25
+ * trusting it.
26
+ */
27
+ /** The codes this normalisation is reported under, owned here, not at the caller. */
28
+ const DUPLICATE_STYLE_ID_WARNING = PARSE_WARNING_CODES.styleSetDuplicateStyleId;
29
+ const INITIAL_PARAGRAPH_STYLE_WARNING = PARSE_WARNING_CODES.styleSetInitialStyleMissing;
30
+ const UNNUMBERED_STYLE_SET_STYLE_WARNING = PARSE_WARNING_CODES.unnumberedStyle;
31
+ /** The part a style-set normalisation names: the set itself, not a package. */
32
+ const STYLE_SET_PART = "style-set";
33
+ /**
34
+ * A normalised copy of the set, leaving the caller's value untouched.
35
+ *
36
+ * The version is the one thing still refused rather than repaired: a value
37
+ * folio has no reader for is programmer misuse, not a document defect, and
38
+ * guessing at its meaning would be worse than saying so.
39
+ */
40
+ const normalizeDocumentStyleSet = (styleSet, context) => {
41
+ if (styleSet.version !== 1) return panic(`Unsupported document style set version: ${String(styleSet.version)}`);
42
+ if (styleSet.name.trim().length === 0) return panic("Document style set name cannot be empty");
43
+ const scoped = context?.scoped({ part: STYLE_SET_PART });
44
+ const normalized = structuredClone(styleSet);
45
+ const styles = dropDuplicateStyleIds(normalized.styles.styles, scoped);
46
+ normalized.styles.styles = styles;
47
+ const unnumbered = normalizeStyleNumberingReferences({
48
+ styles,
49
+ numbering: normalized.numbering ? getCachedNumberingMap(normalized.numbering) : void 0
50
+ });
51
+ for (const styleId of unnumbered.unnumberedStyleIds) scoped?.warn({
52
+ code: UNNUMBERED_STYLE_SET_STYLE_WARNING,
53
+ value: styleId,
54
+ at: `style "${styleId}"`
55
+ });
56
+ normalized.initialParagraphStyleId = resolveInitialParagraphStyleId({
57
+ styles,
58
+ requested: styleSet.initialParagraphStyleId,
59
+ hasDocDefaults: normalized.styles.docDefaults !== void 0,
60
+ context: scoped
61
+ });
62
+ return normalized;
63
+ };
64
+ const dropDuplicateStyleIds = (styles, context) => {
65
+ const seen = /* @__PURE__ */ new Set();
66
+ const kept = [];
67
+ for (const style of styles) {
68
+ if (seen.has(style.styleId)) {
69
+ context?.warn({
70
+ code: DUPLICATE_STYLE_ID_WARNING,
71
+ value: style.styleId,
72
+ at: `style "${style.styleId}"`
73
+ });
74
+ continue;
75
+ }
76
+ seen.add(style.styleId);
77
+ kept.push(style);
78
+ }
79
+ return kept;
80
+ };
81
+ const resolveInitialParagraphStyleId = ({ styles, requested, hasDocDefaults, context }) => {
82
+ if (styles.find((style) => style.styleId === requested && style.type === "paragraph")) return requested;
83
+ const replacement = resolveDefaultParagraphStyle(styles) ?? (() => {
84
+ const minted = mintDefaultParagraphStyle({
85
+ takenStyleIds: new Set(styles.map((style) => style.styleId)),
86
+ hasDocDefaults
87
+ });
88
+ styles.push(minted);
89
+ return minted;
90
+ })();
91
+ context?.warn({
92
+ code: INITIAL_PARAGRAPH_STYLE_WARNING,
93
+ value: requested,
94
+ at: `style "${replacement.styleId}"`
95
+ });
96
+ return replacement.styleId;
97
+ };
98
+ //#endregion
99
+ export { DUPLICATE_STYLE_ID_WARNING, INITIAL_PARAGRAPH_STYLE_WARNING, STYLE_SET_PART, UNNUMBERED_STYLE_SET_STYLE_WARNING, normalizeDocumentStyleSet };