js.documents 7.20.35 → 8.0.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 (45) hide show
  1. package/dist/edit/doc/table.cjs +35 -24
  2. package/dist/edit/doc/table.d.cts +2 -5
  3. package/dist/edit/doc/table.d.ts +2 -5
  4. package/dist/edit/doc/table.js +35 -24
  5. package/dist/edit/docx/content.cjs +27 -28
  6. package/dist/edit/docx/content.js +28 -29
  7. package/dist/edit/docx/table.cjs +5 -0
  8. package/dist/edit/docx/table.d.cts +1 -0
  9. package/dist/edit/docx/table.d.ts +1 -0
  10. package/dist/edit/docx/table.js +5 -0
  11. package/dist/edit/odp/content.cjs +1 -1
  12. package/dist/edit/odp/content.js +1 -1
  13. package/dist/edit/odp/slide.d.cts +1 -1
  14. package/dist/edit/odp/slide.d.ts +1 -1
  15. package/dist/edit/odt/content.cjs +16 -29
  16. package/dist/edit/odt/content.d.cts +1 -1
  17. package/dist/edit/odt/content.d.ts +1 -1
  18. package/dist/edit/odt/content.js +17 -30
  19. package/dist/edit/odt/editor.d.cts +1 -1
  20. package/dist/edit/odt/editor.d.ts +1 -1
  21. package/dist/edit/odt/table.cjs +40 -13
  22. package/dist/edit/odt/table.d.cts +2 -2
  23. package/dist/edit/odt/table.d.ts +2 -2
  24. package/dist/edit/odt/table.js +40 -14
  25. package/dist/edit/pptx/content.cjs +17 -28
  26. package/dist/edit/pptx/content.js +18 -29
  27. package/dist/index.cjs +1 -0
  28. package/dist/index.d.cts +2 -2
  29. package/dist/index.d.ts +2 -2
  30. package/dist/index.js +2 -2
  31. package/dist/layout/engine.cjs +4 -9
  32. package/dist/layout/engine.js +5 -10
  33. package/dist/layout/reconstruct.cjs +12 -13
  34. package/dist/layout/reconstruct.js +12 -13
  35. package/dist/layout/shared.cjs +23 -15
  36. package/dist/layout/shared.d.cts +19 -3
  37. package/dist/layout/shared.d.ts +19 -3
  38. package/dist/layout/shared.js +24 -17
  39. package/dist/layout/slides.cjs +4 -9
  40. package/dist/layout/slides.js +5 -10
  41. package/dist/ooxml/docx/embedded-objects.cjs +17 -7
  42. package/dist/ooxml/docx/embedded-objects.js +17 -7
  43. package/dist/{table-COmzfIOe.d.cts → table-DvKlZmG0.d.cts} +11 -2
  44. package/dist/{table-BmMyqRML.d.ts → table-qWkzpadC.d.ts} +11 -2
  45. package/package.json +13 -13
@@ -5,6 +5,7 @@ const require_layout_shared = require("./shared.cjs");
5
5
  const require_layout_cell_typing = require("./cell-typing.cjs");
6
6
  const require_ports_abort = require("../ports/abort.cjs");
7
7
  const require_layout_lattice = require("./lattice.cjs");
8
+ let document_schema_js = require("document-schema.js");
8
9
  let pdf_codec_fonts = require("pdf-codec/fonts");
9
10
  let pdf_codec_afm_widths = require("pdf-codec/afm-widths");
10
11
  let pdf_codec_text_group = require("pdf-codec/text-group");
@@ -1278,17 +1279,12 @@ function recoverTable(page, pageIndex) {
1278
1279
  if (consumedText.size === 0) return;
1279
1280
  const columnWidthsPt = [];
1280
1281
  for (let j = 0; j < columnCount; j++) columnWidthsPt.push(lattice.columnBoundariesAscPt[j + 1] - lattice.columnBoundariesAscPt[j]);
1281
- const rows = [];
1282
+ const positionedRows = [];
1282
1283
  for (let i = 0; i < rowCount; i++) {
1283
- const cells = [];
1284
- let j = 0;
1285
- while (j < columnCount) {
1284
+ const positioned = [];
1285
+ for (let j = 0; j < columnCount; j++) {
1286
1286
  const region = regionAt[i][j];
1287
- if (region.rowStart !== i) {
1288
- cells.push({ blocks: [] });
1289
- j = region.colEnd;
1290
- continue;
1291
- }
1287
+ if (region.rowStart !== i || region.colStart !== j) continue;
1292
1288
  const colSpan = region.colEnd - region.colStart;
1293
1289
  const rowSpan = region.rowEnd - region.rowStart;
1294
1290
  const cell = {
@@ -1306,14 +1302,17 @@ function recoverTable(page, pageIndex) {
1306
1302
  widthPt: cellRightXPt - cellLeftXPt,
1307
1303
  heightPt: cellTopYPt - cellBottomYPt
1308
1304
  });
1309
- cells.push(cell);
1310
- j = region.colEnd;
1305
+ positioned.push({
1306
+ columnIndex: j,
1307
+ cell
1308
+ });
1311
1309
  }
1312
- rows.push({
1313
- cells,
1310
+ positionedRows.push({
1311
+ cells: positioned,
1314
1312
  heightPt: lattice.rowBoundariesDescPt[i] - lattice.rowBoundariesDescPt[i + 1]
1315
1313
  });
1316
1314
  }
1315
+ const rows = (0, document_schema_js.denseTableRows)(positionedRows, columnCount);
1317
1316
  const leftXPt = lattice.columnBoundariesAscPt[0];
1318
1317
  const rightXPt = lattice.columnBoundariesAscPt[columnCount];
1319
1318
  const topYPt = lattice.rowBoundariesDescPt[0];
@@ -4,6 +4,7 @@ import { stampFrame } from "./shared.js";
4
4
  import { inferCellValue } from "./cell-typing.js";
5
5
  import { throwIfAborted } from "../ports/abort.js";
6
6
  import { detectGridLattice, findColumnIndex, findRowIndex } from "./lattice.js";
7
+ import { denseTableRows } from "document-schema.js";
7
8
  import { resolveStandardFont } from "pdf-codec/fonts";
8
9
  import { STANDARD_METRICS } from "pdf-codec/afm-widths";
9
10
  import { runGapPt, runsShareBaseline } from "pdf-codec/text-group";
@@ -1277,17 +1278,12 @@ function recoverTable(page, pageIndex) {
1277
1278
  if (consumedText.size === 0) return;
1278
1279
  const columnWidthsPt = [];
1279
1280
  for (let j = 0; j < columnCount; j++) columnWidthsPt.push(lattice.columnBoundariesAscPt[j + 1] - lattice.columnBoundariesAscPt[j]);
1280
- const rows = [];
1281
+ const positionedRows = [];
1281
1282
  for (let i = 0; i < rowCount; i++) {
1282
- const cells = [];
1283
- let j = 0;
1284
- while (j < columnCount) {
1283
+ const positioned = [];
1284
+ for (let j = 0; j < columnCount; j++) {
1285
1285
  const region = regionAt[i][j];
1286
- if (region.rowStart !== i) {
1287
- cells.push({ blocks: [] });
1288
- j = region.colEnd;
1289
- continue;
1290
- }
1286
+ if (region.rowStart !== i || region.colStart !== j) continue;
1291
1287
  const colSpan = region.colEnd - region.colStart;
1292
1288
  const rowSpan = region.rowEnd - region.rowStart;
1293
1289
  const cell = {
@@ -1305,14 +1301,17 @@ function recoverTable(page, pageIndex) {
1305
1301
  widthPt: cellRightXPt - cellLeftXPt,
1306
1302
  heightPt: cellTopYPt - cellBottomYPt
1307
1303
  });
1308
- cells.push(cell);
1309
- j = region.colEnd;
1304
+ positioned.push({
1305
+ columnIndex: j,
1306
+ cell
1307
+ });
1310
1308
  }
1311
- rows.push({
1312
- cells,
1309
+ positionedRows.push({
1310
+ cells: positioned,
1313
1311
  heightPt: lattice.rowBoundariesDescPt[i] - lattice.rowBoundariesDescPt[i + 1]
1314
1312
  });
1315
1313
  }
1314
+ const rows = denseTableRows(positionedRows, columnCount);
1316
1315
  const leftXPt = lattice.columnBoundariesAscPt[0];
1317
1316
  const rightXPt = lattice.columnBoundariesAscPt[columnCount];
1318
1317
  const topYPt = lattice.rowBoundariesDescPt[0];
@@ -212,24 +212,31 @@ function registerImage(block, images) {
212
212
  }
213
213
  return imageId;
214
214
  }
215
+ /** The sum of `span` consecutive entries of `columnWidthsPt` from `startIndex`, stopping at the end of the array: a span reaching past the last entry (a spreadsheet merge running off the edge of the printed band, or a table whose declared grid is narrower than a cell claims) contributes only the entries that exist. */
215
216
  function sumColumnWidthsPt(columnWidthsPt, startIndex, span) {
216
- let sum = 0;
217
- for (let i = startIndex; i < startIndex + span && i < columnWidthsPt.length; i++) sum += columnWidthsPt[i] ?? 0;
218
- return sum;
217
+ return columnWidthsPt.slice(startIndex, startIndex + span).reduce((sum, widthPt) => sum + widthPt, 0);
219
218
  }
220
- function estimateRowHeightPt(row, measurer, columnWidthsPt, scale) {
219
+ /**
220
+ * Pairs each row of `table` with the boxes of its anchor cells. Only anchors are boxed: a position a merged region covers is part of that region's own anchor cell, so laying it out as well would draw a second, empty cell over the region. An anchor's column is its position in the row, and its width is the sum of the column widths it spans, all multiplied by `scale`.
221
+ */
222
+ function tableAnchorBoxes(table, scale) {
223
+ const positionsByRow = (0, document_schema_js.walkTableGrid)(table);
224
+ return table.rows.map((row, rowIndex) => ({
225
+ row,
226
+ anchors: positionsByRow[rowIndex].flatMap((position) => position.anchorRowIndex === void 0 ? [{
227
+ cell: position.cell,
228
+ xOffsetPt: sumColumnWidthsPt(table.columnWidthsPt, 0, position.columnIndex) * scale,
229
+ widthPt: sumColumnWidthsPt(table.columnWidthsPt, position.columnIndex, (0, document_schema_js.tableCellColumnSpan)(position.cell)) * scale
230
+ }] : [])
231
+ }));
232
+ }
233
+ function estimateRowHeightPt(anchors, measurer) {
221
234
  let max = FALLBACK_ROW_HEIGHT_PT;
222
- let colIndex = 0;
223
- for (const cell of row.cells) {
224
- const span = cell.colSpan ?? 1;
225
- const cellWidthPt = sumColumnWidthsPt(columnWidthsPt, colIndex, span) * scale;
226
- for (const block of cell.blocks) {
227
- if (block.kind !== "paragraph") continue;
228
- const runs = effectiveStyledRuns(block.runs, 1, headingStyleFor(block.styleId));
229
- const lines = require_layout_text_layout.wrapRunsToWidth(runs, measurer, cellWidthPt);
230
- for (const line of lines) max = Math.max(max, lineNaturalHeightPt(line, measurer, runs[0]));
231
- }
232
- colIndex += span;
235
+ for (const { cell, widthPt } of anchors) for (const block of cell.blocks) {
236
+ if (block.kind !== "paragraph") continue;
237
+ const runs = effectiveStyledRuns(block.runs, 1, headingStyleFor(block.styleId));
238
+ const lines = require_layout_text_layout.wrapRunsToWidth(runs, measurer, widthPt);
239
+ for (const line of lines) max = Math.max(max, lineNaturalHeightPt(line, measurer, runs[0]));
233
240
  }
234
241
  return max;
235
242
  }
@@ -251,5 +258,6 @@ exports.runFont = runFont;
251
258
  exports.stampFragmentFrame = stampFragmentFrame;
252
259
  exports.stampFrame = stampFrame;
253
260
  exports.sumColumnWidthsPt = sumColumnWidthsPt;
261
+ exports.tableAnchorBoxes = tableAnchorBoxes;
254
262
  exports.textBoxForFragment = textBoxForFragment;
255
263
  exports.toStyledRuns = toStyledRuns;
@@ -1,5 +1,5 @@
1
1
  import { SourcedFragment, SourcedRun } from "./text-layout.cjs";
2
- import { Alignment, Box, ContentCellBorders, ContentImageBlock, ContentRun, ContentTableRow, LayoutFont, LayoutFrame, LayoutMetadata, MathFontMetrics, MathMlNode, PageSize, StyledRun, TextMeasurer, WrappedLine } from "document-schema.js";
2
+ import { Alignment, Box, ContentCellBorders, ContentImageBlock, ContentRun, ContentTable, ContentTableCell, ContentTableRow, LayoutFont, LayoutFrame, LayoutMetadata, MathFontMetrics, MathMlNode, PageSize, StyledRun, TextMeasurer, WrappedLine } from "document-schema.js";
3
3
  import { LayoutDocument, LayoutImageAsset, LayoutItem, LayoutPage, LayoutText } from "pdf-codec";
4
4
  //#region src/layout/shared.d.ts
5
5
  declare function stampFrame(node: {
@@ -36,7 +36,23 @@ declare function alignmentOffsetPt(alignment: Alignment | undefined, contentWidt
36
36
  declare function justifyLineGapsPt(line: WrappedLine, targetWidthPt: number, measurer: TextMeasurer): readonly number[];
37
37
  declare function pushCellBorderLines(borders: ContentCellBorders, frameYDown: Box, pageHeightPt: number, sourcePath: string | undefined, out: LayoutItem[]): void;
38
38
  declare function registerImage(block: ContentImageBlock, images: Record<string, LayoutImageAsset>): string;
39
+ /** The sum of `span` consecutive entries of `columnWidthsPt` from `startIndex`, stopping at the end of the array: a span reaching past the last entry (a spreadsheet merge running off the edge of the printed band, or a table whose declared grid is narrower than a cell claims) contributes only the entries that exist. */
39
40
  declare function sumColumnWidthsPt(columnWidthsPt: readonly number[], startIndex: number, span: number): number;
40
- declare function estimateRowHeightPt(row: ContentTableRow, measurer: TextMeasurer, columnWidthsPt: readonly number[], scale: number): number;
41
+ /** One anchor cell of a laid-out table row: the cell itself, its left edge measured from the table's left edge, and its width, both already scaled. */
42
+ interface TableAnchorBox {
43
+ readonly cell: ContentTableCell;
44
+ readonly xOffsetPt: number;
45
+ readonly widthPt: number;
46
+ }
47
+ /** One table row paired with the boxes of the anchor cells that are laid out in it. */
48
+ interface TableRowAnchorBoxes {
49
+ readonly row: ContentTableRow;
50
+ readonly anchors: readonly TableAnchorBox[];
51
+ }
52
+ /**
53
+ * Pairs each row of `table` with the boxes of its anchor cells. Only anchors are boxed: a position a merged region covers is part of that region's own anchor cell, so laying it out as well would draw a second, empty cell over the region. An anchor's column is its position in the row, and its width is the sum of the column widths it spans, all multiplied by `scale`.
54
+ */
55
+ declare function tableAnchorBoxes(table: ContentTable, scale: number): TableRowAnchorBoxes[];
56
+ declare function estimateRowHeightPt(anchors: readonly TableAnchorBox[], measurer: TextMeasurer): number;
41
57
  //#endregion
42
- export { HEADING_STYLES, NOMINAL_TEXT_SIZE_PT, alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, headingStyleFor, justifyLineGapsPt, layoutDocumentOf, lineNaturalHeightPt, packagePagesOf, pushCellBorderLines, registerImage, runFont, stampFragmentFrame, stampFrame, sumColumnWidthsPt, textBoxForFragment, toStyledRuns };
58
+ export { HEADING_STYLES, NOMINAL_TEXT_SIZE_PT, TableAnchorBox, TableRowAnchorBoxes, alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, headingStyleFor, justifyLineGapsPt, layoutDocumentOf, lineNaturalHeightPt, packagePagesOf, pushCellBorderLines, registerImage, runFont, stampFragmentFrame, stampFrame, sumColumnWidthsPt, tableAnchorBoxes, textBoxForFragment, toStyledRuns };
@@ -1,5 +1,5 @@
1
1
  import { SourcedFragment, SourcedRun } from "./text-layout.js";
2
- import { Alignment, Box, ContentCellBorders, ContentImageBlock, ContentRun, ContentTableRow, LayoutFont, LayoutFrame, LayoutMetadata, MathFontMetrics, MathMlNode, PageSize, StyledRun, TextMeasurer, WrappedLine } from "document-schema.js";
2
+ import { Alignment, Box, ContentCellBorders, ContentImageBlock, ContentRun, ContentTable, ContentTableCell, ContentTableRow, LayoutFont, LayoutFrame, LayoutMetadata, MathFontMetrics, MathMlNode, PageSize, StyledRun, TextMeasurer, WrappedLine } from "document-schema.js";
3
3
  import { LayoutDocument, LayoutImageAsset, LayoutItem, LayoutPage, LayoutText } from "pdf-codec";
4
4
  //#region src/layout/shared.d.ts
5
5
  declare function stampFrame(node: {
@@ -36,7 +36,23 @@ declare function alignmentOffsetPt(alignment: Alignment | undefined, contentWidt
36
36
  declare function justifyLineGapsPt(line: WrappedLine, targetWidthPt: number, measurer: TextMeasurer): readonly number[];
37
37
  declare function pushCellBorderLines(borders: ContentCellBorders, frameYDown: Box, pageHeightPt: number, sourcePath: string | undefined, out: LayoutItem[]): void;
38
38
  declare function registerImage(block: ContentImageBlock, images: Record<string, LayoutImageAsset>): string;
39
+ /** The sum of `span` consecutive entries of `columnWidthsPt` from `startIndex`, stopping at the end of the array: a span reaching past the last entry (a spreadsheet merge running off the edge of the printed band, or a table whose declared grid is narrower than a cell claims) contributes only the entries that exist. */
39
40
  declare function sumColumnWidthsPt(columnWidthsPt: readonly number[], startIndex: number, span: number): number;
40
- declare function estimateRowHeightPt(row: ContentTableRow, measurer: TextMeasurer, columnWidthsPt: readonly number[], scale: number): number;
41
+ /** One anchor cell of a laid-out table row: the cell itself, its left edge measured from the table's left edge, and its width, both already scaled. */
42
+ interface TableAnchorBox {
43
+ readonly cell: ContentTableCell;
44
+ readonly xOffsetPt: number;
45
+ readonly widthPt: number;
46
+ }
47
+ /** One table row paired with the boxes of the anchor cells that are laid out in it. */
48
+ interface TableRowAnchorBoxes {
49
+ readonly row: ContentTableRow;
50
+ readonly anchors: readonly TableAnchorBox[];
51
+ }
52
+ /**
53
+ * Pairs each row of `table` with the boxes of its anchor cells. Only anchors are boxed: a position a merged region covers is part of that region's own anchor cell, so laying it out as well would draw a second, empty cell over the region. An anchor's column is its position in the row, and its width is the sum of the column widths it spans, all multiplied by `scale`.
54
+ */
55
+ declare function tableAnchorBoxes(table: ContentTable, scale: number): TableRowAnchorBoxes[];
56
+ declare function estimateRowHeightPt(anchors: readonly TableAnchorBox[], measurer: TextMeasurer): number;
41
57
  //#endregion
42
- export { HEADING_STYLES, NOMINAL_TEXT_SIZE_PT, alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, headingStyleFor, justifyLineGapsPt, layoutDocumentOf, lineNaturalHeightPt, packagePagesOf, pushCellBorderLines, registerImage, runFont, stampFragmentFrame, stampFrame, sumColumnWidthsPt, textBoxForFragment, toStyledRuns };
58
+ export { HEADING_STYLES, NOMINAL_TEXT_SIZE_PT, TableAnchorBox, TableRowAnchorBoxes, alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, headingStyleFor, justifyLineGapsPt, layoutDocumentOf, lineNaturalHeightPt, packagePagesOf, pushCellBorderLines, registerImage, runFont, stampFragmentFrame, stampFrame, sumColumnWidthsPt, tableAnchorBoxes, textBoxForFragment, toStyledRuns };
@@ -1,7 +1,7 @@
1
1
  import { layoutFormula } from "../mathml/layout.js";
2
2
  import { wrapRunsToWidth } from "./text-layout.js";
3
3
  import { base64ToBytes } from "ooxml.js";
4
- import { COLOR_BLACK, DEFAULT_LAYOUT_FONT } from "document-schema.js";
4
+ import { COLOR_BLACK, DEFAULT_LAYOUT_FONT, tableCellColumnSpan, walkTableGrid } from "document-schema.js";
5
5
  import { crc32, decodePng, readJpegInfo } from "byte-codec";
6
6
  import { LAYOUT_FORMAT_VERSION } from "pdf-codec/layout";
7
7
  //#region src/layout/shared.ts
@@ -211,26 +211,33 @@ function registerImage(block, images) {
211
211
  }
212
212
  return imageId;
213
213
  }
214
+ /** The sum of `span` consecutive entries of `columnWidthsPt` from `startIndex`, stopping at the end of the array: a span reaching past the last entry (a spreadsheet merge running off the edge of the printed band, or a table whose declared grid is narrower than a cell claims) contributes only the entries that exist. */
214
215
  function sumColumnWidthsPt(columnWidthsPt, startIndex, span) {
215
- let sum = 0;
216
- for (let i = startIndex; i < startIndex + span && i < columnWidthsPt.length; i++) sum += columnWidthsPt[i] ?? 0;
217
- return sum;
216
+ return columnWidthsPt.slice(startIndex, startIndex + span).reduce((sum, widthPt) => sum + widthPt, 0);
217
+ }
218
+ /**
219
+ * Pairs each row of `table` with the boxes of its anchor cells. Only anchors are boxed: a position a merged region covers is part of that region's own anchor cell, so laying it out as well would draw a second, empty cell over the region. An anchor's column is its position in the row, and its width is the sum of the column widths it spans, all multiplied by `scale`.
220
+ */
221
+ function tableAnchorBoxes(table, scale) {
222
+ const positionsByRow = walkTableGrid(table);
223
+ return table.rows.map((row, rowIndex) => ({
224
+ row,
225
+ anchors: positionsByRow[rowIndex].flatMap((position) => position.anchorRowIndex === void 0 ? [{
226
+ cell: position.cell,
227
+ xOffsetPt: sumColumnWidthsPt(table.columnWidthsPt, 0, position.columnIndex) * scale,
228
+ widthPt: sumColumnWidthsPt(table.columnWidthsPt, position.columnIndex, tableCellColumnSpan(position.cell)) * scale
229
+ }] : [])
230
+ }));
218
231
  }
219
- function estimateRowHeightPt(row, measurer, columnWidthsPt, scale) {
232
+ function estimateRowHeightPt(anchors, measurer) {
220
233
  let max = FALLBACK_ROW_HEIGHT_PT;
221
- let colIndex = 0;
222
- for (const cell of row.cells) {
223
- const span = cell.colSpan ?? 1;
224
- const cellWidthPt = sumColumnWidthsPt(columnWidthsPt, colIndex, span) * scale;
225
- for (const block of cell.blocks) {
226
- if (block.kind !== "paragraph") continue;
227
- const runs = effectiveStyledRuns(block.runs, 1, headingStyleFor(block.styleId));
228
- const lines = wrapRunsToWidth(runs, measurer, cellWidthPt);
229
- for (const line of lines) max = Math.max(max, lineNaturalHeightPt(line, measurer, runs[0]));
230
- }
231
- colIndex += span;
234
+ for (const { cell, widthPt } of anchors) for (const block of cell.blocks) {
235
+ if (block.kind !== "paragraph") continue;
236
+ const runs = effectiveStyledRuns(block.runs, 1, headingStyleFor(block.styleId));
237
+ const lines = wrapRunsToWidth(runs, measurer, widthPt);
238
+ for (const line of lines) max = Math.max(max, lineNaturalHeightPt(line, measurer, runs[0]));
232
239
  }
233
240
  return max;
234
241
  }
235
242
  //#endregion
236
- export { HEADING_STYLES, NOMINAL_TEXT_SIZE_PT, alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, headingStyleFor, justifyLineGapsPt, layoutDocumentOf, lineNaturalHeightPt, packagePagesOf, pushCellBorderLines, registerImage, runFont, stampFragmentFrame, stampFrame, sumColumnWidthsPt, textBoxForFragment, toStyledRuns };
243
+ export { HEADING_STYLES, NOMINAL_TEXT_SIZE_PT, alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, headingStyleFor, justifyLineGapsPt, layoutDocumentOf, lineNaturalHeightPt, packagePagesOf, pushCellBorderLines, registerImage, runFont, stampFragmentFrame, stampFrame, sumColumnWidthsPt, tableAnchorBoxes, textBoxForFragment, toStyledRuns };
@@ -81,13 +81,10 @@ function layoutTable(table, contentLeftXDown, contentWidthPt, startYDown, slideH
81
81
  let cursorYDown = startYDown;
82
82
  const gridWidthPt = table.columnWidthsPt.reduce((sum, w) => sum + w, 0);
83
83
  const scale = gridWidthPt > 0 ? contentWidthPt / gridWidthPt : 1;
84
- for (const row of table.rows) {
85
- const rowHeightPt = row.heightPt ?? require_layout_shared.estimateRowHeightPt(row, measurer, table.columnWidthsPt, scale);
86
- let cellXDown = contentLeftXDown;
87
- let colIndex = 0;
88
- for (const cell of row.cells) {
89
- const span = cell.colSpan ?? 1;
90
- const cellWidthPt = require_layout_shared.sumColumnWidthsPt(table.columnWidthsPt, colIndex, span) * scale;
84
+ for (const { row, anchors } of require_layout_shared.tableAnchorBoxes(table, scale)) {
85
+ const rowHeightPt = row.heightPt ?? require_layout_shared.estimateRowHeightPt(anchors, measurer);
86
+ for (const { cell, xOffsetPt, widthPt: cellWidthPt } of anchors) {
87
+ const cellXDown = contentLeftXDown + xOffsetPt;
91
88
  const cellFrame = require_model_geometry.flipY({
92
89
  xPt: cellXDown,
93
90
  yPt: cursorYDown,
@@ -107,8 +104,6 @@ function layoutTable(table, contentLeftXDown, contentWidthPt, startYDown, slideH
107
104
  });
108
105
  let cellCursorYDown = cursorYDown;
109
106
  for (const block of cell.blocks) if (block.kind === "paragraph") cellCursorYDown = layoutParagraph(block, cellXDown, cellWidthPt, cellCursorYDown, slideHeightPt, pageIndex, placement, 1, 1, measurer, out);
110
- cellXDown += cellWidthPt;
111
- colIndex += span;
112
107
  }
113
108
  cursorYDown += rowHeightPt;
114
109
  }
@@ -2,7 +2,7 @@ import { flipY, rotatePointAboutCenter } from "../model/geometry.js";
2
2
  import { formulaOfBlock } from "../model/formula.js";
3
3
  import { layoutFormula } from "../mathml/layout.js";
4
4
  import { wrapRunsToWidth } from "./text-layout.js";
5
- import { alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, justifyLineGapsPt, layoutDocumentOf, lineNaturalHeightPt, packagePagesOf, registerImage, stampFragmentFrame, stampFrame, sumColumnWidthsPt } from "./shared.js";
5
+ import { alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, justifyLineGapsPt, layoutDocumentOf, lineNaturalHeightPt, packagePagesOf, registerImage, stampFragmentFrame, stampFrame, tableAnchorBoxes } from "./shared.js";
6
6
  import { COLOR_BLACK, resolveCellFillColor } from "document-schema.js";
7
7
  //#region src/layout/slides.ts
8
8
  function shapePlacement(flippedFrame, rotationDeg) {
@@ -80,13 +80,10 @@ function layoutTable(table, contentLeftXDown, contentWidthPt, startYDown, slideH
80
80
  let cursorYDown = startYDown;
81
81
  const gridWidthPt = table.columnWidthsPt.reduce((sum, w) => sum + w, 0);
82
82
  const scale = gridWidthPt > 0 ? contentWidthPt / gridWidthPt : 1;
83
- for (const row of table.rows) {
84
- const rowHeightPt = row.heightPt ?? estimateRowHeightPt(row, measurer, table.columnWidthsPt, scale);
85
- let cellXDown = contentLeftXDown;
86
- let colIndex = 0;
87
- for (const cell of row.cells) {
88
- const span = cell.colSpan ?? 1;
89
- const cellWidthPt = sumColumnWidthsPt(table.columnWidthsPt, colIndex, span) * scale;
83
+ for (const { row, anchors } of tableAnchorBoxes(table, scale)) {
84
+ const rowHeightPt = row.heightPt ?? estimateRowHeightPt(anchors, measurer);
85
+ for (const { cell, xOffsetPt, widthPt: cellWidthPt } of anchors) {
86
+ const cellXDown = contentLeftXDown + xOffsetPt;
90
87
  const cellFrame = flipY({
91
88
  xPt: cellXDown,
92
89
  yPt: cursorYDown,
@@ -106,8 +103,6 @@ function layoutTable(table, contentLeftXDown, contentWidthPt, startYDown, slideH
106
103
  });
107
104
  let cellCursorYDown = cursorYDown;
108
105
  for (const block of cell.blocks) if (block.kind === "paragraph") cellCursorYDown = layoutParagraph(block, cellXDown, cellWidthPt, cellCursorYDown, slideHeightPt, pageIndex, placement, 1, 1, measurer, out);
109
- cellXDown += cellWidthPt;
110
- colIndex += span;
111
106
  }
112
107
  cursorYDown += rowHeightPt;
113
108
  }
@@ -9,6 +9,7 @@ const require_model_block_splice = require("../../model/block-splice.cjs");
9
9
  const require_ooxml_docx_vector = require("./vector.cjs");
10
10
  const require_ooxml_docx_formula = require("./formula.cjs");
11
11
  let ooxml_js = require("ooxml.js");
12
+ let document_schema_js = require("document-schema.js");
12
13
  //#region src/ooxml/docx/embedded-objects.ts
13
14
  function isVectorOnlyRun(run, vectors) {
14
15
  const elementChildren = run.children.filter((child) => child.type === "element");
@@ -153,7 +154,7 @@ function spliceContainerBlocks(blocks, containerChildren, pageSize, sourcePathPr
153
154
  paragraphOrdinal += 1;
154
155
  if (paragraph === void 0) return block;
155
156
  const { placements: paragraphPlacements, consume } = paragraphEmbeddings(block, paragraph, blockIndex, rels, pkg, onMathDiagnostic);
156
- if (paragraphPlacements.length > 0) placements.push(...paragraphPlacements);
157
+ placements.push(...paragraphPlacements);
157
158
  if (consume) consumedIndices.add(blockIndex);
158
159
  return block;
159
160
  }
@@ -165,18 +166,27 @@ function spliceContainerBlocks(blocks, containerChildren, pageSize, sourcePathPr
165
166
  }
166
167
  return block;
167
168
  });
168
- if (!(consumedIndices.size > 0 || rebuiltBlocks.some((block, index) => block !== blocks[index])) && placements.length === 0) return [...blocks];
169
+ if (!(consumedIndices.size > 0 || rebuiltBlocks.some((block, index) => block !== blocks[index])) && placements.length === 0) return blocks;
169
170
  return require_model_block_splice.spliceBlocks(rebuiltBlocks, placements, consumedIndices, (position) => `${sourcePathPrefix}[${position}]`);
170
171
  }
172
+ function isBackedByTableCellElement(position) {
173
+ return position.anchorRowIndex === void 0 || position.columnIndex === position.anchorColumnIndex;
174
+ }
171
175
  function rebuildTable(table, tblElement, pageSize, blockPath, rels, pkg, onMathDiagnostic) {
172
176
  const rowElements = (0, ooxml_js.childrenWithTag)(tblElement, "w:tr");
177
+ const positionsByRow = (0, document_schema_js.walkTableGrid)(table);
173
178
  const rows = table.rows.map((row, rowIndex) => {
174
179
  const rowElement = rowElements[rowIndex];
175
180
  const cellElements = rowElement === void 0 ? [] : (0, ooxml_js.childrenWithTag)(rowElement, "w:tc");
176
- const cells = row.cells.map((cell, cellIndex) => {
177
- const cellElement = cellElements[cellIndex];
181
+ const cellElementByColumn = /* @__PURE__ */ new Map();
182
+ positionsByRow[rowIndex].filter(isBackedByTableCellElement).forEach((position, ordinal) => {
183
+ const cellElement = cellElements[ordinal];
184
+ if (cellElement !== void 0) cellElementByColumn.set(position.columnIndex, cellElement);
185
+ });
186
+ const cells = row.cells.map((cell, columnIndex) => {
187
+ const cellElement = cellElementByColumn.get(columnIndex);
178
188
  if (cellElement === void 0) return cell;
179
- const blocks = spliceContainerBlocks(cell.blocks, cellElement.children, pageSize, `${blockPath}.rows[${rowIndex}].cells[${cellIndex}].blocks`, rels, pkg, onMathDiagnostic);
189
+ const blocks = spliceContainerBlocks(cell.blocks, cellElement.children, pageSize, `${blockPath}.rows[${rowIndex}].cells[${columnIndex}].blocks`, rels, pkg, onMathDiagnostic);
180
190
  return blocks === cell.blocks ? cell : {
181
191
  ...cell,
182
192
  blocks
@@ -210,7 +220,7 @@ function spliceDocxEmbeddedObjects(sections, bodyChildren, pkg, onMathDiagnostic
210
220
  paragraphOrdinal += 1;
211
221
  if (paragraph === void 0) return block;
212
222
  const { placements: paragraphPlacements, consume } = paragraphEmbeddings(block, paragraph, blockIndex, rels, pkg, onMathDiagnostic);
213
- if (paragraphPlacements.length > 0) placements.push(...paragraphPlacements);
223
+ placements.push(...paragraphPlacements);
214
224
  if (consume) consumedIndices.add(blockIndex);
215
225
  return block;
216
226
  }
@@ -218,7 +228,7 @@ function spliceDocxEmbeddedObjects(sections, bodyChildren, pkg, onMathDiagnostic
218
228
  const tableElement = tableElements[tableOrdinal];
219
229
  tableOrdinal += 1;
220
230
  if (tableElement === void 0) return block;
221
- return rebuildTable(block, tableElement, section.pageSize, `sections[${sectionIndex}].blocks`, rels, pkg, onMathDiagnostic);
231
+ return rebuildTable(block, tableElement, section.pageSize, `sections[${sectionIndex}].blocks[${blockIndex}]`, rels, pkg, onMathDiagnostic);
222
232
  }
223
233
  return block;
224
234
  });
@@ -8,6 +8,7 @@ import { spliceBlocks } from "../../model/block-splice.js";
8
8
  import { collectParagraphVectors } from "./vector.js";
9
9
  import { PARAGRAPH_NON_CONTENT_TAGS, collectBodyParagraphs, collectBodyTables, equationFrame } from "./formula.js";
10
10
  import { attr, base64ToBytes, childrenWithTag, elementsWithTag, resolveRelationships } from "ooxml.js";
11
+ import { walkTableGrid } from "document-schema.js";
11
12
  //#region src/ooxml/docx/embedded-objects.ts
12
13
  function isVectorOnlyRun(run, vectors) {
13
14
  const elementChildren = run.children.filter((child) => child.type === "element");
@@ -152,7 +153,7 @@ function spliceContainerBlocks(blocks, containerChildren, pageSize, sourcePathPr
152
153
  paragraphOrdinal += 1;
153
154
  if (paragraph === void 0) return block;
154
155
  const { placements: paragraphPlacements, consume } = paragraphEmbeddings(block, paragraph, blockIndex, rels, pkg, onMathDiagnostic);
155
- if (paragraphPlacements.length > 0) placements.push(...paragraphPlacements);
156
+ placements.push(...paragraphPlacements);
156
157
  if (consume) consumedIndices.add(blockIndex);
157
158
  return block;
158
159
  }
@@ -164,18 +165,27 @@ function spliceContainerBlocks(blocks, containerChildren, pageSize, sourcePathPr
164
165
  }
165
166
  return block;
166
167
  });
167
- if (!(consumedIndices.size > 0 || rebuiltBlocks.some((block, index) => block !== blocks[index])) && placements.length === 0) return [...blocks];
168
+ if (!(consumedIndices.size > 0 || rebuiltBlocks.some((block, index) => block !== blocks[index])) && placements.length === 0) return blocks;
168
169
  return spliceBlocks(rebuiltBlocks, placements, consumedIndices, (position) => `${sourcePathPrefix}[${position}]`);
169
170
  }
171
+ function isBackedByTableCellElement(position) {
172
+ return position.anchorRowIndex === void 0 || position.columnIndex === position.anchorColumnIndex;
173
+ }
170
174
  function rebuildTable(table, tblElement, pageSize, blockPath, rels, pkg, onMathDiagnostic) {
171
175
  const rowElements = childrenWithTag(tblElement, "w:tr");
176
+ const positionsByRow = walkTableGrid(table);
172
177
  const rows = table.rows.map((row, rowIndex) => {
173
178
  const rowElement = rowElements[rowIndex];
174
179
  const cellElements = rowElement === void 0 ? [] : childrenWithTag(rowElement, "w:tc");
175
- const cells = row.cells.map((cell, cellIndex) => {
176
- const cellElement = cellElements[cellIndex];
180
+ const cellElementByColumn = /* @__PURE__ */ new Map();
181
+ positionsByRow[rowIndex].filter(isBackedByTableCellElement).forEach((position, ordinal) => {
182
+ const cellElement = cellElements[ordinal];
183
+ if (cellElement !== void 0) cellElementByColumn.set(position.columnIndex, cellElement);
184
+ });
185
+ const cells = row.cells.map((cell, columnIndex) => {
186
+ const cellElement = cellElementByColumn.get(columnIndex);
177
187
  if (cellElement === void 0) return cell;
178
- const blocks = spliceContainerBlocks(cell.blocks, cellElement.children, pageSize, `${blockPath}.rows[${rowIndex}].cells[${cellIndex}].blocks`, rels, pkg, onMathDiagnostic);
188
+ const blocks = spliceContainerBlocks(cell.blocks, cellElement.children, pageSize, `${blockPath}.rows[${rowIndex}].cells[${columnIndex}].blocks`, rels, pkg, onMathDiagnostic);
179
189
  return blocks === cell.blocks ? cell : {
180
190
  ...cell,
181
191
  blocks
@@ -209,7 +219,7 @@ function spliceDocxEmbeddedObjects(sections, bodyChildren, pkg, onMathDiagnostic
209
219
  paragraphOrdinal += 1;
210
220
  if (paragraph === void 0) return block;
211
221
  const { placements: paragraphPlacements, consume } = paragraphEmbeddings(block, paragraph, blockIndex, rels, pkg, onMathDiagnostic);
212
- if (paragraphPlacements.length > 0) placements.push(...paragraphPlacements);
222
+ placements.push(...paragraphPlacements);
213
223
  if (consume) consumedIndices.add(blockIndex);
214
224
  return block;
215
225
  }
@@ -217,7 +227,7 @@ function spliceDocxEmbeddedObjects(sections, bodyChildren, pkg, onMathDiagnostic
217
227
  const tableElement = tableElements[tableOrdinal];
218
228
  tableOrdinal += 1;
219
229
  if (tableElement === void 0) return block;
220
- return rebuildTable(block, tableElement, section.pageSize, `sections[${sectionIndex}].blocks`, rels, pkg, onMathDiagnostic);
230
+ return rebuildTable(block, tableElement, section.pageSize, `sections[${sectionIndex}].blocks[${blockIndex}]`, rels, pkg, onMathDiagnostic);
221
231
  }
222
232
  return block;
223
233
  });
@@ -29,6 +29,15 @@ declare class OdtTableCell {
29
29
  get borders(): ContentCellBorders | undefined;
30
30
  set borders(value: ContentCellBorders | undefined);
31
31
  }
32
+ declare class OdtCoveredTableCell {
33
+ private readonly node;
34
+ private readonly pkg;
35
+ constructor(node: XmlElement, pkg: Package);
36
+ get background(): Color | undefined;
37
+ set background(value: Color | undefined);
38
+ get borders(): ContentCellBorders | undefined;
39
+ set borders(value: ContentCellBorders | undefined);
40
+ }
32
41
  declare class OdtTableRow {
33
42
  private readonly node;
34
43
  private readonly pkg;
@@ -37,7 +46,7 @@ declare class OdtTableRow {
37
46
  get heightPt(): number | undefined;
38
47
  set heightPt(value: number | undefined);
39
48
  appendCell(): OdtTableCell;
40
- appendCoveredCell(): void;
49
+ appendCoveredCell(): OdtCoveredTableCell;
41
50
  private gridCells;
42
51
  mergeCellsHorizontally(startColumnIndex: number, colSpan: number): OdtTableCell;
43
52
  markCellCovered(columnIndex: number): void;
@@ -58,4 +67,4 @@ declare class OdtTable {
58
67
  }
59
68
  declare function buildTable(pkg: Package, init: TableInit): XmlElement;
60
69
  //#endregion
61
- export { TableInit as a, readCellDecoration as c, OdtTableRow as i, OdtTable as n, buildCellStyle as o, OdtTableCell as r, buildTable as s, CellDecoration as t };
70
+ export { OdtTableRow as a, buildTable as c, OdtTableCell as i, readCellDecoration as l, OdtCoveredTableCell as n, TableInit as o, OdtTable as r, buildCellStyle as s, CellDecoration as t };
@@ -29,6 +29,15 @@ declare class OdtTableCell {
29
29
  get borders(): ContentCellBorders | undefined;
30
30
  set borders(value: ContentCellBorders | undefined);
31
31
  }
32
+ declare class OdtCoveredTableCell {
33
+ private readonly node;
34
+ private readonly pkg;
35
+ constructor(node: XmlElement, pkg: Package);
36
+ get background(): Color | undefined;
37
+ set background(value: Color | undefined);
38
+ get borders(): ContentCellBorders | undefined;
39
+ set borders(value: ContentCellBorders | undefined);
40
+ }
32
41
  declare class OdtTableRow {
33
42
  private readonly node;
34
43
  private readonly pkg;
@@ -37,7 +46,7 @@ declare class OdtTableRow {
37
46
  get heightPt(): number | undefined;
38
47
  set heightPt(value: number | undefined);
39
48
  appendCell(): OdtTableCell;
40
- appendCoveredCell(): void;
49
+ appendCoveredCell(): OdtCoveredTableCell;
41
50
  private gridCells;
42
51
  mergeCellsHorizontally(startColumnIndex: number, colSpan: number): OdtTableCell;
43
52
  markCellCovered(columnIndex: number): void;
@@ -58,4 +67,4 @@ declare class OdtTable {
58
67
  }
59
68
  declare function buildTable(pkg: Package, init: TableInit): XmlElement;
60
69
  //#endregion
61
- export { TableInit as a, readCellDecoration as c, OdtTableRow as i, OdtTable as n, buildCellStyle as o, OdtTableCell as r, buildTable as s, CellDecoration as t };
70
+ export { OdtTableRow as a, buildTable as c, OdtTableCell as i, readCellDecoration as l, OdtCoveredTableCell as n, TableInit as o, OdtTable as r, buildCellStyle as s, CellDecoration as t };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js.documents",
3
- "version": "7.20.35",
3
+ "version": "8.0.0",
4
4
  "description": "Bidirectional docx/pptx <-> PDF conversion and a read+write editable OOXML document model, built on ooxml.js and Zod 4 codecs.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -77,21 +77,21 @@
77
77
  ],
78
78
  "license": "MIT",
79
79
  "dependencies": {
80
- "archive-codec": "1.11.7",
80
+ "archive-codec": "1.11.8",
81
81
  "byte-codec": "1.6.3",
82
- "doc-codec": "3.0.1",
83
- "document-schema.js": "7.11.5",
84
- "epub-codec": "2.0.1",
82
+ "doc-codec": "4.0.0",
83
+ "document-schema.js": "7.12.0",
84
+ "epub-codec": "3.0.0",
85
85
  "fflate": "0.8.3",
86
- "markdown-codec": "7.0.1",
87
- "odf.js": "8.0.1",
88
- "ooxml.js": "9.1.2",
89
- "pdf-codec": "5.1.0",
90
- "ppt-codec": "2.0.1",
91
- "rtf-codec": "5.0.1",
86
+ "markdown-codec": "8.0.0",
87
+ "odf.js": "8.0.2",
88
+ "ooxml.js": "10.0.0",
89
+ "pdf-codec": "5.2.1",
90
+ "ppt-codec": "2.0.2",
91
+ "rtf-codec": "6.0.0",
92
92
  "temml": "0.13.4",
93
- "wpd-codec": "4.0.1",
94
- "xls-codec": "4.15.12",
93
+ "wpd-codec": "5.0.0",
94
+ "xls-codec": "4.15.13",
95
95
  "zod": "4.4.3"
96
96
  },
97
97
  "devDependencies": {