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,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
|
|
212
|
-
const consumedText =
|
|
213
|
-
const
|
|
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)
|
|
218
|
-
|
|
219
|
-
|
|
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
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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
|
|
434
|
-
const consumedText =
|
|
435
|
-
const
|
|
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,
|
|
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 =
|
|
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
|
-
|
|
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);
|
package/dist/layout/shared.cjs
CHANGED
|
@@ -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;
|
package/dist/layout/shared.d.cts
CHANGED
|
@@ -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 };
|
package/dist/layout/shared.d.ts
CHANGED
|
@@ -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 };
|
package/dist/layout/shared.js
CHANGED
|
@@ -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-
|
|
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-
|
|
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-
|
|
2
|
-
import { t as OdtList } from "./list-
|
|
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-
|
|
2
|
-
import { t as OdtList } from "./list-
|
|
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-
|
|
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-
|
|
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.
|
|
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.
|
|
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"
|