documents.js 4.4.8 → 4.6.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 (62) hide show
  1. package/README.md +12 -2
  2. package/dist/convert/convert.cjs +1 -1
  3. package/dist/convert/convert.js +1 -1
  4. package/dist/convert/pdf-package-tables.cjs +15 -0
  5. package/dist/convert/pdf-package-tables.js +15 -0
  6. package/dist/edit/odg/content.cjs +1 -1
  7. package/dist/edit/odg/content.js +1 -1
  8. package/dist/edit/odg/page.d.cts +1 -1
  9. package/dist/edit/odg/page.d.ts +1 -1
  10. package/dist/edit/odp/content.cjs +1 -1
  11. package/dist/edit/odp/content.js +1 -1
  12. package/dist/edit/odp/shape.d.cts +1 -1
  13. package/dist/edit/odp/shape.d.ts +1 -1
  14. package/dist/edit/odp/slide.d.cts +2 -2
  15. package/dist/edit/odp/slide.d.ts +2 -2
  16. package/dist/edit/ods/cell.cjs +1 -1
  17. package/dist/edit/ods/cell.js +1 -1
  18. package/dist/edit/odt/content.cjs +10 -8
  19. package/dist/edit/odt/content.d.cts +7 -4
  20. package/dist/edit/odt/content.d.ts +7 -4
  21. package/dist/edit/odt/content.js +10 -8
  22. package/dist/edit/odt/editor.cjs +1 -1
  23. package/dist/edit/odt/editor.d.cts +3 -3
  24. package/dist/edit/odt/editor.d.ts +3 -3
  25. package/dist/edit/odt/editor.js +1 -1
  26. package/dist/edit/odt/list.cjs +1 -1
  27. package/dist/edit/odt/list.d.cts +1 -1
  28. package/dist/edit/odt/list.d.ts +1 -1
  29. package/dist/edit/odt/list.js +1 -1
  30. package/dist/edit/odt/paragraph.cjs +22 -1
  31. package/dist/edit/odt/paragraph.d.cts +1 -1
  32. package/dist/edit/odt/paragraph.d.ts +1 -1
  33. package/dist/edit/odt/paragraph.js +22 -1
  34. package/dist/edit/odt/scaffold.cjs +12 -1
  35. package/dist/edit/odt/scaffold.js +12 -1
  36. package/dist/edit/odt/table.d.cts +1 -1
  37. package/dist/edit/odt/table.d.ts +1 -1
  38. package/dist/edit/pptx/content.cjs +2 -0
  39. package/dist/edit/pptx/content.d.cts +3 -2
  40. package/dist/edit/pptx/content.d.ts +3 -2
  41. package/dist/edit/pptx/content.js +3 -2
  42. package/dist/index.cjs +2 -1
  43. package/dist/index.d.cts +6 -6
  44. package/dist/index.d.ts +6 -6
  45. package/dist/index.js +3 -3
  46. package/dist/layout/drawing.cjs +1 -1
  47. package/dist/layout/drawing.js +1 -1
  48. package/dist/layout/reconstruct.cjs +263 -47
  49. package/dist/layout/reconstruct.js +263 -47
  50. package/dist/layout/shared.cjs +1 -0
  51. package/dist/layout/shared.d.cts +5 -1
  52. package/dist/layout/shared.d.ts +5 -1
  53. package/dist/layout/shared.js +1 -1
  54. package/dist/{list-D9MtQtjK.d.ts → list-Cg_zlwVv.d.ts} +1 -1
  55. package/dist/{list-BT1Zb3PV.d.cts → list-CzGRStUr.d.cts} +1 -1
  56. package/dist/{paragraph-CdGRPSYA.d.cts → paragraph-C9jf4pMK.d.cts} +3 -0
  57. package/dist/{paragraph-BPRc-VVV.d.ts → paragraph-CeFnOpEi.d.ts} +3 -0
  58. package/dist/{shape-Cuk0RTZn.d.cts → shape-C56METn9.d.cts} +2 -2
  59. package/dist/{shape-CCPBGhbV.d.ts → shape-JrdFW78K.d.ts} +2 -2
  60. package/dist/{table-Dtml8NyR.d.ts → table-CY1ChByv.d.ts} +1 -1
  61. package/dist/{table-b9-ipGtZ.d.cts → table-Cu8f1XmW.d.cts} +1 -1
  62. package/package.json +2 -2
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_model_geometry = require("../model/geometry.cjs");
3
3
  const require_model_embedded_drawing = require("../model/embedded-drawing.cjs");
4
- const require_layout_cell_typing = require("./cell-typing.cjs");
5
4
  const require_layout_shared = require("./shared.cjs");
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
8
  let pdf_codec_fonts = require("pdf-codec/fonts");
@@ -136,19 +136,20 @@ function reconstructWordprocessing(doc, options) {
136
136
  const signal = options?.signal;
137
137
  doc = dropHiddenLayerContent(doc);
138
138
  const headingLevels = headingSizeLevels(doc);
139
+ const structure = indexStructure(doc);
139
140
  const sections = [];
140
141
  let currentGroup = [];
141
142
  let groupStartPageIndex = 0;
142
143
  for (const page of doc.pages) {
143
144
  require_ports_abort.throwIfAborted(signal);
144
145
  if (currentGroup.length > 0 && !samePageSize(currentGroup[0], page)) {
145
- sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form));
146
+ sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form, structure));
146
147
  groupStartPageIndex += currentGroup.length;
147
148
  currentGroup = [];
148
149
  }
149
150
  currentGroup.push(page);
150
151
  }
151
- if (currentGroup.length > 0) sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form));
152
+ if (currentGroup.length > 0) sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form, structure));
152
153
  return {
153
154
  kind: "wordprocessing",
154
155
  metadata: doc.metadata,
@@ -169,6 +170,59 @@ function dropHiddenLayerContent(doc) {
169
170
  }))
170
171
  };
171
172
  }
173
+ const HEADING_LEVELS = /* @__PURE__ */ new Map([
174
+ ["H1", 1],
175
+ ["H2", 2],
176
+ ["H3", 3],
177
+ ["H4", 4],
178
+ ["H5", 5],
179
+ ["H6", 6]
180
+ ]);
181
+ const DIVISION_TYPES = /* @__PURE__ */ new Set([
182
+ "Part",
183
+ "Sect",
184
+ "Div"
185
+ ]);
186
+ const CELL_TYPES = /* @__PURE__ */ new Set(["TD", "TH"]);
187
+ const ROW_TYPES = /* @__PURE__ */ new Set(["TR"]);
188
+ const TABLE_TYPES = /* @__PURE__ */ new Set(["Table"]);
189
+ function indexStructure(doc) {
190
+ if (doc.structure === void 0 || doc.structure.length === 0) return;
191
+ const byId = /* @__PURE__ */ new Map();
192
+ let order = 0;
193
+ const walk = (element, parent) => {
194
+ const node = {
195
+ id: element.id,
196
+ type: element.type,
197
+ parent,
198
+ order: order++
199
+ };
200
+ byId.set(element.id, node);
201
+ for (const child of element.children) walk(child, node);
202
+ };
203
+ for (const root of doc.structure) walk(root, void 0);
204
+ return { nodeOfItem: (item) => item.kind === "link" || item.kind === "internalLink" ? void 0 : byId.get(item.structure ?? "") };
205
+ }
206
+ function nearestOfType(node, types) {
207
+ for (let current = node; current !== void 0; current = current.parent) if (types.has(current.type)) return current;
208
+ }
209
+ function nearestHeadingLevel(node) {
210
+ for (let current = node; current !== void 0; current = current.parent) {
211
+ const level = HEADING_LEVELS.get(current.type);
212
+ if (level !== void 0) return level;
213
+ }
214
+ }
215
+ function structureHeadingLevel(items, structure) {
216
+ if (items.length === 0 || items.some((item) => structure.nodeOfItem(item) === void 0)) return;
217
+ let level;
218
+ for (const item of items) {
219
+ const itemLevel = nearestHeadingLevel(structure.nodeOfItem(item));
220
+ if (itemLevel === void 0) return { level: void 0 };
221
+ if (level === void 0) level = itemLevel;
222
+ else if (level !== itemLevel) return;
223
+ }
224
+ return { level };
225
+ }
172
226
  const HEADING_MIN_SIZE_DELTA_PT = 2;
173
227
  const MAX_HEADING_LEVEL = 6;
174
228
  function headingSizeLevels(doc) {
@@ -193,11 +247,12 @@ function headingLevelOf(paragraph, levels) {
193
247
  function samePageSize(a, b) {
194
248
  return a.widthPt === b.widthPt && a.heightPt === b.heightPt;
195
249
  }
196
- function buildSection(pages, startPageIndex, images, headingLevels, form) {
250
+ function buildSection(pages, startPageIndex, images, headingLevels, form, structure) {
197
251
  const blocks = [];
252
+ const divisionByBlock = /* @__PURE__ */ new WeakMap();
198
253
  pages.forEach((page, i) => {
199
254
  if (i > 0) blocks.push({ kind: "pageBreak" });
200
- blocks.push(...reconstructPageBlocks(page, startPageIndex + i, images, headingLevels, form));
255
+ blocks.push(...reconstructPageBlocks(page, startPageIndex + i, images, headingLevels, form, structure, divisionByBlock));
201
256
  });
202
257
  return {
203
258
  pageSize: {
@@ -205,20 +260,34 @@ function buildSection(pages, startPageIndex, images, headingLevels, form) {
205
260
  heightPt: pages[0].heightPt
206
261
  },
207
262
  margins: ZERO_MARGINS,
208
- blocks
263
+ blocks: wrapDivisionExtents(blocks, divisionByBlock)
209
264
  };
210
265
  }
211
- function reconstructPageBlocks(page, pageIndex, images, headingLevels, form) {
212
- const recoveredTable = recoverTable(page, pageIndex);
213
- const consumedText = recoveredTable?.consumedText;
214
- const textItems = page.items.filter((i) => i.kind === "text" && consumedText?.has(i) !== true);
266
+ function reconstructPageBlocks(page, pageIndex, images, headingLevels, form, structure, divisionByBlock) {
267
+ const recoveredTables = recoverTables(page, pageIndex, structure);
268
+ const consumedText = /* @__PURE__ */ new Set();
269
+ const claimedItems = /* @__PURE__ */ new Set();
270
+ for (const recovered of recoveredTables) {
271
+ for (const item of recovered.consumedText) consumedText.add(item);
272
+ for (const item of recovered.latticeItems) claimedItems.add(item);
273
+ }
274
+ const textItems = page.items.filter((i) => i.kind === "text" && !consumedText.has(i));
215
275
  const imageItems = page.items.filter((i) => i.kind === "image");
216
276
  const paragraphs = clusterIntoParagraphs(clusterIntoLines(textItems));
277
+ const recordDivisions = (block, items) => {
278
+ if (structure !== void 0) divisionByBlock.set(block, divisionChainOf(items, structure));
279
+ };
217
280
  const positioned = [];
218
- for (const paragraph of paragraphs) positioned.push({
219
- yPt: paragraph.lines[0].baselineY,
220
- block: paragraphToContentParagraph(paragraph, pageIndex, headingLevelOf(paragraph, headingLevels))
221
- });
281
+ for (const paragraph of paragraphs) {
282
+ const paragraphItems = paragraph.lines.flatMap((line) => line.items);
283
+ const structural = structure === void 0 ? void 0 : structureHeadingLevel(paragraphItems, structure);
284
+ const block = paragraphToContentParagraph(paragraph, pageIndex, structural !== void 0 ? structural.level : headingLevelOf(paragraph, headingLevels));
285
+ recordDivisions(block, paragraphItems);
286
+ positioned.push({
287
+ yPt: paragraph.lines[0].baselineY,
288
+ block
289
+ });
290
+ }
222
291
  for (const img of imageItems) {
223
292
  const asset = images[img.imageId];
224
293
  if (asset !== void 0) {
@@ -235,21 +304,29 @@ function reconstructPageBlocks(page, pageIndex, images, headingLevels, form) {
235
304
  widthPt: img.widthPt,
236
305
  heightPt: img.heightPt
237
306
  });
307
+ recordDivisions(block, [img]);
238
308
  positioned.push({
239
309
  yPt: img.yPt,
240
310
  block
241
311
  });
242
312
  }
243
313
  }
244
- if (recoveredTable !== void 0) positioned.push({
245
- yPt: recoveredTable.topYPt,
246
- block: recoveredTable.table
247
- });
248
- const recoveredVectors = recoverPageVectors(page, pageIndex, recoveredTable?.latticeItems ?? NO_ITEMS);
249
- if (recoveredVectors !== void 0) positioned.push({
250
- yPt: recoveredVectors.topYPt,
251
- block: recoveredVectors.block
252
- });
314
+ for (const recovered of recoveredTables) {
315
+ recordDivisions(recovered.table, [...recovered.consumedText]);
316
+ positioned.push({
317
+ yPt: recovered.topYPt,
318
+ block: recovered.table
319
+ });
320
+ }
321
+ const recoveredVectors = recoverPageVectors(page, pageIndex, claimedItems);
322
+ if (recoveredVectors !== void 0) {
323
+ const vectorItems = page.items.filter((item) => !claimedItems.has(item) && layoutItemToVector(item, page.heightPt) !== void 0);
324
+ recordDivisions(recoveredVectors.block, vectorItems);
325
+ positioned.push({
326
+ yPt: recoveredVectors.topYPt,
327
+ block: recoveredVectors.block
328
+ });
329
+ }
253
330
  positioned.sort((a, b) => b.yPt - a.yPt);
254
331
  const blocks = positioned.map((p) => p.block);
255
332
  reconcileLinks(blocks, page, pageIndex);
@@ -257,6 +334,49 @@ function reconstructPageBlocks(page, pageIndex, images, headingLevels, form) {
257
334
  appendFormFieldConstructs(blocks, form, pageIndex);
258
335
  return blocks;
259
336
  }
337
+ function divisionChainOf(items, structure) {
338
+ let prefix;
339
+ for (const item of items) {
340
+ const chain = [];
341
+ for (let current = structure.nodeOfItem(item); current !== void 0; current = current.parent) if (DIVISION_TYPES.has(current.type)) chain.push(current.id);
342
+ chain.reverse();
343
+ if (prefix === void 0) {
344
+ prefix = chain;
345
+ continue;
346
+ }
347
+ let shared = 0;
348
+ while (shared < prefix.length && shared < chain.length && prefix[shared] === chain[shared]) shared += 1;
349
+ prefix = prefix.slice(0, shared);
350
+ }
351
+ return prefix ?? [];
352
+ }
353
+ function wrapDivisionExtents(blocks, divisionByBlock) {
354
+ const out = [];
355
+ const open = [];
356
+ for (const block of blocks) {
357
+ const chain = divisionByBlock.get(block);
358
+ if (chain !== void 0) {
359
+ while (open.length > 0 && !chain.includes(open[open.length - 1])) {
360
+ out.push({ kind: "constructEnd" });
361
+ open.pop();
362
+ }
363
+ for (const id of chain) {
364
+ if (open.includes(id)) continue;
365
+ out.push({
366
+ kind: "constructStart",
367
+ descriptor: { kind: "division" }
368
+ });
369
+ open.push(id);
370
+ }
371
+ }
372
+ out.push(block);
373
+ }
374
+ while (open.length > 0) {
375
+ out.push({ kind: "constructEnd" });
376
+ open.pop();
377
+ }
378
+ return out;
379
+ }
260
380
  function framesIntersect(a, b) {
261
381
  return a.xPt < b.xPt + b.widthPt && b.xPt < a.xPt + a.widthPt && a.yPt < b.yPt + b.heightPt && b.yPt < a.yPt + a.heightPt;
262
382
  }
@@ -420,9 +540,10 @@ function paragraphToContentParagraph(paragraph, pageIndex, headingLevel) {
420
540
  }
421
541
  function reconstructPresentation(doc, options) {
422
542
  const signal = options?.signal;
543
+ const structure = indexStructure(doc);
423
544
  const slides = doc.pages.map((page, pageIndex) => {
424
545
  require_ports_abort.throwIfAborted(signal);
425
- return reconstructSlide(page, pageIndex, doc.images);
546
+ return reconstructSlide(page, pageIndex, doc.images, structure);
426
547
  });
427
548
  return {
428
549
  kind: "presentation",
@@ -430,10 +551,15 @@ function reconstructPresentation(doc, options) {
430
551
  slides
431
552
  };
432
553
  }
433
- function reconstructSlide(page, pageIndex, images) {
434
- const recoveredTable = recoverTable(page, pageIndex);
435
- const consumedText = recoveredTable?.consumedText;
436
- const textItems = page.items.filter((i) => i.kind === "text" && consumedText?.has(i) !== true);
554
+ function reconstructSlide(page, pageIndex, images, structure) {
555
+ const recoveredTables = recoverTables(page, pageIndex, structure);
556
+ const consumedText = /* @__PURE__ */ new Set();
557
+ const claimedItems = /* @__PURE__ */ new Set();
558
+ for (const recovered of recoveredTables) {
559
+ for (const item of recovered.consumedText) consumedText.add(item);
560
+ for (const item of recovered.latticeItems) claimedItems.add(item);
561
+ }
562
+ const textItems = page.items.filter((i) => i.kind === "text" && !consumedText.has(i));
437
563
  const imageItems = page.items.filter((i) => i.kind === "image");
438
564
  const textShapes = clusterIntoBlocks(clusterIntoLines(textItems)).map((block) => blockToShape(block, page.heightPt, pageIndex));
439
565
  const imageShapes = [];
@@ -441,14 +567,14 @@ function reconstructSlide(page, pageIndex, images) {
441
567
  const shape = imageToShape(img, page.heightPt, pageIndex, images);
442
568
  if (shape !== void 0) imageShapes.push(shape);
443
569
  }
444
- const recoveredVectors = recoverPageVectors(page, pageIndex, recoveredTable?.latticeItems ?? NO_ITEMS);
570
+ const recoveredVectors = recoverPageVectors(page, pageIndex, claimedItems);
445
571
  const vectorShapes = recoveredVectors === void 0 ? [] : [wrapBlockInShape(recoveredVectors.block, {
446
572
  xPt: 0,
447
573
  yPt: 0,
448
574
  widthPt: page.widthPt,
449
575
  heightPt: page.heightPt
450
576
  }, page.heightPt, pageIndex)];
451
- const tableShapes = recoveredTable === void 0 ? [] : [wrapBlockInShape(recoveredTable.table, recoveredTable.frame, page.heightPt, pageIndex)];
577
+ const tableShapes = recoveredTables.map((recovered) => wrapBlockInShape(recovered.table, recovered.frame, page.heightPt, pageIndex));
452
578
  return {
453
579
  size: {
454
580
  widthPt: page.widthPt,
@@ -894,6 +1020,112 @@ function recoverPageVectors(page, pageIndex, excluded) {
894
1020
  topYPt: page.heightPt - topYDownPt
895
1021
  };
896
1022
  }
1023
+ function recoverTables(page, pageIndex, structure) {
1024
+ if (structure !== void 0) {
1025
+ const tagged = recoverTaggedTables(page, pageIndex, structure);
1026
+ if (tagged.length > 0) return tagged;
1027
+ }
1028
+ const lattice = recoverTable(page, pageIndex);
1029
+ return lattice === void 0 ? [] : [lattice];
1030
+ }
1031
+ function recoverTaggedTables(page, pageIndex, structure) {
1032
+ const cellsByTable = /* @__PURE__ */ new Map();
1033
+ for (const item of page.items) {
1034
+ if (item.kind !== "text") continue;
1035
+ const cell = nearestOfType(structure.nodeOfItem(item), CELL_TYPES);
1036
+ const row = nearestOfType(cell?.parent, ROW_TYPES);
1037
+ const table = nearestOfType(row?.parent, TABLE_TYPES);
1038
+ if (cell === void 0 || row === void 0 || table === void 0) continue;
1039
+ const entry = cellsByTable.get(table.id) ?? {
1040
+ table,
1041
+ cells: []
1042
+ };
1043
+ entry.cells.push({
1044
+ table,
1045
+ row,
1046
+ cell,
1047
+ items: [item]
1048
+ });
1049
+ cellsByTable.set(table.id, entry);
1050
+ }
1051
+ if (cellsByTable.size === 0) return [];
1052
+ const latticeItems = require_layout_lattice.detectGridLattice(page.items)?.sourceItems ?? NO_ITEMS;
1053
+ const recovered = [];
1054
+ for (const { cells } of cellsByTable.values()) {
1055
+ const rowsById = /* @__PURE__ */ new Map();
1056
+ for (const cellEntry of cells) {
1057
+ const rowEntry = rowsById.get(cellEntry.row.id) ?? {
1058
+ row: cellEntry.row,
1059
+ cells: []
1060
+ };
1061
+ rowEntry.cells.push(cellEntry);
1062
+ rowsById.set(cellEntry.row.id, rowEntry);
1063
+ }
1064
+ const rows = [...rowsById.values()].sort((a, b) => a.row.order - b.row.order);
1065
+ for (const row of rows) row.cells.sort((a, b) => a.cell.order - b.cell.order);
1066
+ const columnCount = Math.max(...rows.map((row) => row.cells.length));
1067
+ const columnWidthsPt = [];
1068
+ for (let j = 0; j < columnCount; j++) {
1069
+ let minX = Number.POSITIVE_INFINITY;
1070
+ let maxX = Number.NEGATIVE_INFINITY;
1071
+ for (const row of rows) {
1072
+ const cellEntry = row.cells[j];
1073
+ if (cellEntry === void 0) continue;
1074
+ for (const item of cellEntry.items) {
1075
+ minX = Math.min(minX, item.xPt);
1076
+ maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
1077
+ }
1078
+ }
1079
+ const width = maxX - minX;
1080
+ columnWidthsPt.push(width > 0 ? width : DEFAULT_COLUMN_WIDTH_FALLBACK_PT);
1081
+ }
1082
+ const allItems = cells.flatMap((cellEntry) => cellEntry.items);
1083
+ const contentRows = rows.map((row) => {
1084
+ const contentCells = [];
1085
+ for (let j = 0; j < columnCount; j++) {
1086
+ const cellEntry = row.cells[j];
1087
+ const cell = { blocks: cellBlocksFromItems(cellEntry?.items ?? [], pageIndex) };
1088
+ if (cellEntry !== void 0) require_layout_shared.stampFrame(cell, pageIndex, textItemsPdfBox(cellEntry.items));
1089
+ contentCells.push(cell);
1090
+ }
1091
+ return { cells: contentCells };
1092
+ });
1093
+ const box = textItemsPdfBox(allItems);
1094
+ const table = {
1095
+ kind: "table",
1096
+ rows: contentRows,
1097
+ columnWidthsPt
1098
+ };
1099
+ require_layout_shared.stampFrame(table, pageIndex, box);
1100
+ recovered.push({
1101
+ table,
1102
+ frame: require_model_geometry.flipY(box, page.heightPt),
1103
+ topYPt: box.yPt + box.heightPt,
1104
+ consumedText: new Set(allItems),
1105
+ latticeItems
1106
+ });
1107
+ }
1108
+ return recovered;
1109
+ }
1110
+ function textItemsPdfBox(items) {
1111
+ let minX = Number.POSITIVE_INFINITY;
1112
+ let maxX = Number.NEGATIVE_INFINITY;
1113
+ let minY = Number.POSITIVE_INFINITY;
1114
+ let maxY = Number.NEGATIVE_INFINITY;
1115
+ for (const item of items) {
1116
+ const { ascentPt, descentPt } = textItemVerticalExtent(item);
1117
+ minX = Math.min(minX, item.xPt);
1118
+ maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
1119
+ minY = Math.min(minY, item.yPt - descentPt);
1120
+ maxY = Math.max(maxY, item.yPt + ascentPt);
1121
+ }
1122
+ return {
1123
+ xPt: minX,
1124
+ yPt: minY,
1125
+ widthPt: maxX - minX,
1126
+ heightPt: maxY - minY
1127
+ };
1128
+ }
897
1129
  function cellBlocksFromItems(items, pageIndex) {
898
1130
  return clusterIntoLines(items).map((line) => lineToParagraph(line, pageIndex));
899
1131
  }
@@ -998,23 +1230,7 @@ function buildCellsFromGroups(groups, pageIndex, context) {
998
1230
  value: inferredCellValue(displayText, row, column, context),
999
1231
  displayText
1000
1232
  };
1001
- let minX = Number.POSITIVE_INFINITY;
1002
- let maxX = Number.NEGATIVE_INFINITY;
1003
- let minY = Number.POSITIVE_INFINITY;
1004
- let maxY = Number.NEGATIVE_INFINITY;
1005
- for (const item of items) {
1006
- const { ascentPt, descentPt } = textItemVerticalExtent(item);
1007
- minX = Math.min(minX, item.xPt);
1008
- maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
1009
- minY = Math.min(minY, item.yPt - descentPt);
1010
- maxY = Math.max(maxY, item.yPt + ascentPt);
1011
- }
1012
- require_layout_shared.stampFrame(cell, pageIndex, {
1013
- xPt: minX,
1014
- yPt: minY,
1015
- widthPt: maxX - minX,
1016
- heightPt: maxY - minY
1017
- });
1233
+ require_layout_shared.stampFrame(cell, pageIndex, textItemsPdfBox(items));
1018
1234
  cells.push(cell);
1019
1235
  }
1020
1236
  cells.sort((a, b) => a.row - b.row || a.column - b.column);