js.documents 14.4.56 → 14.4.57
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/dist/codecs/read.cjs +2 -2
- package/dist/codecs/read.js +1 -1
- package/dist/composition-plan-CfvhXeOC.cjs +627 -0
- package/dist/composition-plan-DU9nPPN7.d.cts +102 -0
- package/dist/composition-plan-f0zaExUW.js +508 -0
- package/dist/composition-plan-l6QPO4FX.d.ts +102 -0
- package/dist/convert/composition-plan.cjs +7 -0
- package/dist/convert/composition-plan.d.cts +2 -0
- package/dist/convert/composition-plan.d.ts +2 -0
- package/dist/convert/composition-plan.js +2 -0
- package/dist/convert/composition-to-pdf.cjs +12 -12
- package/dist/convert/composition-to-pdf.d.cts +1 -1
- package/dist/convert/composition-to-pdf.d.ts +1 -1
- package/dist/convert/composition-to-pdf.js +2 -2
- package/dist/convert/composition.cjs +16 -511
- package/dist/convert/composition.d.cts +2 -85
- package/dist/convert/composition.d.ts +2 -85
- package/dist/convert/composition.js +2 -502
- package/dist/convert/convert.cjs +2 -2
- package/dist/convert/convert.js +1 -1
- package/dist/convert/from-package.cjs +3 -3
- package/dist/convert/from-package.js +2 -2
- package/dist/convert/from-pdf.cjs +18 -18
- package/dist/convert/from-pdf.js +2 -2
- package/dist/convert/local.cjs +3 -3
- package/dist/convert/local.js +1 -1
- package/dist/edit/odp/slide.cjs +4 -4
- package/dist/edit/odp/slide.d.cts +1 -1
- package/dist/edit/odp/slide.d.ts +1 -1
- package/dist/edit/odp/slide.js +1 -1
- package/dist/edit/odt/content.d.cts +1 -1
- package/dist/edit/odt/content.d.ts +1 -1
- package/dist/edit/odt/editor.cjs +4 -4
- package/dist/edit/odt/editor.d.cts +1 -1
- package/dist/edit/odt/editor.d.ts +1 -1
- package/dist/edit/odt/editor.js +1 -1
- package/dist/edit/odt/table-grid.cjs +23 -0
- package/dist/edit/odt/table-grid.d.cts +54 -0
- package/dist/edit/odt/table-grid.d.ts +54 -0
- package/dist/edit/odt/table-grid.js +2 -0
- package/dist/edit/odt/table.cjs +12 -653
- package/dist/edit/odt/table.d.cts +2 -2
- package/dist/edit/odt/table.d.ts +2 -2
- package/dist/edit/odt/table.js +2 -647
- package/dist/{evaluate-BbOsgdmN.d.cts → evaluate-BSEUxiUK.d.cts} +3 -1
- package/dist/evaluate-CEzsBx3w.cjs +564 -0
- package/dist/{evaluate-C7fmk69X.d.ts → evaluate-D8fG2ZeB.d.ts} +3 -1
- package/dist/evaluate-IK-3aMv5.js +445 -0
- package/dist/evaluate-columns-CyqKHkIW.d.cts +41 -0
- package/dist/evaluate-columns-cOo8fOfT.d.ts +41 -0
- package/dist/index.cjs +24 -24
- package/dist/index.d.cts +6 -5
- package/dist/index.d.ts +6 -5
- package/dist/index.js +8 -8
- package/dist/latex/lint.cjs +2 -2
- package/dist/latex/lint.js +1 -1
- package/dist/latex/lower-fold.cjs +6 -0
- package/dist/latex/lower-fold.d.cts +17 -0
- package/dist/latex/lower-fold.d.ts +17 -0
- package/dist/latex/lower-fold.js +2 -0
- package/dist/latex/lower.cjs +11 -617
- package/dist/latex/lower.d.cts +18 -1
- package/dist/latex/lower.d.ts +18 -1
- package/dist/latex/lower.js +2 -616
- package/dist/latex/symbols.d.cts +1 -15
- package/dist/latex/symbols.d.ts +1 -15
- package/dist/latex/temml.d.cts +1 -24
- package/dist/latex/temml.d.ts +1 -24
- package/dist/layout/engine.cjs +2 -2
- package/dist/layout/engine.js +1 -1
- package/dist/layout/reconstruct-lines.cjs +315 -0
- package/dist/layout/reconstruct-lines.d.cts +2 -0
- package/dist/layout/reconstruct-lines.d.ts +2 -0
- package/dist/layout/reconstruct-lines.js +297 -0
- package/dist/layout/reconstruct-presentations-prod.cjs +9 -0
- package/dist/layout/reconstruct-presentations-prod.d.cts +26 -0
- package/dist/layout/reconstruct-presentations-prod.d.ts +26 -0
- package/dist/layout/reconstruct-presentations-prod.js +2 -0
- package/dist/layout/reconstruct-tables.cjs +5 -0
- package/dist/layout/reconstruct-tables.d.cts +22 -0
- package/dist/layout/reconstruct-tables.d.ts +22 -0
- package/dist/layout/reconstruct-tables.js +2 -0
- package/dist/layout/reconstruct.cjs +11 -1545
- package/dist/layout/reconstruct.d.cts +2 -14
- package/dist/layout/reconstruct.d.ts +2 -14
- package/dist/layout/reconstruct.js +2 -1542
- package/dist/layout/shared.cjs +2 -2
- package/dist/layout/shared.js +1 -1
- package/dist/layout/sheets-render.cjs +19 -0
- package/dist/layout/sheets-render.d.cts +41 -0
- package/dist/layout/sheets-render.d.ts +41 -0
- package/dist/layout/sheets-render.js +2 -0
- package/dist/layout/sheets.cjs +10 -544
- package/dist/layout/sheets.d.cts +13 -2
- package/dist/layout/sheets.d.ts +13 -2
- package/dist/layout/sheets.js +2 -543
- package/dist/layout/slides.cjs +2 -2
- package/dist/layout/slides.js +1 -1
- package/dist/layout-DIJzJk4x.js +526 -0
- package/dist/layout-iuiyl_Fk.cjs +621 -0
- package/dist/layout-types-oSbHvZid.d.cts +13 -0
- package/dist/layout-types-oSbHvZid.d.ts +13 -0
- package/dist/lower-DCs3rWI7.js +618 -0
- package/dist/lower-DzOb13w4.cjs +701 -0
- package/dist/markdown/math.cjs +2 -2
- package/dist/markdown/math.js +1 -1
- package/dist/mathml/layout-stretch.cjs +16 -0
- package/dist/mathml/layout-stretch.d.cts +24 -0
- package/dist/mathml/layout-stretch.d.ts +24 -0
- package/dist/mathml/layout-stretch.js +2 -0
- package/dist/mathml/layout-types.d.cts +1 -12
- package/dist/mathml/layout-types.d.ts +1 -12
- package/dist/mathml/layout.cjs +3 -525
- package/dist/mathml/layout.d.cts +2 -2
- package/dist/mathml/layout.d.ts +2 -2
- package/dist/mathml/layout.js +1 -523
- package/dist/odb/formula/evaluate.d.cts +1 -1
- package/dist/odb/formula/evaluate.d.ts +1 -1
- package/dist/odb/report/render.d.cts +1 -1
- package/dist/odb/report/render.d.ts +1 -1
- package/dist/odb/report/source.cjs +2 -2
- package/dist/odb/report/source.d.cts +1 -1
- package/dist/odb/report/source.d.ts +1 -1
- package/dist/odb/report/source.js +1 -1
- package/dist/odb/sql/evaluate-columns.cjs +122 -0
- package/dist/odb/sql/evaluate-columns.d.cts +2 -0
- package/dist/odb/sql/evaluate-columns.d.ts +2 -0
- package/dist/odb/sql/evaluate-columns.js +114 -0
- package/dist/odb/sql/evaluate-predicates.cjs +16 -0
- package/dist/odb/sql/evaluate-predicates.d.cts +23 -0
- package/dist/odb/sql/evaluate-predicates.d.ts +23 -0
- package/dist/odb/sql/evaluate-predicates.js +2 -0
- package/dist/odb/sql/evaluate.cjs +7 -556
- package/dist/odb/sql/evaluate.d.cts +2 -2
- package/dist/odb/sql/evaluate.d.ts +2 -2
- package/dist/odb/sql/evaluate.js +2 -552
- package/dist/read-BSH--XB4.js +682 -0
- package/dist/read-CahCZMwG.cjs +759 -0
- package/dist/reconstruct-BKOCAedo.d.ts +29 -0
- package/dist/reconstruct-D4TEteZ6.d.cts +29 -0
- package/dist/reconstruct-lines-B7t66ICm.d.cts +33 -0
- package/dist/reconstruct-lines-B7t66ICm.d.ts +33 -0
- package/dist/reconstruct-presentations-prod-B5fkPiRZ.js +1256 -0
- package/dist/reconstruct-presentations-prod-X315aBmI.cjs +1375 -0
- package/dist/sheets-BQCpNXsE.cjs +700 -0
- package/dist/sheets-DWDvGN-g.js +545 -0
- package/dist/svg/read-geometry.cjs +10 -0
- package/dist/svg/read-geometry.d.cts +24 -0
- package/dist/svg/read-geometry.d.ts +24 -0
- package/dist/svg/read-geometry.js +2 -0
- package/dist/svg/read.cjs +6 -680
- package/dist/svg/read.d.cts +17 -2
- package/dist/svg/read.d.ts +17 -2
- package/dist/svg/read.js +2 -679
- package/dist/symbols-BlzXfLEe.d.cts +16 -0
- package/dist/symbols-CKm2r4D0.d.ts +16 -0
- package/dist/table-B5gSMY7w.js +649 -0
- package/dist/{table-DrE6jEWv.d.cts → table-BK_Ao-Y6.d.cts} +9 -1
- package/dist/{table-B5htMG3g.d.ts → table-CxY85YUj.d.ts} +9 -1
- package/dist/table-DqUIOSPV.cjs +840 -0
- package/dist/temml-1-I9N9DD.d.cts +25 -0
- package/dist/temml-1-I9N9DD.d.ts +25 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1375 @@
|
|
|
1
|
+
const require_model_geometry = require("./model/geometry.cjs");
|
|
2
|
+
const require_model_embedded_drawing = require("./model/embedded-drawing.cjs");
|
|
3
|
+
const require_layout_shared = require("./layout/shared.cjs");
|
|
4
|
+
const require_layout_cell_typing = require("./layout/cell-typing.cjs");
|
|
5
|
+
const require_ports_abort = require("./ports/abort.cjs");
|
|
6
|
+
const require_layout_reconstruct_lines = require("./layout/reconstruct-lines.cjs");
|
|
7
|
+
const require_layout_lattice = require("./layout/lattice.cjs");
|
|
8
|
+
let document_schema_js = require("document-schema.js");
|
|
9
|
+
//#region src/layout/reconstruct-tables.ts
|
|
10
|
+
function recoverTables(page, pageIndex, structure) {
|
|
11
|
+
if (structure !== void 0) {
|
|
12
|
+
const tagged = recoverTaggedTables(page, pageIndex, structure);
|
|
13
|
+
if (tagged.length > 0) return tagged;
|
|
14
|
+
}
|
|
15
|
+
const lattice = recoverTable(page, pageIndex);
|
|
16
|
+
return lattice === void 0 ? [] : [lattice];
|
|
17
|
+
}
|
|
18
|
+
function recoverTaggedTables(page, pageIndex, structure) {
|
|
19
|
+
const cellsByTable = /* @__PURE__ */ new Map();
|
|
20
|
+
for (const item of page.items) {
|
|
21
|
+
if (item.kind !== "text") continue;
|
|
22
|
+
const cell = nearestOfType(structure.nodeOfItem(item), CELL_TYPES);
|
|
23
|
+
const row = nearestOfType(cell?.parent, ROW_TYPES);
|
|
24
|
+
const table = nearestOfType(row?.parent, TABLE_TYPES);
|
|
25
|
+
if (cell === void 0 || row === void 0 || table === void 0) continue;
|
|
26
|
+
const entry = cellsByTable.get(table.id) ?? {
|
|
27
|
+
table,
|
|
28
|
+
cellsById: /* @__PURE__ */ new Map()
|
|
29
|
+
};
|
|
30
|
+
const existing = entry.cellsById.get(cell.id);
|
|
31
|
+
if (existing === void 0) entry.cellsById.set(cell.id, {
|
|
32
|
+
table,
|
|
33
|
+
row,
|
|
34
|
+
cell,
|
|
35
|
+
items: [item]
|
|
36
|
+
});
|
|
37
|
+
else existing.items.push(item);
|
|
38
|
+
cellsByTable.set(table.id, entry);
|
|
39
|
+
}
|
|
40
|
+
if (cellsByTable.size === 0) return [];
|
|
41
|
+
const latticeItems = require_layout_lattice.detectGridLattice(page.items)?.sourceItems ?? NO_ITEMS;
|
|
42
|
+
const recovered = [];
|
|
43
|
+
for (const { cellsById } of cellsByTable.values()) {
|
|
44
|
+
const cells = [...cellsById.values()];
|
|
45
|
+
const rowsById = /* @__PURE__ */ new Map();
|
|
46
|
+
for (const cellEntry of cells) {
|
|
47
|
+
const rowEntry = rowsById.get(cellEntry.row.id) ?? {
|
|
48
|
+
row: cellEntry.row,
|
|
49
|
+
cells: []
|
|
50
|
+
};
|
|
51
|
+
rowEntry.cells.push(cellEntry);
|
|
52
|
+
rowsById.set(cellEntry.row.id, rowEntry);
|
|
53
|
+
}
|
|
54
|
+
const rows = [...rowsById.values()].sort((a, b) => a.row.order - b.row.order);
|
|
55
|
+
for (const row of rows) row.cells.sort((a, b) => a.cell.order - b.cell.order);
|
|
56
|
+
const columnCount = Math.max(...rows.map((row) => row.cells.length));
|
|
57
|
+
const columns = [];
|
|
58
|
+
for (let j = 0; j < columnCount; j++) {
|
|
59
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
60
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
61
|
+
for (const row of rows) {
|
|
62
|
+
const cellEntry = row.cells[j];
|
|
63
|
+
if (cellEntry === void 0) continue;
|
|
64
|
+
for (const item of cellEntry.items) {
|
|
65
|
+
minX = Math.min(minX, item.xPt);
|
|
66
|
+
maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const width = maxX - minX;
|
|
70
|
+
columns.push({ widthPt: width > 0 ? width : 40 });
|
|
71
|
+
}
|
|
72
|
+
const allItems = cells.flatMap((cellEntry) => cellEntry.items);
|
|
73
|
+
const contentRows = rows.map((row) => {
|
|
74
|
+
const contentCells = [];
|
|
75
|
+
for (let j = 0; j < columnCount; j++) {
|
|
76
|
+
const cellEntry = row.cells[j];
|
|
77
|
+
const cell = { blocks: cellBlocksFromItems(cellEntry?.items ?? [], pageIndex) };
|
|
78
|
+
if (cellEntry !== void 0) require_layout_shared.stampFrame(cell, pageIndex, textItemsPdfBox(cellEntry.items));
|
|
79
|
+
contentCells.push(cell);
|
|
80
|
+
}
|
|
81
|
+
return { cells: contentCells };
|
|
82
|
+
});
|
|
83
|
+
const box = textItemsPdfBox(allItems);
|
|
84
|
+
const table = {
|
|
85
|
+
kind: "table",
|
|
86
|
+
rows: contentRows,
|
|
87
|
+
columns
|
|
88
|
+
};
|
|
89
|
+
require_layout_shared.stampFrame(table, pageIndex, box);
|
|
90
|
+
recovered.push({
|
|
91
|
+
table,
|
|
92
|
+
frame: require_model_geometry.flipY(box, page.heightPt),
|
|
93
|
+
topYPt: box.yPt + box.heightPt,
|
|
94
|
+
consumedText: new Set(allItems),
|
|
95
|
+
latticeItems
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return recovered;
|
|
99
|
+
}
|
|
100
|
+
function textItemsPdfBox(items) {
|
|
101
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
102
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
103
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
104
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
105
|
+
for (const item of items) {
|
|
106
|
+
const { ascentPt, descentPt } = require_layout_reconstruct_lines.textItemVerticalExtent(item);
|
|
107
|
+
minX = Math.min(minX, item.xPt);
|
|
108
|
+
maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
|
|
109
|
+
minY = Math.min(minY, item.yPt - descentPt);
|
|
110
|
+
maxY = Math.max(maxY, item.yPt + ascentPt);
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
xPt: minX,
|
|
114
|
+
yPt: minY,
|
|
115
|
+
widthPt: maxX - minX,
|
|
116
|
+
heightPt: maxY - minY
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function cellBlocksFromItems(items, pageIndex) {
|
|
120
|
+
return require_layout_reconstruct_lines.clusterIntoLines(items).map((line) => lineToParagraph(line, pageIndex));
|
|
121
|
+
}
|
|
122
|
+
function indexRegions(lattice, rowCount, columnCount) {
|
|
123
|
+
const regionAt = Array.from({ length: rowCount }, () => new Array(columnCount));
|
|
124
|
+
for (const region of lattice.regions) for (let i = region.rowStart; i < region.rowEnd; i++) for (let j = region.colStart; j < region.colEnd; j++) regionAt[i][j] = region;
|
|
125
|
+
return regionAt;
|
|
126
|
+
}
|
|
127
|
+
function recoverTable(page, pageIndex) {
|
|
128
|
+
const lattice = require_layout_lattice.detectGridLattice(page.items);
|
|
129
|
+
if (lattice === void 0) return;
|
|
130
|
+
const rowCount = lattice.rowBoundariesDescPt.length - 1;
|
|
131
|
+
const columnCount = lattice.columnBoundariesAscPt.length - 1;
|
|
132
|
+
const regionAt = indexRegions(lattice, rowCount, columnCount);
|
|
133
|
+
const textByRegion = /* @__PURE__ */ new Map();
|
|
134
|
+
const consumedText = /* @__PURE__ */ new Set();
|
|
135
|
+
for (const item of page.items) {
|
|
136
|
+
if (item.kind !== "text") continue;
|
|
137
|
+
const row = require_layout_lattice.findRowIndex(lattice.rowBoundariesDescPt, item.yPt);
|
|
138
|
+
const column = require_layout_lattice.findColumnIndex(lattice.columnBoundariesAscPt, item.xPt);
|
|
139
|
+
if (row === void 0 || column === void 0) continue;
|
|
140
|
+
const region = regionAt[row][column];
|
|
141
|
+
const existing = textByRegion.get(region);
|
|
142
|
+
if (existing === void 0) textByRegion.set(region, [item]);
|
|
143
|
+
else existing.push(item);
|
|
144
|
+
consumedText.add(item);
|
|
145
|
+
}
|
|
146
|
+
if (consumedText.size === 0) return;
|
|
147
|
+
const columns = [];
|
|
148
|
+
for (let j = 0; j < columnCount; j++) columns.push({ widthPt: lattice.columnBoundariesAscPt[j + 1] - lattice.columnBoundariesAscPt[j] });
|
|
149
|
+
const positionedRows = [];
|
|
150
|
+
for (let i = 0; i < rowCount; i++) {
|
|
151
|
+
const positioned = [];
|
|
152
|
+
for (let j = 0; j < columnCount; j++) {
|
|
153
|
+
const region = regionAt[i][j];
|
|
154
|
+
if (region.rowStart !== i || region.colStart !== j) continue;
|
|
155
|
+
const colSpan = region.colEnd - region.colStart;
|
|
156
|
+
const rowSpan = region.rowEnd - region.rowStart;
|
|
157
|
+
const cell = {
|
|
158
|
+
blocks: cellBlocksFromItems(textByRegion.get(region) ?? [], pageIndex),
|
|
159
|
+
colSpan: colSpan > 1 ? colSpan : void 0,
|
|
160
|
+
rowSpan: rowSpan > 1 ? rowSpan : void 0
|
|
161
|
+
};
|
|
162
|
+
const cellLeftXPt = lattice.columnBoundariesAscPt[region.colStart];
|
|
163
|
+
const cellRightXPt = lattice.columnBoundariesAscPt[region.colEnd];
|
|
164
|
+
const cellTopYPt = lattice.rowBoundariesDescPt[region.rowStart];
|
|
165
|
+
const cellBottomYPt = lattice.rowBoundariesDescPt[region.rowEnd];
|
|
166
|
+
require_layout_shared.stampFrame(cell, pageIndex, {
|
|
167
|
+
xPt: cellLeftXPt,
|
|
168
|
+
yPt: cellBottomYPt,
|
|
169
|
+
widthPt: cellRightXPt - cellLeftXPt,
|
|
170
|
+
heightPt: cellTopYPt - cellBottomYPt
|
|
171
|
+
});
|
|
172
|
+
positioned.push({
|
|
173
|
+
columnIndex: j,
|
|
174
|
+
cell
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
positionedRows.push({
|
|
178
|
+
cells: positioned,
|
|
179
|
+
heightPt: lattice.rowBoundariesDescPt[i] - lattice.rowBoundariesDescPt[i + 1]
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
const rows = (0, document_schema_js.denseTableRows)(positionedRows, columnCount);
|
|
183
|
+
const leftXPt = lattice.columnBoundariesAscPt[0];
|
|
184
|
+
const rightXPt = lattice.columnBoundariesAscPt[columnCount];
|
|
185
|
+
const topYPt = lattice.rowBoundariesDescPt[0];
|
|
186
|
+
const bottomYPt = lattice.rowBoundariesDescPt[rowCount];
|
|
187
|
+
const pdfBox = {
|
|
188
|
+
xPt: leftXPt,
|
|
189
|
+
yPt: bottomYPt,
|
|
190
|
+
widthPt: rightXPt - leftXPt,
|
|
191
|
+
heightPt: topYPt - bottomYPt
|
|
192
|
+
};
|
|
193
|
+
const frame = require_model_geometry.flipY(pdfBox, page.heightPt);
|
|
194
|
+
const table = {
|
|
195
|
+
kind: "table",
|
|
196
|
+
rows,
|
|
197
|
+
columns
|
|
198
|
+
};
|
|
199
|
+
require_layout_shared.stampFrame(table, pageIndex, pdfBox);
|
|
200
|
+
return {
|
|
201
|
+
table,
|
|
202
|
+
frame,
|
|
203
|
+
topYPt,
|
|
204
|
+
consumedText,
|
|
205
|
+
latticeItems: lattice.sourceItems
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
function joinCellText(items) {
|
|
209
|
+
const sorted = [...items].sort((a, b) => a.xPt - b.xPt);
|
|
210
|
+
let text = "";
|
|
211
|
+
sorted.forEach((item, i) => {
|
|
212
|
+
if (i > 0) {
|
|
213
|
+
const prev = sorted[i - 1];
|
|
214
|
+
if (require_layout_reconstruct_lines.gapExceeds(prev, item, .5)) text += " ";
|
|
215
|
+
}
|
|
216
|
+
text += item.text;
|
|
217
|
+
});
|
|
218
|
+
return text;
|
|
219
|
+
}
|
|
220
|
+
function groupKey(row, column) {
|
|
221
|
+
return `${row},${column}`;
|
|
222
|
+
}
|
|
223
|
+
function addToGroup(groups, row, column, item) {
|
|
224
|
+
const key = groupKey(row, column);
|
|
225
|
+
const existing = groups.get(key);
|
|
226
|
+
if (existing === void 0) groups.set(key, [item]);
|
|
227
|
+
else existing.push(item);
|
|
228
|
+
}
|
|
229
|
+
function buildCellsFromGroups(groups, pageIndex, context) {
|
|
230
|
+
const cells = [];
|
|
231
|
+
for (const [key, items] of groups) {
|
|
232
|
+
const displayText = joinCellText(items);
|
|
233
|
+
if (displayText.length === 0) continue;
|
|
234
|
+
const [rowPart, columnPart] = key.split(",");
|
|
235
|
+
const row = Number(rowPart);
|
|
236
|
+
const column = Number(columnPart);
|
|
237
|
+
const cell = {
|
|
238
|
+
row,
|
|
239
|
+
column,
|
|
240
|
+
value: inferredCellValue(displayText, row, column, context),
|
|
241
|
+
displayText
|
|
242
|
+
};
|
|
243
|
+
require_layout_shared.stampFrame(cell, pageIndex, textItemsPdfBox(items));
|
|
244
|
+
cells.push(cell);
|
|
245
|
+
}
|
|
246
|
+
cells.sort((a, b) => a.row - b.row || a.column - b.column);
|
|
247
|
+
return cells;
|
|
248
|
+
}
|
|
249
|
+
function inferredCellValue(displayText, row, column, context) {
|
|
250
|
+
const inference = require_layout_cell_typing.inferCellValue(displayText);
|
|
251
|
+
if (inference === void 0) return {
|
|
252
|
+
kind: "string",
|
|
253
|
+
value: displayText
|
|
254
|
+
};
|
|
255
|
+
const reported = {
|
|
256
|
+
sheetIndex: context.sheetIndex,
|
|
257
|
+
row,
|
|
258
|
+
column,
|
|
259
|
+
displayText,
|
|
260
|
+
...inference
|
|
261
|
+
};
|
|
262
|
+
context.sink?.(reported);
|
|
263
|
+
return inference.outcome === "retyped" ? inference.value : {
|
|
264
|
+
kind: "string",
|
|
265
|
+
value: displayText
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
function buildGridFromLattice(textItems, lattice, pageIndex, context) {
|
|
269
|
+
const groups = /* @__PURE__ */ new Map();
|
|
270
|
+
for (const item of textItems) {
|
|
271
|
+
const row = require_layout_lattice.findRowIndex(lattice.rowBoundariesDescPt, item.yPt);
|
|
272
|
+
const column = require_layout_lattice.findColumnIndex(lattice.columnBoundariesAscPt, item.xPt);
|
|
273
|
+
if (row === void 0 || column === void 0) continue;
|
|
274
|
+
addToGroup(groups, row, column, item);
|
|
275
|
+
}
|
|
276
|
+
const columns = [];
|
|
277
|
+
for (let j = 0; j < lattice.columnBoundariesAscPt.length - 1; j++) columns.push({
|
|
278
|
+
index: j,
|
|
279
|
+
widthPt: lattice.columnBoundariesAscPt[j + 1] - lattice.columnBoundariesAscPt[j]
|
|
280
|
+
});
|
|
281
|
+
const rows = [];
|
|
282
|
+
for (let i = 0; i < lattice.rowBoundariesDescPt.length - 1; i++) rows.push({
|
|
283
|
+
index: i,
|
|
284
|
+
heightPt: lattice.rowBoundariesDescPt[i] - lattice.rowBoundariesDescPt[i + 1]
|
|
285
|
+
});
|
|
286
|
+
return {
|
|
287
|
+
cells: buildCellsFromGroups(groups, pageIndex, context),
|
|
288
|
+
columns,
|
|
289
|
+
rows,
|
|
290
|
+
gridlines: true
|
|
291
|
+
};
|
|
292
|
+
}
|
|
293
|
+
const COLUMN_ALIGNMENT_TOLERANCE_PT = 3;
|
|
294
|
+
const MIN_COLUMN_RECURRENCE = 2;
|
|
295
|
+
function detectColumnPositions(segmentsByLine) {
|
|
296
|
+
const allXs = segmentsByLine.flatMap((segments) => segments.map((segment) => segment.items[0].xPt));
|
|
297
|
+
if (allXs.length === 0) return [];
|
|
298
|
+
const counts = require_layout_reconstruct_lines.bucketCounts(allXs, COLUMN_ALIGNMENT_TOLERANCE_PT);
|
|
299
|
+
const recurring = [...counts.entries()].filter(([, count]) => count >= MIN_COLUMN_RECURRENCE).map(([bucket]) => bucket);
|
|
300
|
+
const positions = recurring.length > 0 ? recurring : [...counts.keys()];
|
|
301
|
+
positions.sort((a, b) => a - b);
|
|
302
|
+
return positions;
|
|
303
|
+
}
|
|
304
|
+
function nearestColumnIndex(positions, xPt) {
|
|
305
|
+
let bestIndex = 0;
|
|
306
|
+
let bestDistancePt = Number.POSITIVE_INFINITY;
|
|
307
|
+
positions.forEach((position, index) => {
|
|
308
|
+
const distancePt = Math.abs(position - xPt);
|
|
309
|
+
if (distancePt < bestDistancePt) {
|
|
310
|
+
bestDistancePt = distancePt;
|
|
311
|
+
bestIndex = index;
|
|
312
|
+
}
|
|
313
|
+
});
|
|
314
|
+
return bestIndex;
|
|
315
|
+
}
|
|
316
|
+
function lastColumnWidthPt(groups, columnIndex, anchorXPt) {
|
|
317
|
+
let maxWidthPt = 0;
|
|
318
|
+
for (const [key, items] of groups) {
|
|
319
|
+
const [, columnPart] = key.split(",");
|
|
320
|
+
if (Number(columnPart) !== columnIndex) continue;
|
|
321
|
+
for (const item of items) maxWidthPt = Math.max(maxWidthPt, item.xPt + (item.widthPt ?? 0) - anchorXPt);
|
|
322
|
+
}
|
|
323
|
+
return maxWidthPt > 0 ? maxWidthPt : 40;
|
|
324
|
+
}
|
|
325
|
+
function buildGridFromTextClustering(textItems, pageIndex, context) {
|
|
326
|
+
const lines = require_layout_reconstruct_lines.clusterIntoLines(textItems);
|
|
327
|
+
if (lines.length === 0) return {
|
|
328
|
+
cells: [],
|
|
329
|
+
columns: [],
|
|
330
|
+
rows: [],
|
|
331
|
+
gridlines: false
|
|
332
|
+
};
|
|
333
|
+
const segmentsByLine = lines.map((l) => splitLineByLargeGaps(l));
|
|
334
|
+
const columnPositions = detectColumnPositions(segmentsByLine);
|
|
335
|
+
const groups = /* @__PURE__ */ new Map();
|
|
336
|
+
segmentsByLine.forEach((segments, rowIndex) => {
|
|
337
|
+
for (const segment of segments) {
|
|
338
|
+
const key = groupKey(rowIndex, nearestColumnIndex(columnPositions, segment.items[0].xPt));
|
|
339
|
+
const existing = groups.get(key);
|
|
340
|
+
if (existing === void 0) groups.set(key, [...segment.items]);
|
|
341
|
+
else existing.push(...segment.items);
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
const nominalRowHeightPt = require_layout_reconstruct_lines.estimateModalLineSpacing(lines);
|
|
345
|
+
const rows = lines.map((line, i) => {
|
|
346
|
+
const nextBaselineY = lines[i + 1]?.baselineY;
|
|
347
|
+
const heightPt = nextBaselineY !== void 0 ? line.baselineY - nextBaselineY : nominalRowHeightPt;
|
|
348
|
+
return {
|
|
349
|
+
index: i,
|
|
350
|
+
heightPt: heightPt > 0 ? heightPt : nominalRowHeightPt
|
|
351
|
+
};
|
|
352
|
+
});
|
|
353
|
+
const columns = columnPositions.map((position, j) => {
|
|
354
|
+
const nextPosition = columnPositions[j + 1];
|
|
355
|
+
return {
|
|
356
|
+
index: j,
|
|
357
|
+
widthPt: nextPosition !== void 0 ? nextPosition - position : lastColumnWidthPt(groups, j, position)
|
|
358
|
+
};
|
|
359
|
+
});
|
|
360
|
+
return {
|
|
361
|
+
cells: buildCellsFromGroups(groups, pageIndex, context),
|
|
362
|
+
columns,
|
|
363
|
+
rows,
|
|
364
|
+
gridlines: false
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
//#endregion
|
|
368
|
+
//#region src/layout/reconstruct.ts
|
|
369
|
+
const DEFAULT_COLUMN_WIDTH_FALLBACK_PT = 40;
|
|
370
|
+
const NO_ITEMS = /* @__PURE__ */ new Set();
|
|
371
|
+
const ZERO_MARGINS = {
|
|
372
|
+
topPt: 0,
|
|
373
|
+
rightPt: 0,
|
|
374
|
+
bottomPt: 0,
|
|
375
|
+
leftPt: 0
|
|
376
|
+
};
|
|
377
|
+
function reconstructWordprocessing(doc, options) {
|
|
378
|
+
const signal = options?.signal;
|
|
379
|
+
doc = dropHiddenLayerContent(doc);
|
|
380
|
+
const headingLevels = headingSizeLevels(doc);
|
|
381
|
+
const structure = indexStructure(doc);
|
|
382
|
+
const sections = [];
|
|
383
|
+
let currentGroup = [];
|
|
384
|
+
let groupStartPageIndex = 0;
|
|
385
|
+
for (const page of doc.pages) {
|
|
386
|
+
require_ports_abort.throwIfAborted(signal);
|
|
387
|
+
if (currentGroup.length > 0 && !samePageSize(currentGroup[0], page)) {
|
|
388
|
+
sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form, structure));
|
|
389
|
+
groupStartPageIndex += currentGroup.length;
|
|
390
|
+
currentGroup = [];
|
|
391
|
+
}
|
|
392
|
+
currentGroup.push(page);
|
|
393
|
+
}
|
|
394
|
+
if (currentGroup.length > 0) sections.push(buildSection(currentGroup, groupStartPageIndex, doc.images, headingLevels, doc.form, structure));
|
|
395
|
+
return {
|
|
396
|
+
kind: "wordprocessing",
|
|
397
|
+
metadata: doc.metadata,
|
|
398
|
+
sections
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
function layerOf(item) {
|
|
402
|
+
return item.kind === "link" || item.kind === "internalLink" ? void 0 : item.layer;
|
|
403
|
+
}
|
|
404
|
+
function dropHiddenLayerContent(doc) {
|
|
405
|
+
const hidden = new Set((doc.layers ?? []).filter((layer) => !layer.visible).map((layer) => layer.name));
|
|
406
|
+
if (hidden.size === 0) return doc;
|
|
407
|
+
return {
|
|
408
|
+
...doc,
|
|
409
|
+
pages: doc.pages.map((page) => ({
|
|
410
|
+
...page,
|
|
411
|
+
items: page.items.filter((item) => layerOf(item) === void 0 || !hidden.has(layerOf(item)))
|
|
412
|
+
}))
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
const HEADING_LEVELS = new Map([
|
|
416
|
+
"H1",
|
|
417
|
+
"H2",
|
|
418
|
+
"H3",
|
|
419
|
+
"H4",
|
|
420
|
+
"H5",
|
|
421
|
+
"H6"
|
|
422
|
+
].map((tag, index) => [tag, index + 1]));
|
|
423
|
+
const DIVISION_TYPES = /* @__PURE__ */ new Set([
|
|
424
|
+
"Part",
|
|
425
|
+
"Sect",
|
|
426
|
+
"Div"
|
|
427
|
+
]);
|
|
428
|
+
const CELL_TYPES = /* @__PURE__ */ new Set(["TD", "TH"]);
|
|
429
|
+
const ROW_TYPES = /* @__PURE__ */ new Set(["TR"]);
|
|
430
|
+
const TABLE_TYPES = /* @__PURE__ */ new Set(["Table"]);
|
|
431
|
+
function indexStructure(doc) {
|
|
432
|
+
if (doc.structure === void 0 || doc.structure.length === 0) return;
|
|
433
|
+
const byId = /* @__PURE__ */ new Map();
|
|
434
|
+
let order = 0;
|
|
435
|
+
const walk = (element, parent) => {
|
|
436
|
+
const node = {
|
|
437
|
+
id: element.id,
|
|
438
|
+
type: element.type,
|
|
439
|
+
parent,
|
|
440
|
+
order: order++
|
|
441
|
+
};
|
|
442
|
+
byId.set(element.id, node);
|
|
443
|
+
for (const child of element.children) walk(child, node);
|
|
444
|
+
};
|
|
445
|
+
for (const root of doc.structure) walk(root, void 0);
|
|
446
|
+
return { nodeOfItem: (item) => item.kind === "link" || item.kind === "internalLink" ? void 0 : byId.get(item.structure ?? "") };
|
|
447
|
+
}
|
|
448
|
+
function nearestOfType(node, types) {
|
|
449
|
+
for (let current = node; current !== void 0; current = current.parent) if (types.has(current.type)) return current;
|
|
450
|
+
}
|
|
451
|
+
function nearestHeadingLevel(node) {
|
|
452
|
+
for (let current = node; current !== void 0; current = current.parent) {
|
|
453
|
+
const level = HEADING_LEVELS.get(current.type);
|
|
454
|
+
if (level !== void 0) return level;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
function structureHeadingLevel(items, structure) {
|
|
458
|
+
if (items.length === 0 || items.some((item) => structure.nodeOfItem(item) === void 0)) return;
|
|
459
|
+
let level;
|
|
460
|
+
for (const item of items) {
|
|
461
|
+
const itemLevel = nearestHeadingLevel(structure.nodeOfItem(item));
|
|
462
|
+
if (itemLevel === void 0) return { level: void 0 };
|
|
463
|
+
if (level === void 0) level = itemLevel;
|
|
464
|
+
else if (level !== itemLevel) return;
|
|
465
|
+
}
|
|
466
|
+
return { level };
|
|
467
|
+
}
|
|
468
|
+
const HEADING_MIN_SIZE_DELTA_PT = 2;
|
|
469
|
+
const MAX_HEADING_LEVEL = 6;
|
|
470
|
+
function hasVisibleText(text) {
|
|
471
|
+
return text.trim().length > 0;
|
|
472
|
+
}
|
|
473
|
+
function headingSizeLevels(doc) {
|
|
474
|
+
const sizes = [];
|
|
475
|
+
for (const page of doc.pages) for (const item of page.items) if (item.kind === "text" && hasVisibleText(item.text)) sizes.push(item.sizePt);
|
|
476
|
+
if (sizes.length === 0) return /* @__PURE__ */ new Map();
|
|
477
|
+
const bodySizePt = require_layout_reconstruct_lines.modeOf(sizes, require_layout_reconstruct_lines.HALF_POINT_BUCKET_PT);
|
|
478
|
+
const headingBuckets = /* @__PURE__ */ new Set();
|
|
479
|
+
for (const size of sizes) {
|
|
480
|
+
const bucket = Math.round(size / require_layout_reconstruct_lines.HALF_POINT_BUCKET_PT) * require_layout_reconstruct_lines.HALF_POINT_BUCKET_PT;
|
|
481
|
+
if (bucket - bodySizePt >= HEADING_MIN_SIZE_DELTA_PT) headingBuckets.add(bucket);
|
|
482
|
+
}
|
|
483
|
+
const levels = /* @__PURE__ */ new Map();
|
|
484
|
+
[...headingBuckets].sort((a, b) => b - a).forEach((bucket, index) => {
|
|
485
|
+
levels.set(bucket, Math.min(index + 1, MAX_HEADING_LEVEL));
|
|
486
|
+
});
|
|
487
|
+
return levels;
|
|
488
|
+
}
|
|
489
|
+
function headingLevelOf(paragraph, levels) {
|
|
490
|
+
return levels.get(require_layout_reconstruct_lines.modeOf(paragraph.lines.flatMap((line) => line.items).filter((item) => hasVisibleText(item.text)).map((item) => item.sizePt), require_layout_reconstruct_lines.HALF_POINT_BUCKET_PT));
|
|
491
|
+
}
|
|
492
|
+
function samePageSize(a, b) {
|
|
493
|
+
return a.widthPt === b.widthPt && a.heightPt === b.heightPt;
|
|
494
|
+
}
|
|
495
|
+
function buildSection(pages, startPageIndex, images, headingLevels, form, structure) {
|
|
496
|
+
const blocks = [];
|
|
497
|
+
const divisionByBlock = /* @__PURE__ */ new WeakMap();
|
|
498
|
+
pages.forEach((page, i) => {
|
|
499
|
+
if (i > 0) blocks.push({ kind: "pageBreak" });
|
|
500
|
+
blocks.push(...reconstructPageBlocks(page, startPageIndex + i, images, headingLevels, form, structure, divisionByBlock));
|
|
501
|
+
});
|
|
502
|
+
return {
|
|
503
|
+
pageSize: {
|
|
504
|
+
widthPt: pages[0].widthPt,
|
|
505
|
+
heightPt: pages[0].heightPt
|
|
506
|
+
},
|
|
507
|
+
margins: ZERO_MARGINS,
|
|
508
|
+
blocks: wrapDivisionExtents(blocks, divisionByBlock)
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
function reconstructPageBlocks(page, pageIndex, images, headingLevels, form, structure, divisionByBlock) {
|
|
512
|
+
const recoveredTables = recoverTables(page, pageIndex, structure);
|
|
513
|
+
const consumedText = /* @__PURE__ */ new Set();
|
|
514
|
+
const claimedItems = /* @__PURE__ */ new Set();
|
|
515
|
+
for (const recovered of recoveredTables) {
|
|
516
|
+
for (const item of recovered.consumedText) consumedText.add(item);
|
|
517
|
+
for (const item of recovered.latticeItems) claimedItems.add(item);
|
|
518
|
+
}
|
|
519
|
+
const textItems = page.items.filter((i) => i.kind === "text" && !consumedText.has(i));
|
|
520
|
+
const imageItems = page.items.filter((i) => i.kind === "image");
|
|
521
|
+
const lines = require_layout_reconstruct_lines.clusterIntoLines(textItems);
|
|
522
|
+
const paragraphs = require_layout_reconstruct_lines.clusterIntoParagraphs(lines);
|
|
523
|
+
const recordDivisions = (block, items) => {
|
|
524
|
+
if (structure !== void 0) divisionByBlock.set(block, divisionChainOf(items, structure));
|
|
525
|
+
};
|
|
526
|
+
const positioned = [];
|
|
527
|
+
for (const paragraph of paragraphs) {
|
|
528
|
+
const paragraphItems = paragraph.lines.flatMap((line) => line.items);
|
|
529
|
+
const structural = structure === void 0 ? void 0 : structureHeadingLevel(paragraphItems, structure);
|
|
530
|
+
const headingLevel = structural !== void 0 ? structural.level : headingLevelOf(paragraph, headingLevels);
|
|
531
|
+
const block = require_layout_reconstruct_lines.paragraphToContentParagraph(paragraph, pageIndex, headingLevel);
|
|
532
|
+
recordDivisions(block, paragraphItems);
|
|
533
|
+
positioned.push({
|
|
534
|
+
yPt: paragraph.lines[0].baselineY,
|
|
535
|
+
block
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
for (const img of imageItems) {
|
|
539
|
+
const asset = images[img.imageId];
|
|
540
|
+
if (asset !== void 0) {
|
|
541
|
+
const block = {
|
|
542
|
+
kind: "image",
|
|
543
|
+
format: asset.format,
|
|
544
|
+
base64: asset.base64,
|
|
545
|
+
widthPt: img.widthPt,
|
|
546
|
+
heightPt: img.heightPt
|
|
547
|
+
};
|
|
548
|
+
require_layout_shared.stampFrame(block, pageIndex, {
|
|
549
|
+
xPt: img.xPt,
|
|
550
|
+
yPt: img.yPt,
|
|
551
|
+
widthPt: img.widthPt,
|
|
552
|
+
heightPt: img.heightPt
|
|
553
|
+
});
|
|
554
|
+
recordDivisions(block, [img]);
|
|
555
|
+
positioned.push({
|
|
556
|
+
yPt: img.yPt,
|
|
557
|
+
block
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
for (const recovered of recoveredTables) {
|
|
562
|
+
recordDivisions(recovered.table, [...recovered.consumedText]);
|
|
563
|
+
positioned.push({
|
|
564
|
+
yPt: recovered.topYPt,
|
|
565
|
+
block: recovered.table
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
const recoveredVectors = recoverPageVectors(page, pageIndex, claimedItems);
|
|
569
|
+
if (recoveredVectors !== void 0) {
|
|
570
|
+
const vectorItems = page.items.filter((item) => !claimedItems.has(item) && layoutItemToVector(item, page.heightPt) !== void 0);
|
|
571
|
+
recordDivisions(recoveredVectors.block, vectorItems);
|
|
572
|
+
positioned.push({
|
|
573
|
+
yPt: recoveredVectors.topYPt,
|
|
574
|
+
block: recoveredVectors.block
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
positioned.sort((a, b) => b.yPt - a.yPt);
|
|
578
|
+
const blocks = positioned.map((p) => p.block);
|
|
579
|
+
reconcileLinks(blocks, page, pageIndex);
|
|
580
|
+
appendAnnotationConstructs(blocks, page, pageIndex);
|
|
581
|
+
appendFormFieldConstructs(blocks, form, pageIndex);
|
|
582
|
+
return blocks;
|
|
583
|
+
}
|
|
584
|
+
function divisionChainOf(items, structure) {
|
|
585
|
+
let prefix;
|
|
586
|
+
for (const item of items) {
|
|
587
|
+
const chain = [];
|
|
588
|
+
for (let current = structure.nodeOfItem(item); current !== void 0; current = current.parent) if (DIVISION_TYPES.has(current.type)) chain.push(current.id);
|
|
589
|
+
chain.reverse();
|
|
590
|
+
if (prefix === void 0) {
|
|
591
|
+
prefix = chain;
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
let shared = 0;
|
|
595
|
+
while (shared < prefix.length && shared < chain.length && prefix[shared] === chain[shared]) shared += 1;
|
|
596
|
+
prefix = prefix.slice(0, shared);
|
|
597
|
+
}
|
|
598
|
+
return prefix ?? [];
|
|
599
|
+
}
|
|
600
|
+
function wrapDivisionExtents(blocks, divisionByBlock) {
|
|
601
|
+
const out = [];
|
|
602
|
+
const open = [];
|
|
603
|
+
for (const block of blocks) {
|
|
604
|
+
const chain = divisionByBlock.get(block);
|
|
605
|
+
if (chain !== void 0) {
|
|
606
|
+
while (open.length > 0 && !chain.includes(open[open.length - 1])) {
|
|
607
|
+
out.push({ kind: "constructEnd" });
|
|
608
|
+
open.pop();
|
|
609
|
+
}
|
|
610
|
+
for (const id of chain) {
|
|
611
|
+
if (open.includes(id)) continue;
|
|
612
|
+
out.push({
|
|
613
|
+
kind: "constructStart",
|
|
614
|
+
descriptor: { kind: "division" }
|
|
615
|
+
});
|
|
616
|
+
open.push(id);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
out.push(block);
|
|
620
|
+
}
|
|
621
|
+
while (open.length > 0) {
|
|
622
|
+
out.push({ kind: "constructEnd" });
|
|
623
|
+
open.pop();
|
|
624
|
+
}
|
|
625
|
+
return out;
|
|
626
|
+
}
|
|
627
|
+
function framesIntersect(a, b) {
|
|
628
|
+
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;
|
|
629
|
+
}
|
|
630
|
+
function intersectionArea(a, b) {
|
|
631
|
+
const width = Math.min(a.xPt + a.widthPt, b.xPt + b.widthPt) - Math.max(a.xPt, b.xPt);
|
|
632
|
+
const height = Math.min(a.yPt + a.heightPt, b.yPt + b.heightPt) - Math.max(a.yPt, b.yPt);
|
|
633
|
+
return width > 0 && height > 0 ? width * height : 0;
|
|
634
|
+
}
|
|
635
|
+
function reconcileLinks(blocks, page, pageIndex) {
|
|
636
|
+
for (const item of page.items) {
|
|
637
|
+
if (item.kind !== "link" && item.kind !== "internalLink") continue;
|
|
638
|
+
if (item.kind === "link") {
|
|
639
|
+
let matchedRun = false;
|
|
640
|
+
for (const block of blocks) {
|
|
641
|
+
if (block.kind !== "paragraph") continue;
|
|
642
|
+
for (const run of block.runs) if ((run.frames ?? []).some((frame) => frame.pageIndex === pageIndex && framesIntersect(item, frame))) {
|
|
643
|
+
run.hyperlink = item.uri;
|
|
644
|
+
matchedRun = true;
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
if (matchedRun) continue;
|
|
648
|
+
}
|
|
649
|
+
wrapBestBlock(blocks, item, pageIndex, linkDescriptor(item));
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
function linkDescriptor(item) {
|
|
653
|
+
if (item.kind === "link") return {
|
|
654
|
+
kind: "link",
|
|
655
|
+
target: {
|
|
656
|
+
kind: "external",
|
|
657
|
+
uri: item.uri
|
|
658
|
+
},
|
|
659
|
+
...item.title !== void 0 ? { title: item.title } : {}
|
|
660
|
+
};
|
|
661
|
+
return {
|
|
662
|
+
kind: "link",
|
|
663
|
+
target: {
|
|
664
|
+
kind: "internal",
|
|
665
|
+
anchor: item.destination
|
|
666
|
+
},
|
|
667
|
+
...item.title !== void 0 ? { title: item.title } : {}
|
|
668
|
+
};
|
|
669
|
+
}
|
|
670
|
+
function blockFramesOn(block, pageIndex) {
|
|
671
|
+
return block.kind === "constructStart" || block.kind === "constructEnd" ? [] : (block.frames ?? []).filter((frame) => frame.pageIndex === pageIndex);
|
|
672
|
+
}
|
|
673
|
+
function wrapBestBlock(blocks, rect, pageIndex, descriptor) {
|
|
674
|
+
let bestIndex = -1;
|
|
675
|
+
let bestArea = 0;
|
|
676
|
+
blocks.forEach((block, index) => {
|
|
677
|
+
const area = blockFramesOn(block, pageIndex).reduce((sum, frame) => sum + intersectionArea(rect, frame), 0);
|
|
678
|
+
if (area > bestArea) {
|
|
679
|
+
bestArea = area;
|
|
680
|
+
bestIndex = index;
|
|
681
|
+
}
|
|
682
|
+
});
|
|
683
|
+
const start = {
|
|
684
|
+
kind: "constructStart",
|
|
685
|
+
descriptor
|
|
686
|
+
};
|
|
687
|
+
const end = { kind: "constructEnd" };
|
|
688
|
+
if (bestIndex >= 0) {
|
|
689
|
+
blocks.splice(bestIndex, 0, start);
|
|
690
|
+
blocks.splice(bestIndex + 2, 0, end);
|
|
691
|
+
} else blocks.push(start, end);
|
|
692
|
+
}
|
|
693
|
+
function appendAnnotationConstructs(blocks, page, pageIndex) {
|
|
694
|
+
(page.annotations ?? []).forEach((annotation, annotIndex) => {
|
|
695
|
+
const key = `pdf-annot-${String(pageIndex)}-${String(annotIndex)}`;
|
|
696
|
+
blocks.push({
|
|
697
|
+
kind: "constructStart",
|
|
698
|
+
descriptor: {
|
|
699
|
+
kind: "anchor",
|
|
700
|
+
anchorType: "comment",
|
|
701
|
+
name: key,
|
|
702
|
+
definition: key,
|
|
703
|
+
...annotation.source !== void 0 ? { source: annotation.source } : {}
|
|
704
|
+
}
|
|
705
|
+
}, { kind: "constructEnd" });
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
function controlTypeOf(field) {
|
|
709
|
+
if (field.fieldType === "text") return "plainText";
|
|
710
|
+
if (field.fieldType === "button") return "button";
|
|
711
|
+
if (field.fieldType === "combobox") return "comboBox";
|
|
712
|
+
if (field.fieldType === "listbox") return "dropDown";
|
|
713
|
+
return "checkbox";
|
|
714
|
+
}
|
|
715
|
+
function appendFormFieldConstructs(blocks, form, pageIndex) {
|
|
716
|
+
const visit = (fields) => {
|
|
717
|
+
for (const field of fields) {
|
|
718
|
+
visit(field.children);
|
|
719
|
+
if (field.fieldType === "group" || field.fieldType === "signature") continue;
|
|
720
|
+
for (const widget of field.widgets) {
|
|
721
|
+
if (widget.pageIndex !== pageIndex) continue;
|
|
722
|
+
wrapBestBlock(blocks, widget, pageIndex, {
|
|
723
|
+
kind: "contentControl",
|
|
724
|
+
controlType: controlTypeOf(field),
|
|
725
|
+
tag: field.name,
|
|
726
|
+
...field.alias !== void 0 ? { alias: field.alias } : {},
|
|
727
|
+
...field.readOnly === true ? { lock: "content" } : {},
|
|
728
|
+
...field.value !== void 0 ? { value: field.value } : {},
|
|
729
|
+
...field.checked !== void 0 ? { checked: field.checked } : {},
|
|
730
|
+
...field.options !== void 0 ? { options: [...field.options] } : {}
|
|
731
|
+
});
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
visit(form ?? []);
|
|
736
|
+
}
|
|
737
|
+
function reconstructSpreadsheet(doc, options) {
|
|
738
|
+
const signal = options?.signal;
|
|
739
|
+
const sheets = doc.pages.map((page, index) => {
|
|
740
|
+
require_ports_abort.throwIfAborted(signal);
|
|
741
|
+
return reconstructSheet(page, index, options?.onCellTypeInference);
|
|
742
|
+
});
|
|
743
|
+
return {
|
|
744
|
+
kind: "spreadsheet",
|
|
745
|
+
metadata: doc.metadata,
|
|
746
|
+
sheets
|
|
747
|
+
};
|
|
748
|
+
}
|
|
749
|
+
//#endregion
|
|
750
|
+
//#region src/layout/reconstruct-presentations-prod.ts
|
|
751
|
+
function reconstructPresentation(doc, options) {
|
|
752
|
+
const signal = options?.signal;
|
|
753
|
+
const structure = indexStructure(doc);
|
|
754
|
+
const slides = doc.pages.map((page, pageIndex) => {
|
|
755
|
+
require_ports_abort.throwIfAborted(signal);
|
|
756
|
+
return reconstructSlide(page, pageIndex, doc.images, structure);
|
|
757
|
+
});
|
|
758
|
+
return {
|
|
759
|
+
kind: "presentation",
|
|
760
|
+
metadata: doc.metadata,
|
|
761
|
+
slides
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
function reconstructSlide(page, pageIndex, images, structure) {
|
|
765
|
+
const recoveredTables = recoverTables(page, pageIndex, structure);
|
|
766
|
+
const consumedText = /* @__PURE__ */ new Set();
|
|
767
|
+
const claimedItems = /* @__PURE__ */ new Set();
|
|
768
|
+
for (const recovered of recoveredTables) {
|
|
769
|
+
for (const item of recovered.consumedText) consumedText.add(item);
|
|
770
|
+
for (const item of recovered.latticeItems) claimedItems.add(item);
|
|
771
|
+
}
|
|
772
|
+
const textItems = page.items.filter((i) => i.kind === "text" && !consumedText.has(i));
|
|
773
|
+
const imageItems = page.items.filter((i) => i.kind === "image");
|
|
774
|
+
const textShapes = clusterIntoBlocks(require_layout_reconstruct_lines.clusterIntoLines(textItems)).map((block) => blockToShape(block, page.heightPt, pageIndex));
|
|
775
|
+
const imageShapes = [];
|
|
776
|
+
for (const img of imageItems) {
|
|
777
|
+
const shape = imageToShape(img, page.heightPt, pageIndex, images);
|
|
778
|
+
if (shape !== void 0) imageShapes.push(shape);
|
|
779
|
+
}
|
|
780
|
+
const recoveredVectors = recoverPageVectors(page, pageIndex, claimedItems);
|
|
781
|
+
const vectorShapes = recoveredVectors === void 0 ? [] : [wrapBlockInShape(recoveredVectors.block, {
|
|
782
|
+
xPt: 0,
|
|
783
|
+
yPt: 0,
|
|
784
|
+
widthPt: page.widthPt,
|
|
785
|
+
heightPt: page.heightPt
|
|
786
|
+
}, page.heightPt, pageIndex)];
|
|
787
|
+
const tableShapes = recoveredTables.map((recovered) => wrapBlockInShape(recovered.table, recovered.frame, page.heightPt, pageIndex));
|
|
788
|
+
return {
|
|
789
|
+
size: {
|
|
790
|
+
widthPt: page.widthPt,
|
|
791
|
+
heightPt: page.heightPt
|
|
792
|
+
},
|
|
793
|
+
shapes: [
|
|
794
|
+
...vectorShapes,
|
|
795
|
+
...imageShapes,
|
|
796
|
+
...tableShapes,
|
|
797
|
+
...textShapes
|
|
798
|
+
],
|
|
799
|
+
notes: page.notes ?? ""
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
function wrapBlockInShape(block, frame, pageHeightPt, pageIndex) {
|
|
803
|
+
const shape = {
|
|
804
|
+
frame,
|
|
805
|
+
insetLeftPt: 0,
|
|
806
|
+
insetTopPt: 0,
|
|
807
|
+
insetRightPt: 0,
|
|
808
|
+
insetBottomPt: 0,
|
|
809
|
+
blocks: [block]
|
|
810
|
+
};
|
|
811
|
+
require_layout_shared.stampFrame(shape, pageIndex, require_model_geometry.flipY(frame, pageHeightPt));
|
|
812
|
+
return shape;
|
|
813
|
+
}
|
|
814
|
+
function splitLineByLargeGaps(line) {
|
|
815
|
+
const segments = [];
|
|
816
|
+
let current = [];
|
|
817
|
+
line.items.forEach((item, i) => {
|
|
818
|
+
if (i > 0) {
|
|
819
|
+
const prev = line.items[i - 1];
|
|
820
|
+
if (require_layout_reconstruct_lines.gapExceeds(prev, item, 2 * item.sizePt)) {
|
|
821
|
+
segments.push({
|
|
822
|
+
items: current,
|
|
823
|
+
baselineY: line.baselineY
|
|
824
|
+
});
|
|
825
|
+
current = [];
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
current.push(item);
|
|
829
|
+
});
|
|
830
|
+
if (current.length > 0) segments.push({
|
|
831
|
+
items: current,
|
|
832
|
+
baselineY: line.baselineY
|
|
833
|
+
});
|
|
834
|
+
return segments;
|
|
835
|
+
}
|
|
836
|
+
function clusterIntoBlocks(pageLines) {
|
|
837
|
+
const segments = pageLines.flatMap(splitLineByLargeGaps);
|
|
838
|
+
const blocks = [];
|
|
839
|
+
for (const segment of segments) {
|
|
840
|
+
const leftX = segment.items[0].xPt;
|
|
841
|
+
const sizePt = segment.items[0].sizePt;
|
|
842
|
+
const matched = blocks.find((block) => {
|
|
843
|
+
const lastLine = block.lines[block.lines.length - 1];
|
|
844
|
+
const lastLeftX = lastLine.items[0].xPt;
|
|
845
|
+
const lastSizePt = lastLine.items[0].sizePt;
|
|
846
|
+
const gap = lastLine.baselineY - segment.baselineY;
|
|
847
|
+
if (gap <= 0) return false;
|
|
848
|
+
return Math.abs(leftX - lastLeftX) <= 2 && require_layout_reconstruct_lines.fontSizesClose(sizePt, lastSizePt) && gap <= 1.25 * lastSizePt;
|
|
849
|
+
});
|
|
850
|
+
if (matched !== void 0) matched.lines.push(segment);
|
|
851
|
+
else blocks.push({ lines: [segment] });
|
|
852
|
+
}
|
|
853
|
+
return blocks;
|
|
854
|
+
}
|
|
855
|
+
function computeBlockFrame(block, slideHeightPt) {
|
|
856
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
857
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
858
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
859
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
860
|
+
for (const line of block.lines) for (const item of line.items) {
|
|
861
|
+
const { ascentPt, descentPt } = require_layout_reconstruct_lines.textItemVerticalExtent(item);
|
|
862
|
+
minX = Math.min(minX, item.xPt);
|
|
863
|
+
maxX = Math.max(maxX, item.xPt + (item.widthPt ?? 0));
|
|
864
|
+
minY = Math.min(minY, item.yPt - descentPt);
|
|
865
|
+
maxY = Math.max(maxY, item.yPt + ascentPt);
|
|
866
|
+
}
|
|
867
|
+
return require_model_geometry.flipY({
|
|
868
|
+
xPt: minX,
|
|
869
|
+
yPt: minY,
|
|
870
|
+
widthPt: maxX - minX,
|
|
871
|
+
heightPt: maxY - minY
|
|
872
|
+
}, slideHeightPt);
|
|
873
|
+
}
|
|
874
|
+
function lineToParagraph(line, pageIndex) {
|
|
875
|
+
const paragraph = {
|
|
876
|
+
kind: "paragraph",
|
|
877
|
+
runs: []
|
|
878
|
+
};
|
|
879
|
+
require_layout_shared.stampFrame(paragraph, pageIndex, require_layout_reconstruct_lines.lineBox(line, pageIndex));
|
|
880
|
+
require_layout_reconstruct_lines.pushRunsForLine(paragraph.runs, line, pageIndex);
|
|
881
|
+
return paragraph;
|
|
882
|
+
}
|
|
883
|
+
function blockToShape(block, slideHeightPt, pageIndex) {
|
|
884
|
+
const shape = {
|
|
885
|
+
frame: computeBlockFrame(block, slideHeightPt),
|
|
886
|
+
insetLeftPt: 0,
|
|
887
|
+
insetTopPt: 0,
|
|
888
|
+
insetRightPt: 0,
|
|
889
|
+
insetBottomPt: 0,
|
|
890
|
+
blocks: block.lines.map((line) => lineToParagraph(line, pageIndex))
|
|
891
|
+
};
|
|
892
|
+
require_layout_shared.stampFrame(shape, pageIndex, require_model_geometry.flipY(shape.frame, slideHeightPt));
|
|
893
|
+
return shape;
|
|
894
|
+
}
|
|
895
|
+
function imageToShape(img, slideHeightPt, pageIndex, images) {
|
|
896
|
+
const asset = images[img.imageId];
|
|
897
|
+
if (asset === void 0) return;
|
|
898
|
+
const frame = require_model_geometry.flipY({
|
|
899
|
+
xPt: img.xPt,
|
|
900
|
+
yPt: img.yPt,
|
|
901
|
+
widthPt: img.widthPt,
|
|
902
|
+
heightPt: img.heightPt
|
|
903
|
+
}, slideHeightPt);
|
|
904
|
+
const block = {
|
|
905
|
+
kind: "image",
|
|
906
|
+
format: asset.format,
|
|
907
|
+
base64: asset.base64,
|
|
908
|
+
widthPt: img.widthPt,
|
|
909
|
+
heightPt: img.heightPt
|
|
910
|
+
};
|
|
911
|
+
require_layout_shared.stampFrame(block, pageIndex, {
|
|
912
|
+
xPt: img.xPt,
|
|
913
|
+
yPt: img.yPt,
|
|
914
|
+
widthPt: img.widthPt,
|
|
915
|
+
heightPt: img.heightPt
|
|
916
|
+
});
|
|
917
|
+
const shape = {
|
|
918
|
+
frame,
|
|
919
|
+
rotationDeg: img.rotationDeg !== void 0 ? -img.rotationDeg : void 0,
|
|
920
|
+
insetLeftPt: 0,
|
|
921
|
+
insetTopPt: 0,
|
|
922
|
+
insetRightPt: 0,
|
|
923
|
+
insetBottomPt: 0,
|
|
924
|
+
blocks: [block]
|
|
925
|
+
};
|
|
926
|
+
require_layout_shared.stampFrame(shape, pageIndex, {
|
|
927
|
+
xPt: img.xPt,
|
|
928
|
+
yPt: img.yPt,
|
|
929
|
+
widthPt: img.widthPt,
|
|
930
|
+
heightPt: img.heightPt
|
|
931
|
+
});
|
|
932
|
+
return shape;
|
|
933
|
+
}
|
|
934
|
+
function reconstructDrawing(doc, options) {
|
|
935
|
+
const signal = options?.signal;
|
|
936
|
+
const pages = doc.pages.map((page, pageIndex) => {
|
|
937
|
+
require_ports_abort.throwIfAborted(signal);
|
|
938
|
+
return reconstructDrawPage(page, pageIndex, doc.images);
|
|
939
|
+
});
|
|
940
|
+
return {
|
|
941
|
+
kind: "drawing",
|
|
942
|
+
metadata: doc.metadata,
|
|
943
|
+
pages
|
|
944
|
+
};
|
|
945
|
+
}
|
|
946
|
+
function reconstructDrawPage(page, pageIndex, images) {
|
|
947
|
+
const vectors = [];
|
|
948
|
+
const shapes = [];
|
|
949
|
+
let paintOrder = 0;
|
|
950
|
+
for (const item of page.items) {
|
|
951
|
+
const vector = layoutItemToVector(item, page.heightPt);
|
|
952
|
+
if (vector !== void 0) {
|
|
953
|
+
stampVectorFrame(vector, item, pageIndex);
|
|
954
|
+
vectors.push({
|
|
955
|
+
...vector,
|
|
956
|
+
paintOrder: paintOrder++
|
|
957
|
+
});
|
|
958
|
+
continue;
|
|
959
|
+
}
|
|
960
|
+
if (item.kind === "text") {
|
|
961
|
+
const shape = layoutTextToShape(item, page.heightPt, pageIndex);
|
|
962
|
+
require_layout_shared.stampFrame(shape, pageIndex, require_model_geometry.flipY(shape.frame, page.heightPt));
|
|
963
|
+
shapes.push({
|
|
964
|
+
...shape,
|
|
965
|
+
paintOrder: paintOrder++
|
|
966
|
+
});
|
|
967
|
+
} else if (item.kind === "image") {
|
|
968
|
+
const shape = imageToShape(item, page.heightPt, pageIndex, images);
|
|
969
|
+
if (shape !== void 0) shapes.push({
|
|
970
|
+
...shape,
|
|
971
|
+
paintOrder: paintOrder++
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
return {
|
|
976
|
+
size: {
|
|
977
|
+
widthPt: page.widthPt,
|
|
978
|
+
heightPt: page.heightPt
|
|
979
|
+
},
|
|
980
|
+
shapes,
|
|
981
|
+
vectors
|
|
982
|
+
};
|
|
983
|
+
}
|
|
984
|
+
function stampVectorFrame(vector, item, pageIndex) {
|
|
985
|
+
if (item.kind === "rect" || item.kind === "ellipse") {
|
|
986
|
+
require_layout_shared.stampFrame(vector, pageIndex, {
|
|
987
|
+
xPt: item.xPt,
|
|
988
|
+
yPt: item.yPt,
|
|
989
|
+
widthPt: item.widthPt,
|
|
990
|
+
heightPt: item.heightPt
|
|
991
|
+
});
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
if (item.kind === "line") {
|
|
995
|
+
require_layout_shared.stampFrame(vector, pageIndex, {
|
|
996
|
+
xPt: Math.min(item.x1Pt, item.x2Pt),
|
|
997
|
+
yPt: Math.min(item.y1Pt, item.y2Pt),
|
|
998
|
+
widthPt: Math.abs(item.x2Pt - item.x1Pt),
|
|
999
|
+
heightPt: Math.abs(item.y2Pt - item.y1Pt)
|
|
1000
|
+
});
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
if (item.kind !== "path") return;
|
|
1004
|
+
const points = collectPathPoints(item.subpaths);
|
|
1005
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
1006
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
1007
|
+
let minY = Number.POSITIVE_INFINITY;
|
|
1008
|
+
let maxY = Number.NEGATIVE_INFINITY;
|
|
1009
|
+
for (const point of points) {
|
|
1010
|
+
minX = Math.min(minX, point.xPt);
|
|
1011
|
+
maxX = Math.max(maxX, point.xPt);
|
|
1012
|
+
minY = Math.min(minY, point.yPt);
|
|
1013
|
+
maxY = Math.max(maxY, point.yPt);
|
|
1014
|
+
}
|
|
1015
|
+
require_layout_shared.stampFrame(vector, pageIndex, {
|
|
1016
|
+
xPt: minX,
|
|
1017
|
+
yPt: minY,
|
|
1018
|
+
widthPt: maxX - minX,
|
|
1019
|
+
heightPt: maxY - minY
|
|
1020
|
+
});
|
|
1021
|
+
}
|
|
1022
|
+
function layoutItemToVector(item, pageHeightPt) {
|
|
1023
|
+
if (item.kind === "rect") return layoutRectToVector(item, pageHeightPt);
|
|
1024
|
+
if (item.kind === "ellipse") return layoutEllipseToVector(item, pageHeightPt);
|
|
1025
|
+
if (item.kind === "line") return layoutLineToVector(item, pageHeightPt);
|
|
1026
|
+
if (item.kind === "path") return layoutPathToVector(item, pageHeightPt);
|
|
1027
|
+
}
|
|
1028
|
+
function layoutRectToVector(item, pageHeightPt) {
|
|
1029
|
+
return {
|
|
1030
|
+
kind: "rect",
|
|
1031
|
+
frame: require_model_geometry.flipY({
|
|
1032
|
+
xPt: item.xPt,
|
|
1033
|
+
yPt: item.yPt,
|
|
1034
|
+
widthPt: item.widthPt,
|
|
1035
|
+
heightPt: item.heightPt
|
|
1036
|
+
}, pageHeightPt),
|
|
1037
|
+
fill: item.fill,
|
|
1038
|
+
stroke: item.stroke,
|
|
1039
|
+
sourcePath: item.sourcePath
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
function layoutEllipseToVector(item, pageHeightPt) {
|
|
1043
|
+
return {
|
|
1044
|
+
kind: "ellipse",
|
|
1045
|
+
frame: require_model_geometry.flipY({
|
|
1046
|
+
xPt: item.xPt,
|
|
1047
|
+
yPt: item.yPt,
|
|
1048
|
+
widthPt: item.widthPt,
|
|
1049
|
+
heightPt: item.heightPt
|
|
1050
|
+
}, pageHeightPt),
|
|
1051
|
+
fill: item.fill,
|
|
1052
|
+
stroke: item.stroke,
|
|
1053
|
+
sourcePath: item.sourcePath
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
function layoutLineToVector(item, pageHeightPt) {
|
|
1057
|
+
return {
|
|
1058
|
+
kind: "line",
|
|
1059
|
+
from: {
|
|
1060
|
+
xPt: item.x1Pt,
|
|
1061
|
+
yPt: pageHeightPt - item.y1Pt
|
|
1062
|
+
},
|
|
1063
|
+
to: {
|
|
1064
|
+
xPt: item.x2Pt,
|
|
1065
|
+
yPt: pageHeightPt - item.y2Pt
|
|
1066
|
+
},
|
|
1067
|
+
stroke: {
|
|
1068
|
+
color: item.color,
|
|
1069
|
+
widthPt: item.widthPt
|
|
1070
|
+
},
|
|
1071
|
+
sourcePath: item.sourcePath
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
function collectPathPoints(subpaths) {
|
|
1075
|
+
const points = [];
|
|
1076
|
+
for (const subpath of subpaths) {
|
|
1077
|
+
points.push({
|
|
1078
|
+
xPt: subpath.startXPt,
|
|
1079
|
+
yPt: subpath.startYPt
|
|
1080
|
+
});
|
|
1081
|
+
for (const segment of subpath.segments) {
|
|
1082
|
+
if (segment.kind === "cubic") {
|
|
1083
|
+
points.push({
|
|
1084
|
+
xPt: segment.c1xPt,
|
|
1085
|
+
yPt: segment.c1yPt
|
|
1086
|
+
});
|
|
1087
|
+
points.push({
|
|
1088
|
+
xPt: segment.c2xPt,
|
|
1089
|
+
yPt: segment.c2yPt
|
|
1090
|
+
});
|
|
1091
|
+
}
|
|
1092
|
+
points.push({
|
|
1093
|
+
xPt: segment.xPt,
|
|
1094
|
+
yPt: segment.yPt
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
return points;
|
|
1099
|
+
}
|
|
1100
|
+
function pathBoundingFrame(points, pageHeightPt) {
|
|
1101
|
+
if (points.length === 0) return {
|
|
1102
|
+
xPt: 0,
|
|
1103
|
+
yPt: 0,
|
|
1104
|
+
widthPt: 0,
|
|
1105
|
+
heightPt: 0
|
|
1106
|
+
};
|
|
1107
|
+
let minX = Number.POSITIVE_INFINITY;
|
|
1108
|
+
let maxX = Number.NEGATIVE_INFINITY;
|
|
1109
|
+
let minYDown = Number.POSITIVE_INFINITY;
|
|
1110
|
+
let maxYDown = Number.NEGATIVE_INFINITY;
|
|
1111
|
+
for (const point of points) {
|
|
1112
|
+
const yDown = pageHeightPt - point.yPt;
|
|
1113
|
+
minX = Math.min(minX, point.xPt);
|
|
1114
|
+
maxX = Math.max(maxX, point.xPt);
|
|
1115
|
+
minYDown = Math.min(minYDown, yDown);
|
|
1116
|
+
maxYDown = Math.max(maxYDown, yDown);
|
|
1117
|
+
}
|
|
1118
|
+
return {
|
|
1119
|
+
xPt: minX,
|
|
1120
|
+
yPt: minYDown,
|
|
1121
|
+
widthPt: maxX - minX,
|
|
1122
|
+
heightPt: maxYDown - minYDown
|
|
1123
|
+
};
|
|
1124
|
+
}
|
|
1125
|
+
function localizePathPoint(frame, point, pageHeightPt) {
|
|
1126
|
+
return {
|
|
1127
|
+
xPt: point.xPt - frame.xPt,
|
|
1128
|
+
yPt: pageHeightPt - frame.yPt - point.yPt
|
|
1129
|
+
};
|
|
1130
|
+
}
|
|
1131
|
+
function layoutPathToVector(item, pageHeightPt) {
|
|
1132
|
+
const frame = pathBoundingFrame(collectPathPoints(item.subpaths), pageHeightPt);
|
|
1133
|
+
return {
|
|
1134
|
+
kind: "path",
|
|
1135
|
+
frame,
|
|
1136
|
+
subpaths: item.subpaths.map((subpath) => ({
|
|
1137
|
+
start: localizePathPoint(frame, {
|
|
1138
|
+
xPt: subpath.startXPt,
|
|
1139
|
+
yPt: subpath.startYPt
|
|
1140
|
+
}, pageHeightPt),
|
|
1141
|
+
closed: subpath.closed,
|
|
1142
|
+
segments: subpath.segments.map((segment) => {
|
|
1143
|
+
if (segment.kind === "line") return {
|
|
1144
|
+
kind: "line",
|
|
1145
|
+
to: localizePathPoint(frame, {
|
|
1146
|
+
xPt: segment.xPt,
|
|
1147
|
+
yPt: segment.yPt
|
|
1148
|
+
}, pageHeightPt)
|
|
1149
|
+
};
|
|
1150
|
+
return {
|
|
1151
|
+
kind: "cubic",
|
|
1152
|
+
control1: localizePathPoint(frame, {
|
|
1153
|
+
xPt: segment.c1xPt,
|
|
1154
|
+
yPt: segment.c1yPt
|
|
1155
|
+
}, pageHeightPt),
|
|
1156
|
+
control2: localizePathPoint(frame, {
|
|
1157
|
+
xPt: segment.c2xPt,
|
|
1158
|
+
yPt: segment.c2yPt
|
|
1159
|
+
}, pageHeightPt),
|
|
1160
|
+
to: localizePathPoint(frame, {
|
|
1161
|
+
xPt: segment.xPt,
|
|
1162
|
+
yPt: segment.yPt
|
|
1163
|
+
}, pageHeightPt)
|
|
1164
|
+
};
|
|
1165
|
+
})
|
|
1166
|
+
})),
|
|
1167
|
+
fill: item.fill,
|
|
1168
|
+
fillRule: item.fillRule,
|
|
1169
|
+
stroke: item.stroke,
|
|
1170
|
+
sourcePath: item.sourcePath
|
|
1171
|
+
};
|
|
1172
|
+
}
|
|
1173
|
+
function layoutTextToShape(item, pageHeightPt, pageIndex) {
|
|
1174
|
+
const frame = computeBlockFrame({ lines: [{
|
|
1175
|
+
items: [item],
|
|
1176
|
+
baselineY: item.yPt
|
|
1177
|
+
}] }, pageHeightPt);
|
|
1178
|
+
const run = require_layout_reconstruct_lines.textItemToContentRun(item);
|
|
1179
|
+
require_layout_shared.stampFrame(run, pageIndex, require_layout_reconstruct_lines.textBoxOfItem(item, pageIndex));
|
|
1180
|
+
const paragraph = {
|
|
1181
|
+
kind: "paragraph",
|
|
1182
|
+
runs: [run]
|
|
1183
|
+
};
|
|
1184
|
+
require_layout_shared.stampFrame(paragraph, pageIndex, require_layout_reconstruct_lines.textBoxOfItem(item, pageIndex));
|
|
1185
|
+
return {
|
|
1186
|
+
frame,
|
|
1187
|
+
rotationDeg: item.rotationDeg !== void 0 ? -item.rotationDeg : void 0,
|
|
1188
|
+
insetLeftPt: 0,
|
|
1189
|
+
insetTopPt: 0,
|
|
1190
|
+
insetRightPt: 0,
|
|
1191
|
+
insetBottomPt: 0,
|
|
1192
|
+
blocks: [paragraph]
|
|
1193
|
+
};
|
|
1194
|
+
}
|
|
1195
|
+
function vectorTopYDownPt(vector) {
|
|
1196
|
+
return vector.kind === "line" ? Math.min(vector.from.yPt, vector.to.yPt) : vector.frame.yPt;
|
|
1197
|
+
}
|
|
1198
|
+
function recoverPageVectors(page, pageIndex, excluded) {
|
|
1199
|
+
const vectors = [];
|
|
1200
|
+
for (const item of page.items) {
|
|
1201
|
+
if (excluded.has(item)) continue;
|
|
1202
|
+
const vector = layoutItemToVector(item, page.heightPt);
|
|
1203
|
+
if (vector !== void 0) {
|
|
1204
|
+
stampVectorFrame(vector, item, pageIndex);
|
|
1205
|
+
vectors.push({
|
|
1206
|
+
...vector,
|
|
1207
|
+
paintOrder: vectors.length
|
|
1208
|
+
});
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
if (vectors.length === 0) return;
|
|
1212
|
+
const topYDownPt = Math.min(...vectors.map(vectorTopYDownPt));
|
|
1213
|
+
const block = require_model_embedded_drawing.buildDrawingBlock({
|
|
1214
|
+
widthPt: page.widthPt,
|
|
1215
|
+
heightPt: page.heightPt
|
|
1216
|
+
}, vectors);
|
|
1217
|
+
require_layout_shared.stampFrame(block, pageIndex, {
|
|
1218
|
+
xPt: 0,
|
|
1219
|
+
yPt: 0,
|
|
1220
|
+
widthPt: page.widthPt,
|
|
1221
|
+
heightPt: page.heightPt
|
|
1222
|
+
});
|
|
1223
|
+
return {
|
|
1224
|
+
block,
|
|
1225
|
+
topYPt: page.heightPt - topYDownPt
|
|
1226
|
+
};
|
|
1227
|
+
}
|
|
1228
|
+
function reconstructSheet(page, pageIndex, sink) {
|
|
1229
|
+
const textItems = page.items.filter((i) => i.kind === "text");
|
|
1230
|
+
const lattice = require_layout_lattice.detectGridLattice(page.items);
|
|
1231
|
+
const context = {
|
|
1232
|
+
sheetIndex: pageIndex,
|
|
1233
|
+
sink
|
|
1234
|
+
};
|
|
1235
|
+
const grid = lattice !== void 0 ? buildGridFromLattice(textItems, lattice, pageIndex, context) : buildGridFromTextClustering(textItems, pageIndex, context);
|
|
1236
|
+
const printSettings = {
|
|
1237
|
+
pageSize: {
|
|
1238
|
+
widthPt: page.widthPt,
|
|
1239
|
+
heightPt: page.heightPt
|
|
1240
|
+
},
|
|
1241
|
+
margins: ZERO_MARGINS,
|
|
1242
|
+
gridlines: grid.gridlines,
|
|
1243
|
+
headers: false,
|
|
1244
|
+
pageOrder: "downThenOver"
|
|
1245
|
+
};
|
|
1246
|
+
return {
|
|
1247
|
+
name: `Sheet${pageIndex + 1}`,
|
|
1248
|
+
cells: grid.cells,
|
|
1249
|
+
columns: grid.columns,
|
|
1250
|
+
rows: grid.rows,
|
|
1251
|
+
images: [],
|
|
1252
|
+
printSettings
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
//#endregion
|
|
1256
|
+
Object.defineProperty(exports, "CELL_TYPES", {
|
|
1257
|
+
enumerable: true,
|
|
1258
|
+
get: function() {
|
|
1259
|
+
return CELL_TYPES;
|
|
1260
|
+
}
|
|
1261
|
+
});
|
|
1262
|
+
Object.defineProperty(exports, "DEFAULT_COLUMN_WIDTH_FALLBACK_PT", {
|
|
1263
|
+
enumerable: true,
|
|
1264
|
+
get: function() {
|
|
1265
|
+
return DEFAULT_COLUMN_WIDTH_FALLBACK_PT;
|
|
1266
|
+
}
|
|
1267
|
+
});
|
|
1268
|
+
Object.defineProperty(exports, "NO_ITEMS", {
|
|
1269
|
+
enumerable: true,
|
|
1270
|
+
get: function() {
|
|
1271
|
+
return NO_ITEMS;
|
|
1272
|
+
}
|
|
1273
|
+
});
|
|
1274
|
+
Object.defineProperty(exports, "ROW_TYPES", {
|
|
1275
|
+
enumerable: true,
|
|
1276
|
+
get: function() {
|
|
1277
|
+
return ROW_TYPES;
|
|
1278
|
+
}
|
|
1279
|
+
});
|
|
1280
|
+
Object.defineProperty(exports, "TABLE_TYPES", {
|
|
1281
|
+
enumerable: true,
|
|
1282
|
+
get: function() {
|
|
1283
|
+
return TABLE_TYPES;
|
|
1284
|
+
}
|
|
1285
|
+
});
|
|
1286
|
+
Object.defineProperty(exports, "ZERO_MARGINS", {
|
|
1287
|
+
enumerable: true,
|
|
1288
|
+
get: function() {
|
|
1289
|
+
return ZERO_MARGINS;
|
|
1290
|
+
}
|
|
1291
|
+
});
|
|
1292
|
+
Object.defineProperty(exports, "buildGridFromLattice", {
|
|
1293
|
+
enumerable: true,
|
|
1294
|
+
get: function() {
|
|
1295
|
+
return buildGridFromLattice;
|
|
1296
|
+
}
|
|
1297
|
+
});
|
|
1298
|
+
Object.defineProperty(exports, "buildGridFromTextClustering", {
|
|
1299
|
+
enumerable: true,
|
|
1300
|
+
get: function() {
|
|
1301
|
+
return buildGridFromTextClustering;
|
|
1302
|
+
}
|
|
1303
|
+
});
|
|
1304
|
+
Object.defineProperty(exports, "indexStructure", {
|
|
1305
|
+
enumerable: true,
|
|
1306
|
+
get: function() {
|
|
1307
|
+
return indexStructure;
|
|
1308
|
+
}
|
|
1309
|
+
});
|
|
1310
|
+
Object.defineProperty(exports, "layoutItemToVector", {
|
|
1311
|
+
enumerable: true,
|
|
1312
|
+
get: function() {
|
|
1313
|
+
return layoutItemToVector;
|
|
1314
|
+
}
|
|
1315
|
+
});
|
|
1316
|
+
Object.defineProperty(exports, "lineToParagraph", {
|
|
1317
|
+
enumerable: true,
|
|
1318
|
+
get: function() {
|
|
1319
|
+
return lineToParagraph;
|
|
1320
|
+
}
|
|
1321
|
+
});
|
|
1322
|
+
Object.defineProperty(exports, "nearestOfType", {
|
|
1323
|
+
enumerable: true,
|
|
1324
|
+
get: function() {
|
|
1325
|
+
return nearestOfType;
|
|
1326
|
+
}
|
|
1327
|
+
});
|
|
1328
|
+
Object.defineProperty(exports, "reconstructDrawing", {
|
|
1329
|
+
enumerable: true,
|
|
1330
|
+
get: function() {
|
|
1331
|
+
return reconstructDrawing;
|
|
1332
|
+
}
|
|
1333
|
+
});
|
|
1334
|
+
Object.defineProperty(exports, "reconstructPresentation", {
|
|
1335
|
+
enumerable: true,
|
|
1336
|
+
get: function() {
|
|
1337
|
+
return reconstructPresentation;
|
|
1338
|
+
}
|
|
1339
|
+
});
|
|
1340
|
+
Object.defineProperty(exports, "reconstructSheet", {
|
|
1341
|
+
enumerable: true,
|
|
1342
|
+
get: function() {
|
|
1343
|
+
return reconstructSheet;
|
|
1344
|
+
}
|
|
1345
|
+
});
|
|
1346
|
+
Object.defineProperty(exports, "reconstructSpreadsheet", {
|
|
1347
|
+
enumerable: true,
|
|
1348
|
+
get: function() {
|
|
1349
|
+
return reconstructSpreadsheet;
|
|
1350
|
+
}
|
|
1351
|
+
});
|
|
1352
|
+
Object.defineProperty(exports, "reconstructWordprocessing", {
|
|
1353
|
+
enumerable: true,
|
|
1354
|
+
get: function() {
|
|
1355
|
+
return reconstructWordprocessing;
|
|
1356
|
+
}
|
|
1357
|
+
});
|
|
1358
|
+
Object.defineProperty(exports, "recoverPageVectors", {
|
|
1359
|
+
enumerable: true,
|
|
1360
|
+
get: function() {
|
|
1361
|
+
return recoverPageVectors;
|
|
1362
|
+
}
|
|
1363
|
+
});
|
|
1364
|
+
Object.defineProperty(exports, "recoverTables", {
|
|
1365
|
+
enumerable: true,
|
|
1366
|
+
get: function() {
|
|
1367
|
+
return recoverTables;
|
|
1368
|
+
}
|
|
1369
|
+
});
|
|
1370
|
+
Object.defineProperty(exports, "splitLineByLargeGaps", {
|
|
1371
|
+
enumerable: true,
|
|
1372
|
+
get: function() {
|
|
1373
|
+
return splitLineByLargeGaps;
|
|
1374
|
+
}
|
|
1375
|
+
});
|