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.
- package/README.md +12 -2
- package/dist/convert/convert.cjs +1 -1
- package/dist/convert/convert.js +1 -1
- package/dist/convert/pdf-package-tables.cjs +15 -0
- package/dist/convert/pdf-package-tables.js +15 -0
- package/dist/edit/odg/content.cjs +1 -1
- package/dist/edit/odg/content.js +1 -1
- package/dist/edit/odg/page.d.cts +1 -1
- package/dist/edit/odg/page.d.ts +1 -1
- package/dist/edit/odp/content.cjs +1 -1
- package/dist/edit/odp/content.js +1 -1
- package/dist/edit/odp/shape.d.cts +1 -1
- package/dist/edit/odp/shape.d.ts +1 -1
- package/dist/edit/odp/slide.d.cts +2 -2
- package/dist/edit/odp/slide.d.ts +2 -2
- package/dist/edit/ods/cell.cjs +1 -1
- package/dist/edit/ods/cell.js +1 -1
- package/dist/edit/odt/content.cjs +10 -8
- package/dist/edit/odt/content.d.cts +7 -4
- package/dist/edit/odt/content.d.ts +7 -4
- package/dist/edit/odt/content.js +10 -8
- package/dist/edit/odt/editor.cjs +1 -1
- package/dist/edit/odt/editor.d.cts +3 -3
- package/dist/edit/odt/editor.d.ts +3 -3
- package/dist/edit/odt/editor.js +1 -1
- package/dist/edit/odt/list.cjs +1 -1
- package/dist/edit/odt/list.d.cts +1 -1
- package/dist/edit/odt/list.d.ts +1 -1
- package/dist/edit/odt/list.js +1 -1
- package/dist/edit/odt/paragraph.cjs +22 -1
- package/dist/edit/odt/paragraph.d.cts +1 -1
- package/dist/edit/odt/paragraph.d.ts +1 -1
- package/dist/edit/odt/paragraph.js +22 -1
- package/dist/edit/odt/scaffold.cjs +12 -1
- package/dist/edit/odt/scaffold.js +12 -1
- package/dist/edit/odt/table.d.cts +1 -1
- package/dist/edit/odt/table.d.ts +1 -1
- package/dist/edit/pptx/content.cjs +2 -0
- package/dist/edit/pptx/content.d.cts +3 -2
- package/dist/edit/pptx/content.d.ts +3 -2
- package/dist/edit/pptx/content.js +3 -2
- package/dist/index.cjs +2 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +3 -3
- package/dist/layout/drawing.cjs +1 -1
- package/dist/layout/drawing.js +1 -1
- package/dist/layout/reconstruct.cjs +263 -47
- package/dist/layout/reconstruct.js +263 -47
- package/dist/layout/shared.cjs +1 -0
- package/dist/layout/shared.d.cts +5 -1
- package/dist/layout/shared.d.ts +5 -1
- package/dist/layout/shared.js +1 -1
- package/dist/{list-D9MtQtjK.d.ts → list-Cg_zlwVv.d.ts} +1 -1
- package/dist/{list-BT1Zb3PV.d.cts → list-CzGRStUr.d.cts} +1 -1
- package/dist/{paragraph-CdGRPSYA.d.cts → paragraph-C9jf4pMK.d.cts} +3 -0
- package/dist/{paragraph-BPRc-VVV.d.ts → paragraph-CeFnOpEi.d.ts} +3 -0
- package/dist/{shape-Cuk0RTZn.d.cts → shape-C56METn9.d.cts} +2 -2
- package/dist/{shape-CCPBGhbV.d.ts → shape-JrdFW78K.d.ts} +2 -2
- package/dist/{table-Dtml8NyR.d.ts → table-CY1ChByv.d.ts} +1 -1
- package/dist/{table-b9-ipGtZ.d.cts → table-Cu8f1XmW.d.cts} +1 -1
- 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
|
|
213
|
-
const consumedText =
|
|
214
|
-
const
|
|
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)
|
|
219
|
-
|
|
220
|
-
|
|
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
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
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
|
|
435
|
-
const consumedText =
|
|
436
|
-
const
|
|
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,
|
|
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 =
|
|
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
|
-
|
|
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);
|