@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,303 @@
1
+ import { setTextBoxGroupId } from "../../layout-engine/textBoxGroup.js";
2
+ import { DEFAULT_TEXTBOX_MARGINS } from "../../layout-engine/types.js";
3
+ import { expectParagraphAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs } from "../../prosemirror/attrs/index.js";
4
+ import { textBoxHostParagraph } from "../../prosemirror/textBoxHostParagraph.js";
5
+ import { normalizeShapeTextAnchor } from "../../types/documentEnumValues.js";
6
+ import { convertBorderSpecToLayout } from "./flowBorders.js";
7
+ import { nextBlockId, twipsToPixels } from "./flowConversionShared.js";
8
+ import { countPageBreakRuns, hasSingleLeadingProjectedPageBreak } from "./pageBreakSplitting.js";
9
+ import { convertParagraphAttrs } from "./paragraphAttrs.js";
10
+ import { convertParagraph } from "./paragraphConversion.js";
11
+ import { groupParagraphFrames } from "./paragraphFrames.js";
12
+ import { resolveParagraphMarkFormatting } from "./paragraphMarkFormatting.js";
13
+ import { inlineEffectExtentPx, resolveLinearGradientFill } from "./textBoxFill.js";
14
+ //#region src/layout-bridge/convert/tableConversion.ts
15
+ const TEXT_BOX_ANCHOR_BLOCK_ID = Symbol.for("stll.textBoxAnchorBlockId");
16
+ const DEFAULT_TABLE_CELL_MARGIN_TWIPS = {
17
+ top: 0,
18
+ right: 108,
19
+ bottom: 0,
20
+ left: 108
21
+ };
22
+ /**
23
+ * Extract cell borders from ProseMirror attributes.
24
+ * Borders are full BorderSpec objects with style/size/color.
25
+ */
26
+ function extractCellBorders(borders, theme) {
27
+ if (!borders) return;
28
+ const result = {};
29
+ for (const side of [
30
+ "top",
31
+ "bottom",
32
+ "left",
33
+ "right"
34
+ ]) {
35
+ const border = borders[side];
36
+ const converted = border ? convertBorderSpecToLayout(border, theme) : void 0;
37
+ if (!converted) {
38
+ result[side] = {
39
+ width: 0,
40
+ style: "none"
41
+ };
42
+ continue;
43
+ }
44
+ result[side] = border?.size === 0 ? {
45
+ ...converted,
46
+ width: 0
47
+ } : converted;
48
+ }
49
+ for (const side of ["topLeftToBottomRight", "topRightToBottomLeft"]) {
50
+ const border = borders[side];
51
+ const converted = border ? convertBorderSpecToLayout(border, theme) : void 0;
52
+ if (converted) result[side] = converted;
53
+ }
54
+ return Object.keys(result).length > 0 ? result : void 0;
55
+ }
56
+ function convertTableCell(node, startPos, options, tableCellMargins) {
57
+ const blocks = [];
58
+ let offset = startPos + 1;
59
+ const authoredPageBreakPosition = options.firstPageBreakRunPosition(node);
60
+ const leadingParagraph = node.firstChild?.type.name === "paragraph" && countPageBreakRuns(node) === 1 && options.firstPageBreakRunPosition(node.firstChild) === authoredPageBreakPosition ? node.firstChild : void 0;
61
+ const pageBreaks = [];
62
+ const convertCellChild = (child, childStart) => {
63
+ if (child.type.name === "paragraph") {
64
+ const block = convertParagraph(child, childStart, options, child === leadingParagraph ? pageBreaks : void 0);
65
+ blocks.push(block);
66
+ } else if (child.type.name === "table") blocks.push(convertTable(child, childStart, options));
67
+ else if (child.type.name === "textBox") blocks.push(convertTextBoxNode(child, childStart, options));
68
+ else if (child.type.name === "blockSdt") {
69
+ let sdtChildStart = childStart + 1;
70
+ child.forEach((sdtChild) => {
71
+ convertCellChild(sdtChild, sdtChildStart);
72
+ sdtChildStart += sdtChild.nodeSize;
73
+ });
74
+ }
75
+ };
76
+ node.forEach((child) => {
77
+ convertCellChild(child, offset);
78
+ offset += child.nodeSize;
79
+ });
80
+ const trailingBlock = blocks.at(-1);
81
+ if (blocks.at(-2)?.kind === "table" && trailingBlock?.kind === "paragraph" && trailingBlock.runs.every((run) => run.kind === "text" && run.text.length === 0)) trailingBlock.attrs = {
82
+ ...trailingBlock.attrs,
83
+ suppressEmptyParagraphHeight: true
84
+ };
85
+ const attrs = expectTableCellAttrs(node);
86
+ if (attrs.hideMark && trailingBlock?.kind === "paragraph" && trailingBlock.runs.every((run) => run.kind === "text" && run.text.length === 0)) trailingBlock.attrs = {
87
+ ...trailingBlock.attrs,
88
+ suppressEmptyParagraphHeight: true
89
+ };
90
+ const margins = attrs.margins;
91
+ const resolvePaddingSide = (side, cellTwips, tableTwips) => {
92
+ if (cellTwips !== void 0) return twipsToPixels(cellTwips);
93
+ if (tableTwips !== void 0) return twipsToPixels(tableTwips);
94
+ return twipsToPixels(DEFAULT_TABLE_CELL_MARGIN_TWIPS[side]);
95
+ };
96
+ const padding = {
97
+ top: resolvePaddingSide("top", margins?.top, tableCellMargins?.top),
98
+ right: resolvePaddingSide("right", margins?.right, tableCellMargins?.right),
99
+ bottom: resolvePaddingSide("bottom", margins?.bottom, tableCellMargins?.bottom),
100
+ left: resolvePaddingSide("left", margins?.left, tableCellMargins?.left)
101
+ };
102
+ const cell = {
103
+ id: nextBlockId(),
104
+ blocks: groupParagraphFrames(blocks, nextBlockId),
105
+ colSpan: attrs.colspan,
106
+ rowSpan: attrs.rowspan,
107
+ padding
108
+ };
109
+ if (attrs.width) cell.width = twipsToPixels(attrs.width);
110
+ if (attrs.verticalAlign) cell.verticalAlign = attrs.verticalAlign;
111
+ if (attrs.textDirection) cell.textDirection = attrs.textDirection;
112
+ if (attrs.backgroundColor) cell.background = `#${attrs.backgroundColor}`;
113
+ const cellBorders = extractCellBorders(attrs.borders, options.theme);
114
+ if (cellBorders) cell.borders = cellBorders;
115
+ if (attrs.noWrap) cell.noWrap = true;
116
+ if (authoredPageBreakPosition === void 0 || pageBreaks.length === 0) return { cell };
117
+ const paragraph = blocks.at(0);
118
+ if (paragraph?.kind !== "paragraph" || !hasSingleLeadingProjectedPageBreak(paragraph.runs, pageBreaks)) return { cell };
119
+ return {
120
+ cell,
121
+ breakBefore: "page"
122
+ };
123
+ }
124
+ /**
125
+ * Resolve an `ST_JcTable` placement to the flow engine's logical alignment.
126
+ *
127
+ * `start` and `end` name an edge of the writing direction, not a side of the
128
+ * page, the same distinction `ST_Jc` draws for a paragraph. The flow engine
129
+ * applies `w:bidiVisual` when it resolves that logical alignment to a physical
130
+ * side, so the bridge must not mirror it first.
131
+ */
132
+ const resolveTablePlacement = (placement) => {
133
+ switch (placement) {
134
+ case "start": return "left";
135
+ case "end": return "right";
136
+ case "left":
137
+ case "center":
138
+ case "right": return placement;
139
+ default: return placement;
140
+ }
141
+ };
142
+ function convertTableRow(node, startPos, options, { cellMargins }) {
143
+ const cells = [];
144
+ let offset = startPos + 1;
145
+ let breakBefore;
146
+ node.forEach((child) => {
147
+ if (child.type.name === "tableCell" || child.type.name === "tableHeader") {
148
+ if (!expectTableCellAttrs(child)._omittedGridSlot) {
149
+ const converted = convertTableCell(child, offset, options, cellMargins);
150
+ if (converted.breakBefore !== void 0) breakBefore = converted.breakBefore;
151
+ cells.push(converted.cell);
152
+ }
153
+ }
154
+ offset += child.nodeSize;
155
+ });
156
+ const attrs = expectTableRowAttrs(node);
157
+ const row = {
158
+ id: nextBlockId(),
159
+ cells
160
+ };
161
+ if (attrs._originalFormatting?.gridBefore) row.gridBefore = attrs._originalFormatting.gridBefore;
162
+ if (attrs._originalFormatting?.gridAfter) row.gridAfter = attrs._originalFormatting.gridAfter;
163
+ if (attrs.height) row.height = twipsToPixels(attrs.height);
164
+ if (attrs.heightRule) row.heightRule = attrs.heightRule;
165
+ if (attrs.isHeader) row.isHeader = attrs.isHeader;
166
+ if (attrs._originalFormatting?.cantSplit) row.cantSplit = true;
167
+ if (breakBefore !== void 0) row.breakBefore = breakBefore;
168
+ if (attrs.hidden) row.hidden = attrs.hidden;
169
+ const effectiveJustification = attrs._originalFormatting?.justification ?? attrs._resolvedJustification;
170
+ if (effectiveJustification) row.justification = resolveTablePlacement(effectiveJustification);
171
+ return row;
172
+ }
173
+ /**
174
+ * Convert a table node to a TableBlock.
175
+ */
176
+ function convertTable(node, startPos, options) {
177
+ const rows = [];
178
+ let offset = startPos + 1;
179
+ const attrs = expectTableAttrs(node);
180
+ const rightToLeft = (attrs._resolvedBidi ?? attrs._originalFormatting?.bidi) === true;
181
+ const rowContext = { ...attrs.cellMargins === void 0 ? {} : { cellMargins: attrs.cellMargins } };
182
+ node.forEach((child) => {
183
+ if (child.type.name === "tableRow") rows.push(convertTableRow(child, offset, options, rowContext));
184
+ offset += child.nodeSize;
185
+ });
186
+ let columnWidths = attrs.columnWidths?.map(twipsToPixels);
187
+ const width = attrs.width;
188
+ const widthType = attrs.widthType;
189
+ if (!columnWidths && rows.length > 0) {
190
+ const cellWidths = rows[0].cells.map((cell) => cell.width);
191
+ if (cellWidths.every((w) => w !== void 0 && w > 0)) columnWidths = cellWidths;
192
+ }
193
+ const authoredJustification = attrs.justification ?? attrs._resolvedJustification;
194
+ const justification = authoredJustification === void 0 ? void 0 : resolveTablePlacement(authoredJustification);
195
+ const originalFormatting = attrs._originalFormatting;
196
+ const effectiveIndent = attrs._resolvedIndent ?? originalFormatting?.indent;
197
+ const indentPx = effectiveIndent?.value !== void 0 && effectiveIndent?.type === "dxa" ? twipsToPixels(effectiveIndent.value) : void 0;
198
+ const dropsAuthoredIndent = effectiveIndent?.value !== void 0 && indentPx === void 0;
199
+ const floating = attrs.floating;
200
+ let floatingPx;
201
+ if (floating) {
202
+ const fp = {};
203
+ if (floating.horzAnchor) fp.horzAnchor = floating.horzAnchor;
204
+ if (floating.vertAnchor) fp.vertAnchor = floating.vertAnchor;
205
+ if (floating.tblpX !== void 0) fp.tblpX = twipsToPixels(floating.tblpX);
206
+ if (floating.tblpXSpec) fp.tblpXSpec = floating.tblpXSpec;
207
+ if (floating.tblpY !== void 0) fp.tblpY = twipsToPixels(floating.tblpY);
208
+ if (floating.tblpYSpec) fp.tblpYSpec = floating.tblpYSpec;
209
+ if (floating.topFromText !== void 0) fp.topFromText = twipsToPixels(floating.topFromText);
210
+ if (floating.bottomFromText !== void 0) fp.bottomFromText = twipsToPixels(floating.bottomFromText);
211
+ if (floating.leftFromText !== void 0) fp.leftFromText = twipsToPixels(floating.leftFromText);
212
+ if (floating.rightFromText !== void 0) fp.rightFromText = twipsToPixels(floating.rightFromText);
213
+ floatingPx = fp;
214
+ }
215
+ const tableBlock = {
216
+ kind: "table",
217
+ id: nextBlockId(),
218
+ rows,
219
+ pmStart: startPos,
220
+ pmEnd: startPos + node.nodeSize
221
+ };
222
+ if (columnWidths) tableBlock.columnWidths = columnWidths;
223
+ if (width !== void 0) tableBlock.width = width;
224
+ if (widthType !== void 0) tableBlock.widthType = widthType;
225
+ if (originalFormatting?.layout !== void 0) tableBlock.layout = originalFormatting.layout;
226
+ if (justification) tableBlock.justification = justification;
227
+ if (indentPx !== void 0) tableBlock.indent = indentPx;
228
+ const cellSpacing = originalFormatting?.cellSpacing;
229
+ if (cellSpacing?.type === "dxa" && cellSpacing.value > 0) tableBlock.cellSpacing = twipsToPixels(cellSpacing.value);
230
+ if (options.tableIndentCompatibility && !dropsAuthoredIndent) tableBlock.indentCompatibility = options.tableIndentCompatibility;
231
+ if (floatingPx) tableBlock.floating = floatingPx;
232
+ if (rightToLeft) tableBlock.bidi = true;
233
+ return tableBlock;
234
+ }
235
+ /** Convert a textBox PM node to a TextBoxBlock. */
236
+ function convertTextBoxNode(node, startPos, opts) {
237
+ const attrs = expectTextBoxAttrs(node);
238
+ const contentBlocks = [];
239
+ node.forEach((child, offset) => {
240
+ const childPos = startPos + 1 + offset;
241
+ if (child.type.name === "paragraph") {
242
+ contentBlocks.push(convertParagraph(child, childPos, opts));
243
+ return;
244
+ }
245
+ if (child.type.name === "table") contentBlocks.push(convertTable(child, childPos, opts));
246
+ });
247
+ const textBox = {
248
+ kind: "textBox",
249
+ id: nextBlockId(),
250
+ width: attrs.width ?? 200,
251
+ margins: {
252
+ top: attrs.marginTop ?? DEFAULT_TEXTBOX_MARGINS.top,
253
+ bottom: attrs.marginBottom ?? DEFAULT_TEXTBOX_MARGINS.bottom,
254
+ left: attrs.marginLeft ?? DEFAULT_TEXTBOX_MARGINS.left,
255
+ right: attrs.marginRight ?? DEFAULT_TEXTBOX_MARGINS.right
256
+ },
257
+ content: contentBlocks,
258
+ pmStart: startPos,
259
+ pmEnd: startPos + node.nodeSize
260
+ };
261
+ const verticalAlign = normalizeShapeTextAnchor(attrs.verticalAlign);
262
+ if (verticalAlign !== void 0) textBox.verticalAlign = verticalAlign;
263
+ if (attrs.height !== void 0) textBox.height = attrs.height;
264
+ if (attrs.autoFit !== void 0) textBox.autoFit = attrs.autoFit;
265
+ if (attrs.textWrap !== void 0) textBox.textWrap = attrs.textWrap;
266
+ if (attrs.fillColor !== void 0) textBox.fillColor = attrs.fillColor;
267
+ else {
268
+ const fillGradient = resolveLinearGradientFill(attrs.gradientFill, opts.theme);
269
+ if (fillGradient !== void 0) textBox.fillGradient = fillGradient;
270
+ }
271
+ if (attrs.outlineWidth !== void 0) textBox.outlineWidth = attrs.outlineWidth;
272
+ if (attrs.outlineColor !== void 0) textBox.outlineColor = attrs.outlineColor;
273
+ if (attrs.outlineStyle !== void 0) textBox.outlineStyle = attrs.outlineStyle;
274
+ if (attrs.transform !== void 0) textBox.transform = attrs.transform;
275
+ if (attrs.displayMode !== void 0) textBox.displayMode = attrs.displayMode;
276
+ if (attrs.cssFloat !== void 0) textBox.cssFloat = attrs.cssFloat;
277
+ if (attrs.wrapType !== void 0) textBox.wrapType = attrs.wrapType;
278
+ if (attrs.wrapText !== void 0) textBox.wrapText = attrs.wrapText;
279
+ if (attrs.distTop !== void 0) textBox.distTop = attrs.distTop;
280
+ if (attrs.distBottom !== void 0) textBox.distBottom = attrs.distBottom;
281
+ if (attrs.distLeft !== void 0) textBox.distLeft = attrs.distLeft;
282
+ if (attrs.distRight !== void 0) textBox.distRight = attrs.distRight;
283
+ if (attrs.position !== void 0) textBox.position = attrs.position;
284
+ const effectExtent = inlineEffectExtentPx(attrs.wrapType, attrs.wrapEffectExtentSlots?.drawing);
285
+ if (effectExtent !== void 0) textBox.effectExtent = effectExtent;
286
+ const host = textBoxHostParagraph(node);
287
+ if (host && attrs.position === void 0 && (attrs.wrapType ?? "inline") === "inline") {
288
+ const hostAttrs = expectParagraphAttrs(host);
289
+ textBox.hostParagraph = convertParagraphAttrs(hostAttrs, {
290
+ theme: opts.theme,
291
+ fontAlternates: opts.fontAlternates,
292
+ listCounterStreams: opts.listCounterStreams,
293
+ defaultTabStopTwips: opts.defaultTabStopTwips,
294
+ paragraphMarkFormatting: () => resolveParagraphMarkFormatting(hostAttrs, opts.styleResolver)
295
+ });
296
+ }
297
+ if (attrs._docxGroupId !== void 0) setTextBoxGroupId(textBox, attrs._docxGroupId);
298
+ const anchorBlockId = attrs._docxAnchorId ? opts.textBoxAnchorBlockIds.get(attrs._docxAnchorId) : void 0;
299
+ if (anchorBlockId !== void 0) Reflect.set(textBox, TEXT_BOX_ANCHOR_BLOCK_ID, anchorBlockId);
300
+ return textBox;
301
+ }
302
+ //#endregion
303
+ export { convertTable, convertTextBoxNode };
@@ -0,0 +1,20 @@
1
+ import { document_d_exports } from "../../types/document.js";
2
+ import { TextBoxBlock, TextBoxGradientFill } from "../../layout-engine/types.js";
3
+ import { ImagePadding } from "@stll/docx-core/model";
4
+ //#region src/layout-bridge/convert/textBoxFill.d.ts
5
+ /**
6
+ * The `wp:effectExtent` of an inline (`wp:inline`) box, in unrounded pixels.
7
+ *
8
+ * An inline object occupies its extent plus the effect extent on every side,
9
+ * so the box itself sits `l`/`t` inside the space the line gives it. On a
10
+ * `wp:anchor` the position offsets already locate the shape's own extent, so
11
+ * the reservation only affects wrapping and is not applied here.
12
+ */
13
+ declare function inlineEffectExtentPx(wrapType: TextBoxBlock["wrapType"], extent: ImagePadding | undefined): TextBoxBlock["effectExtent"];
14
+ /**
15
+ * A linear `a:gradFill` with its stop colors resolved through the theme. A path
16
+ * gradient (`a:path`) is not painted: nothing here places its focus.
17
+ */
18
+ declare function resolveLinearGradientFill(fill: document_d_exports.ShapeFill | undefined, theme: document_d_exports.Theme | null | undefined): TextBoxGradientFill | undefined;
19
+ //#endregion
20
+ export { inlineEffectExtentPx, resolveLinearGradientFill };
@@ -0,0 +1,42 @@
1
+ import { resolveColor } from "../../utils/colorResolver.js";
2
+ //#region src/layout-bridge/convert/textBoxFill.ts
3
+ const EMUS_PER_PIXEL = 9525;
4
+ /**
5
+ * The `wp:effectExtent` of an inline (`wp:inline`) box, in unrounded pixels.
6
+ *
7
+ * An inline object occupies its extent plus the effect extent on every side,
8
+ * so the box itself sits `l`/`t` inside the space the line gives it. On a
9
+ * `wp:anchor` the position offsets already locate the shape's own extent, so
10
+ * the reservation only affects wrapping and is not applied here.
11
+ */
12
+ function inlineEffectExtentPx(wrapType, extent) {
13
+ if (wrapType !== void 0 && wrapType !== "inline" || extent === void 0) return;
14
+ const px = (emu) => Math.max(0, (emu ?? 0) / EMUS_PER_PIXEL);
15
+ const resolved = {
16
+ top: px(extent.top),
17
+ bottom: px(extent.bottom),
18
+ left: px(extent.left),
19
+ right: px(extent.right)
20
+ };
21
+ return resolved.top === 0 && resolved.bottom === 0 && resolved.left === 0 && resolved.right === 0 ? void 0 : resolved;
22
+ }
23
+ const GRADIENT_POSITION_SCALE = 1e5;
24
+ /**
25
+ * A linear `a:gradFill` with its stop colors resolved through the theme. A path
26
+ * gradient (`a:path`) is not painted: nothing here places its focus.
27
+ */
28
+ function resolveLinearGradientFill(fill, theme) {
29
+ const gradient = fill?.gradient;
30
+ if (gradient === void 0 || gradient.type !== "linear" || gradient.stops.length === 0) return;
31
+ const stops = gradient.stops.map((stop) => ({
32
+ offset: Math.min(1, Math.max(0, stop.position / GRADIENT_POSITION_SCALE)),
33
+ color: resolveColor(stop.color, theme)
34
+ })).toSorted((left, right) => left.offset - right.offset);
35
+ return {
36
+ angle: gradient.angle ?? 0,
37
+ scaled: gradient.scaled ?? false,
38
+ stops
39
+ };
40
+ }
41
+ //#endregion
42
+ export { inlineEffectExtentPx, resolveLinearGradientFill };
@@ -0,0 +1,22 @@
1
+ import { document_d_exports } from "../../types/document.js";
2
+ import { ParagraphAttrs } from "../../prosemirror/schema/nodes.js";
3
+ import { ListMarkerFormatting, RunFormatting } from "../../layout-engine/types.js";
4
+ import { FontAlternates } from "../../fonts/fontAlternates.js";
5
+ //#region src/layout-bridge/convert/textFormattingConversion.d.ts
6
+ type ThemeFontAttributes = Omit<NonNullable<document_d_exports.TextFormatting["fontFamily"]>, "asciiTheme"> & {
7
+ /** The ProseMirror attr reader validates this against the canonical theme values. */
8
+ asciiTheme?: string;
9
+ };
10
+ declare const resolveWesternThemeFont: (fontFamily: ThemeFontAttributes, theme?: document_d_exports.Theme | null) => string | undefined;
11
+ declare const resolveComplexScriptThemeFont: (fontFamily: ThemeFontAttributes, theme?: document_d_exports.Theme | null) => string | undefined;
12
+ declare const resolveEastAsiaThemeFont: (fontFamily: ThemeFontAttributes, theme?: document_d_exports.Theme | null) => string | undefined;
13
+ declare function isAutomaticTextColorValue(color: document_d_exports.ColorValue): boolean;
14
+ /**
15
+ * The numbering symbol's typography: the numbering level's `w:rPr` applied
16
+ * over the paragraph mark's run properties (ECMA-376 §17.9.24, §17.3.1.29).
17
+ * Text runs of the paragraph play no part.
18
+ */
19
+ declare function listMarkerFormattingFor(levelFormatting: document_d_exports.TextFormatting | undefined, paragraphMarkFormatting: document_d_exports.TextFormatting | undefined, theme: document_d_exports.Theme | null | undefined, fontAlternates: FontAlternates | undefined): ListMarkerFormatting | undefined;
20
+ declare function paragraphRunDefaults(pmAttrs: ParagraphAttrs, theme?: document_d_exports.Theme | null, fontAlternates?: FontAlternates): RunFormatting;
21
+ //#endregion
22
+ export { isAutomaticTextColorValue, listMarkerFormattingFor, paragraphRunDefaults, resolveComplexScriptThemeFont, resolveEastAsiaThemeFont, resolveWesternThemeFont };
@@ -0,0 +1,120 @@
1
+ import { getFontAlternate } from "../../fonts/fontAlternates.js";
2
+ import { resolveColor, resolveHighlightToCss } from "../../utils/colorResolver.js";
3
+ import { resolveThemeFont } from "../../utils/fontResolver.js";
4
+ import { normalizeHorizontalScalePercent } from "../../utils/horizontalScale.js";
5
+ import { mergeTextFormatting } from "../../utils/textFormattingMerge.js";
6
+ import { halfPointsToPixels, halfPointsToPoints } from "../../utils/units.js";
7
+ import { twipsToPixels } from "./flowConversionShared.js";
8
+ //#region src/layout-bridge/convert/textFormattingConversion.ts
9
+ /**
10
+ * Converts document-model TextFormatting (style, paragraph-mark, and list
11
+ * marker run properties) to layout RunFormatting, including theme-font
12
+ * resolution per script slot.
13
+ */
14
+ const resolveWesternThemeFont = (fontFamily, theme) => {
15
+ const themeRef = fontFamily.asciiTheme ?? fontFamily.hAnsiTheme;
16
+ return (themeRef ? resolveThemeFont(themeRef, theme?.fontScheme) : null) ?? fontFamily.ascii ?? fontFamily.hAnsi ?? void 0;
17
+ };
18
+ const resolveComplexScriptThemeFont = (fontFamily, theme) => {
19
+ return (fontFamily.csTheme ? resolveThemeFont(fontFamily.csTheme, theme?.fontScheme) : null) ?? fontFamily.cs ?? void 0;
20
+ };
21
+ const resolveEastAsiaThemeFont = (fontFamily, theme) => {
22
+ return (fontFamily.eastAsiaTheme ? resolveThemeFont(fontFamily.eastAsiaTheme, theme?.fontScheme) : null) ?? fontFamily.eastAsia ?? void 0;
23
+ };
24
+ function isAutomaticTextColorValue(color) {
25
+ const rgb = color.rgb?.trim().toLowerCase();
26
+ return color.auto === true || rgb === "auto" || !rgb && !color.themeColor;
27
+ }
28
+ function textFormattingToRunFormatting(defaultTextFormatting, theme, fontAlternates) {
29
+ if (!defaultTextFormatting) return {};
30
+ const result = {};
31
+ const fontFamily = defaultTextFormatting.fontFamily ? resolveWesternThemeFont(defaultTextFormatting.fontFamily, theme) : void 0;
32
+ if (fontFamily) {
33
+ result.fontFamily = fontFamily;
34
+ const alternate = getFontAlternate(fontFamily, fontAlternates);
35
+ if (alternate) result.alternateFontFamily = alternate;
36
+ }
37
+ const eastAsiaFontFamily = defaultTextFormatting.fontFamily ? resolveEastAsiaThemeFont(defaultTextFormatting.fontFamily, theme) : void 0;
38
+ if (eastAsiaFontFamily) {
39
+ result.eastAsiaFontFamily = eastAsiaFontFamily;
40
+ const alternate = getFontAlternate(eastAsiaFontFamily, fontAlternates);
41
+ if (alternate) result.eastAsiaAlternateFontFamily = alternate;
42
+ }
43
+ if (defaultTextFormatting.fontFamily?.hint) result.eastAsiaHint = defaultTextFormatting.fontFamily.hint === "eastAsia";
44
+ const complexScriptFontFamily = defaultTextFormatting.fontFamily ? resolveComplexScriptThemeFont(defaultTextFormatting.fontFamily, theme) : void 0;
45
+ if (complexScriptFontFamily) {
46
+ result.complexScriptFontFamily = complexScriptFontFamily;
47
+ const alternate = getFontAlternate(complexScriptFontFamily, fontAlternates);
48
+ if (alternate) result.complexScriptAlternateFontFamily = alternate;
49
+ }
50
+ if (defaultTextFormatting.language) result.language = { ...defaultTextFormatting.language };
51
+ if (defaultTextFormatting.fontSize !== void 0) result.fontSize = defaultTextFormatting.fontSize / 2;
52
+ if (defaultTextFormatting.fontSizeCs !== void 0) result.complexScriptFontSize = defaultTextFormatting.fontSizeCs / 2;
53
+ if (defaultTextFormatting.bold !== void 0) result.bold = defaultTextFormatting.bold;
54
+ if (defaultTextFormatting.boldCs !== void 0) result.complexScriptBold = defaultTextFormatting.boldCs;
55
+ if (defaultTextFormatting.italic !== void 0) result.italic = defaultTextFormatting.italic;
56
+ if (defaultTextFormatting.italicCs !== void 0) result.complexScriptItalic = defaultTextFormatting.italicCs;
57
+ if (defaultTextFormatting.rtl !== void 0) result.rtl = defaultTextFormatting.rtl;
58
+ if (defaultTextFormatting.cs !== void 0) result.forceComplexScript = defaultTextFormatting.cs;
59
+ if (defaultTextFormatting.underline && defaultTextFormatting.underline.style !== "none") {
60
+ result.underline = { style: defaultTextFormatting.underline.style };
61
+ if (defaultTextFormatting.underline.color) result.underline.color = resolveColor(defaultTextFormatting.underline.color, theme);
62
+ }
63
+ if (defaultTextFormatting.strike !== void 0) result.strike = defaultTextFormatting.strike;
64
+ if (defaultTextFormatting.color && !isAutomaticTextColorValue(defaultTextFormatting.color)) {
65
+ result.color = resolveColor(defaultTextFormatting.color, theme);
66
+ result.textColorSource = "paragraphDefault";
67
+ }
68
+ if (defaultTextFormatting.highlight) {
69
+ const highlight = resolveHighlightToCss(defaultTextFormatting.highlight);
70
+ if (highlight) result.highlight = highlight;
71
+ }
72
+ if (defaultTextFormatting.vertAlign === "superscript") result.superscript = true;
73
+ if (defaultTextFormatting.vertAlign === "subscript") result.subscript = true;
74
+ if (defaultTextFormatting.allCaps !== void 0) result.allCaps = defaultTextFormatting.allCaps;
75
+ if (defaultTextFormatting.smallCaps !== void 0) result.smallCaps = defaultTextFormatting.smallCaps;
76
+ if (defaultTextFormatting.spacing !== void 0 && defaultTextFormatting.spacing !== 0) result.letterSpacing = twipsToPixels(defaultTextFormatting.spacing);
77
+ if (defaultTextFormatting.position !== void 0 && defaultTextFormatting.position !== 0) result.positionPx = halfPointsToPixels(defaultTextFormatting.position);
78
+ const horizontalScale = normalizeHorizontalScalePercent(defaultTextFormatting.scale);
79
+ if (horizontalScale !== void 0 && horizontalScale !== 100) result.horizontalScale = horizontalScale;
80
+ if (defaultTextFormatting.kerning !== void 0 && defaultTextFormatting.kerning > 0) result.kerningMinPt = halfPointsToPoints(defaultTextFormatting.kerning);
81
+ if (defaultTextFormatting.emboss !== void 0) result.emboss = defaultTextFormatting.emboss;
82
+ if (defaultTextFormatting.imprint !== void 0) result.imprint = defaultTextFormatting.imprint;
83
+ if (defaultTextFormatting.shadow !== void 0) result.textShadow = defaultTextFormatting.shadow;
84
+ if (defaultTextFormatting.outline !== void 0) result.textOutline = defaultTextFormatting.outline;
85
+ if (defaultTextFormatting.emphasisMark && defaultTextFormatting.emphasisMark !== "none") result.emphasisMark = defaultTextFormatting.emphasisMark;
86
+ return result;
87
+ }
88
+ const LIST_MARKER_FORMATTING_KEYS = [
89
+ "fontFamily",
90
+ "alternateFontFamily",
91
+ "eastAsiaFontFamily",
92
+ "eastAsiaAlternateFontFamily",
93
+ "complexScriptFontFamily",
94
+ "complexScriptAlternateFontFamily",
95
+ "fontSize",
96
+ "complexScriptFontSize",
97
+ "bold",
98
+ "complexScriptBold",
99
+ "italic",
100
+ "complexScriptItalic",
101
+ "rtl",
102
+ "forceComplexScript",
103
+ "color"
104
+ ];
105
+ /**
106
+ * The numbering symbol's typography: the numbering level's `w:rPr` applied
107
+ * over the paragraph mark's run properties (ECMA-376 §17.9.24, §17.3.1.29).
108
+ * Text runs of the paragraph play no part.
109
+ */
110
+ function listMarkerFormattingFor(levelFormatting, paragraphMarkFormatting, theme, fontAlternates) {
111
+ const runFormatting = textFormattingToRunFormatting(mergeTextFormatting(paragraphMarkFormatting, levelFormatting), theme, fontAlternates);
112
+ const formatting = {};
113
+ for (const key of LIST_MARKER_FORMATTING_KEYS) if (runFormatting[key] !== void 0) Reflect.set(formatting, key, runFormatting[key]);
114
+ return Object.keys(formatting).length > 0 ? formatting : void 0;
115
+ }
116
+ function paragraphRunDefaults(pmAttrs, theme, fontAlternates) {
117
+ return textFormattingToRunFormatting(pmAttrs.defaultTextFormatting, theme, fontAlternates);
118
+ }
119
+ //#endregion
120
+ export { isAutomaticTextColorValue, listMarkerFormattingFor, paragraphRunDefaults, resolveComplexScriptThemeFont, resolveEastAsiaThemeFont, resolveWesternThemeFont };
@@ -1,102 +1,10 @@
1
- import { document_d_exports } from "../../types/document.js";
2
- import { BorderStyle, FlowBlock, ParagraphAttrs, TableBlock } from "../../layout-engine/types.js";
3
- import { FontAlternates } from "../../fonts/fontAlternates.js";
1
+ import { FlowBlock } from "../../layout-engine/types.js";
4
2
  import { formatCounter, resolveListTemplate } from "../../prosemirror/listMarker.js";
3
+ import { ToFlowBlocksOptions, resetBlockIdCounter } from "./flowConversionShared.js";
4
+ import { collectNoteRefs, isNoteReferenceMarkXml } from "./noteReferences.js";
5
+ import { convertBorderSpecToLayout } from "./flowBorders.js";
5
6
  import { Node } from "prosemirror-model";
6
7
  //#region src/layout-bridge/convert/toFlowBlocks.d.ts
7
- /**
8
- * Options for the conversion.
9
- */
10
- type ToFlowBlocksOptions = {
11
- /** Default font family. */
12
- defaultFont?: string;
13
- /** Default font size in points. */
14
- defaultSize?: number;
15
- /** Theme for resolving theme colors. */
16
- theme?: document_d_exports.Theme | null;
17
- /** Document styles used to resolve character-style toggles without per-run copies. */
18
- styles?: document_d_exports.StyleDefinitions;
19
- /** Document-scoped OOXML primary-font to `w:altName` lookup. */
20
- fontAlternates?: FontAlternates;
21
- /** Page content height in pixels (pageHeight - marginTop - marginBottom). Images taller than this are scaled down to fit. */
22
- pageContentHeight?: number;
23
- /** Whether a trailing page break moves its paragraph mark to the next page. */
24
- splitPageBreakAndParagraphMark?: boolean;
25
- /** Shared list counters for nested containers. */
26
- listCounters?: Map<number, number[]>;
27
- /** Latest concrete counters by abstract numbering definition. */
28
- listAbstractCounters?: Map<number, number[]>;
29
- /** Shared startOverride state for nested containers. */
30
- listSeenNumIds?: Set<string>;
31
- /**
32
- * Parallel counter state for the "original" (pre-revision) document, used to
33
- * number tracked-deletion list items. Word numbers inserted and deleted list
34
- * runs as if they never coexist: insertions get final-document numbering,
35
- * deletions keep their original numbering. Without a separate stream a deleted
36
- * item continues the counter of the inserted item before it (a, b → c, d, e
37
- * instead of a, b and a, b, c). Normal items advance both streams.
38
- */
39
- originalListCounters?: Map<number, number[]>;
40
- /** Latest concrete original-stream counters by abstract numbering definition. */
41
- originalListAbstractCounters?: Map<number, number[]>;
42
- /** Original-stream startOverride state. */
43
- originalListSeenNumIds?: Set<string>;
44
- /**
45
- * Document-wide `w:defaultTabStop` (§17.6.13) in twips. Stamped onto
46
- * every paragraph block so paragraph-local layout helpers (list marker
47
- * tab-stop math) can read it without taking a `Document` reference.
48
- * Defaults to the OOXML 720-twip value when absent.
49
- */
50
- defaultTabStopTwips?: number;
51
- /** Document-wide custom Word line-breaking settings. */
52
- lineBreakRules?: {
53
- noLineBreaksBefore?: {
54
- language?: string;
55
- characters: string;
56
- };
57
- noLineBreaksAfter?: {
58
- language?: string;
59
- characters: string;
60
- };
61
- useLegacyEthiopicAmharicRules?: boolean;
62
- };
63
- /** Document-generation policy for justified line fitting. */
64
- justificationCompatibility?: NonNullable<ParagraphAttrs["justificationCompatibility"]>;
65
- /** Document-generation policy for where `w:tblInd` is measured from. */
66
- tableIndentCompatibility?: NonNullable<TableBlock["indentCompatibility"]>;
67
- /**
68
- * When set, every table-cell anchor lays out inside its cell regardless of
69
- * an authored `wp:anchor/@layoutInCell="0"`. Compatibility mode 15 and
70
- * above ignore that opt-out; see `resolveAnchorLayoutInCellCompatibility`.
71
- */
72
- forceAnchorLayoutInCell?: boolean;
73
- /** Document-wide automatic hyphenation policy. */
74
- automaticHyphenation?: NonNullable<ParagraphAttrs["automaticHyphenation"]>;
75
- /** Line pitch for the final body section, whose properties live outside the PM body. */
76
- finalSectionDocumentGridLinePitchTwips?: number;
77
- /**
78
- * The number a note story's `w:footnoteRef`/`w:endnoteRef` marks show. The
79
- * mark stands for its note's reference number and shows it where it sits
80
- * among the story's runs, in that run's formatting.
81
- */
82
- noteReferenceMarkText?: string;
83
- /**
84
- * Endnotes laid out after the body's last block (`w:pos="docEnd"`). A body
85
- * that references one ends in its endnote area, so its final paragraph is no
86
- * longer the document's last and keeps its height.
87
- */
88
- trailingEndnoteIds?: ReadonlySet<number>;
89
- };
90
- /**
91
- * Runs with `idKey` set, in document order: the note references a block list
92
- * makes, through table cells (and tables within cells) and text boxes.
93
- */
94
- declare function collectNoteRefs(blocks: readonly FlowBlock[], idKey: "footnoteRefId" | "endnoteRefId"): {
95
- noteId: number;
96
- pmPos: number;
97
- }[];
98
- /** Whether captured run-child markup is a note story's `w:footnoteRef`/`w:endnoteRef`. */
99
- declare function isNoteReferenceMarkXml(xml: string): boolean;
100
8
  /**
101
9
  * Word's layout fallback when an imported OOXML style hierarchy never supplies
102
10
  * `w:sz`. ECMA-376 deliberately leaves that terminal fallback to the consumer;
@@ -105,22 +13,6 @@ declare function isNoteReferenceMarkXml(xml: string): boolean;
105
13
  * default.
106
14
  */
107
15
  declare const WORD_UNSPECIFIED_FONT_SIZE = 10;
108
- /**
109
- * Reset the block ID counter (useful for testing).
110
- */
111
- declare function resetBlockIdCounter(): void;
112
- /** A parsed border, or the same shape read off ProseMirror attributes. */
113
- type ConvertibleBorder = {
114
- style?: document_d_exports.BorderStyleValue;
115
- size?: number;
116
- space?: number;
117
- color?: document_d_exports.ColorValue;
118
- };
119
- /**
120
- * Convert an OOXML BorderSpec to a layout-engine BorderStyle.
121
- * Shared by paragraph borders, cell borders, and header/footer borders.
122
- */
123
- declare function convertBorderSpecToLayout(border: ConvertibleBorder, theme?: document_d_exports.Theme | null): BorderStyle | undefined;
124
16
  /**
125
17
  * Convert a ProseMirror document to FlowBlock array.
126
18
  *
@@ -129,4 +21,4 @@ declare function convertBorderSpecToLayout(border: ConvertibleBorder, theme?: do
129
21
  */
130
22
  declare function toFlowBlocks(doc: Node, options?: ToFlowBlocksOptions): FlowBlock[];
131
23
  //#endregion
132
- export { ToFlowBlocksOptions, WORD_UNSPECIFIED_FONT_SIZE, collectNoteRefs, convertBorderSpecToLayout, formatCounter, isNoteReferenceMarkXml, resetBlockIdCounter, resolveListTemplate, toFlowBlocks };
24
+ export { type ToFlowBlocksOptions, WORD_UNSPECIFIED_FONT_SIZE, collectNoteRefs, convertBorderSpecToLayout, formatCounter, isNoteReferenceMarkXml, resetBlockIdCounter, resolveListTemplate, toFlowBlocks };