js.documents 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,7 +1,7 @@
1
1
  import { flipY } from "../model/geometry.js";
2
2
  import { buildDrawingBlock } from "../model/embedded-drawing.js";
3
- import { inferCellValue } from "./cell-typing.js";
4
3
  import { stampFrame } from "./shared.js";
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
7
  import { resolveStandardFont } from "pdf-codec/fonts";
@@ -135,19 +135,20 @@ function reconstructWordprocessing(doc, options) {
135
135
  const signal = options?.signal;
136
136
  doc = dropHiddenLayerContent(doc);
137
137
  const headingLevels = headingSizeLevels(doc);
138
+ const structure = indexStructure(doc);
138
139
  const sections = [];
139
140
  let currentGroup = [];
140
141
  let groupStartPageIndex = 0;
141
142
  for (const page of doc.pages) {
142
143
  throwIfAborted(signal);
143
144
  if (currentGroup.length > 0 && !samePageSize(currentGroup[0], page)) {
144
- sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form));
145
+ sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form, structure));
145
146
  groupStartPageIndex += currentGroup.length;
146
147
  currentGroup = [];
147
148
  }
148
149
  currentGroup.push(page);
149
150
  }
150
- if (currentGroup.length > 0) sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form));
151
+ if (currentGroup.length > 0) sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form, structure));
151
152
  return {
152
153
  kind: "wordprocessing",
153
154
  metadata: doc.metadata,
@@ -168,6 +169,59 @@ function dropHiddenLayerContent(doc) {
168
169
  }))
169
170
  };
170
171
  }
172
+ const HEADING_LEVELS = /* @__PURE__ */ new Map([
173
+ ["H1", 1],
174
+ ["H2", 2],
175
+ ["H3", 3],
176
+ ["H4", 4],
177
+ ["H5", 5],
178
+ ["H6", 6]
179
+ ]);
180
+ const DIVISION_TYPES = /* @__PURE__ */ new Set([
181
+ "Part",
182
+ "Sect",
183
+ "Div"
184
+ ]);
185
+ const CELL_TYPES = /* @__PURE__ */ new Set(["TD", "TH"]);
186
+ const ROW_TYPES = /* @__PURE__ */ new Set(["TR"]);
187
+ const TABLE_TYPES = /* @__PURE__ */ new Set(["Table"]);
188
+ function indexStructure(doc) {
189
+ if (doc.structure === void 0 || doc.structure.length === 0) return;
190
+ const byId = /* @__PURE__ */ new Map();
191
+ let order = 0;
192
+ const walk = (element, parent) => {
193
+ const node = {
194
+ id: element.id,
195
+ type: element.type,
196
+ parent,
197
+ order: order++
198
+ };
199
+ byId.set(element.id, node);
200
+ for (const child of element.children) walk(child, node);
201
+ };
202
+ for (const root of doc.structure) walk(root, void 0);
203
+ return { nodeOfItem: (item) => item.kind === "link" || item.kind === "internalLink" ? void 0 : byId.get(item.structure ?? "") };
204
+ }
205
+ function nearestOfType(node, types) {
206
+ for (let current = node; current !== void 0; current = current.parent) if (types.has(current.type)) return current;
207
+ }
208
+ function nearestHeadingLevel(node) {
209
+ for (let current = node; current !== void 0; current = current.parent) {
210
+ const level = HEADING_LEVELS.get(current.type);
211
+ if (level !== void 0) return level;
212
+ }
213
+ }
214
+ function structureHeadingLevel(items, structure) {
215
+ if (items.length === 0 || items.some((item) => structure.nodeOfItem(item) === void 0)) return;
216
+ let level;
217
+ for (const item of items) {
218
+ const itemLevel = nearestHeadingLevel(structure.nodeOfItem(item));
219
+ if (itemLevel === void 0) return { level: void 0 };
220
+ if (level === void 0) level = itemLevel;
221
+ else if (level !== itemLevel) return;
222
+ }
223
+ return { level };
224
+ }
171
225
  const HEADING_MIN_SIZE_DELTA_PT = 2;
172
226
  const MAX_HEADING_LEVEL = 6;
173
227
  function headingSizeLevels(doc) {
@@ -192,11 +246,12 @@ function headingLevelOf(paragraph, levels) {
192
246
  function samePageSize(a, b) {
193
247
  return a.widthPt === b.widthPt && a.heightPt === b.heightPt;
194
248
  }
195
- function buildSection(pages, startPageIndex, images, headingLevels, form) {
249
+ function buildSection(pages, startPageIndex, images, headingLevels, form, structure) {
196
250
  const blocks = [];
251
+ const divisionByBlock = /* @__PURE__ */ new WeakMap();
197
252
  pages.forEach((page, i) => {
198
253
  if (i > 0) blocks.push({ kind: "pageBreak" });
199
- blocks.push(...reconstructPageBlocks(page, startPageIndex + i, images, headingLevels, form));
254
+ blocks.push(...reconstructPageBlocks(page, startPageIndex + i, images, headingLevels, form, structure, divisionByBlock));
200
255
  });
201
256
  return {
202
257
  pageSize: {
@@ -204,20 +259,34 @@ function buildSection(pages, startPageIndex, images, headingLevels, form) {
204
259
  heightPt: pages[0].heightPt
205
260
  },
206
261
  margins: ZERO_MARGINS,
207
- blocks
262
+ blocks: wrapDivisionExtents(blocks, divisionByBlock)
208
263
  };
209
264
  }
210
- function reconstructPageBlocks(page, pageIndex, images, headingLevels, form) {
211
- const recoveredTable = recoverTable(page, pageIndex);
212
- const consumedText = recoveredTable?.consumedText;
213
- const textItems = page.items.filter((i) => i.kind === "text" && consumedText?.has(i) !== true);
265
+ function reconstructPageBlocks(page, pageIndex, images, headingLevels, form, structure, divisionByBlock) {
266
+ const recoveredTables = recoverTables(page, pageIndex, structure);
267
+ const consumedText = /* @__PURE__ */ new Set();
268
+ const claimedItems = /* @__PURE__ */ new Set();
269
+ for (const recovered of recoveredTables) {
270
+ for (const item of recovered.consumedText) consumedText.add(item);
271
+ for (const item of recovered.latticeItems) claimedItems.add(item);
272
+ }
273
+ const textItems = page.items.filter((i) => i.kind === "text" && !consumedText.has(i));
214
274
  const imageItems = page.items.filter((i) => i.kind === "image");
215
275
  const paragraphs = clusterIntoParagraphs(clusterIntoLines(textItems));
276
+ const recordDivisions = (block, items) => {
277
+ if (structure !== void 0) divisionByBlock.set(block, divisionChainOf(items, structure));
278
+ };
216
279
  const positioned = [];
217
- for (const paragraph of paragraphs) positioned.push({
218
- yPt: paragraph.lines[0].baselineY,
219
- block: paragraphToContentParagraph(paragraph, pageIndex, headingLevelOf(paragraph, headingLevels))
220
- });
280
+ for (const paragraph of paragraphs) {
281
+ const paragraphItems = paragraph.lines.flatMap((line) => line.items);
282
+ const structural = structure === void 0 ? void 0 : structureHeadingLevel(paragraphItems, structure);
283
+ const block = paragraphToContentParagraph(paragraph, pageIndex, structural !== void 0 ? structural.level : headingLevelOf(paragraph, headingLevels));
284
+ recordDivisions(block, paragraphItems);
285
+ positioned.push({
286
+ yPt: paragraph.lines[0].baselineY,
287
+ block
288
+ });
289
+ }
221
290
  for (const img of imageItems) {
222
291
  const asset = images[img.imageId];
223
292
  if (asset !== void 0) {
@@ -234,21 +303,29 @@ function reconstructPageBlocks(page, pageIndex, images, headingLevels, form) {
234
303
  widthPt: img.widthPt,
235
304
  heightPt: img.heightPt
236
305
  });
306
+ recordDivisions(block, [img]);
237
307
  positioned.push({
238
308
  yPt: img.yPt,
239
309
  block
240
310
  });
241
311
  }
242
312
  }
243
- if (recoveredTable !== void 0) positioned.push({
244
- yPt: recoveredTable.topYPt,
245
- block: recoveredTable.table
246
- });
247
- const recoveredVectors = recoverPageVectors(page, pageIndex, recoveredTable?.latticeItems ?? NO_ITEMS);
248
- if (recoveredVectors !== void 0) positioned.push({
249
- yPt: recoveredVectors.topYPt,
250
- block: recoveredVectors.block
251
- });
313
+ for (const recovered of recoveredTables) {
314
+ recordDivisions(recovered.table, [...recovered.consumedText]);
315
+ positioned.push({
316
+ yPt: recovered.topYPt,
317
+ block: recovered.table
318
+ });
319
+ }
320
+ const recoveredVectors = recoverPageVectors(page, pageIndex, claimedItems);
321
+ if (recoveredVectors !== void 0) {
322
+ const vectorItems = page.items.filter((item) => !claimedItems.has(item) && layoutItemToVector(item, page.heightPt) !== void 0);
323
+ recordDivisions(recoveredVectors.block, vectorItems);
324
+ positioned.push({
325
+ yPt: recoveredVectors.topYPt,
326
+ block: recoveredVectors.block
327
+ });
328
+ }
252
329
  positioned.sort((a, b) => b.yPt - a.yPt);
253
330
  const blocks = positioned.map((p) => p.block);
254
331
  reconcileLinks(blocks, page, pageIndex);
@@ -256,6 +333,49 @@ function reconstructPageBlocks(page, pageIndex, images, headingLevels, form) {
256
333
  appendFormFieldConstructs(blocks, form, pageIndex);
257
334
  return blocks;
258
335
  }
336
+ function divisionChainOf(items, structure) {
337
+ let prefix;
338
+ for (const item of items) {
339
+ const chain = [];
340
+ for (let current = structure.nodeOfItem(item); current !== void 0; current = current.parent) if (DIVISION_TYPES.has(current.type)) chain.push(current.id);
341
+ chain.reverse();
342
+ if (prefix === void 0) {
343
+ prefix = chain;
344
+ continue;
345
+ }
346
+ let shared = 0;
347
+ while (shared < prefix.length && shared < chain.length && prefix[shared] === chain[shared]) shared += 1;
348
+ prefix = prefix.slice(0, shared);
349
+ }
350
+ return prefix ?? [];
351
+ }
352
+ function wrapDivisionExtents(blocks, divisionByBlock) {
353
+ const out = [];
354
+ const open = [];
355
+ for (const block of blocks) {
356
+ const chain = divisionByBlock.get(block);
357
+ if (chain !== void 0) {
358
+ while (open.length > 0 && !chain.includes(open[open.length - 1])) {
359
+ out.push({ kind: "constructEnd" });
360
+ open.pop();
361
+ }
362
+ for (const id of chain) {
363
+ if (open.includes(id)) continue;
364
+ out.push({
365
+ kind: "constructStart",
366
+ descriptor: { kind: "division" }
367
+ });
368
+ open.push(id);
369
+ }
370
+ }
371
+ out.push(block);
372
+ }
373
+ while (open.length > 0) {
374
+ out.push({ kind: "constructEnd" });
375
+ open.pop();
376
+ }
377
+ return out;
378
+ }
259
379
  function framesIntersect(a, b) {
260
380
  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;
261
381
  }
@@ -419,9 +539,10 @@ function paragraphToContentParagraph(paragraph, pageIndex, headingLevel) {
419
539
  }
420
540
  function reconstructPresentation(doc, options) {
421
541
  const signal = options?.signal;
542
+ const structure = indexStructure(doc);
422
543
  const slides = doc.pages.map((page, pageIndex) => {
423
544
  throwIfAborted(signal);
424
- return reconstructSlide(page, pageIndex, doc.images);
545
+ return reconstructSlide(page, pageIndex, doc.images, structure);
425
546
  });
426
547
  return {
427
548
  kind: "presentation",
@@ -429,10 +550,15 @@ function reconstructPresentation(doc, options) {
429
550
  slides
430
551
  };
431
552
  }
432
- function reconstructSlide(page, pageIndex, images) {
433
- const recoveredTable = recoverTable(page, pageIndex);
434
- const consumedText = recoveredTable?.consumedText;
435
- const textItems = page.items.filter((i) => i.kind === "text" && consumedText?.has(i) !== true);
553
+ function reconstructSlide(page, pageIndex, images, structure) {
554
+ const recoveredTables = recoverTables(page, pageIndex, structure);
555
+ const consumedText = /* @__PURE__ */ new Set();
556
+ const claimedItems = /* @__PURE__ */ new Set();
557
+ for (const recovered of recoveredTables) {
558
+ for (const item of recovered.consumedText) consumedText.add(item);
559
+ for (const item of recovered.latticeItems) claimedItems.add(item);
560
+ }
561
+ const textItems = page.items.filter((i) => i.kind === "text" && !consumedText.has(i));
436
562
  const imageItems = page.items.filter((i) => i.kind === "image");
437
563
  const textShapes = clusterIntoBlocks(clusterIntoLines(textItems)).map((block) => blockToShape(block, page.heightPt, pageIndex));
438
564
  const imageShapes = [];
@@ -440,14 +566,14 @@ function reconstructSlide(page, pageIndex, images) {
440
566
  const shape = imageToShape(img, page.heightPt, pageIndex, images);
441
567
  if (shape !== void 0) imageShapes.push(shape);
442
568
  }
443
- const recoveredVectors = recoverPageVectors(page, pageIndex, recoveredTable?.latticeItems ?? NO_ITEMS);
569
+ const recoveredVectors = recoverPageVectors(page, pageIndex, claimedItems);
444
570
  const vectorShapes = recoveredVectors === void 0 ? [] : [wrapBlockInShape(recoveredVectors.block, {
445
571
  xPt: 0,
446
572
  yPt: 0,
447
573
  widthPt: page.widthPt,
448
574
  heightPt: page.heightPt
449
575
  }, page.heightPt, pageIndex)];
450
- const tableShapes = recoveredTable === void 0 ? [] : [wrapBlockInShape(recoveredTable.table, recoveredTable.frame, page.heightPt, pageIndex)];
576
+ const tableShapes = recoveredTables.map((recovered) => wrapBlockInShape(recovered.table, recovered.frame, page.heightPt, pageIndex));
451
577
  return {
452
578
  size: {
453
579
  widthPt: page.widthPt,
@@ -893,6 +1019,112 @@ function recoverPageVectors(page, pageIndex, excluded) {
893
1019
  topYPt: page.heightPt - topYDownPt
894
1020
  };
895
1021
  }
1022
+ function recoverTables(page, pageIndex, structure) {
1023
+ if (structure !== void 0) {
1024
+ const tagged = recoverTaggedTables(page, pageIndex, structure);
1025
+ if (tagged.length > 0) return tagged;
1026
+ }
1027
+ const lattice = recoverTable(page, pageIndex);
1028
+ return lattice === void 0 ? [] : [lattice];
1029
+ }
1030
+ function recoverTaggedTables(page, pageIndex, structure) {
1031
+ const cellsByTable = /* @__PURE__ */ new Map();
1032
+ for (const item of page.items) {
1033
+ if (item.kind !== "text") continue;
1034
+ const cell = nearestOfType(structure.nodeOfItem(item), CELL_TYPES);
1035
+ const row = nearestOfType(cell?.parent, ROW_TYPES);
1036
+ const table = nearestOfType(row?.parent, TABLE_TYPES);
1037
+ if (cell === void 0 || row === void 0 || table === void 0) continue;
1038
+ const entry = cellsByTable.get(table.id) ?? {
1039
+ table,
1040
+ cells: []
1041
+ };
1042
+ entry.cells.push({
1043
+ table,
1044
+ row,
1045
+ cell,
1046
+ items: [item]
1047
+ });
1048
+ cellsByTable.set(table.id, entry);
1049
+ }
1050
+ if (cellsByTable.size === 0) return [];
1051
+ const latticeItems = detectGridLattice(page.items)?.sourceItems ?? NO_ITEMS;
1052
+ const recovered = [];
1053
+ for (const { cells } of cellsByTable.values()) {
1054
+ const rowsById = /* @__PURE__ */ new Map();
1055
+ for (const cellEntry of cells) {
1056
+ const rowEntry = rowsById.get(cellEntry.row.id) ?? {
1057
+ row: cellEntry.row,
1058
+ cells: []
1059
+ };
1060
+ rowEntry.cells.push(cellEntry);
1061
+ rowsById.set(cellEntry.row.id, rowEntry);
1062
+ }
1063
+ const rows = [...rowsById.values()].sort((a, b) => a.row.order - b.row.order);
1064
+ for (const row of rows) row.cells.sort((a, b) => a.cell.order - b.cell.order);
1065
+ const columnCount = Math.max(...rows.map((row) => row.cells.length));
1066
+ const columnWidthsPt = [];
1067
+ for (let j = 0; j < columnCount; j++) {
1068
+ let minX = Number.POSITIVE_INFINITY;
1069
+ let maxX = Number.NEGATIVE_INFINITY;
1070
+ for (const row of rows) {
1071
+ const cellEntry = row.cells[j];
1072
+ if (cellEntry === void 0) continue;
1073
+ for (const item of cellEntry.items) {
1074
+ minX = Math.min(minX, item.xPt);
1075
+ maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
1076
+ }
1077
+ }
1078
+ const width = maxX - minX;
1079
+ columnWidthsPt.push(width > 0 ? width : DEFAULT_COLUMN_WIDTH_FALLBACK_PT);
1080
+ }
1081
+ const allItems = cells.flatMap((cellEntry) => cellEntry.items);
1082
+ const contentRows = rows.map((row) => {
1083
+ const contentCells = [];
1084
+ for (let j = 0; j < columnCount; j++) {
1085
+ const cellEntry = row.cells[j];
1086
+ const cell = { blocks: cellBlocksFromItems(cellEntry?.items ?? [], pageIndex) };
1087
+ if (cellEntry !== void 0) stampFrame(cell, pageIndex, textItemsPdfBox(cellEntry.items));
1088
+ contentCells.push(cell);
1089
+ }
1090
+ return { cells: contentCells };
1091
+ });
1092
+ const box = textItemsPdfBox(allItems);
1093
+ const table = {
1094
+ kind: "table",
1095
+ rows: contentRows,
1096
+ columnWidthsPt
1097
+ };
1098
+ stampFrame(table, pageIndex, box);
1099
+ recovered.push({
1100
+ table,
1101
+ frame: flipY(box, page.heightPt),
1102
+ topYPt: box.yPt + box.heightPt,
1103
+ consumedText: new Set(allItems),
1104
+ latticeItems
1105
+ });
1106
+ }
1107
+ return recovered;
1108
+ }
1109
+ function textItemsPdfBox(items) {
1110
+ let minX = Number.POSITIVE_INFINITY;
1111
+ let maxX = Number.NEGATIVE_INFINITY;
1112
+ let minY = Number.POSITIVE_INFINITY;
1113
+ let maxY = Number.NEGATIVE_INFINITY;
1114
+ for (const item of items) {
1115
+ const { ascentPt, descentPt } = textItemVerticalExtent(item);
1116
+ minX = Math.min(minX, item.xPt);
1117
+ maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
1118
+ minY = Math.min(minY, item.yPt - descentPt);
1119
+ maxY = Math.max(maxY, item.yPt + ascentPt);
1120
+ }
1121
+ return {
1122
+ xPt: minX,
1123
+ yPt: minY,
1124
+ widthPt: maxX - minX,
1125
+ heightPt: maxY - minY
1126
+ };
1127
+ }
896
1128
  function cellBlocksFromItems(items, pageIndex) {
897
1129
  return clusterIntoLines(items).map((line) => lineToParagraph(line, pageIndex));
898
1130
  }
@@ -997,23 +1229,7 @@ function buildCellsFromGroups(groups, pageIndex, context) {
997
1229
  value: inferredCellValue(displayText, row, column, context),
998
1230
  displayText
999
1231
  };
1000
- let minX = Number.POSITIVE_INFINITY;
1001
- let maxX = Number.NEGATIVE_INFINITY;
1002
- let minY = Number.POSITIVE_INFINITY;
1003
- let maxY = Number.NEGATIVE_INFINITY;
1004
- for (const item of items) {
1005
- const { ascentPt, descentPt } = textItemVerticalExtent(item);
1006
- minX = Math.min(minX, item.xPt);
1007
- maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
1008
- minY = Math.min(minY, item.yPt - descentPt);
1009
- maxY = Math.max(maxY, item.yPt + ascentPt);
1010
- }
1011
- stampFrame(cell, pageIndex, {
1012
- xPt: minX,
1013
- yPt: minY,
1014
- widthPt: maxX - minX,
1015
- heightPt: maxY - minY
1016
- });
1232
+ stampFrame(cell, pageIndex, textItemsPdfBox(items));
1017
1233
  cells.push(cell);
1018
1234
  }
1019
1235
  cells.sort((a, b) => a.row - b.row || a.column - b.column);
@@ -233,6 +233,7 @@ function estimateRowHeightPt(row, measurer, columnWidthsPt, scale) {
233
233
  return max;
234
234
  }
235
235
  //#endregion
236
+ exports.HEADING_STYLES = HEADING_STYLES;
236
237
  exports.NOMINAL_TEXT_SIZE_PT = NOMINAL_TEXT_SIZE_PT;
237
238
  exports.alignmentOffsetPt = alignmentOffsetPt;
238
239
  exports.effectiveStyledRuns = effectiveStyledRuns;
@@ -14,6 +14,10 @@ declare function packagePagesOf(pages: readonly LayoutPage[]): PageSize[];
14
14
  declare function layoutDocumentOf(metadata: LayoutMetadata, pages: LayoutPage[], images: Record<string, LayoutImageAsset>): LayoutDocument;
15
15
  declare const NOMINAL_TEXT_SIZE_PT = 18;
16
16
  declare function formulaSizePtForFrame(mathml: readonly MathMlNode[], frame: Box, mathMetricsAt: (sizePt: number) => MathFontMetrics): number;
17
+ declare const HEADING_STYLES: Record<number, {
18
+ bold: boolean;
19
+ sizePt: number;
20
+ }>;
17
21
  declare function headingStyleFor(styleId: string | undefined): {
18
22
  bold: boolean;
19
23
  sizePt: number;
@@ -35,4 +39,4 @@ declare function registerImage(block: ContentImageBlock, images: Record<string,
35
39
  declare function sumColumnWidthsPt(columnWidthsPt: readonly number[], startIndex: number, span: number): number;
36
40
  declare function estimateRowHeightPt(row: ContentTableRow, measurer: TextMeasurer, columnWidthsPt: readonly number[], scale: number): number;
37
41
  //#endregion
38
- export { NOMINAL_TEXT_SIZE_PT, alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, headingStyleFor, justifyLineGapsPt, layoutDocumentOf, lineNaturalHeightPt, packagePagesOf, pushCellBorderLines, registerImage, runFont, stampFragmentFrame, stampFrame, sumColumnWidthsPt, textBoxForFragment, toStyledRuns };
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 };
@@ -14,6 +14,10 @@ declare function packagePagesOf(pages: readonly LayoutPage[]): PageSize[];
14
14
  declare function layoutDocumentOf(metadata: LayoutMetadata, pages: LayoutPage[], images: Record<string, LayoutImageAsset>): LayoutDocument;
15
15
  declare const NOMINAL_TEXT_SIZE_PT = 18;
16
16
  declare function formulaSizePtForFrame(mathml: readonly MathMlNode[], frame: Box, mathMetricsAt: (sizePt: number) => MathFontMetrics): number;
17
+ declare const HEADING_STYLES: Record<number, {
18
+ bold: boolean;
19
+ sizePt: number;
20
+ }>;
17
21
  declare function headingStyleFor(styleId: string | undefined): {
18
22
  bold: boolean;
19
23
  sizePt: number;
@@ -35,4 +39,4 @@ declare function registerImage(block: ContentImageBlock, images: Record<string,
35
39
  declare function sumColumnWidthsPt(columnWidthsPt: readonly number[], startIndex: number, span: number): number;
36
40
  declare function estimateRowHeightPt(row: ContentTableRow, measurer: TextMeasurer, columnWidthsPt: readonly number[], scale: number): number;
37
41
  //#endregion
38
- export { NOMINAL_TEXT_SIZE_PT, alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, headingStyleFor, justifyLineGapsPt, layoutDocumentOf, lineNaturalHeightPt, packagePagesOf, pushCellBorderLines, registerImage, runFont, stampFragmentFrame, stampFrame, sumColumnWidthsPt, textBoxForFragment, toStyledRuns };
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 };
@@ -232,4 +232,4 @@ function estimateRowHeightPt(row, measurer, columnWidthsPt, scale) {
232
232
  return max;
233
233
  }
234
234
  //#endregion
235
- export { NOMINAL_TEXT_SIZE_PT, alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, headingStyleFor, justifyLineGapsPt, layoutDocumentOf, lineNaturalHeightPt, packagePagesOf, pushCellBorderLines, registerImage, runFont, stampFragmentFrame, stampFrame, sumColumnWidthsPt, textBoxForFragment, toStyledRuns };
235
+ export { HEADING_STYLES, NOMINAL_TEXT_SIZE_PT, alignmentOffsetPt, effectiveStyledRuns, estimateRowHeightPt, formulaSizePtForFrame, headingStyleFor, justifyLineGapsPt, layoutDocumentOf, lineNaturalHeightPt, packagePagesOf, pushCellBorderLines, registerImage, runFont, stampFragmentFrame, stampFrame, sumColumnWidthsPt, textBoxForFragment, toStyledRuns };
@@ -1,4 +1,4 @@
1
- import { n as ParagraphInit, t as OdtParagraph } from "./paragraph-BPRc-VVV.js";
1
+ import { n as ParagraphInit, t as OdtParagraph } from "./paragraph-CeFnOpEi.js";
2
2
  import { Package, XmlElement, XmlNode } from "odf.js";
3
3
  //#region src/edit/odt/list.d.ts
4
4
  declare class OdtListItem {
@@ -1,4 +1,4 @@
1
- import { n as ParagraphInit, t as OdtParagraph } from "./paragraph-CdGRPSYA.cjs";
1
+ import { n as ParagraphInit, t as OdtParagraph } from "./paragraph-C9jf4pMK.cjs";
2
2
  import { Package, XmlElement, XmlNode } from "odf.js";
3
3
  //#region src/edit/odt/list.d.ts
4
4
  declare class OdtListItem {
@@ -6,6 +6,7 @@ import { Package, XmlElement, XmlNode } from "odf.js";
6
6
  interface ParagraphInit {
7
7
  readonly text?: string;
8
8
  readonly styleId?: string;
9
+ readonly headingLevel?: number;
9
10
  readonly alignment?: Alignment;
10
11
  }
11
12
  declare class OdtParagraph {
@@ -23,6 +24,8 @@ declare class OdtParagraph {
23
24
  insertRunAt(index: number, init?: RunInit): OdtRun;
24
25
  get styleId(): string | undefined;
25
26
  set styleId(value: string | undefined);
27
+ get headingLevel(): number | undefined;
28
+ set headingLevel(value: number | undefined);
26
29
  get alignment(): Alignment | undefined;
27
30
  set alignment(value: Alignment | undefined);
28
31
  get spacingBeforePt(): number | undefined;
@@ -6,6 +6,7 @@ import { Package, XmlElement, XmlNode } from "odf.js";
6
6
  interface ParagraphInit {
7
7
  readonly text?: string;
8
8
  readonly styleId?: string;
9
+ readonly headingLevel?: number;
9
10
  readonly alignment?: Alignment;
10
11
  }
11
12
  declare class OdtParagraph {
@@ -23,6 +24,8 @@ declare class OdtParagraph {
23
24
  insertRunAt(index: number, init?: RunInit): OdtRun;
24
25
  get styleId(): string | undefined;
25
26
  set styleId(value: string | undefined);
27
+ get headingLevel(): number | undefined;
28
+ set headingLevel(value: number | undefined);
26
29
  get alignment(): Alignment | undefined;
27
30
  set alignment(value: Alignment | undefined);
28
31
  get spacingBeforePt(): number | undefined;
@@ -1,5 +1,5 @@
1
- import { n as ParagraphInit, t as OdtParagraph } from "./paragraph-CdGRPSYA.cjs";
2
- import { t as OdtList } from "./list-BT1Zb3PV.cjs";
1
+ import { n as ParagraphInit, t as OdtParagraph } from "./paragraph-C9jf4pMK.cjs";
2
+ import { t as OdtList } from "./list-CzGRStUr.cjs";
3
3
  import { Box } from "document-schema.js";
4
4
  import { Package, XmlElement, XmlNode } from "odf.js";
5
5
  //#region src/edit/odp/shape.d.ts
@@ -1,5 +1,5 @@
1
- import { n as ParagraphInit, t as OdtParagraph } from "./paragraph-BPRc-VVV.js";
2
- import { t as OdtList } from "./list-D9MtQtjK.js";
1
+ import { n as ParagraphInit, t as OdtParagraph } from "./paragraph-CeFnOpEi.js";
2
+ import { t as OdtList } from "./list-Cg_zlwVv.js";
3
3
  import { Box } from "document-schema.js";
4
4
  import { Package, XmlElement, XmlNode } from "odf.js";
5
5
  //#region src/edit/odp/shape.d.ts
@@ -1,4 +1,4 @@
1
- import { n as ParagraphInit, t as OdtParagraph } from "./paragraph-BPRc-VVV.js";
1
+ import { n as ParagraphInit, t as OdtParagraph } from "./paragraph-CeFnOpEi.js";
2
2
  import { Color, ContentCellBorders } from "document-schema.js";
3
3
  import { Package, XmlElement, XmlNode } from "odf.js";
4
4
  //#region src/edit/odt/table.d.ts
@@ -1,4 +1,4 @@
1
- import { n as ParagraphInit, t as OdtParagraph } from "./paragraph-CdGRPSYA.cjs";
1
+ import { n as ParagraphInit, t as OdtParagraph } from "./paragraph-C9jf4pMK.cjs";
2
2
  import { Color, ContentCellBorders } from "document-schema.js";
3
3
  import { Package, XmlElement, XmlNode } from "odf.js";
4
4
  //#region src/edit/odt/table.d.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "js.documents",
3
- "version": "4.4.8",
3
+ "version": "4.6.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": {
@@ -82,7 +82,7 @@
82
82
  "fflate": "^0.8.3",
83
83
  "markdown-codec": "^5.0.1",
84
84
  "odf.js": "^5.3.0",
85
- "ooxml.js": "^4.5.2",
85
+ "ooxml.js": "^4.6.0",
86
86
  "pdf-codec": "^3.3.1",
87
87
  "temml": "0.13.4",
88
88
  "zod": "^4.4.3"