@stll/folio-core 0.48.0 → 0.50.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 (170) hide show
  1. package/dist/ai-edits/apply.js +565 -121
  2. package/dist/ai-edits/headless.d.ts +37 -1
  3. package/dist/ai-edits/headless.js +47 -16
  4. package/dist/ai-edits/minimal-replacement.d.ts +64 -0
  5. package/dist/ai-edits/minimal-replacement.js +282 -0
  6. package/dist/controller/layoutPipeline.js +11 -1
  7. package/dist/display-list/build/paragraphPrimitives.js +63 -7
  8. package/dist/display-list/build/textBoxPrimitives.js +1 -1
  9. package/dist/display-list/build/unsupported.d.ts +2 -2
  10. package/dist/display-list/build/unsupported.js +0 -0
  11. package/dist/display-list/dom/renderDisplayListToDom.d.ts +10 -1
  12. package/dist/display-list/dom/renderDisplayListToDom.js +8 -8
  13. package/dist/display-list/html/renderDisplayListToHtml.d.ts +21 -0
  14. package/dist/display-list/html/renderDisplayListToHtml.js +126 -0
  15. package/dist/display-list/selectDisplayPages.d.ts +6 -0
  16. package/dist/display-list/selectDisplayPages.js +44 -0
  17. package/dist/docx/blockContentParser.js +2 -2
  18. package/dist/docx/bulletMarkers.d.ts +18 -2
  19. package/dist/docx/bulletMarkers.js +27 -2
  20. package/dist/docx/drawingGroupChildren.d.ts +60 -0
  21. package/dist/docx/drawingGroupChildren.js +176 -0
  22. package/dist/docx/drawingUtils.js +3 -0
  23. package/dist/docx/groupDrawingParser.d.ts +7 -1
  24. package/dist/docx/groupDrawingParser.js +123 -32
  25. package/dist/docx/packageParts.d.ts +45 -1
  26. package/dist/docx/packageParts.js +93 -2
  27. package/dist/docx/paraIdAttribute.d.ts +3 -2
  28. package/dist/docx/paragraphParser.js +91 -7
  29. package/dist/docx/paragraphTextBoxEnrichment.js +126 -4
  30. package/dist/docx/runParser.js +10 -0
  31. package/dist/docx/selectiveSaveFlags.d.ts +10 -3
  32. package/dist/docx/selectiveSaveFlags.js +1 -1
  33. package/dist/docx/selectiveXmlPatch.d.ts +56 -34
  34. package/dist/docx/selectiveXmlPatch.js +222 -115
  35. package/dist/docx/serializer/groupTextBoxWriteBack.d.ts +12 -0
  36. package/dist/docx/serializer/groupTextBoxWriteBack.js +101 -0
  37. package/dist/docx/serializer/paragraphSerializer.js +5 -4
  38. package/dist/docx/serializer/runSerializer.d.ts +5 -1
  39. package/dist/docx/serializer/runSerializer.js +4 -3
  40. package/dist/docx/shapeAlternateContent.d.ts +25 -0
  41. package/dist/docx/shapeAlternateContent.js +52 -0
  42. package/dist/docx/textBoxParser.d.ts +10 -2
  43. package/dist/docx/textBoxParser.js +9 -3
  44. package/dist/export-pdf.d.ts +35 -2
  45. package/dist/export-pdf.js +51 -20
  46. package/dist/fonts/fontsourceFaces.d.ts +47 -0
  47. package/dist/fonts/fontsourceFaces.js +230 -0
  48. package/dist/internal/headlessRevisionResolution.js +50 -13
  49. package/dist/layout-bridge/convert/flowBlockPostprocessing.d.ts +8 -0
  50. package/dist/layout-bridge/convert/flowBlockPostprocessing.js +106 -0
  51. package/dist/layout-bridge/convert/flowBorders.d.ts +17 -0
  52. package/dist/layout-bridge/convert/flowBorders.js +31 -0
  53. package/dist/layout-bridge/convert/flowConversionShared.d.ts +111 -0
  54. package/dist/layout-bridge/convert/flowConversionShared.js +23 -0
  55. package/dist/layout-bridge/convert/footnoteLayout.d.ts +2 -1
  56. package/dist/layout-bridge/convert/footnoteLayout.js +2 -1
  57. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +2 -1
  58. package/dist/layout-bridge/convert/imageConversion.d.ts +33 -0
  59. package/dist/layout-bridge/convert/imageConversion.js +118 -0
  60. package/dist/layout-bridge/convert/listMarkers.d.ts +28 -0
  61. package/dist/layout-bridge/convert/listMarkers.js +98 -0
  62. package/dist/layout-bridge/convert/noteReferences.d.ts +14 -0
  63. package/dist/layout-bridge/convert/noteReferences.js +29 -0
  64. package/dist/layout-bridge/convert/pageBreakSplitting.d.ts +16 -0
  65. package/dist/layout-bridge/convert/pageBreakSplitting.js +140 -0
  66. package/dist/layout-bridge/convert/paragraphAttrs.d.ts +20 -0
  67. package/dist/layout-bridge/convert/paragraphAttrs.js +234 -0
  68. package/dist/layout-bridge/convert/paragraphConversion.d.ts +12 -0
  69. package/dist/layout-bridge/convert/paragraphConversion.js +112 -0
  70. package/dist/layout-bridge/convert/paragraphRuns.d.ts +15 -0
  71. package/dist/layout-bridge/convert/paragraphRuns.js +281 -0
  72. package/dist/layout-bridge/convert/runFormattingMerge.d.ts +19 -0
  73. package/dist/layout-bridge/convert/runFormattingMerge.js +167 -0
  74. package/dist/layout-bridge/convert/runMarkFormatting.d.ts +11 -0
  75. package/dist/layout-bridge/convert/runMarkFormatting.js +291 -0
  76. package/dist/layout-bridge/convert/sectionBoundaries.d.ts +35 -0
  77. package/dist/layout-bridge/convert/sectionBoundaries.js +114 -0
  78. package/dist/layout-bridge/convert/tableConversion.d.ts +12 -0
  79. package/dist/layout-bridge/convert/tableConversion.js +303 -0
  80. package/dist/layout-bridge/convert/textBoxFill.d.ts +20 -0
  81. package/dist/layout-bridge/convert/textBoxFill.js +42 -0
  82. package/dist/layout-bridge/convert/textFormattingConversion.d.ts +22 -0
  83. package/dist/layout-bridge/convert/textFormattingConversion.js +120 -0
  84. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +5 -113
  85. package/dist/layout-bridge/convert/toFlowBlocks.js +11 -2060
  86. package/dist/layout-bridge/engine/hitTest.js +1 -1
  87. package/dist/layout-bridge/engine/measuring/index.d.ts +2 -1
  88. package/dist/layout-bridge/engine/measuring/index.js +2 -1
  89. package/dist/layout-bridge/engine/selectionRects.js +1 -1
  90. package/dist/layout-engine/imageLayout.d.ts +9 -0
  91. package/dist/layout-engine/imageLayout.js +48 -0
  92. package/dist/layout-engine/index.d.ts +4 -19
  93. package/dist/layout-engine/index.js +14 -910
  94. package/dist/layout-engine/keep-together.d.ts +5 -2
  95. package/dist/layout-engine/keep-together.js +5 -1
  96. package/dist/layout-engine/layoutFlowShared.d.ts +6 -0
  97. package/dist/layout-engine/layoutFlowShared.js +8 -0
  98. package/dist/layout-engine/measure/advanceComposition.js +49 -3
  99. package/dist/layout-engine/measure/crossRunWords.d.ts +45 -0
  100. package/dist/layout-engine/measure/crossRunWords.js +172 -0
  101. package/dist/layout-engine/measure/floatingLineClearance.d.ts +24 -0
  102. package/dist/layout-engine/measure/floatingLineClearance.js +44 -0
  103. package/dist/layout-engine/measure/inlineObjectMetrics.d.ts +6 -0
  104. package/dist/layout-engine/measure/inlineObjectMetrics.js +52 -0
  105. package/dist/layout-engine/measure/justification.d.ts +32 -0
  106. package/dist/layout-engine/measure/justification.js +83 -0
  107. package/dist/layout-engine/measure/lineFitting.d.ts +48 -0
  108. package/dist/layout-engine/measure/lineFitting.js +145 -0
  109. package/dist/layout-engine/measure/lineTypography.d.ts +44 -0
  110. package/dist/layout-engine/measure/lineTypography.js +124 -0
  111. package/dist/layout-engine/measure/measureBlocks.js +7 -4
  112. package/dist/layout-engine/measure/measureContainer.js +46 -3
  113. package/dist/layout-engine/measure/measureHelpers.js +13 -3
  114. package/dist/layout-engine/measure/measureParagraph.d.ts +1 -20
  115. package/dist/layout-engine/measure/measureParagraph.js +41 -780
  116. package/dist/layout-engine/measure/paragraphMeasureShared.d.ts +109 -0
  117. package/dist/layout-engine/measure/paragraphMeasureShared.js +82 -0
  118. package/dist/layout-engine/measure/paragraphTabs.d.ts +18 -0
  119. package/dist/layout-engine/measure/paragraphTabs.js +78 -0
  120. package/dist/layout-engine/measure/smallCapsCasing.d.ts +56 -0
  121. package/dist/layout-engine/measure/smallCapsCasing.js +88 -0
  122. package/dist/layout-engine/paginator.d.ts +2 -0
  123. package/dist/layout-engine/paginator.js +5 -1
  124. package/dist/layout-engine/paragraphLayout.d.ts +23 -0
  125. package/dist/layout-engine/paragraphLayout.js +204 -0
  126. package/dist/layout-engine/paragraphSpacing.d.ts +4 -2
  127. package/dist/layout-engine/paragraphSpacing.js +2 -1
  128. package/dist/layout-engine/sectionLayout.d.ts +45 -0
  129. package/dist/layout-engine/sectionLayout.js +216 -0
  130. package/dist/layout-engine/tableLayout.d.ts +17 -0
  131. package/dist/layout-engine/tableLayout.js +369 -0
  132. package/dist/layout-engine/tableRowBreak.d.ts +8 -1
  133. package/dist/layout-engine/tableRowBreak.js +22 -1
  134. package/dist/layout-engine/textBoxLayout.d.ts +15 -0
  135. package/dist/layout-engine/textBoxLayout.js +137 -0
  136. package/dist/layout-engine/types.d.ts +21 -2
  137. package/dist/layout-painter/renderPage.js +1 -0
  138. package/dist/layout-painter/renderParagraph.js +41 -4
  139. package/dist/layout-painter/renderTextBox.d.ts +12 -2
  140. package/dist/layout-painter/renderTextBox.js +26 -2
  141. package/dist/paged-layout/sectionBlockWidths.d.ts +2 -1
  142. package/dist/paged-layout/sectionBlockWidths.js +1 -1
  143. package/dist/prosemirror/alternateContentAttrs.d.ts +9 -0
  144. package/dist/prosemirror/alternateContentAttrs.js +35 -0
  145. package/dist/prosemirror/attrs/index.js +90 -0
  146. package/dist/prosemirror/commands/comments.js +51 -41
  147. package/dist/prosemirror/contentControlRevisions.d.ts +43 -0
  148. package/dist/prosemirror/contentControlRevisions.js +84 -0
  149. package/dist/prosemirror/conversion/fromProseDoc.js +46 -22
  150. package/dist/prosemirror/conversion/toProseDoc.js +42 -19
  151. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.d.ts +7 -7
  152. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +7 -7
  153. package/dist/prosemirror/extensions/nodes/FieldExtension.js +6 -3
  154. package/dist/prosemirror/extensions/nodes/SdtExtension.js +9 -2
  155. package/dist/prosemirror/extensions/nodes/ShapeExtension.js +1 -0
  156. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +3 -0
  157. package/dist/prosemirror/listMarker.js +2 -2
  158. package/dist/prosemirror/paragraphDirection.d.ts +29 -2
  159. package/dist/prosemirror/paragraphDirection.js +21 -2
  160. package/dist/prosemirror/plugins/suggestionMode.js +37 -8
  161. package/dist/prosemirror/rejoinRunCarriers.d.ts +27 -0
  162. package/dist/prosemirror/rejoinRunCarriers.js +66 -0
  163. package/dist/prosemirror/runIdentityAcrossRevisions.d.ts +10 -0
  164. package/dist/prosemirror/runIdentityAcrossRevisions.js +90 -0
  165. package/dist/prosemirror/schema/nodes.d.ts +37 -5
  166. package/dist/server.d.ts +3 -2
  167. package/dist/types/content.d.ts +2 -2
  168. package/package.json +2 -2
  169. package/dist/layout-engine/justifiedLineFit.d.ts +0 -7
  170. package/dist/layout-engine/justifiedLineFit.js +0 -6
@@ -0,0 +1,291 @@
1
+ import { getFontAlternate } from "../../fonts/fontAlternates.js";
2
+ import { setHyperlinkInstanceIndex } from "../../layout-engine/measure/hyperlinkInstance.js";
3
+ import { expectCharacterSpacingMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectInlineWrapperMarkAttrs, expectLanguageMarkAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs } from "../../prosemirror/attrs/index.js";
4
+ import { runShadingAttrsToShading } from "../../prosemirror/conversion/runShadingMark.js";
5
+ import { resolveColor, resolveHighlightToCss } from "../../utils/colorResolver.js";
6
+ import { resolveShadingFill } from "../../utils/formatToStyle.js";
7
+ import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
8
+ import { halfPointsToPixels, halfPointsToPoints } from "../../utils/units.js";
9
+ import { twipsToPixels } from "./flowConversionShared.js";
10
+ import { applyRunFormattingOverrides } from "./runFormattingMerge.js";
11
+ import { isAutomaticTextColorValue, resolveComplexScriptThemeFont, resolveEastAsiaThemeFont, resolveWesternThemeFont } from "./textFormattingConversion.js";
12
+ import { panic } from "better-result";
13
+ //#region src/layout-bridge/convert/runMarkFormatting.ts
14
+ /**
15
+ * What the painter does with each mark the schema declares.
16
+ *
17
+ * The switch below used to end in `default: break`, so a mark that reached it
18
+ * was silently not painted whether that was the decision or an omission. The
19
+ * table is total over {@link SchemaMarkName}: a mark added to the schema
20
+ * without a paint decision does not compile, and a mark this table says is
21
+ * painted but the switch does not handle panics rather than disappearing.
22
+ */
23
+ const MARK_PAINT_DISPOSITIONS = {
24
+ bold: "runFormatting",
25
+ italic: "runFormatting",
26
+ underline: "runFormatting",
27
+ strike: "runFormatting",
28
+ textColor: "runFormatting",
29
+ runShading: "runFormatting",
30
+ highlight: "runFormatting",
31
+ fontSize: "runFormatting",
32
+ fontFamily: "runFormatting",
33
+ language: "runFormatting",
34
+ superscript: "runFormatting",
35
+ subscript: "runFormatting",
36
+ hyperlink: "runFormatting",
37
+ allCaps: "runFormatting",
38
+ smallCaps: "runFormatting",
39
+ footnoteRef: "runFormatting",
40
+ characterSpacing: "runFormatting",
41
+ emboss: "runFormatting",
42
+ imprint: "runFormatting",
43
+ hidden: "runFormatting",
44
+ textShadow: "runFormatting",
45
+ emphasisMark: "runFormatting",
46
+ textOutline: "runFormatting",
47
+ rtl: "runFormatting",
48
+ textEffect: "runFormatting",
49
+ runFormattingOverride: "runFormatting",
50
+ comment: "runFormatting",
51
+ insertion: "runFormatting",
52
+ deletion: "runFormatting",
53
+ inlineWrapper: "runFormatting",
54
+ characterStyle: "resolvedElsewhere",
55
+ runIdentity: "notPainted",
56
+ runPropertyChange: "notPainted"
57
+ };
58
+ const markPaintDisposition = (name) => {
59
+ return MARK_PAINT_DISPOSITIONS[name];
60
+ };
61
+ /**
62
+ * Whether a layer states how its content is laid out.
63
+ *
64
+ * A smart tag and a custom-XML wrapper name an element in another vocabulary
65
+ * and say nothing about layout, so the painter draws the text exactly as it
66
+ * would without them. The `switch` is here rather than inline so a kind added
67
+ * to the model has to answer the question.
68
+ */
69
+ const paintedDirection = (layer) => {
70
+ switch (layer.kind) {
71
+ case "bidi": return layer.direction === void 0 ? { control: layer.control } : {
72
+ control: layer.control,
73
+ direction: layer.direction
74
+ };
75
+ case "smartTag":
76
+ case "customXml": return;
77
+ default: return;
78
+ }
79
+ };
80
+ /**
81
+ * The direction the innermost bidirectional layer of a stack lays its content out in.
82
+ *
83
+ * Innermost wins: a bidirectional wrapper inside another is the one the text is
84
+ * laid out in, and the outer layers are what the save leg rebuilds the nesting
85
+ * from. The layers that state no direction are skipped rather than ending the
86
+ * search, so a smart tag inside a `w:dir` still reads right to left.
87
+ */
88
+ const innermostBidiWrapper = (stack) => {
89
+ for (const layer of stack.toReversed()) {
90
+ const direction = paintedDirection(layer);
91
+ if (direction !== void 0) return direction;
92
+ }
93
+ };
94
+ /**
95
+ * Extract run formatting from ProseMirror marks.
96
+ */
97
+ function extractRunFormatting(marks, theme, fontAlternates) {
98
+ const formatting = {};
99
+ let hasNoteRef = false;
100
+ let runFormattingOverride;
101
+ for (const mark of marks) switch (mark.type.name) {
102
+ case "bold":
103
+ formatting.bold = true;
104
+ break;
105
+ case "italic":
106
+ formatting.italic = true;
107
+ break;
108
+ case "underline": {
109
+ const attrs = expectUnderlineMarkAttrs(mark);
110
+ if (attrs.style || attrs.color) {
111
+ const underlineObj = {};
112
+ if (attrs.style) underlineObj.style = attrs.style;
113
+ if (attrs.color) underlineObj.color = resolveColor(attrs.color, theme);
114
+ formatting.underline = underlineObj;
115
+ } else formatting.underline = true;
116
+ break;
117
+ }
118
+ case "strike":
119
+ formatting.strike = true;
120
+ break;
121
+ case "textColor": {
122
+ const attrs = expectTextColorMarkAttrs(mark);
123
+ if (attrs.themeColor || attrs.rgb) {
124
+ const colorArg = {};
125
+ if (attrs.rgb) colorArg.rgb = attrs.rgb;
126
+ if (attrs.themeColor) colorArg.themeColor = attrs.themeColor;
127
+ if (attrs.themeTint) colorArg.themeTint = attrs.themeTint;
128
+ if (attrs.themeShade) colorArg.themeShade = attrs.themeShade;
129
+ if (!isAutomaticTextColorValue(colorArg)) {
130
+ formatting.color = resolveColor(colorArg, theme);
131
+ formatting.textColorSource = "direct";
132
+ }
133
+ }
134
+ break;
135
+ }
136
+ case "highlight":
137
+ formatting.highlight = resolveHighlightToCss(expectHighlightMarkAttrs(mark).color);
138
+ break;
139
+ case "runShading": {
140
+ const shadingCss = resolveShadingFill(runShadingAttrsToShading(expectRunShadingMarkAttrs(mark)), theme);
141
+ if (shadingCss) formatting.shading = shadingCss;
142
+ break;
143
+ }
144
+ case "fontSize":
145
+ formatting.fontSize = expectFontSizeMarkAttrs(mark).size / 2;
146
+ break;
147
+ case "fontFamily": {
148
+ const attrs = expectFontFamilyMarkAttrs(mark);
149
+ const font = resolveWesternThemeFont(attrs, theme);
150
+ if (font) {
151
+ formatting.fontFamily = font;
152
+ const alternate = getFontAlternate(font, fontAlternates);
153
+ if (alternate) formatting.alternateFontFamily = alternate;
154
+ }
155
+ const eastAsiaFont = resolveEastAsiaThemeFont(attrs, theme);
156
+ if (eastAsiaFont) {
157
+ formatting.eastAsiaFontFamily = eastAsiaFont;
158
+ const alternate = getFontAlternate(eastAsiaFont, fontAlternates);
159
+ if (alternate) formatting.eastAsiaAlternateFontFamily = alternate;
160
+ }
161
+ if (attrs.hint) formatting.eastAsiaHint = attrs.hint === "eastAsia";
162
+ const complexScriptFont = resolveComplexScriptThemeFont(attrs, theme);
163
+ if (complexScriptFont) {
164
+ formatting.complexScriptFontFamily = complexScriptFont;
165
+ const alternate = getFontAlternate(complexScriptFont, fontAlternates);
166
+ if (alternate) formatting.complexScriptAlternateFontFamily = alternate;
167
+ }
168
+ break;
169
+ }
170
+ case "language": {
171
+ const attrs = expectLanguageMarkAttrs(mark);
172
+ formatting.language = {
173
+ ...attrs.val ? { val: attrs.val } : {},
174
+ ...attrs.eastAsia ? { eastAsia: attrs.eastAsia } : {},
175
+ ...attrs.bidi ? { bidi: attrs.bidi } : {}
176
+ };
177
+ break;
178
+ }
179
+ case "characterSpacing": {
180
+ const attrs = expectCharacterSpacingMarkAttrs(mark);
181
+ if (attrs.spacing !== void 0) formatting.letterSpacing = twipsToPixels(attrs.spacing);
182
+ if (attrs.position !== void 0 && attrs.position !== 0) formatting.positionPx = halfPointsToPixels(attrs.position);
183
+ const horizontalScale = normalizeHorizontalScalePercent(attrs.scale);
184
+ if (horizontalScale !== void 0) formatting.horizontalScale = horizontalScale;
185
+ if (attrs.kerning !== void 0 && attrs.kerning > 0) formatting.kerningMinPt = halfPointsToPoints(attrs.kerning);
186
+ break;
187
+ }
188
+ case "allCaps":
189
+ formatting.allCaps = true;
190
+ break;
191
+ case "smallCaps":
192
+ formatting.smallCaps = true;
193
+ break;
194
+ case "emboss":
195
+ formatting.emboss = true;
196
+ break;
197
+ case "imprint":
198
+ formatting.imprint = true;
199
+ break;
200
+ case "hidden":
201
+ formatting.hidden = true;
202
+ break;
203
+ case "textShadow":
204
+ formatting.textShadow = true;
205
+ break;
206
+ case "textOutline":
207
+ formatting.textOutline = true;
208
+ break;
209
+ case "rtl":
210
+ formatting.rtl = true;
211
+ break;
212
+ case "textEffect":
213
+ formatting.textEffect = expectTextEffectMarkAttrs(mark).effect;
214
+ break;
215
+ case "runFormattingOverride":
216
+ runFormattingOverride = expectRunFormattingOverrideMarkAttrs(mark);
217
+ break;
218
+ case "emphasisMark":
219
+ formatting.emphasisMark = expectEmphasisMarkAttrs(mark).type ?? "dot";
220
+ break;
221
+ case "superscript":
222
+ formatting.superscript = true;
223
+ break;
224
+ case "subscript":
225
+ formatting.subscript = true;
226
+ break;
227
+ case "hyperlink": {
228
+ const attrs = expectHyperlinkMarkAttrs(mark);
229
+ const link = { href: attrs.href };
230
+ if (attrs.tooltip !== void 0) link.tooltip = attrs.tooltip;
231
+ if (attrs._docxHyperlinkIndex !== void 0) setHyperlinkInstanceIndex(link, attrs._docxHyperlinkIndex);
232
+ formatting.hyperlink = link;
233
+ break;
234
+ }
235
+ case "footnoteRef": {
236
+ hasNoteRef = true;
237
+ const attrs = expectFootnoteRefMarkAttrs(mark);
238
+ if (attrs.vertAlign === "superscript") formatting.superscript = true;
239
+ const id = typeof attrs.id === "string" ? Number.parseInt(attrs.id, 10) : attrs.id;
240
+ if (attrs.noteType === "endnote") formatting.endnoteRefId = id;
241
+ else formatting.footnoteRefId = id;
242
+ break;
243
+ }
244
+ case "comment": {
245
+ const commentId = expectCommentMarkAttrs(mark).commentId;
246
+ if (commentId) {
247
+ if (!formatting.commentIds) formatting.commentIds = [];
248
+ formatting.commentIds.push(commentId);
249
+ }
250
+ break;
251
+ }
252
+ case "insertion": {
253
+ const attrs = expectTrackedChangeMarkAttrs(mark);
254
+ formatting.isInsertion = true;
255
+ formatting.changeAuthor = attrs.author;
256
+ if (attrs.date !== void 0) formatting.changeDate = attrs.date;
257
+ formatting.changeRevisionId = attrs.revisionId;
258
+ if (attrs.provenance === "suggested") {
259
+ formatting.isSuggestion = true;
260
+ if (attrs.suggestionId) formatting.suggestionId = attrs.suggestionId;
261
+ }
262
+ break;
263
+ }
264
+ case "deletion": {
265
+ const attrs = expectTrackedChangeMarkAttrs(mark);
266
+ formatting.isDeletion = true;
267
+ if (attrs._historicalFormatting) formatting.usesHistoricalFormatting = true;
268
+ formatting.changeAuthor = attrs.author;
269
+ if (attrs.date !== void 0) formatting.changeDate = attrs.date;
270
+ formatting.changeRevisionId = attrs.revisionId;
271
+ if (attrs.provenance === "suggested") {
272
+ formatting.isSuggestion = true;
273
+ if (attrs.suggestionId) formatting.suggestionId = attrs.suggestionId;
274
+ }
275
+ break;
276
+ }
277
+ case "inlineWrapper": {
278
+ const bidiWrapper = innermostBidiWrapper(expectInlineWrapperMarkAttrs(mark).stack);
279
+ if (bidiWrapper) formatting.bidiWrapper = bidiWrapper;
280
+ break;
281
+ }
282
+ default:
283
+ if (markPaintDisposition(mark.type.name) === "runFormatting") panic(`Mark ${mark.type.name} is painted as run formatting but has no branch here`);
284
+ break;
285
+ }
286
+ if (runFormattingOverride) applyRunFormattingOverrides(formatting, runFormattingOverride);
287
+ if (hasNoteRef && formatting.subscript) delete formatting.superscript;
288
+ return formatting;
289
+ }
290
+ //#endregion
291
+ export { extractRunFormatting };
@@ -0,0 +1,35 @@
1
+ import { FlowBlock, SectionBreakBlock } from "../../layout-engine/types.js";
2
+ import { Node } from "prosemirror-model";
3
+ //#region src/layout-bridge/convert/sectionBoundaries.d.ts
4
+ declare function getLastMapKey<K, V>(map: ReadonlyMap<K, V>): K | undefined;
5
+ /**
6
+ * Translate section-owned start modes into the boundary-owned values consumed
7
+ * by the paginator. Each flow section break carries the properties for the
8
+ * section it ends, so its start mode belongs on the preceding boundary.
9
+ */
10
+ declare function applySectionStartsToBoundaries(blocks: readonly FlowBlock[], finalSectionStart: NonNullable<SectionBreakBlock["type"]> | undefined): FlowBlock[];
11
+ /**
12
+ * A trailing page break belongs to its section-ending paragraph. When the
13
+ * paragraph mark stays on the current page, an immediately following
14
+ * continuous section resumes there too. Accept both the legacy generated
15
+ * carrier and the inline atom's one-token paragraph-mark fragment; neither is
16
+ * a physical layout boundary.
17
+ *
18
+ * A section break in `breaksWithoutMarker` ends at an empty w:sectPr paragraph
19
+ * that projected no block, so a page break just before it ends an earlier
20
+ * paragraph and still starts the next page.
21
+ */
22
+ declare function coalesceTrailingPageBreakBeforeContinuousSection(blocks: readonly FlowBlock[], splitPageBreakAndParagraphMark: boolean, breaksWithoutMarker: ReadonlySet<SectionBreakBlock["id"]>): FlowBlock[];
23
+ /**
24
+ * The last section's start mode, off a document attribute the schema types as
25
+ * `any`. `parseSectionBreakType` owns the enumeration, so a member added to
26
+ * `ST_SectionMark` reaches the paginator instead of being dropped here.
27
+ */
28
+ declare function readFinalSectionStart(doc: Node): NonNullable<SectionBreakBlock["type"]> | undefined;
29
+ type SectionDocumentGridOptions = {
30
+ finalLinePitchTwips: number | undefined;
31
+ tableCellLinePitch: "sectionGrid" | undefined;
32
+ };
33
+ declare function applySectionDocumentGrid(blocks: FlowBlock[], { finalLinePitchTwips, tableCellLinePitch }: SectionDocumentGridOptions): FlowBlock[];
34
+ //#endregion
35
+ export { applySectionDocumentGrid, applySectionStartsToBoundaries, coalesceTrailingPageBreakBeforeContinuousSection, getLastMapKey, readFinalSectionStart };
@@ -0,0 +1,114 @@
1
+ import { parseSectionBreakType } from "../../prosemirror/sectionCarrier.js";
2
+ import { twipsToPixels } from "./flowConversionShared.js";
3
+ //#region src/layout-bridge/convert/sectionBoundaries.ts
4
+ function getLastMapKey(map) {
5
+ let lastKey;
6
+ for (const key of map.keys()) lastKey = key;
7
+ return lastKey;
8
+ }
9
+ /**
10
+ * Translate section-owned start modes into the boundary-owned values consumed
11
+ * by the paginator. Each flow section break carries the properties for the
12
+ * section it ends, so its start mode belongs on the preceding boundary.
13
+ */
14
+ function applySectionStartsToBoundaries(blocks, finalSectionStart) {
15
+ const breakIndexes = [];
16
+ for (let index = 0; index < blocks.length; index += 1) if (blocks[index]?.kind === "sectionBreak") breakIndexes.push(index);
17
+ if (breakIndexes.length === 0) return [...blocks];
18
+ const result = [...blocks];
19
+ for (let index = 0; index < breakIndexes.length; index += 1) {
20
+ const boundaryIndex = breakIndexes[index];
21
+ if (boundaryIndex === void 0) continue;
22
+ const boundary = blocks[boundaryIndex];
23
+ if (boundary?.kind !== "sectionBreak") continue;
24
+ const nextBoundaryIndex = breakIndexes[index + 1];
25
+ const nextBoundary = nextBoundaryIndex === void 0 ? void 0 : blocks[nextBoundaryIndex];
26
+ const nextStart = nextBoundary?.kind === "sectionBreak" ? nextBoundary.type : finalSectionStart;
27
+ const translated = { ...boundary };
28
+ if (nextStart === void 0) delete translated.type;
29
+ else translated.type = nextStart;
30
+ result[boundaryIndex] = translated;
31
+ }
32
+ return result;
33
+ }
34
+ /**
35
+ * A trailing page break belongs to its section-ending paragraph. When the
36
+ * paragraph mark stays on the current page, an immediately following
37
+ * continuous section resumes there too. Accept both the legacy generated
38
+ * carrier and the inline atom's one-token paragraph-mark fragment; neither is
39
+ * a physical layout boundary.
40
+ *
41
+ * A section break in `breaksWithoutMarker` ends at an empty w:sectPr paragraph
42
+ * that projected no block, so a page break just before it ends an earlier
43
+ * paragraph and still starts the next page.
44
+ */
45
+ function coalesceTrailingPageBreakBeforeContinuousSection(blocks, splitPageBreakAndParagraphMark, breaksWithoutMarker) {
46
+ if (splitPageBreakAndParagraphMark) return [...blocks];
47
+ const result = [];
48
+ for (let index = 0; index < blocks.length; index += 1) {
49
+ const block = blocks[index];
50
+ const carrier = blocks[index + 1];
51
+ const section = blocks[index + 2];
52
+ const isLegacyGeneratedCarrier = block?.kind === "pageBreak" && carrier?.kind === "paragraph" && carrier.runs.length === 0 && block.pmStart !== void 0 && block.pmStart === carrier.pmStart && carrier.pmStart === carrier.pmEnd;
53
+ const isInlineParagraphMarkCarrier = block?.kind === "pageBreak" && carrier?.kind === "paragraph" && carrier.runs.length === 0 && block.pmEnd !== void 0 && carrier.pmStart === block.pmEnd && carrier.pmEnd === block.pmEnd + 1;
54
+ const isUnresolvedInsertion = block?.kind === "pageBreak" && block.isInsertion === true;
55
+ if (block?.kind === "pageBreak" && !isUnresolvedInsertion && carrier?.kind === "sectionBreak" && carrier.type === "continuous" && !breaksWithoutMarker.has(carrier.id)) continue;
56
+ if (block?.kind === "pageBreak" && !isUnresolvedInsertion && (isLegacyGeneratedCarrier || isInlineParagraphMarkCarrier) && section?.kind === "sectionBreak" && section.type === "continuous" && !breaksWithoutMarker.has(section.id)) {
57
+ index += 1;
58
+ continue;
59
+ }
60
+ if (block) result.push(block);
61
+ }
62
+ return result;
63
+ }
64
+ /**
65
+ * The last section's start mode, off a document attribute the schema types as
66
+ * `any`. `parseSectionBreakType` owns the enumeration, so a member added to
67
+ * `ST_SectionMark` reaches the paginator instead of being dropped here.
68
+ */
69
+ function readFinalSectionStart(doc) {
70
+ return parseSectionBreakType(doc.attrs["_finalSectionStart"]) ?? void 0;
71
+ }
72
+ function applySectionDocumentGrid(blocks, { finalLinePitchTwips, tableCellLinePitch }) {
73
+ const result = [...blocks];
74
+ let sectionStart = 0;
75
+ const stampSection = (end, linePitchTwips) => {
76
+ if (linePitchTwips === void 0 || linePitchTwips <= 0) return;
77
+ const linePitch = twipsToPixels(linePitchTwips);
78
+ const stampBlock = (block) => {
79
+ if (block.kind === "paragraph") return {
80
+ ...block,
81
+ attrs: {
82
+ ...block.attrs,
83
+ documentGridLinePitch: linePitch
84
+ }
85
+ };
86
+ if (block.kind !== "table" || tableCellLinePitch !== "sectionGrid") return block;
87
+ return {
88
+ ...block,
89
+ rows: block.rows.map((row) => ({
90
+ ...row,
91
+ cells: row.cells.map((cell) => ({
92
+ ...cell,
93
+ blocks: cell.blocks.map(stampBlock)
94
+ }))
95
+ }))
96
+ };
97
+ };
98
+ for (let index = sectionStart; index < end; index += 1) {
99
+ const block = result[index];
100
+ if (!block) continue;
101
+ result[index] = stampBlock(block);
102
+ }
103
+ };
104
+ for (let index = 0; index < blocks.length; index += 1) {
105
+ const block = blocks[index];
106
+ if (block?.kind !== "sectionBreak") continue;
107
+ stampSection(index, block.documentGridLinePitchTwips);
108
+ sectionStart = index + 1;
109
+ }
110
+ stampSection(blocks.length, finalLinePitchTwips);
111
+ return result;
112
+ }
113
+ //#endregion
114
+ export { applySectionDocumentGrid, applySectionStartsToBoundaries, coalesceTrailingPageBreakBeforeContinuousSection, getLastMapKey, readFinalSectionStart };
@@ -0,0 +1,12 @@
1
+ import { TableBlock, TextBoxBlock } from "../../layout-engine/types.js";
2
+ import { FlowConversionOptions } from "./flowConversionShared.js";
3
+ import { Node } from "prosemirror-model";
4
+ //#region src/layout-bridge/convert/tableConversion.d.ts
5
+ /**
6
+ * Convert a table node to a TableBlock.
7
+ */
8
+ declare function convertTable(node: Node, startPos: number, options: FlowConversionOptions): TableBlock;
9
+ /** Convert a textBox PM node to a TextBoxBlock. */
10
+ declare function convertTextBoxNode(node: Node, startPos: number, opts: FlowConversionOptions): TextBoxBlock;
11
+ //#endregion
12
+ export { convertTable, convertTextBoxNode };