@stll/folio-core 0.7.0 → 0.9.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 (193) hide show
  1. package/README.md +39 -0
  2. package/dist/ai-edits/apply.js +18 -4
  3. package/dist/ai-edits/blockRange.d.ts +13 -2
  4. package/dist/ai-edits/blockRange.js +23 -2
  5. package/dist/ai-edits/headless.d.ts +31 -4
  6. package/dist/ai-edits/headless.js +148 -35
  7. package/dist/ai-edits/index.d.ts +6 -4
  8. package/dist/ai-edits/index.js +4 -1
  9. package/dist/ai-edits/scoped-reading.d.ts +9 -0
  10. package/dist/ai-edits/scoped-reading.js +60 -0
  11. package/dist/ai-edits/snapshot.js +53 -7
  12. package/dist/ai-edits/types.d.ts +46 -3
  13. package/dist/compat/eigenpal.d.ts +8 -3
  14. package/dist/compat/eigenpal.js +7 -2
  15. package/dist/controller/fontReadiness.d.ts +29 -0
  16. package/dist/controller/fontReadiness.js +139 -0
  17. package/dist/controller/latestRequestGate.d.ts +13 -0
  18. package/dist/controller/latestRequestGate.js +16 -0
  19. package/dist/controller/layoutPipeline.js +88 -10
  20. package/dist/document-operations.d.ts +10 -3
  21. package/dist/document-operations.js +29 -14
  22. package/dist/docx/blockContentParser.js +53 -10
  23. package/dist/docx/commentParser.js +1 -1
  24. package/dist/docx/compatibility.d.ts +30 -2
  25. package/dist/docx/compatibility.js +118 -39
  26. package/dist/docx/conformance.d.ts +6 -0
  27. package/dist/docx/conformance.js +18 -0
  28. package/dist/docx/encryption/agileDecryption.js +1 -1
  29. package/dist/docx/encryption/encryptionInfo.js +1 -1
  30. package/dist/docx/encryption/openEncryptedDocx.js +1 -1
  31. package/dist/docx/ensureParaIds.d.ts +29 -0
  32. package/dist/docx/ensureParaIds.js +423 -0
  33. package/dist/docx/fontTableParser.d.ts +6 -0
  34. package/dist/docx/fontTableParser.js +72 -0
  35. package/dist/docx/groupDrawingParser.js +7 -2
  36. package/dist/docx/headerFooterParser.js +1 -1
  37. package/dist/docx/normalizeBaseDirection.js +1 -1
  38. package/dist/docx/numberingParser.js +2 -0
  39. package/dist/docx/paragraphParser.js +21 -1
  40. package/dist/docx/paragraphTextBoxEnrichment.js +141 -2
  41. package/dist/docx/parser.d.ts +1 -1
  42. package/dist/docx/parser.js +14 -9
  43. package/dist/docx/rezip.js +70 -5
  44. package/dist/docx/runConsolidator.js +4 -0
  45. package/dist/docx/runParser.js +19 -1
  46. package/dist/docx/selectiveSave.js +3 -3
  47. package/dist/docx/selectiveXmlPatch.d.ts +10 -1
  48. package/dist/docx/selectiveXmlPatch.js +1 -1
  49. package/dist/docx/serializer/fontTableSerializer.d.ts +6 -0
  50. package/dist/docx/serializer/fontTableSerializer.js +26 -0
  51. package/dist/docx/serializer/headerFooterSerializer.js +1 -1
  52. package/dist/docx/serializer/paragraphSerializer.js +8 -0
  53. package/dist/docx/serializer/runSerializer.js +14 -2
  54. package/dist/docx/serializer/settingsSerializer.d.ts +6 -0
  55. package/dist/docx/serializer/settingsSerializer.js +16 -0
  56. package/dist/docx/serializer/stylesSerializer.d.ts +6 -0
  57. package/dist/docx/serializer/stylesSerializer.js +56 -0
  58. package/dist/docx/serializer/tableSerializer.js +29 -26
  59. package/dist/docx/serializer/themeSerializer.d.ts +6 -0
  60. package/dist/docx/serializer/themeSerializer.js +36 -0
  61. package/dist/docx/settingsParser.js +46 -0
  62. package/dist/docx/styleParser.js +26 -1
  63. package/dist/docx/tableParser.js +19 -1
  64. package/dist/docx/textBoxParser.js +6 -1
  65. package/dist/docx/vmlImageParser.js +146 -1
  66. package/dist/i18n/messages/catalogs.gen.d.ts +5916 -5916
  67. package/dist/i18n/messages/catalogs.gen.js +5910 -5910
  68. package/dist/index.d.ts +8 -3
  69. package/dist/index.js +7 -2
  70. package/dist/layout-bridge/convert/footnoteLayout.d.ts +3 -0
  71. package/dist/layout-bridge/convert/footnoteLayout.js +3 -1
  72. package/dist/layout-bridge/convert/headerFooterLayout.d.ts +3 -0
  73. package/dist/layout-bridge/convert/headerFooterLayout.js +22 -3
  74. package/dist/layout-bridge/convert/paragraphFrames.d.ts +7 -0
  75. package/dist/layout-bridge/convert/paragraphFrames.js +136 -0
  76. package/dist/layout-bridge/convert/toFlowBlocks.d.ts +14 -2
  77. package/dist/layout-bridge/convert/toFlowBlocks.js +93 -17
  78. package/dist/layout-bridge/engine/hitTest.js +2 -1
  79. package/dist/layout-bridge/engine/measuring/index.d.ts +2 -1
  80. package/dist/layout-bridge/engine/measuring/index.js +2 -1
  81. package/dist/layout-bridge/engine/selectionRects.js +2 -1
  82. package/dist/layout-engine/headerFooterRefs.d.ts +7 -0
  83. package/dist/layout-engine/headerFooterRefs.js +40 -0
  84. package/dist/layout-engine/index.d.ts +3 -2
  85. package/dist/layout-engine/index.js +68 -106
  86. package/dist/layout-engine/measure/cache.js +11 -3
  87. package/dist/layout-engine/measure/font-metrics.worker.js +1 -0
  88. package/dist/layout-engine/measure/index.d.ts +2 -1
  89. package/dist/layout-engine/measure/index.js +2 -1
  90. package/dist/layout-engine/measure/lineBreakProvider.d.ts +33 -0
  91. package/dist/layout-engine/measure/lineBreakProvider.js +252 -0
  92. package/dist/layout-engine/measure/lineBreaks.d.ts +7 -2
  93. package/dist/layout-engine/measure/lineBreaks.js +11 -18
  94. package/dist/layout-engine/measure/listMarkerWidth.d.ts +4 -1
  95. package/dist/layout-engine/measure/listMarkerWidth.js +33 -8
  96. package/dist/layout-engine/measure/measureBlocks.d.ts +4 -2
  97. package/dist/layout-engine/measure/measureBlocks.js +138 -86
  98. package/dist/layout-engine/measure/measureContainer.js +32 -9
  99. package/dist/layout-engine/measure/measureHelpers.js +5 -2
  100. package/dist/layout-engine/measure/measureParagraph.js +346 -74
  101. package/dist/layout-engine/measure/measureTypes.d.ts +2 -1
  102. package/dist/layout-engine/measure/measureWorker.d.ts +2 -2
  103. package/dist/layout-engine/measure/measureWorker.js +8 -19
  104. package/dist/layout-engine/measure/measureWorkerProtocol.d.ts +3 -14
  105. package/dist/layout-engine/measure/tableCellFloating.d.ts +10 -3
  106. package/dist/layout-engine/measure/tableCellFloating.js +37 -29
  107. package/dist/layout-engine/measure/tableCellFlow.d.ts +27 -0
  108. package/dist/layout-engine/measure/tableCellFlow.js +73 -0
  109. package/dist/layout-engine/measure/tableCellGrid.d.ts +15 -0
  110. package/dist/layout-engine/measure/tableCellGrid.js +62 -0
  111. package/dist/layout-engine/measure/textBoxParagraphLayout.d.ts +18 -0
  112. package/dist/layout-engine/measure/textBoxParagraphLayout.js +32 -0
  113. package/dist/layout-engine/measure/textMeasurementPolicy.d.ts +18 -0
  114. package/dist/layout-engine/measure/textMeasurementPolicy.js +24 -0
  115. package/dist/layout-engine/paginator.d.ts +2 -1
  116. package/dist/layout-engine/paginator.js +7 -6
  117. package/dist/layout-engine/paragraphFrame.d.ts +22 -0
  118. package/dist/layout-engine/paragraphFrame.js +17 -0
  119. package/dist/layout-engine/paragraphSequence.d.ts +7 -0
  120. package/dist/layout-engine/paragraphSequence.js +25 -0
  121. package/dist/layout-engine/paragraphSpacing.d.ts +17 -0
  122. package/dist/layout-engine/paragraphSpacing.js +30 -0
  123. package/dist/layout-engine/renderedBreakReconciliation.d.ts +63 -0
  124. package/dist/layout-engine/renderedBreakReconciliation.js +86 -0
  125. package/dist/layout-engine/tableRowBreak.d.ts +5 -2
  126. package/dist/layout-engine/tableRowBreak.js +62 -29
  127. package/dist/layout-engine/types.d.ts +54 -12
  128. package/dist/layout-engine/types.js +15 -2
  129. package/dist/layout-painter/anchoredImagePosition.d.ts +23 -0
  130. package/dist/layout-painter/anchoredImagePosition.js +95 -0
  131. package/dist/layout-painter/borderStroke.d.ts +23 -0
  132. package/dist/layout-painter/borderStroke.js +39 -0
  133. package/dist/layout-painter/renderImage.d.ts +5 -4
  134. package/dist/layout-painter/renderImage.js +18 -4
  135. package/dist/layout-painter/renderPage.d.ts +2 -27
  136. package/dist/layout-painter/renderPage.js +15 -101
  137. package/dist/layout-painter/renderParagraph.js +45 -26
  138. package/dist/layout-painter/renderTable.d.ts +2 -0
  139. package/dist/layout-painter/renderTable.js +257 -47
  140. package/dist/layout-painter/renderTextBox.js +17 -7
  141. package/dist/managers/DocumentLoaderManager.d.ts +1 -1
  142. package/dist/managers/DocumentLoaderManager.js +2 -2
  143. package/dist/paged-layout/sectionBlockWidths.d.ts +3 -0
  144. package/dist/paged-layout/sectionBlockWidths.js +9 -0
  145. package/dist/paged-layout/sectionGeometry.js +1 -1
  146. package/dist/prosemirror/attrs/index.d.ts +4 -2
  147. package/dist/prosemirror/attrs/index.js +32 -2
  148. package/dist/prosemirror/commands/propertyChangeScope.js +1 -1
  149. package/dist/prosemirror/conversion/fromProseDoc.js +35 -18
  150. package/dist/prosemirror/conversion/toProseDoc.js +73 -37
  151. package/dist/prosemirror/extensions/StarterKit.js +2 -0
  152. package/dist/prosemirror/extensions/core/ParagraphExtension.js +8 -2
  153. package/dist/prosemirror/extensions/features/AutoBidiDetectionExtension.js +1 -1
  154. package/dist/prosemirror/extensions/features/ListExtension.js +2 -0
  155. package/dist/prosemirror/extensions/features/ParaIdAllocatorExtension.js +68 -16
  156. package/dist/prosemirror/extensions/marks/FootnoteRefExtension.js +1 -0
  157. package/dist/prosemirror/extensions/marks/HighlightExtension.js +1 -1
  158. package/dist/prosemirror/extensions/marks/LanguageExtension.d.ts +7 -0
  159. package/dist/prosemirror/extensions/marks/LanguageExtension.js +30 -0
  160. package/dist/prosemirror/extensions/marks/RunShadingExtension.js +1 -1
  161. package/dist/prosemirror/extensions/marks/TextColorExtension.js +1 -1
  162. package/dist/prosemirror/extensions/marks/TrackedChangeExtensions.js +1 -1
  163. package/dist/prosemirror/extensions/marks/markUtils.js +12 -0
  164. package/dist/prosemirror/extensions/nodes/ImageExtension.js +2 -1
  165. package/dist/prosemirror/extensions/nodes/TableExtension.js +4 -2
  166. package/dist/prosemirror/extensions/nodes/TextBoxExtension.d.ts +2 -1
  167. package/dist/prosemirror/extensions/nodes/TextBoxExtension.js +7 -0
  168. package/dist/prosemirror/schema/index.d.ts +2 -2
  169. package/dist/prosemirror/schema/marks.d.ts +6 -1
  170. package/dist/prosemirror/schema/nodes.d.ts +16 -12
  171. package/dist/prosemirror/styles/resolvedStyleAttrs.js +2 -0
  172. package/dist/prosemirror/utils/tabCalculator.d.ts +3 -1
  173. package/dist/prosemirror/utils/tabCalculator.js +12 -10
  174. package/dist/prosemirror/validation.js +4 -1
  175. package/dist/redline.js +13 -3
  176. package/dist/server.d.ts +9 -4
  177. package/dist/server.js +7 -2
  178. package/dist/style-sets/extract.d.ts +35 -0
  179. package/dist/style-sets/extract.js +123 -0
  180. package/dist/style-sets/stellaStyle.d.ts +13 -0
  181. package/dist/style-sets/stellaStyle.js +516 -0
  182. package/dist/style-sets/types.d.ts +31 -0
  183. package/dist/style-sets/types.js +5 -0
  184. package/dist/types/index.d.ts +2 -1
  185. package/dist/utils/createDocument.d.ts +12 -2
  186. package/dist/utils/createDocument.js +55 -36
  187. package/dist/utils/fontResolver.js +6 -6
  188. package/dist/utils/formatToStyle.js +1 -1
  189. package/dist/utils/hexId.d.ts +8 -1
  190. package/dist/utils/hexId.js +11 -3
  191. package/dist/utils/paragraphFormattingMerge.d.ts +14 -3
  192. package/dist/utils/paragraphFormattingMerge.js +14 -4
  193. package/package.json +5 -1
@@ -1,8 +1,12 @@
1
1
  import { emuToPixels } from "../utils/units.js";
2
- import { isFloatingImageRun, isFloatingTextBoxBlock, tableColumnsArePinned } from "../layout-engine/types.js";
2
+ import { getTableRowLeadingWidth, isFloatingImageRun, isFloatingTextBoxBlock, tableColumnsArePinned } from "../layout-engine/types.js";
3
3
  import { measureParagraph } from "../layout-engine/measure/measureParagraph.js";
4
+ import { resolveAnchoredImagePosition } from "./anchoredImagePosition.js";
5
+ import { applyImageVisualAttrs, hasImageCrop, hasImageVisualAttrs } from "./renderImage.js";
6
+ import { borderStrokeToCss, resolveCssBorderStroke } from "./borderStroke.js";
4
7
  import { getAutomaticTextColorForBackground } from "./documentColors.js";
5
8
  import { renderParagraphFragment } from "./renderParagraph.js";
9
+ import { createTableCellFlowState, finishTableCellFlow, placeTableCellBlock } from "../layout-engine/measure/tableCellFlow.js";
6
10
  import { buildTableCellFloatingZones, getTableCellContentWidth, getTableCellFloatingImages } from "../layout-engine/measure/tableCellFloating.js";
7
11
  import { renderTextBoxFragment } from "./renderTextBox.js";
8
12
  //#region src/layout-painter/renderTable.ts
@@ -28,13 +32,21 @@ const TABLE_CLASS_NAMES = {
28
32
  tableEdgeHandleBottom: "layout-table-edge-handle-bottom",
29
33
  tableEdgeHandleRight: "layout-table-edge-handle-right"
30
34
  };
31
- function renderCellContent(cell, cellMeasure, context, doc) {
35
+ const CELL_DIAGONAL_BORDER_CLASS = "layout-table-cell-diagonal-border";
36
+ function renderCellContent({ cell, cellMeasure, context, doc, contentWidthOverride, pageContentPosition }) {
32
37
  const contentEl = doc.createElement("div");
33
38
  contentEl.className = TABLE_CLASS_NAMES.cellContent;
34
39
  contentEl.style.position = "relative";
35
- const contentWidth = getTableCellContentWidth(cell, cellMeasure);
40
+ const contentWidth = contentWidthOverride ?? getTableCellContentWidth(cell, cellMeasure);
36
41
  contentEl.style.width = `${contentWidth}px`;
37
- const cellFloatingImages = getTableCellFloatingImages(cell, cellMeasure, contentWidth);
42
+ const cellFloatingImages = getTableCellFloatingImages(cell, cellMeasure, contentWidth, pageContentPosition ? (run, paragraphY) => {
43
+ const position = resolveAnchoredImagePosition(run, pageContentPosition.y + paragraphY, pageContentPosition.geometry);
44
+ return {
45
+ x: position.x - pageContentPosition.x,
46
+ y: position.y - pageContentPosition.y,
47
+ side: position.side
48
+ };
49
+ } : void 0);
38
50
  const floatingZones = buildTableCellFloatingZones(cellFloatingImages, contentWidth);
39
51
  const floatingLayers = [];
40
52
  if (cellFloatingImages.length > 0) {
@@ -62,14 +74,24 @@ function renderCellContent(cell, cellMeasure, context, doc) {
62
74
  imgEl.style.width = `${img.width}px`;
63
75
  imgEl.style.height = `${img.height}px`;
64
76
  imgEl.style.display = "block";
77
+ imgEl.style.maxWidth = "none";
78
+ imgEl.style.maxHeight = "none";
65
79
  if (img.alt) imgEl.alt = img.alt;
66
80
  if (img.transform) imgEl.style.transform = img.transform;
81
+ if (hasImageVisualAttrs(img)) {
82
+ if (hasImageCrop(img)) {
83
+ imgContainer.style.width = `${img.width}px`;
84
+ imgContainer.style.height = `${img.height}px`;
85
+ imgContainer.style.overflow = "hidden";
86
+ }
87
+ applyImageVisualAttrs(imgEl, img);
88
+ }
67
89
  imgContainer.append(imgEl);
68
90
  floatingLayer.append(imgContainer);
69
91
  }
70
92
  floatingLayers.push(floatingLayer);
71
93
  }
72
- let cumulativeY = 0;
94
+ const flowState = createTableCellFlowState();
73
95
  let anchorParagraphY = 0;
74
96
  let floatingTextBoxesLayer;
75
97
  for (let i = 0; i < cell.blocks.length; i++) {
@@ -78,17 +100,18 @@ function renderCellContent(cell, cellMeasure, context, doc) {
78
100
  if (block?.kind === "paragraph" && measure?.kind === "paragraph") {
79
101
  const paragraphBlock = block;
80
102
  let paragraphMeasure = measure;
81
- if (floatingZones.length > 0) paragraphMeasure = measureParagraph(paragraphBlock, contentWidth, {
103
+ if (floatingZones.length > 0 || contentWidthOverride !== void 0) paragraphMeasure = measureParagraph(paragraphBlock, contentWidth, {
82
104
  floatingZones,
83
- paragraphYOffset: cumulativeY
105
+ paragraphYOffset: placeTableCellBlock({ ...flowState }, paragraphBlock, paragraphMeasure).contentTop
84
106
  });
107
+ const placement = placeTableCellBlock(flowState, paragraphBlock, paragraphMeasure);
85
108
  const syntheticFragment = {
86
109
  kind: "paragraph",
87
110
  blockId: paragraphBlock.id,
88
111
  x: 0,
89
112
  y: 0,
90
113
  width: contentWidth,
91
- height: paragraphMeasure.totalHeight,
114
+ height: placement.contentHeight,
92
115
  fromLine: 0,
93
116
  toLine: paragraphMeasure.lines.length,
94
117
  ...paragraphBlock.pmStart !== void 0 ? { pmStart: paragraphBlock.pmStart } : {},
@@ -101,18 +124,23 @@ function renderCellContent(cell, cellMeasure, context, doc) {
101
124
  const fragEl = renderParagraphFragment(syntheticFragment, paragraphBlock, paragraphMeasure, cellContext, { document: doc });
102
125
  fragEl.style.position = "relative";
103
126
  fragEl.style.boxSizing = "border-box";
104
- fragEl.style.height = `${paragraphMeasure.totalHeight}px`;
105
- const spaceBefore = paragraphBlock.attrs?.spacing?.before ?? 0;
106
- if (spaceBefore > 0) fragEl.style.paddingTop = `${spaceBefore}px`;
127
+ fragEl.style.height = `${placement.leadingSpacing + placement.contentHeight}px`;
128
+ if (placement.leadingSpacing > 0) fragEl.style.paddingTop = `${placement.leadingSpacing}px`;
107
129
  contentEl.append(fragEl);
108
- anchorParagraphY = cumulativeY;
109
- cumulativeY += paragraphMeasure.totalHeight;
130
+ anchorParagraphY = placement.contentTop;
110
131
  } else if (block?.kind === "table" && measure?.kind === "table") {
111
- const nestedTableEl = renderNestedTable(block, measure, context, doc);
132
+ const tableBlock = block;
133
+ const tableMeasure = measure;
134
+ const nestedTableEl = renderNestedTable(tableBlock, tableMeasure, context, doc);
112
135
  nestedTableEl.style.position = "relative";
136
+ const placement = placeTableCellBlock(flowState, tableBlock, tableMeasure);
137
+ if (placement.leadingSpacing > 0) {
138
+ const spacer = doc.createElement("div");
139
+ spacer.style.height = `${placement.leadingSpacing}px`;
140
+ contentEl.append(spacer);
141
+ }
113
142
  contentEl.append(nestedTableEl);
114
- cumulativeY += measure.totalHeight;
115
- anchorParagraphY = cumulativeY;
143
+ anchorParagraphY = flowState.height;
116
144
  } else if (block?.kind === "textBox" && measure?.kind === "textBox") {
117
145
  const textBoxBlock = block;
118
146
  const textBoxMeasure = measure;
@@ -137,14 +165,20 @@ function renderCellContent(cell, cellMeasure, context, doc) {
137
165
  floatingTextBoxesLayer.append(textBoxEl);
138
166
  continue;
139
167
  }
168
+ const placement = placeTableCellBlock(flowState, textBoxBlock, textBoxMeasure);
169
+ if (placement.leadingSpacing > 0) {
170
+ const spacer = doc.createElement("div");
171
+ spacer.style.height = `${placement.leadingSpacing}px`;
172
+ contentEl.append(spacer);
173
+ }
140
174
  textBoxEl.style.position = "relative";
141
175
  textBoxEl.style.left = "0";
142
176
  textBoxEl.style.top = "0";
143
177
  contentEl.append(textBoxEl);
144
- cumulativeY += textBoxMeasure.height;
145
- anchorParagraphY = cumulativeY;
178
+ anchorParagraphY = flowState.height;
146
179
  }
147
180
  }
181
+ contentEl.style.height = `${finishTableCellFlow(flowState)}px`;
148
182
  if (floatingTextBoxesLayer) floatingLayers.push(floatingTextBoxesLayer);
149
183
  return {
150
184
  content: contentEl,
@@ -207,6 +241,7 @@ function renderNestedTable(block, measure, context, doc) {
207
241
  rowYPositions.push(yPos);
208
242
  const spanningCells = /* @__PURE__ */ new Map();
209
243
  const columnsPinned = tableColumnsArePinned(block);
244
+ const cellGrid = buildTableCellGrid(block, measure.columnWidths.length);
210
245
  let y = 0;
211
246
  for (let rowIndex = 0; rowIndex < block.rows.length; rowIndex++) {
212
247
  const row = block.rows[rowIndex];
@@ -216,7 +251,21 @@ function renderNestedTable(block, measure, context, doc) {
216
251
  y += rowMeasure.height;
217
252
  continue;
218
253
  }
219
- const rowEl = renderTableRow(row, rowMeasure, rowIndex, y, measure.columnWidths, block.rows.length, context, doc, spanningCells, rowYPositions, void 0, block.bidi, columnsPinned);
254
+ const rowEl = renderTableRow({
255
+ row,
256
+ rowMeasure,
257
+ rowIndex,
258
+ y,
259
+ columnWidths: measure.columnWidths,
260
+ totalRows: block.rows.length,
261
+ context,
262
+ doc,
263
+ spanningCells,
264
+ rowYPositions,
265
+ bidi: block.bidi === true,
266
+ columnsPinned,
267
+ cellGrid
268
+ });
220
269
  tableEl.append(rowEl);
221
270
  y += rowMeasure.height;
222
271
  }
@@ -228,18 +277,46 @@ function renderNestedTable(block, measure, context, doc) {
228
277
  */
229
278
  function applyBorder(el, side, border) {
230
279
  const styleProp = `border${side.charAt(0).toUpperCase() + side.slice(1)}`;
231
- if (!border || border.style === "none" || border.style === "nil" || border.width === 0) el.style[styleProp] = "none";
232
- else {
233
- const width = border.width ?? 1;
234
- const color = border.color ?? "#000000";
235
- const style = border.style ?? "solid";
236
- el.style[styleProp] = `${width}px ${style} ${color}`;
280
+ if (!border || border.style === "none" || border.style === "nil") el.style[styleProp] = "none";
281
+ else el.style[styleProp] = borderStrokeToCss(border);
282
+ }
283
+ function renderCellDiagonalBorder({ border, direction, cellWidth, cellHeight, doc }) {
284
+ if (!hasVisibleBorder(border)) return null;
285
+ const line = doc.createElement("div");
286
+ const stroke = resolveCssBorderStroke(border ?? {});
287
+ const strokeWidth = stroke.width;
288
+ const color = stroke.color;
289
+ const length = Math.hypot(cellWidth, cellHeight);
290
+ const angle = Math.atan2(cellHeight, cellWidth);
291
+ line.className = CELL_DIAGONAL_BORDER_CLASS;
292
+ line.dataset["direction"] = direction;
293
+ line.style.position = "absolute";
294
+ line.style.left = "0";
295
+ line.style.top = direction === "top-left-to-bottom-right" ? `${-strokeWidth / 2}px` : `${cellHeight - strokeWidth / 2}px`;
296
+ line.style.width = `${length}px`;
297
+ line.style.height = `${strokeWidth}px`;
298
+ line.style.transformOrigin = "0 50%";
299
+ line.style.transform = `rotate(${direction === "top-left-to-bottom-right" ? angle : -angle}rad)`;
300
+ line.style.pointerEvents = "none";
301
+ line.style.zIndex = "1";
302
+ switch (border?.style) {
303
+ case "dashed":
304
+ line.style.backgroundImage = `repeating-linear-gradient(to right, ${color} 0, ${color} ${strokeWidth * 3}px, transparent ${strokeWidth * 3}px, transparent ${strokeWidth * 5}px)`;
305
+ break;
306
+ case "dotted":
307
+ line.style.backgroundImage = `radial-gradient(circle at ${strokeWidth / 2}px 50%, ${color} ${strokeWidth / 2}px, transparent ${strokeWidth / 2}px)`;
308
+ line.style.backgroundSize = `${strokeWidth * 2}px ${strokeWidth}px`;
309
+ break;
310
+ case "double":
311
+ line.style.backgroundImage = `linear-gradient(to bottom, ${color} 0, ${color} 33%, transparent 33%, transparent 67%, ${color} 67%, ${color} 100%)`;
312
+ break;
313
+ default:
314
+ line.style.backgroundColor = color;
315
+ break;
237
316
  }
317
+ return line;
238
318
  }
239
- /**
240
- * Render a single table cell
241
- */
242
- function renderTableCell(cell, cellMeasure, x, rowHeight, borderFlags, columnsPinned, context, doc) {
319
+ function renderTableCell({ cell, cellMeasure, x, rowHeight, borderFlags, columnsPinned, context, doc, contentClip, pageContentPosition }) {
243
320
  const cellEl = doc.createElement("div");
244
321
  cellEl.className = TABLE_CLASS_NAMES.cell;
245
322
  cellEl.style.position = "absolute";
@@ -255,10 +332,10 @@ function renderTableCell(cell, cellMeasure, x, rowHeight, borderFlags, columnsPi
255
332
  const padLeft = cell.padding?.left ?? 7;
256
333
  cellEl.style.padding = `${padTop}px ${padRight}px ${padBottom}px ${padLeft}px`;
257
334
  if (cell.borders) {
258
- if (borderFlags.isFirstRow) applyBorder(cellEl, "top", cell.borders.top);
335
+ if (borderFlags.drawTop) applyBorder(cellEl, "top", cell.borders.top);
259
336
  applyBorder(cellEl, "right", cell.borders.right);
260
337
  applyBorder(cellEl, "bottom", cell.borders.bottom);
261
- if (borderFlags.isFirstCol) applyBorder(cellEl, "left", cell.borders.left);
338
+ if (borderFlags.drawLeft) applyBorder(cellEl, "left", cell.borders.left);
262
339
  }
263
340
  if (cell.background) {
264
341
  cellEl.style.backgroundColor = cell.background;
@@ -282,13 +359,55 @@ function renderTableCell(cell, cellMeasure, x, rowHeight, borderFlags, columnsPi
282
359
  default: break;
283
360
  }
284
361
  }
285
- const renderedContent = renderCellContent(cell, cellMeasure, context, doc);
362
+ const contentWidthOverride = cell.textDirection === "btLr" ? Math.max(1, rowHeight - padTop - padBottom) : void 0;
363
+ const renderedContent = renderCellContent({
364
+ cell,
365
+ cellMeasure,
366
+ context,
367
+ doc,
368
+ ...contentWidthOverride !== void 0 ? { contentWidthOverride } : {},
369
+ ...pageContentPosition ? { pageContentPosition: {
370
+ geometry: pageContentPosition.geometry,
371
+ x: pageContentPosition.x + padLeft,
372
+ y: pageContentPosition.y + padTop
373
+ } } : {}
374
+ });
375
+ if (cell.textDirection === "btLr") {
376
+ renderedContent.content.style.position = "absolute";
377
+ renderedContent.content.style.left = "50%";
378
+ renderedContent.content.style.top = "50%";
379
+ renderedContent.content.style.transform = "translate(-50%, -50%) rotate(-90deg)";
380
+ }
286
381
  if (renderedContent.floatingLayers.length > 0) {
287
382
  renderedContent.content.style.height = "100%";
288
383
  renderedContent.content.style.overflow = "hidden";
289
384
  cellEl.style.overflow = "visible";
290
385
  }
386
+ if (contentClip) {
387
+ const contentHeight = Math.max(0, rowHeight - padTop - padBottom);
388
+ const clipTop = Math.min(contentHeight, Math.max(0, contentClip.top - padTop));
389
+ const clipBottom = Math.min(contentHeight, Math.max(clipTop, contentClip.bottom - padTop));
390
+ renderedContent.content.style.height = `${contentHeight}px`;
391
+ renderedContent.content.style.overflow = "hidden";
392
+ renderedContent.content.style.clipPath = `inset(${clipTop}px 0 ${contentHeight - clipBottom}px 0)`;
393
+ }
291
394
  cellEl.append(renderedContent.content);
395
+ const topLeftToBottomRight = renderCellDiagonalBorder({
396
+ border: cell.borders?.topLeftToBottomRight,
397
+ direction: "top-left-to-bottom-right",
398
+ cellWidth: cellMeasure.width,
399
+ cellHeight: rowHeight,
400
+ doc
401
+ });
402
+ if (topLeftToBottomRight) cellEl.append(topLeftToBottomRight);
403
+ const topRightToBottomLeft = renderCellDiagonalBorder({
404
+ border: cell.borders?.topRightToBottomLeft,
405
+ direction: "top-right-to-bottom-left",
406
+ cellWidth: cellMeasure.width,
407
+ cellHeight: rowHeight,
408
+ doc
409
+ });
410
+ if (topRightToBottomLeft) cellEl.append(topRightToBottomLeft);
292
411
  for (const floatingLayer of renderedContent.floatingLayers) {
293
412
  floatingLayer.style.left = `${padLeft}px`;
294
413
  floatingLayer.style.top = `${padTop}px`;
@@ -303,10 +422,27 @@ function renderTableCell(cell, cellMeasure, x, rowHeight, borderFlags, columnsPi
303
422
  }
304
423
  return cellEl;
305
424
  }
306
- /**
307
- * Render a table row with rowSpan support
308
- */
309
- function renderTableRow(row, rowMeasure, rowIndex, y, columnWidths, totalRows, context, doc, spanningCells, rowYPositions, isFirstRowInFragment, bidi = false, columnsPinned = false) {
425
+ const tableCellGridKey = (rowIndex, columnIndex) => `${rowIndex}:${columnIndex}`;
426
+ function buildTableCellGrid(block, columnCount) {
427
+ const grid = /* @__PURE__ */ new Map();
428
+ for (let rowIndex = 0; rowIndex < block.rows.length; rowIndex++) {
429
+ const row = block.rows[rowIndex];
430
+ if (!row) continue;
431
+ let columnIndex = 0;
432
+ for (const cell of row.cells) {
433
+ while (grid.has(tableCellGridKey(rowIndex, columnIndex))) columnIndex += 1;
434
+ const colSpan = cell.colSpan ?? 1;
435
+ const rowSpan = cell.rowSpan ?? 1;
436
+ const rowEnd = Math.min(block.rows.length, rowIndex + rowSpan);
437
+ const columnEnd = Math.min(columnCount, columnIndex + colSpan);
438
+ for (let gridRow = rowIndex; gridRow < rowEnd; gridRow++) for (let gridColumn = columnIndex; gridColumn < columnEnd; gridColumn++) grid.set(tableCellGridKey(gridRow, gridColumn), cell);
439
+ columnIndex += colSpan;
440
+ }
441
+ }
442
+ return grid;
443
+ }
444
+ const hasVisibleBorder = (border) => border !== void 0 && border.style !== "none" && border.style !== "nil";
445
+ function renderTableRow({ row, rowMeasure, rowIndex, y, columnWidths, totalRows, context, doc, spanningCells, rowYPositions, isFirstRowInFragment, bidi = false, columnsPinned = false, cellGrid, contentClip, pageContentPosition }) {
310
446
  const rowEl = doc.createElement("div");
311
447
  rowEl.className = TABLE_CLASS_NAMES.row;
312
448
  const tableWidth = bidi ? columnWidths.reduce((sum, columnWidth) => sum + columnWidth, 0) : 0;
@@ -320,8 +456,9 @@ function renderTableRow(row, rowMeasure, rowIndex, y, columnWidths, totalRows, c
320
456
  if (spanningCells) {
321
457
  for (const [, spanCell] of spanningCells) if (spanCell.startRow < rowIndex && spanCell.startRow + spanCell.rowSpan > rowIndex) for (let c = 0; c < spanCell.colSpan; c++) occupiedColumns.add(spanCell.columnIndex + c);
322
458
  }
323
- let x = 0;
324
- let columnIndex = 0;
459
+ const gridBefore = row.gridBefore ?? 0;
460
+ let x = getTableRowLeadingWidth(row, columnWidths);
461
+ let columnIndex = gridBefore;
325
462
  while (occupiedColumns.has(columnIndex)) {
326
463
  x += columnWidths[columnIndex] ?? 0;
327
464
  columnIndex++;
@@ -345,12 +482,34 @@ function renderTableRow(row, rowMeasure, rowIndex, y, columnWidths, totalRows, c
345
482
  const isLastRow = rowIndex + rowSpan >= totalRows;
346
483
  const atLogicalStart = columnIndex === 0;
347
484
  const atLogicalEnd = columnIndex + colSpan >= columnWidths.length;
348
- const cellEl = renderTableCell(cell, cellMeasure, cellLeft, cellHeight, {
349
- isFirstRow,
350
- isLastRow,
351
- isFirstCol: bidi ? atLogicalEnd : atLogicalStart,
352
- isLastCol: bidi ? atLogicalStart : atLogicalEnd
353
- }, columnsPinned, context, doc);
485
+ const isFirstCol = bidi ? atLogicalEnd : atLogicalStart;
486
+ const isLastCol = bidi ? atLogicalStart : atLogicalEnd;
487
+ const aboveCell = cellGrid?.get(tableCellGridKey(rowIndex - 1, columnIndex));
488
+ const leftNeighborColumn = bidi ? columnIndex + colSpan : columnIndex - 1;
489
+ const leftCell = cellGrid?.get(tableCellGridKey(rowIndex, leftNeighborColumn));
490
+ const drawTop = isFirstRow || !hasVisibleBorder(aboveCell?.borders?.bottom);
491
+ const drawLeft = isFirstCol || !hasVisibleBorder(leftCell?.borders?.right);
492
+ const cellEl = renderTableCell({
493
+ cell,
494
+ cellMeasure,
495
+ x: cellLeft,
496
+ rowHeight: cellHeight,
497
+ borderFlags: {
498
+ drawTop,
499
+ isLastRow,
500
+ drawLeft,
501
+ isLastCol
502
+ },
503
+ columnsPinned,
504
+ context,
505
+ doc,
506
+ ...contentClip ? { contentClip } : {},
507
+ ...pageContentPosition ? { pageContentPosition: {
508
+ geometry: pageContentPosition.geometry,
509
+ x: pageContentPosition.x + cellLeft,
510
+ y: pageContentPosition.y
511
+ } } : {}
512
+ });
354
513
  cellEl.dataset["cellIndex"] = String(cellIndex);
355
514
  cellEl.dataset["columnIndex"] = String(columnIndex);
356
515
  if (rowSpan > 1) cellEl.dataset["rowSpan"] = String(rowSpan);
@@ -389,6 +548,11 @@ function renderTableRow(row, rowMeasure, rowIndex, y, columnWidths, totalRows, c
389
548
  */
390
549
  function renderTableFragment(fragment, block, measure, context, options = {}) {
391
550
  const doc = options.document ?? document;
551
+ const tablePageContentPosition = options.pageGeometry ? {
552
+ geometry: options.pageGeometry,
553
+ x: fragment.x - options.pageGeometry.marginLeft,
554
+ y: fragment.y - options.pageGeometry.marginTop
555
+ } : void 0;
392
556
  const tableEl = doc.createElement("div");
393
557
  tableEl.className = TABLE_CLASS_NAMES.table;
394
558
  tableEl.style.position = "absolute";
@@ -429,6 +593,7 @@ function renderTableFragment(fragment, block, measure, context, options = {}) {
429
593
  rowYPositions.push(yPos);
430
594
  const spanningCells = /* @__PURE__ */ new Map();
431
595
  const columnsPinned = tableColumnsArePinned(block);
596
+ const cellGrid = buildTableCellGrid(block, measure.columnWidths.length);
432
597
  const headerRowCount = fragment.headerRowCount ?? 0;
433
598
  let y = 0;
434
599
  if (headerRowCount > 0 && fragment.continuesFromPrev) for (let hdrIdx = 0; hdrIdx < headerRowCount; hdrIdx++) {
@@ -439,7 +604,26 @@ function renderTableFragment(fragment, block, measure, context, options = {}) {
439
604
  y += hdrRowMeasure.height;
440
605
  continue;
441
606
  }
442
- const rowEl = renderTableRow(hdrRow, hdrRowMeasure, hdrIdx, y, measure.columnWidths, block.rows.length, context, doc, spanningCells, rowYPositions, hdrIdx === 0, block.bidi, columnsPinned);
607
+ const rowEl = renderTableRow({
608
+ row: hdrRow,
609
+ rowMeasure: hdrRowMeasure,
610
+ rowIndex: hdrIdx,
611
+ y,
612
+ columnWidths: measure.columnWidths,
613
+ totalRows: block.rows.length,
614
+ context,
615
+ doc,
616
+ spanningCells,
617
+ rowYPositions,
618
+ isFirstRowInFragment: hdrIdx === 0,
619
+ bidi: block.bidi === true,
620
+ columnsPinned,
621
+ cellGrid,
622
+ ...tablePageContentPosition ? { pageContentPosition: {
623
+ ...tablePageContentPosition,
624
+ y: tablePageContentPosition.y + y
625
+ } } : {}
626
+ });
443
627
  rowEl.dataset["repeatedHeader"] = "true";
444
628
  tableEl.append(rowEl);
445
629
  y += hdrRowMeasure.height;
@@ -466,8 +650,34 @@ function renderTableFragment(fragment, block, measure, context, options = {}) {
466
650
  y += rowMeasure.height;
467
651
  continue;
468
652
  }
469
- const isFirstRowInFragment = headerRowCount > 0 && fragment.continuesFromPrev ? false : fragment.continuesFromPrev && rowIndex === fragment.fromRow;
470
- const rowEl = renderTableRow(row, rowMeasure, rowIndex, y, measure.columnWidths, block.rows.length, context, doc, spanningCells, rowYPositions, isFirstRowInFragment, block.bidi, columnsPinned);
653
+ const isFirstRowInFragment = headerRowCount > 0 && fragment.continuesFromPrev ? false : fragment.continuesFromPrev === true && rowIndex === fragment.fromRow;
654
+ const rowTopClip = rowIndex === fragment.fromRow ? fragment.topClip : void 0;
655
+ const rowBottomClip = rowIndex === fragment.toRow - 1 ? fragment.bottomClip : void 0;
656
+ const contentClip = rowTopClip !== void 0 || rowBottomClip !== void 0 ? {
657
+ top: rowTopClip ?? 0,
658
+ bottom: rowBottomClip ?? rowMeasure.height
659
+ } : void 0;
660
+ const rowEl = renderTableRow({
661
+ row,
662
+ rowMeasure,
663
+ rowIndex,
664
+ y,
665
+ columnWidths: measure.columnWidths,
666
+ totalRows: block.rows.length,
667
+ context,
668
+ doc,
669
+ spanningCells,
670
+ rowYPositions,
671
+ isFirstRowInFragment,
672
+ bidi: block.bidi === true,
673
+ columnsPinned,
674
+ cellGrid,
675
+ ...contentClip ? { contentClip } : {},
676
+ ...tablePageContentPosition ? { pageContentPosition: {
677
+ ...tablePageContentPosition,
678
+ y: tablePageContentPosition.y + y
679
+ } } : {}
680
+ });
471
681
  contentParent.append(rowEl);
472
682
  y += rowMeasure.height;
473
683
  }
@@ -1,5 +1,6 @@
1
1
  import { DEFAULT_TEXTBOX_MARGINS } from "../layout-engine/types.js";
2
2
  import { renderParagraphFragment } from "./renderParagraph.js";
3
+ import { layoutTextBoxParagraphs } from "../layout-engine/measure/textBoxParagraphLayout.js";
3
4
  //#region src/layout-painter/renderTextBox.ts
4
5
  /**
5
6
  * Text Box Renderer
@@ -38,28 +39,37 @@ function renderTextBoxFragment(fragment, block, measure, context, options = {})
38
39
  if (fragment.pmStart !== void 0) containerEl.dataset["pmStart"] = String(fragment.pmStart);
39
40
  if (fragment.pmEnd !== void 0) containerEl.dataset["pmEnd"] = String(fragment.pmEnd);
40
41
  const innerWidth = fragment.width - margins.left - margins.right;
41
- let yOffset = 0;
42
+ const paragraphLayout = layoutTextBoxParagraphs(block.content, measure.innerMeasures);
42
43
  for (let i = 0; i < block.content.length; i++) {
43
44
  const paraBlock = block.content[i];
44
45
  const paraMeasure = measure.innerMeasures[i];
45
- if (!paraBlock || !paraMeasure) continue;
46
- const paraEl = renderParagraphFragment({
46
+ const placement = paragraphLayout.placements[i];
47
+ if (!paraBlock || !paraMeasure || !placement) continue;
48
+ const paraFragment = {
47
49
  kind: "paragraph",
48
50
  blockId: paraBlock.id,
49
51
  x: 0,
50
- y: yOffset,
52
+ y: 0,
51
53
  width: innerWidth,
52
- height: paraMeasure.totalHeight,
54
+ height: placement.contentHeight,
53
55
  ...paraBlock.pmStart !== void 0 ? { pmStart: paraBlock.pmStart } : {},
54
56
  ...paraBlock.pmEnd !== void 0 ? { pmEnd: paraBlock.pmEnd } : {},
55
57
  fromLine: 0,
56
58
  toLine: paraMeasure.lines.length
57
- }, paraBlock, paraMeasure, context, { document: doc });
59
+ };
60
+ const prevBorders = block.content[i - 1]?.attrs?.borders;
61
+ const nextBorders = block.content[i + 1]?.attrs?.borders;
62
+ const paraEl = renderParagraphFragment(paraFragment, paraBlock, paraMeasure, context, {
63
+ document: doc,
64
+ ...prevBorders !== void 0 ? { prevBorders } : {},
65
+ ...nextBorders !== void 0 ? { nextBorders } : {}
66
+ });
58
67
  paraEl.style.position = "relative";
59
68
  paraEl.style.left = "0";
60
69
  paraEl.style.top = "0";
70
+ paraEl.style.height = `${placement.contentHeight}px`;
71
+ paraEl.style.marginTop = `${placement.leadingSpacing}px`;
61
72
  containerEl.append(paraEl);
62
- yOffset += paraMeasure.totalHeight;
63
73
  }
64
74
  return containerEl;
65
75
  }
@@ -1,6 +1,6 @@
1
1
  import { document_d_exports } from "../types/document.js";
2
- import { DocxCompatibility } from "../docx/compatibility.js";
3
2
  import { DocxInput } from "../utils/docxInput.js";
3
+ import { DocxCompatibility } from "../docx/compatibility.js";
4
4
 
5
5
  //#region src/managers/DocumentLoaderManager.d.ts
6
6
  type DocumentLoadState = {
@@ -1,8 +1,8 @@
1
- import { resetAuthorColors } from "../utils/authorColors.js";
2
1
  import { loadFontsWithMapping } from "../utils/fontLoader.js";
3
2
  import { parseDocx } from "../docx/parser.js";
4
- import { recordDocumentLoadPhase } from "../layout-engine/layoutInstrumentation.js";
5
3
  import { inspectDocxCompatibility } from "../docx/compatibility.js";
4
+ import { resetAuthorColors } from "../utils/authorColors.js";
5
+ import { recordDocumentLoadPhase } from "../layout-engine/layoutInstrumentation.js";
6
6
  //#region src/managers/DocumentLoaderManager.ts
7
7
  /**
8
8
  * DocumentLoaderManager
@@ -11,6 +11,9 @@ type PerBlockMeasureInputs = {
11
11
  widths: number[];
12
12
  marginTops: number[];
13
13
  pageHeights: number[];
14
+ pageWidths: number[];
15
+ marginLefts: number[];
16
+ marginRights: number[];
14
17
  marginBottoms: number[];
15
18
  };
16
19
  /**
@@ -35,6 +35,9 @@ function computePerBlockMeasureInputs({ blocks, bodyConfig, finalConfig }) {
35
35
  const widths = [];
36
36
  const marginTops = [];
37
37
  const pageHeights = [];
38
+ const pageWidths = [];
39
+ const marginLefts = [];
40
+ const marginRights = [];
38
41
  const marginBottoms = [];
39
42
  for (let i = 0; i < blocks.length; i++) {
40
43
  const config = sectionConfigs[sectionIdx] ?? finalConfig;
@@ -42,6 +45,9 @@ function computePerBlockMeasureInputs({ blocks, bodyConfig, finalConfig }) {
42
45
  widths.push(colWidth(contentWidth(config), columns, columnIndex));
43
46
  marginTops.push(config.margins.top);
44
47
  pageHeights.push(config.pageSize.h);
48
+ pageWidths.push(config.pageSize.w);
49
+ marginLefts.push(config.margins.left);
50
+ marginRights.push(config.margins.right);
45
51
  marginBottoms.push(config.margins.bottom);
46
52
  if (sectionIdx < breakIndices.length && i === breakIndices[sectionIdx]) {
47
53
  sectionIdx++;
@@ -53,6 +59,9 @@ function computePerBlockMeasureInputs({ blocks, bodyConfig, finalConfig }) {
53
59
  widths,
54
60
  marginTops,
55
61
  pageHeights,
62
+ pageWidths,
63
+ marginLefts,
64
+ marginRights,
56
65
  marginBottoms
57
66
  };
58
67
  }
@@ -9,7 +9,7 @@ const DEFAULT_MARGINS = {
9
9
  bottom: 96,
10
10
  left: 96
11
11
  };
12
- const twipsToPixels = (twips) => Math.round(twips / 1440 * 96);
12
+ const twipsToPixels = (twips) => twips / 1440 * 96;
13
13
  /**
14
14
  * Convert an offset-like twip dimension to px. Explicit 0 is meaningful for
15
15
  * page margins and header/footer distances; only absence should use fallback.
@@ -1,5 +1,5 @@
1
1
  import { BlockSdtAttrs, FieldAttrs, HardBreakAttrs, ImageAttrs, MathAttrs, ParagraphAttrs, SdtAttrs, ShapeAttrs, TableAttrs, TableCellAttrs, TableRowAttrs, TextBoxAttrs } from "../schema/nodes.js";
2
- import { CharacterSpacingAttrs, CharacterStyleAttrs, CommentAttrs, EmphasisMarkAttrs, FontFamilyAttrs, FontSizeAttrs, FootnoteRefAttrs, HighlightAttrs, HyperlinkAttrs, RunFormattingOverrideAttrs, RunShadingAttrs, StrikeAttrs, TextColorAttrs, TextEffectAttrs, TrackedChangeMarkAttrs, UnderlineAttrs } from "../schema/marks.js";
2
+ import { CharacterSpacingAttrs, CharacterStyleAttrs, CommentAttrs, EmphasisMarkAttrs, FontFamilyAttrs, FontSizeAttrs, FootnoteRefAttrs, HighlightAttrs, HyperlinkAttrs, LanguageAttrs, RunFormattingOverrideAttrs, RunShadingAttrs, StrikeAttrs, TextColorAttrs, TextEffectAttrs, TrackedChangeMarkAttrs, UnderlineAttrs } from "../schema/marks.js";
3
3
  import { Mark, Node } from "prosemirror-model";
4
4
 
5
5
  //#region src/prosemirror/attrs/index.d.ts
@@ -54,6 +54,8 @@ declare const readFontSizeMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResult<
54
54
  declare const expectFontSizeMarkAttrs: (mark: Mark) => FontSizeAttrs;
55
55
  declare const readFontFamilyMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResult<FontFamilyAttrs>;
56
56
  declare const expectFontFamilyMarkAttrs: (mark: Mark) => FontFamilyAttrs;
57
+ declare const readLanguageMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResult<LanguageAttrs>;
58
+ declare const expectLanguageMarkAttrs: (mark: Mark) => LanguageAttrs;
57
59
  declare const readCharacterSpacingMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResult<CharacterSpacingAttrs>;
58
60
  declare const expectCharacterSpacingMarkAttrs: (mark: Mark) => CharacterSpacingAttrs;
59
61
  declare const readEmphasisMarkAttrs: (mark: Mark) => ReadProseMirrorAttrsResult<EmphasisMarkAttrs>;
@@ -77,4 +79,4 @@ declare const mergeTableAttrs: (node: Node, patch: NodeAttrPatch<TableAttrs>) =>
77
79
  declare const mergeTableRowAttrs: (node: Node, patch: NodeAttrPatch<TableRowAttrs>) => TableRowAttrs;
78
80
  declare const mergeTableCellAttrs: (node: Node, patch: NodeAttrPatch<TableCellAttrs>) => TableCellAttrs;
79
81
  //#endregion
80
- export { ProseMirrorAttrIssue, ReadProseMirrorAttrsResult, expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readMathAttrs, readParagraphAttrs, readRunFormattingOverrideMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };
82
+ export { ProseMirrorAttrIssue, ReadProseMirrorAttrsResult, expectBlockSdtAttrs, expectCharacterSpacingMarkAttrs, expectCharacterStyleMarkAttrs, expectCommentMarkAttrs, expectEmphasisMarkAttrs, expectFieldAttrs, expectFontFamilyMarkAttrs, expectFontSizeMarkAttrs, expectFootnoteRefMarkAttrs, expectHardBreakAttrs, expectHighlightMarkAttrs, expectHyperlinkMarkAttrs, expectImageAttrs, expectLanguageMarkAttrs, expectMathAttrs, expectParagraphAttrs, expectRunFormattingOverrideMarkAttrs, expectRunShadingMarkAttrs, expectSdtAttrs, expectShapeAttrs, expectStrikeMarkAttrs, expectTableAttrs, expectTableCellAttrs, expectTableRowAttrs, expectTextBoxAttrs, expectTextColorMarkAttrs, expectTextEffectMarkAttrs, expectTrackedChangeMarkAttrs, expectUnderlineMarkAttrs, mergeImageAttrs, mergeParagraphAttrs, mergeTableAttrs, mergeTableCellAttrs, mergeTableRowAttrs, readBlockSdtAttrs, readCharacterSpacingMarkAttrs, readCharacterStyleMarkAttrs, readCommentMarkAttrs, readEmphasisMarkAttrs, readFieldAttrs, readFontFamilyMarkAttrs, readFontSizeMarkAttrs, readFootnoteRefMarkAttrs, readHardBreakAttrs, readHighlightMarkAttrs, readHyperlinkMarkAttrs, readImageAttrs, readLanguageMarkAttrs, readMathAttrs, readParagraphAttrs, readRunFormattingOverrideMarkAttrs, readRunShadingMarkAttrs, readSdtAttrs, readShapeAttrs, readStrikeMarkAttrs, readTableAttrs, readTableCellAttrs, readTableRowAttrs, readTextBoxAttrs, readTextColorMarkAttrs, readTextEffectMarkAttrs, readTrackedChangeMarkAttrs, readUnderlineMarkAttrs };