kordoc 4.12.0 → 4.12.2
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 +26 -5
- package/dist/{-B3EUUBPV.js → -EZH6NKTE.js} +8 -8
- package/dist/{chunk-HGUNWAXK.js → chunk-2B7OIEJJ.js} +9 -5
- package/dist/chunk-2B7OIEJJ.js.map +1 -0
- package/dist/{chunk-QKFCGJJY.js → chunk-2HBYWA5X.js} +2 -2
- package/dist/{chunk-HFJWCAJ2.cjs → chunk-2LKYJ4G3.cjs} +6 -6
- package/dist/chunk-2LKYJ4G3.cjs.map +1 -0
- package/dist/{chunk-COGFPMEB.js → chunk-2LO525TL.js} +2 -2
- package/dist/{chunk-TROD36DK.cjs → chunk-2LPBIW2B.cjs} +3 -3
- package/dist/chunk-2LPBIW2B.cjs.map +1 -0
- package/dist/{chunk-BQSWSMRG.cjs → chunk-62IU4NV3.cjs} +2 -2
- package/dist/chunk-62IU4NV3.cjs.map +1 -0
- package/dist/{chunk-SMGSCP57.js → chunk-7XUXSDH5.js} +308 -53
- package/dist/chunk-7XUXSDH5.js.map +1 -0
- package/dist/{chunk-YASFVKDT.js → chunk-DBGEUDBY.js} +2 -2
- package/dist/chunk-DCZVOIEO.cjs.map +1 -1
- package/dist/{chunk-4PKNWBXJ.js → chunk-FBLMVHDK.js} +2 -2
- package/dist/{chunk-I2OETEEL.js → chunk-FVBR7SC3.js} +2 -2
- package/dist/chunk-GS7T56RP.cjs.map +1 -1
- package/dist/{chunk-46UDI56N.js → chunk-IOJX4Q63.js} +3 -3
- package/dist/{chunk-BQE7AMFS.js → chunk-JCMBQC5N.js} +2 -2
- package/dist/{chunk-TF5DS74F.js → chunk-KX7IYCCZ.js} +3 -3
- package/dist/{chunk-PFUW4I4I.js → chunk-LD2K4K5V.js} +170 -18
- package/dist/chunk-LD2K4K5V.js.map +1 -0
- package/dist/{chunk-MJPRWCI5.js → chunk-MUYU4JI5.js} +2 -2
- package/dist/{chunk-SKGYPM6L.js → chunk-OEYECZGV.js} +308 -53
- package/dist/chunk-OEYECZGV.js.map +1 -0
- package/dist/{chunk-AT23GFSK.cjs → chunk-ONNAHSPV.cjs} +323 -68
- package/dist/chunk-ONNAHSPV.cjs.map +1 -0
- package/dist/{chunk-GHVXLV52.js → chunk-Q6ETEJFK.js} +9 -5
- package/dist/chunk-Q6ETEJFK.js.map +1 -0
- package/dist/{chunk-2IR3PEZU.js → chunk-QBCMFNHS.js} +2 -2
- package/dist/{chunk-DRLKMFDV.js → chunk-QM2RSJ2S.js} +3 -3
- package/dist/chunk-T7GRHAIW.cjs.map +1 -1
- package/dist/{chunk-TJYZY2O6.js → chunk-UL2MDA5C.js} +3 -3
- package/dist/{chunk-TYYJSOZS.cjs → chunk-V5BUPZ6I.cjs} +23 -19
- package/dist/chunk-V5BUPZ6I.cjs.map +1 -0
- package/dist/{chunk-7JQ2ITT2.js → chunk-XXDZ2KTW.js} +2 -2
- package/dist/chunks-TT7ZE5QQ.js +10 -0
- package/dist/cli.js +21 -21
- package/dist/cli.js.map +1 -1
- package/dist/{formula-WGKKR5OQ.js → formula-6RQX4NMJ.js} +4 -4
- package/dist/{formula-YMGXXRBQ.cjs → formula-NBEO6CFC.cjs} +9 -9
- package/dist/formula-NBEO6CFC.cjs.map +1 -0
- package/dist/{formula-G4CD5KQ6.js → formula-NW33S4TA.js} +3 -3
- package/dist/{image-ocr-MBWZK3ZT.js → image-ocr-CAVU2TNZ.js} +5 -5
- package/dist/{image-ocr-M4RP4INO.js → image-ocr-SO56VETS.js} +7 -7
- package/dist/{image-ocr-BE2HHMVN.cjs → image-ocr-V4KY373B.cjs} +11 -11
- package/dist/image-ocr-V4KY373B.cjs.map +1 -0
- package/dist/index.cjs +547 -395
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +166 -14
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +15 -15
- package/dist/{model-bundle-BIMP5DIH.js → model-bundle-EIJF34DR.js} +5 -5
- package/dist/{models-QPOEGHVA.js → models-6V4CPQXC.js} +5 -5
- package/dist/page-range-P7SDW6LR.cjs.map +1 -1
- package/dist/{parser-CMNHBVTL.js → parser-GIREMEPD.js} +307 -6
- package/dist/parser-GIREMEPD.js.map +1 -0
- package/dist/{parser-NR3XO4SM.js → parser-OBHNXEQM.js} +307 -6
- package/dist/parser-OBHNXEQM.js.map +1 -0
- package/dist/{parser-QJY5W47V.cjs → parser-OMT25WH2.cjs} +334 -33
- package/dist/parser-OMT25WH2.cjs.map +1 -0
- package/dist/pdf-ocr-IRXQ5GBM.js +13 -0
- package/dist/pdf-ocr-SL4GCOGS.js +16 -0
- package/dist/pdf-ocr-TFYVK4FI.cjs +14 -0
- package/dist/pdf-ocr-TFYVK4FI.cjs.map +1 -0
- package/dist/{profile-io-UZ43CLWX.js → profile-io-PZVMM66V.js} +3 -3
- package/dist/{rasterize-JC2JVVOF.js → rasterize-NRWP2C6L.js} +2 -2
- package/dist/render-V5ZPTZQ7.js +10 -0
- package/dist/seal-LVG2DGAB.js +10 -0
- package/dist/{setup-WDUVPFX3.js → setup-V55AJP6H.js} +3 -3
- package/dist/{watch-UI7OXIES.js → watch-7CQSMDDP.js} +9 -9
- package/package.json +1 -1
- package/dist/chunk-AT23GFSK.cjs.map +0 -1
- package/dist/chunk-BQSWSMRG.cjs.map +0 -1
- package/dist/chunk-GHVXLV52.js.map +0 -1
- package/dist/chunk-HFJWCAJ2.cjs.map +0 -1
- package/dist/chunk-HGUNWAXK.js.map +0 -1
- package/dist/chunk-PFUW4I4I.js.map +0 -1
- package/dist/chunk-SKGYPM6L.js.map +0 -1
- package/dist/chunk-SMGSCP57.js.map +0 -1
- package/dist/chunk-TROD36DK.cjs.map +0 -1
- package/dist/chunk-TYYJSOZS.cjs.map +0 -1
- package/dist/chunks-Q4GCPRRU.js +0 -10
- package/dist/formula-YMGXXRBQ.cjs.map +0 -1
- package/dist/image-ocr-BE2HHMVN.cjs.map +0 -1
- package/dist/parser-CMNHBVTL.js.map +0 -1
- package/dist/parser-NR3XO4SM.js.map +0 -1
- package/dist/parser-QJY5W47V.cjs.map +0 -1
- package/dist/pdf-ocr-DF3OTBKH.js +0 -13
- package/dist/pdf-ocr-R4DIKF4Q.js +0 -16
- package/dist/pdf-ocr-T3RHIZKY.cjs +0 -14
- package/dist/pdf-ocr-T3RHIZKY.cjs.map +0 -1
- package/dist/render-KSQ6UGCP.js +0 -10
- package/dist/seal-EOFFQ4JR.js +0 -10
- /package/dist/{-B3EUUBPV.js.map → -EZH6NKTE.js.map} +0 -0
- /package/dist/{chunk-QKFCGJJY.js.map → chunk-2HBYWA5X.js.map} +0 -0
- /package/dist/{chunk-COGFPMEB.js.map → chunk-2LO525TL.js.map} +0 -0
- /package/dist/{chunk-YASFVKDT.js.map → chunk-DBGEUDBY.js.map} +0 -0
- /package/dist/{chunk-4PKNWBXJ.js.map → chunk-FBLMVHDK.js.map} +0 -0
- /package/dist/{chunk-I2OETEEL.js.map → chunk-FVBR7SC3.js.map} +0 -0
- /package/dist/{chunk-46UDI56N.js.map → chunk-IOJX4Q63.js.map} +0 -0
- /package/dist/{chunk-BQE7AMFS.js.map → chunk-JCMBQC5N.js.map} +0 -0
- /package/dist/{chunk-TF5DS74F.js.map → chunk-KX7IYCCZ.js.map} +0 -0
- /package/dist/{chunk-MJPRWCI5.js.map → chunk-MUYU4JI5.js.map} +0 -0
- /package/dist/{chunk-2IR3PEZU.js.map → chunk-QBCMFNHS.js.map} +0 -0
- /package/dist/{chunk-DRLKMFDV.js.map → chunk-QM2RSJ2S.js.map} +0 -0
- /package/dist/{chunk-TJYZY2O6.js.map → chunk-UL2MDA5C.js.map} +0 -0
- /package/dist/{chunk-7JQ2ITT2.js.map → chunk-XXDZ2KTW.js.map} +0 -0
- /package/dist/{chunks-Q4GCPRRU.js.map → chunks-TT7ZE5QQ.js.map} +0 -0
- /package/dist/{formula-WGKKR5OQ.js.map → formula-6RQX4NMJ.js.map} +0 -0
- /package/dist/{formula-G4CD5KQ6.js.map → formula-NW33S4TA.js.map} +0 -0
- /package/dist/{image-ocr-MBWZK3ZT.js.map → image-ocr-CAVU2TNZ.js.map} +0 -0
- /package/dist/{image-ocr-M4RP4INO.js.map → image-ocr-SO56VETS.js.map} +0 -0
- /package/dist/{model-bundle-BIMP5DIH.js.map → model-bundle-EIJF34DR.js.map} +0 -0
- /package/dist/{models-QPOEGHVA.js.map → models-6V4CPQXC.js.map} +0 -0
- /package/dist/{pdf-ocr-DF3OTBKH.js.map → pdf-ocr-IRXQ5GBM.js.map} +0 -0
- /package/dist/{pdf-ocr-R4DIKF4Q.js.map → pdf-ocr-SL4GCOGS.js.map} +0 -0
- /package/dist/{profile-io-UZ43CLWX.js.map → profile-io-PZVMM66V.js.map} +0 -0
- /package/dist/{rasterize-JC2JVVOF.js.map → rasterize-NRWP2C6L.js.map} +0 -0
- /package/dist/{render-KSQ6UGCP.js.map → render-V5ZPTZQ7.js.map} +0 -0
- /package/dist/{seal-EOFFQ4JR.js.map → seal-LVG2DGAB.js.map} +0 -0
- /package/dist/{setup-WDUVPFX3.js.map → setup-V55AJP6H.js.map} +0 -0
- /package/dist/{watch-UI7OXIES.js.map → watch-7CQSMDDP.js.map} +0 -0
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
safeMax,
|
|
8
8
|
safeMin
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-MUYU4JI5.js";
|
|
10
10
|
|
|
11
11
|
// src/pdf/image-regions.ts
|
|
12
12
|
import { OPS } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
@@ -68,6 +68,8 @@ var MAX_LINE_WIDTH = 5;
|
|
|
68
68
|
function extractLines(fnArray, argsArray) {
|
|
69
69
|
const horizontals = [];
|
|
70
70
|
const verticals = [];
|
|
71
|
+
const clipRects = [];
|
|
72
|
+
let pendingClip = false;
|
|
71
73
|
let lineWidth = 1;
|
|
72
74
|
let ctm = [1, 0, 0, 1, 0, 0];
|
|
73
75
|
const ctmStack = [];
|
|
@@ -97,9 +99,12 @@ function extractLines(fnArray, argsArray) {
|
|
|
97
99
|
}
|
|
98
100
|
function flushPath(isStroke, fromFill = false) {
|
|
99
101
|
if (!isStroke) {
|
|
102
|
+
if (pendingClip) captureClipRect(currentPath, clipRects);
|
|
103
|
+
pendingClip = false;
|
|
100
104
|
currentPath = [];
|
|
101
105
|
return;
|
|
102
106
|
}
|
|
107
|
+
pendingClip = false;
|
|
103
108
|
const effWidth = lineWidth * ctmScale();
|
|
104
109
|
for (const seg of currentPath) {
|
|
105
110
|
classifyAndAdd(seg, effWidth, horizontals, verticals, fromFill);
|
|
@@ -227,9 +232,29 @@ function extractLines(fnArray, argsArray) {
|
|
|
227
232
|
case OPS2.endPath:
|
|
228
233
|
flushPath(false);
|
|
229
234
|
break;
|
|
235
|
+
case OPS2.clip:
|
|
236
|
+
case OPS2.eoClip:
|
|
237
|
+
pendingClip = true;
|
|
238
|
+
break;
|
|
230
239
|
}
|
|
231
240
|
}
|
|
232
|
-
return { horizontals, verticals };
|
|
241
|
+
return { horizontals, verticals, clipRects };
|
|
242
|
+
}
|
|
243
|
+
var CLIP_MIN_W = 4;
|
|
244
|
+
var CLIP_MIN_H = 2;
|
|
245
|
+
function captureClipRect(path, out) {
|
|
246
|
+
if (path.length < 3 || path.length > 5) return;
|
|
247
|
+
let x1 = Infinity, y1 = Infinity, x2 = -Infinity, y2 = -Infinity;
|
|
248
|
+
for (const s of path) {
|
|
249
|
+
const dx = Math.abs(s.x2 - s.x1), dy = Math.abs(s.y2 - s.y1);
|
|
250
|
+
if (dx > ORIENTATION_TOL && dy > ORIENTATION_TOL) return;
|
|
251
|
+
x1 = Math.min(x1, s.x1, s.x2);
|
|
252
|
+
x2 = Math.max(x2, s.x1, s.x2);
|
|
253
|
+
y1 = Math.min(y1, s.y1, s.y2);
|
|
254
|
+
y2 = Math.max(y2, s.y1, s.y2);
|
|
255
|
+
}
|
|
256
|
+
if (x2 - x1 < CLIP_MIN_W || y2 - y1 < CLIP_MIN_H) return;
|
|
257
|
+
out.push({ x1, y1, x2, y2 });
|
|
233
258
|
}
|
|
234
259
|
function classifyAndAdd(seg, lineWidth, horizontals, verticals, fromFill = false) {
|
|
235
260
|
const dx = Math.abs(seg.x2 - seg.x1);
|
|
@@ -442,9 +467,9 @@ function mergeParallelLines(lines, dir) {
|
|
|
442
467
|
const prevEnd = dir === "h" ? prev.x2 : prev.y2;
|
|
443
468
|
const currStart = dir === "h" ? curr.x1 : curr.y1;
|
|
444
469
|
const currEnd = dir === "h" ? curr.x2 : curr.y2;
|
|
445
|
-
const
|
|
470
|
+
const overlap2 = Math.min(prevEnd, currEnd) - Math.max(prevStart, currStart);
|
|
446
471
|
const minLen = Math.min(prevEnd - prevStart, currEnd - currStart);
|
|
447
|
-
if (
|
|
472
|
+
if (overlap2 > minLen * 0.3) {
|
|
448
473
|
if (dir === "h") {
|
|
449
474
|
prev.x1 = Math.min(prev.x1, curr.x1);
|
|
450
475
|
prev.x2 = Math.max(prev.x2, curr.x2);
|
|
@@ -933,6 +958,186 @@ function linesIntersect(a, b) {
|
|
|
933
958
|
return v.x1 >= h.x1 - tol && v.x1 <= h.x2 + tol && h.y1 >= v.y1 - tol && h.y1 <= v.y2 + tol;
|
|
934
959
|
}
|
|
935
960
|
|
|
961
|
+
// src/pdf/clip-cells.ts
|
|
962
|
+
var CLIP_EDGE_TOL = 1.5;
|
|
963
|
+
var CLIP_MIN_GROUP = 2;
|
|
964
|
+
var CLIP_MAX_PAGE_FRAC = 0.75;
|
|
965
|
+
var CLIP_MIN_W2 = 4;
|
|
966
|
+
var CLIP_MIN_H2 = 2;
|
|
967
|
+
var STROKE_NEAR = 2;
|
|
968
|
+
var STROKE_COVER = 0.5;
|
|
969
|
+
var CLIP_MIN_INVISIBLE = 0;
|
|
970
|
+
var overlap = (a1, a2, b1, b2) => Math.min(a2, b2) - Math.max(a1, b1);
|
|
971
|
+
function adjacent(a, b) {
|
|
972
|
+
if ((Math.abs(a.x2 - b.x1) <= CLIP_EDGE_TOL || Math.abs(b.x2 - a.x1) <= CLIP_EDGE_TOL) && overlap(a.y1, a.y2, b.y1, b.y2) > CLIP_EDGE_TOL) return true;
|
|
973
|
+
if ((Math.abs(a.y2 - b.y1) <= CLIP_EDGE_TOL || Math.abs(b.y2 - a.y1) <= CLIP_EDGE_TOL) && overlap(a.x1, a.x2, b.x1, b.x2) > CLIP_EDGE_TOL) return true;
|
|
974
|
+
return false;
|
|
975
|
+
}
|
|
976
|
+
function contains(a, b) {
|
|
977
|
+
return b.x1 >= a.x1 - CLIP_EDGE_TOL && b.x2 <= a.x2 + CLIP_EDGE_TOL && b.y1 >= a.y1 - CLIP_EDGE_TOL && b.y2 <= a.y2 + CLIP_EDGE_TOL && (b.x2 - b.x1 < a.x2 - a.x1 - CLIP_EDGE_TOL || b.y2 - b.y1 < a.y2 - a.y1 - CLIP_EDGE_TOL);
|
|
978
|
+
}
|
|
979
|
+
function clusterCoords(values) {
|
|
980
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
981
|
+
const out = [];
|
|
982
|
+
let run = [];
|
|
983
|
+
for (const v of sorted) {
|
|
984
|
+
if (run.length > 0 && v - run[run.length - 1] > CLIP_EDGE_TOL) {
|
|
985
|
+
out.push(run.reduce((s, x) => s + x, 0) / run.length);
|
|
986
|
+
run = [];
|
|
987
|
+
}
|
|
988
|
+
run.push(v);
|
|
989
|
+
}
|
|
990
|
+
if (run.length > 0) out.push(run.reduce((s, x) => s + x, 0) / run.length);
|
|
991
|
+
return out;
|
|
992
|
+
}
|
|
993
|
+
var nearestIndex = (coords, v) => {
|
|
994
|
+
let best = 0;
|
|
995
|
+
for (let i = 1; i < coords.length; i++) if (Math.abs(coords[i] - v) < Math.abs(coords[best] - v)) best = i;
|
|
996
|
+
return best;
|
|
997
|
+
};
|
|
998
|
+
function edgeStroked(lines, dir, pos, a1, a2) {
|
|
999
|
+
const len = a2 - a1;
|
|
1000
|
+
if (len <= 0) return true;
|
|
1001
|
+
for (const l of lines) {
|
|
1002
|
+
if (dir === "h") {
|
|
1003
|
+
if (Math.abs(l.y1 - pos) <= STROKE_NEAR && overlap(l.x1, l.x2, a1, a2) >= len * STROKE_COVER) return true;
|
|
1004
|
+
} else if (Math.abs(l.x1 - pos) <= STROKE_NEAR && overlap(l.y1, l.y2, a1, a2) >= len * STROKE_COVER) {
|
|
1005
|
+
return true;
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
return false;
|
|
1009
|
+
}
|
|
1010
|
+
function buildClipCellGrids(rects, strokedH, strokedV, pageWidth, pageHeight) {
|
|
1011
|
+
const pageArea = pageWidth * pageHeight;
|
|
1012
|
+
const sameRect = (a, b) => Math.abs(a.x1 - b.x1) <= CLIP_EDGE_TOL && Math.abs(a.x2 - b.x2) <= CLIP_EDGE_TOL && Math.abs(a.y1 - b.y1) <= CLIP_EDGE_TOL && Math.abs(a.y2 - b.y2) <= CLIP_EDGE_TOL;
|
|
1013
|
+
const cells = [];
|
|
1014
|
+
for (const r of rects) {
|
|
1015
|
+
if (r.x2 - r.x1 < CLIP_MIN_W2 || r.y2 - r.y1 < CLIP_MIN_H2) continue;
|
|
1016
|
+
if (pageArea > 0 && (r.x2 - r.x1) * (r.y2 - r.y1) >= pageArea * CLIP_MAX_PAGE_FRAC) continue;
|
|
1017
|
+
if (!cells.some((c) => sameRect(c, r))) cells.push(r);
|
|
1018
|
+
}
|
|
1019
|
+
if (cells.length < 1) return { grids: [], containers: [] };
|
|
1020
|
+
const parent = new Array(cells.length).fill(-1);
|
|
1021
|
+
for (let i = 0; i < cells.length; i++) {
|
|
1022
|
+
for (let j = 0; j < cells.length; j++) {
|
|
1023
|
+
if (i === j || !contains(cells[j], cells[i])) continue;
|
|
1024
|
+
const cur = parent[i];
|
|
1025
|
+
if (cur < 0 || contains(cells[cur], cells[j])) parent[i] = j;
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
const isContainer = new Array(cells.length).fill(false);
|
|
1029
|
+
for (const p of parent) if (p >= 0) isContainer[p] = true;
|
|
1030
|
+
const root = cells.map((_, i) => i);
|
|
1031
|
+
const find = (i) => {
|
|
1032
|
+
while (root[i] !== i) {
|
|
1033
|
+
root[i] = root[root[i]];
|
|
1034
|
+
i = root[i];
|
|
1035
|
+
}
|
|
1036
|
+
return i;
|
|
1037
|
+
};
|
|
1038
|
+
for (let i = 0; i < cells.length; i++) {
|
|
1039
|
+
for (let j = i + 1; j < cells.length; j++) {
|
|
1040
|
+
if (parent[i] !== parent[j]) continue;
|
|
1041
|
+
if (adjacent(cells[i], cells[j])) {
|
|
1042
|
+
const ra = find(i), rb = find(j);
|
|
1043
|
+
if (ra !== rb) root[ra] = rb;
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1048
|
+
for (let i = 0; i < cells.length; i++) {
|
|
1049
|
+
const r = find(i);
|
|
1050
|
+
const g = groups.get(r);
|
|
1051
|
+
if (g) g.push(i);
|
|
1052
|
+
else groups.set(r, [i]);
|
|
1053
|
+
}
|
|
1054
|
+
const containers = cells.filter((_, i) => isContainer[i]);
|
|
1055
|
+
const groupSize = (i) => groups.get(find(i))?.length ?? 0;
|
|
1056
|
+
const isGridMember = (i) => groupSize(i) >= CLIP_MIN_GROUP;
|
|
1057
|
+
const framed = (r) => edgeStroked(strokedH, "h", r.y1, r.x1, r.x2) && edgeStroked(strokedH, "h", r.y2, r.x1, r.x2) && edgeStroked(strokedV, "v", r.x1, r.y1, r.y2) && edgeStroked(strokedV, "v", r.x2, r.y1, r.y2);
|
|
1058
|
+
const loneFrame = (i) => isContainer[i] && !isGridMember(i) && framed(cells[i]);
|
|
1059
|
+
const parentAttachable = (i) => parent[i] >= 0 && (isGridMember(parent[i]) || loneFrame(parent[i]));
|
|
1060
|
+
const onlyChild = (i) => parent[i] >= 0 && parent.filter((p) => p === parent[i]).length === 1;
|
|
1061
|
+
const grids = [];
|
|
1062
|
+
for (const idxs of groups.values()) {
|
|
1063
|
+
const first = idxs[0];
|
|
1064
|
+
const parentRect = parentAttachable(first) ? cells[parent[first]] : void 0;
|
|
1065
|
+
if (idxs.length < CLIP_MIN_GROUP) {
|
|
1066
|
+
if (!loneFrame(first) && !((parentRect || onlyChild(first)) && framed(cells[first]))) continue;
|
|
1067
|
+
const r = cells[first];
|
|
1068
|
+
grids.push({
|
|
1069
|
+
rowYs: [r.y2, r.y1],
|
|
1070
|
+
colXs: [r.x1, r.x2],
|
|
1071
|
+
bbox: { x1: r.x1, y1: r.y1, x2: r.x2, y2: r.y2 },
|
|
1072
|
+
vertexRadius: 1,
|
|
1073
|
+
cells: [{ row: 0, col: 0, rowSpan: 1, colSpan: 1, bbox: { x1: r.x1, y1: r.y1, x2: r.x2, y2: r.y2 } }],
|
|
1074
|
+
...parentRect ? { clipParent: parentRect } : {}
|
|
1075
|
+
});
|
|
1076
|
+
continue;
|
|
1077
|
+
}
|
|
1078
|
+
const members = idxs.map((i) => cells[i]);
|
|
1079
|
+
let edges = 0, invisible = 0;
|
|
1080
|
+
for (const r of members) {
|
|
1081
|
+
edges += 4;
|
|
1082
|
+
if (!edgeStroked(strokedH, "h", r.y1, r.x1, r.x2)) invisible++;
|
|
1083
|
+
if (!edgeStroked(strokedH, "h", r.y2, r.x1, r.x2)) invisible++;
|
|
1084
|
+
if (!edgeStroked(strokedV, "v", r.x1, r.y1, r.y2)) invisible++;
|
|
1085
|
+
if (!edgeStroked(strokedV, "v", r.x2, r.y1, r.y2)) invisible++;
|
|
1086
|
+
}
|
|
1087
|
+
if (invisible / edges < CLIP_MIN_INVISIBLE) continue;
|
|
1088
|
+
const colXs = clusterCoords(members.flatMap((r) => [r.x1, r.x2]));
|
|
1089
|
+
const rowYs = clusterCoords(members.flatMap((r) => [r.y1, r.y2])).reverse();
|
|
1090
|
+
const numRows = rowYs.length - 1, numCols = colXs.length - 1;
|
|
1091
|
+
if (numRows < 1 || numCols < 1) continue;
|
|
1092
|
+
const occupied = Array.from({ length: numRows }, () => new Array(numCols).fill(false));
|
|
1093
|
+
const out = [];
|
|
1094
|
+
for (const r of members) {
|
|
1095
|
+
const c0 = nearestIndex(colXs, r.x1), c1 = nearestIndex(colXs, r.x2);
|
|
1096
|
+
const r0 = nearestIndex(rowYs, r.y2), r1 = nearestIndex(rowYs, r.y1);
|
|
1097
|
+
if (c1 <= c0 || r1 <= r0) continue;
|
|
1098
|
+
let clash = false;
|
|
1099
|
+
for (let rr = r0; rr < r1 && !clash; rr++) for (let cc = c0; cc < c1; cc++) if (occupied[rr][cc]) {
|
|
1100
|
+
clash = true;
|
|
1101
|
+
break;
|
|
1102
|
+
}
|
|
1103
|
+
if (clash) continue;
|
|
1104
|
+
for (let rr = r0; rr < r1; rr++) for (let cc = c0; cc < c1; cc++) occupied[rr][cc] = true;
|
|
1105
|
+
out.push({ row: r0, col: c0, rowSpan: r1 - r0, colSpan: c1 - c0, bbox: { x1: r.x1, y1: r.y1, x2: r.x2, y2: r.y2 } });
|
|
1106
|
+
}
|
|
1107
|
+
for (let rr = 0; rr < numRows; rr++) {
|
|
1108
|
+
for (let cc = 0; cc < numCols; cc++) {
|
|
1109
|
+
if (occupied[rr][cc]) continue;
|
|
1110
|
+
out.push({ row: rr, col: cc, rowSpan: 1, colSpan: 1, bbox: { x1: colXs[cc], y1: rowYs[rr + 1], x2: colXs[cc + 1], y2: rowYs[rr] } });
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
grids.push({
|
|
1114
|
+
rowYs,
|
|
1115
|
+
colXs,
|
|
1116
|
+
bbox: { x1: colXs[0], y1: rowYs[numRows], x2: colXs[numCols], y2: rowYs[0] },
|
|
1117
|
+
vertexRadius: 1,
|
|
1118
|
+
cells: out,
|
|
1119
|
+
...parentRect ? { clipParent: parentRect } : {}
|
|
1120
|
+
});
|
|
1121
|
+
}
|
|
1122
|
+
return { grids, containers };
|
|
1123
|
+
}
|
|
1124
|
+
function dropGridsInside(lineGrids, clipGrids, containers = []) {
|
|
1125
|
+
if (clipGrids.length === 0 && containers.length === 0) return lineGrids;
|
|
1126
|
+
const area = (b) => Math.max(0, b.x2 - b.x1) * Math.max(0, b.y2 - b.y1);
|
|
1127
|
+
const overlapsHalf = (g, b) => {
|
|
1128
|
+
const ix = Math.min(g.x2, b.x2) - Math.max(g.x1, b.x1);
|
|
1129
|
+
const iy = Math.min(g.y2, b.y2) - Math.max(g.y1, b.y1);
|
|
1130
|
+
if (ix <= 0 || iy <= 0) return false;
|
|
1131
|
+
const ga = area(g);
|
|
1132
|
+
return ga > 0 && ix * iy / ga >= 0.5;
|
|
1133
|
+
};
|
|
1134
|
+
return lineGrids.filter((g) => {
|
|
1135
|
+
if (clipGrids.some((c) => overlapsHalf(g.bbox, c.bbox))) return false;
|
|
1136
|
+
if (containers.some((c) => overlapsHalf(g.bbox, c))) return false;
|
|
1137
|
+
return true;
|
|
1138
|
+
});
|
|
1139
|
+
}
|
|
1140
|
+
|
|
936
1141
|
// src/pdf/cell-extract.ts
|
|
937
1142
|
function extractCells(grid, horizontals, verticals) {
|
|
938
1143
|
const { rowYs, colXs } = grid;
|
|
@@ -1011,8 +1216,8 @@ function hasVerticalLine(verticals, x, topY, botY, vertexRadius) {
|
|
|
1011
1216
|
if (cellH < 0.1) continue;
|
|
1012
1217
|
const overlapTop = Math.min(v.y2, topY);
|
|
1013
1218
|
const overlapBot = Math.max(v.y1, botY);
|
|
1014
|
-
const
|
|
1015
|
-
if (
|
|
1219
|
+
const overlap2 = overlapTop - overlapBot;
|
|
1220
|
+
if (overlap2 >= cellH * 0.75) return true;
|
|
1016
1221
|
}
|
|
1017
1222
|
}
|
|
1018
1223
|
return false;
|
|
@@ -1025,8 +1230,8 @@ function hasHorizontalLine(horizontals, y, leftX, rightX, vertexRadius) {
|
|
|
1025
1230
|
if (cellW < 0.1) continue;
|
|
1026
1231
|
const overlapLeft = Math.max(h.x1, leftX);
|
|
1027
1232
|
const overlapRight = Math.min(h.x2, rightX);
|
|
1028
|
-
const
|
|
1029
|
-
if (
|
|
1233
|
+
const overlap2 = overlapRight - overlapLeft;
|
|
1234
|
+
if (overlap2 >= cellW * 0.75) return true;
|
|
1030
1235
|
}
|
|
1031
1236
|
}
|
|
1032
1237
|
return false;
|
|
@@ -1133,9 +1338,9 @@ function mergeSuperscriptRows(lines) {
|
|
|
1133
1338
|
const curr = lines[i];
|
|
1134
1339
|
const a = band(prev);
|
|
1135
1340
|
const b = band(curr);
|
|
1136
|
-
const
|
|
1137
|
-
const prevIsFrag = isFrag(prev) && a.height <= b.height * 0.8 &&
|
|
1138
|
-
const currIsFrag = isFrag(curr) && b.height <= a.height * 0.8 &&
|
|
1341
|
+
const overlap2 = Math.min(a.top, b.top) - Math.max(a.bottom, b.bottom);
|
|
1342
|
+
const prevIsFrag = isFrag(prev) && a.height <= b.height * 0.8 && overlap2 >= a.height * 0.5;
|
|
1343
|
+
const currIsFrag = isFrag(curr) && b.height <= a.height * 0.8 && overlap2 >= b.height * 0.5;
|
|
1139
1344
|
if (prevIsFrag || currIsFrag) {
|
|
1140
1345
|
result[result.length - 1] = [...prev, ...curr];
|
|
1141
1346
|
} else {
|
|
@@ -1354,14 +1559,17 @@ function filterHiddenText(items, pageWidth, pageHeight) {
|
|
|
1354
1559
|
function collapseEvenSpacing(text) {
|
|
1355
1560
|
const tokens = text.split(" ");
|
|
1356
1561
|
const singleCharCount = tokens.filter((t) => t.length === 1).length;
|
|
1357
|
-
if (tokens.length >= 3 && singleCharCount / tokens.length >= 0.7) {
|
|
1562
|
+
if (tokens.length >= 3 && singleCharCount / tokens.length >= 0.7 && !isDateUnitBlank(tokens)) {
|
|
1358
1563
|
return tokens.join("");
|
|
1359
1564
|
}
|
|
1360
1565
|
return text.replace(
|
|
1361
1566
|
/(?<![가-힣])[가-힣](?: [가-힣\d]){2,}(?![가-힣])/g,
|
|
1362
|
-
(match) => match.replace(/ /g, "")
|
|
1567
|
+
(match) => isDateUnitBlank(match.split(" ")) ? match : match.replace(/ /g, "")
|
|
1363
1568
|
);
|
|
1364
1569
|
}
|
|
1570
|
+
function isDateUnitBlank(tokens) {
|
|
1571
|
+
return tokens.every((t) => t.length !== 1 || !/[가-힣]/.test(t) || /[년월일시분초]/.test(t));
|
|
1572
|
+
}
|
|
1365
1573
|
function computeBBox(items, pageNum) {
|
|
1366
1574
|
let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
|
|
1367
1575
|
for (const i of items) {
|
|
@@ -1502,9 +1710,9 @@ function mergeSuperscriptLines(lines) {
|
|
|
1502
1710
|
const curr = lines[i];
|
|
1503
1711
|
const a = band(prev);
|
|
1504
1712
|
const b = band(curr);
|
|
1505
|
-
const
|
|
1506
|
-
const prevIsFrag = isFrag(prev) && a.height <= b.height * 0.8 &&
|
|
1507
|
-
const currIsFrag = isFrag(curr) && b.height <= a.height * 0.8 &&
|
|
1713
|
+
const overlap2 = Math.min(a.top, b.top) - Math.max(a.bottom, b.bottom);
|
|
1714
|
+
const prevIsFrag = isFrag(prev) && a.height <= b.height * 0.8 && overlap2 >= a.height * 0.5;
|
|
1715
|
+
const currIsFrag = isFrag(curr) && b.height <= a.height * 0.8 && overlap2 >= b.height * 0.5;
|
|
1508
1716
|
if (prevIsFrag || currIsFrag) {
|
|
1509
1717
|
result[result.length - 1] = [...prev, ...curr];
|
|
1510
1718
|
} else {
|
|
@@ -1653,8 +1861,8 @@ function detectTableCaptions(blocks) {
|
|
|
1653
1861
|
const tblBottom = table.bbox.y;
|
|
1654
1862
|
const gap = capBottom >= tblTop ? capBottom - tblTop : tblBottom - capTop;
|
|
1655
1863
|
if (gap > CAPTION_MAX_GAP) return false;
|
|
1656
|
-
const
|
|
1657
|
-
if (
|
|
1864
|
+
const overlap2 = Math.min(b.bbox.x + b.bbox.width, table.bbox.x + table.bbox.width) - Math.max(b.bbox.x, table.bbox.x);
|
|
1865
|
+
if (overlap2 < Math.min(b.bbox.width, table.bbox.width) * 0.3) return false;
|
|
1658
1866
|
}
|
|
1659
1867
|
return true;
|
|
1660
1868
|
};
|
|
@@ -1918,8 +2126,8 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings) {
|
|
|
1918
2126
|
if (!o.bbox || o.bbox.page !== cb.page) continue;
|
|
1919
2127
|
const oNorm = o.text?.trim().replace(/\d+/g, "#");
|
|
1920
2128
|
if (oNorm && repeatedPatterns.has(oNorm)) continue;
|
|
1921
|
-
const
|
|
1922
|
-
if (
|
|
2129
|
+
const overlap2 = Math.min(cb.y + cb.height, o.bbox.y + o.bbox.height) - Math.max(cb.y, o.bbox.y);
|
|
2130
|
+
if (overlap2 >= cb.height * 0.5) {
|
|
1923
2131
|
sharesLine = true;
|
|
1924
2132
|
break;
|
|
1925
2133
|
}
|
|
@@ -2191,9 +2399,9 @@ function mergeOverlappingRows(rows) {
|
|
|
2191
2399
|
const curr = rows[i];
|
|
2192
2400
|
const a = rowBand(prev);
|
|
2193
2401
|
const b = rowBand(curr);
|
|
2194
|
-
const
|
|
2195
|
-
const prevIsFrag = isFragmentRow(prev) && a.height <= b.height * 0.8 &&
|
|
2196
|
-
const currIsFrag = isFragmentRow(curr) && b.height <= a.height * 0.8 &&
|
|
2402
|
+
const overlap2 = Math.min(a.top, b.top) - Math.max(a.bottom, b.bottom);
|
|
2403
|
+
const prevIsFrag = isFragmentRow(prev) && a.height <= b.height * 0.8 && overlap2 >= a.height * 0.5;
|
|
2404
|
+
const currIsFrag = isFragmentRow(curr) && b.height <= a.height * 0.8 && overlap2 >= b.height * 0.5;
|
|
2197
2405
|
if (prevIsFrag || currIsFrag) {
|
|
2198
2406
|
const baseY = prevIsFrag ? curr.y : prev.y;
|
|
2199
2407
|
result[result.length - 1] = { y: baseY, items: [...prev.items, ...curr.items] };
|
|
@@ -3070,8 +3278,8 @@ function markUnderlineItems(items, horizontals, verticals) {
|
|
|
3070
3278
|
if (h <= 0 || item.w <= 0 || !item.text.trim()) continue;
|
|
3071
3279
|
const below = Math.max(h * UNDER_BELOW_EM, UNDER_BELOW_MIN_PT);
|
|
3072
3280
|
if (line.y1 < item.y - below || line.y1 > item.y + UNDER_ABOVE_PT) continue;
|
|
3073
|
-
const
|
|
3074
|
-
if (
|
|
3281
|
+
const overlap2 = Math.min(line.x2, item.x + item.w) - Math.max(line.x1, item.x);
|
|
3282
|
+
if (overlap2 / item.w < UNDER_MIN_OVERLAP_RATIO) continue;
|
|
3075
3283
|
matches.push(item);
|
|
3076
3284
|
}
|
|
3077
3285
|
if (matches.length === 0) continue;
|
|
@@ -3115,8 +3323,8 @@ function hasBoxTopPair(line, maxH, horizontals) {
|
|
|
3115
3323
|
if (dy < maxH * UNDER_BOX_PAIR_MIN_EM || dy > maxH * UNDER_BOX_PAIR_MAX_EM) continue;
|
|
3116
3324
|
const ow = o.x2 - o.x1;
|
|
3117
3325
|
if (ow <= 0) continue;
|
|
3118
|
-
const
|
|
3119
|
-
if (
|
|
3326
|
+
const overlap2 = Math.min(line.x2, o.x2) - Math.max(line.x1, o.x1);
|
|
3327
|
+
if (overlap2 / Math.max(w, ow) >= UNDER_BOX_PAIR_OVERLAP) return true;
|
|
3120
3328
|
}
|
|
3121
3329
|
return false;
|
|
3122
3330
|
}
|
|
@@ -3127,8 +3335,8 @@ function isRepeatedSpanRule(line, horizontals) {
|
|
|
3127
3335
|
for (const o of horizontals) {
|
|
3128
3336
|
const ow = o.x2 - o.x1;
|
|
3129
3337
|
if (ow <= 0) continue;
|
|
3130
|
-
const
|
|
3131
|
-
if (
|
|
3338
|
+
const overlap2 = Math.min(line.x2, o.x2) - Math.max(line.x1, o.x1);
|
|
3339
|
+
if (overlap2 / Math.max(w, ow) < UNDER_SPAN_OVERLAP_RATIO) continue;
|
|
3132
3340
|
if (!ys.some((y) => Math.abs(y - o.y1) < 2)) ys.push(o.y1);
|
|
3133
3341
|
}
|
|
3134
3342
|
return ys.length >= UNDER_REPEATED_SPAN_LEVELS;
|
|
@@ -3162,7 +3370,10 @@ function wrapUnderlineRuns(items) {
|
|
|
3162
3370
|
// src/pdf/page-blocks.ts
|
|
3163
3371
|
function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeight, extraLines, detectTables = true) {
|
|
3164
3372
|
if (items.length === 0) return [];
|
|
3165
|
-
|
|
3373
|
+
const extracted = extractLines(opList.fnArray, opList.argsArray);
|
|
3374
|
+
let { horizontals, verticals } = extracted;
|
|
3375
|
+
const clipResult = detectTables ? buildClipCellGrids(extracted.clipRects, horizontals, verticals, pageWidth, pageHeight) : { grids: [], containers: [] };
|
|
3376
|
+
const clipGrids = clipResult.grids;
|
|
3166
3377
|
if (extraLines) {
|
|
3167
3378
|
horizontals = horizontals.concat(extraLines.horizontals);
|
|
3168
3379
|
verticals = verticals.concat(extraLines.verticals);
|
|
@@ -3176,7 +3387,8 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
|
|
|
3176
3387
|
wrapStrikethroughRuns(items);
|
|
3177
3388
|
markUnderlineItems(items, horizontals, verticals);
|
|
3178
3389
|
wrapUnderlineRuns(items);
|
|
3179
|
-
const
|
|
3390
|
+
const lineGrids = detectTables ? buildTableGrids(horizontals, verticals) : [];
|
|
3391
|
+
const grids = [...clipGrids, ...dropGridsInside(lineGrids, clipGrids, clipResult.containers)];
|
|
3180
3392
|
if (grids.length > 0) {
|
|
3181
3393
|
return extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals);
|
|
3182
3394
|
}
|
|
@@ -3198,8 +3410,8 @@ function markStrikethroughItems(items, horizontals) {
|
|
|
3198
3410
|
if (line.lineWidth > h * STRIKE_MAX_THICKNESS_RATIO) continue;
|
|
3199
3411
|
const centerY = item.y + h * 0.4;
|
|
3200
3412
|
if (Math.abs(line.y1 - centerY) > h * STRIKE_CENTER_TOLERANCE) continue;
|
|
3201
|
-
const
|
|
3202
|
-
if (
|
|
3413
|
+
const overlap2 = Math.min(line.x2, item.x + item.w) - Math.max(line.x1, item.x);
|
|
3414
|
+
if (overlap2 / item.w < STRIKE_MIN_OVERLAP_RATIO) continue;
|
|
3203
3415
|
matches.push(item);
|
|
3204
3416
|
}
|
|
3205
3417
|
if (matches.length === 0) continue;
|
|
@@ -3273,15 +3485,54 @@ function isProseBoxGrid(grid, verticals, table) {
|
|
|
3273
3485
|
if (longCells < PROSEBOX_LONG_CELL_MIN || longCells < texts.length * PROSEBOX_LONG_CELL_RATIO) return false;
|
|
3274
3486
|
return true;
|
|
3275
3487
|
}
|
|
3488
|
+
function cleanCellText(text) {
|
|
3489
|
+
const stripped = text.replace(/^[\s]*[-–—]\s*\d+\s*[-–—][\s]*$/gm, "").trim();
|
|
3490
|
+
return stripped.split("\n").map((line) => collapseEvenSpacing(line)).join("\n");
|
|
3491
|
+
}
|
|
3492
|
+
var FRAME_RECT_TOL = 1.5;
|
|
3493
|
+
function takePendingNested(pending, cellBox) {
|
|
3494
|
+
const out = [];
|
|
3495
|
+
for (let i = pending.length - 1; i >= 0; i--) {
|
|
3496
|
+
const p = pending[i].parent;
|
|
3497
|
+
if (Math.abs(p.x1 - cellBox.x1) <= FRAME_RECT_TOL && Math.abs(p.x2 - cellBox.x2) <= FRAME_RECT_TOL && Math.abs(p.y1 - cellBox.y1) <= FRAME_RECT_TOL && Math.abs(p.y2 - cellBox.y2) <= FRAME_RECT_TOL) {
|
|
3498
|
+
out.push(pending[i].block);
|
|
3499
|
+
pending.splice(i, 1);
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3502
|
+
return out;
|
|
3503
|
+
}
|
|
3504
|
+
function buildFrameCellBlocks(cellItems, nested, pageNum) {
|
|
3505
|
+
const tables = [...nested].sort((a, b) => b.bbox.y + b.bbox.height - (a.bbox.y + a.bbox.height));
|
|
3506
|
+
const blocks = [];
|
|
3507
|
+
let rest = [...cellItems];
|
|
3508
|
+
const pushParagraphs = (items) => {
|
|
3509
|
+
if (items.length === 0) return;
|
|
3510
|
+
for (const line of cleanCellText(cellTextToString(items)).split("\n")) {
|
|
3511
|
+
const t = line.trim();
|
|
3512
|
+
if (t) blocks.push({ type: "paragraph", text: t, pageNumber: pageNum });
|
|
3513
|
+
}
|
|
3514
|
+
};
|
|
3515
|
+
for (const tb of tables) {
|
|
3516
|
+
const bottom = tb.bbox.y;
|
|
3517
|
+
pushParagraphs(rest.filter((it) => it.y >= bottom));
|
|
3518
|
+
rest = rest.filter((it) => it.y < bottom);
|
|
3519
|
+
blocks.push(tb);
|
|
3520
|
+
}
|
|
3521
|
+
pushParagraphs(rest);
|
|
3522
|
+
const text = blocks.map((b) => b.type === "table" && b.table ? b.table.cells.flat().map((c) => c.text).filter(Boolean).join("\n") : b.text ?? "").filter(Boolean).join("\n");
|
|
3523
|
+
return { blocks, text };
|
|
3524
|
+
}
|
|
3276
3525
|
function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
3277
3526
|
const blocks = [];
|
|
3278
3527
|
const usedItems = /* @__PURE__ */ new Set();
|
|
3279
|
-
const
|
|
3528
|
+
const pendingNested = [];
|
|
3529
|
+
const gridArea = (g) => (g.bbox.x2 - g.bbox.x1) * (g.bbox.y2 - g.bbox.y1);
|
|
3530
|
+
const sortedGrids = [...grids].sort((a, b) => (b.cells ? 1 : 0) - (a.cells ? 1 : 0) || (a.cells && b.cells ? gridArea(a) - gridArea(b) : 0) || b.bbox.y2 - a.bbox.y2);
|
|
3280
3531
|
for (const grid of sortedGrids) {
|
|
3281
3532
|
const numGridRows = grid.rowYs.length - 1;
|
|
3282
3533
|
const numGridCols = grid.colXs.length - 1;
|
|
3283
|
-
if (numGridRows === 1 && numGridCols >= 2) continue;
|
|
3284
|
-
if (numGridCols === 1 && numGridRows >= 2) continue;
|
|
3534
|
+
if (!grid.cells && numGridRows === 1 && numGridCols >= 2) continue;
|
|
3535
|
+
if (!grid.cells && numGridCols === 1 && numGridRows >= 2) continue;
|
|
3285
3536
|
const tableItems = [];
|
|
3286
3537
|
const pad = 3;
|
|
3287
3538
|
const gridW = grid.bbox.x2 - grid.bbox.x1;
|
|
@@ -3293,7 +3544,7 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3293
3544
|
tableItems.push(item);
|
|
3294
3545
|
usedItems.add(item);
|
|
3295
3546
|
}
|
|
3296
|
-
const cells = extractCells(grid, horizontals, verticals);
|
|
3547
|
+
const cells = grid.cells ?? extractCells(grid, horizontals, verticals);
|
|
3297
3548
|
if (cells.length === 0) continue;
|
|
3298
3549
|
const textItems = tableItems.map((i) => ({
|
|
3299
3550
|
text: i.text,
|
|
@@ -3314,13 +3565,18 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3314
3565
|
{ length: numRows },
|
|
3315
3566
|
() => Array.from({ length: numCols }, () => ({ text: "", colSpan: 1, rowSpan: 1 }))
|
|
3316
3567
|
);
|
|
3568
|
+
let nestedAttached = false;
|
|
3317
3569
|
for (const cell of cells) {
|
|
3318
3570
|
const cellItems = cellTextMap.get(cell) || [];
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3571
|
+
const nested = grid.cells ? takePendingNested(pendingNested, cell.bbox) : [];
|
|
3572
|
+
if (nested.length > 0) {
|
|
3573
|
+
nestedAttached = true;
|
|
3574
|
+
const built = buildFrameCellBlocks(cellItems, nested, pageNum);
|
|
3575
|
+
irGrid[cell.row][cell.col] = { text: built.text, colSpan: cell.colSpan, rowSpan: cell.rowSpan, blocks: built.blocks };
|
|
3576
|
+
continue;
|
|
3577
|
+
}
|
|
3322
3578
|
irGrid[cell.row][cell.col] = {
|
|
3323
|
-
text,
|
|
3579
|
+
text: cleanCellText(cellTextToString(cellItems)),
|
|
3324
3580
|
colSpan: cell.colSpan,
|
|
3325
3581
|
rowSpan: cell.rowSpan
|
|
3326
3582
|
};
|
|
@@ -3328,18 +3584,11 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3328
3584
|
let finalGrid = irGrid;
|
|
3329
3585
|
let finalRows = numRows;
|
|
3330
3586
|
let rebuiltUsed = false;
|
|
3331
|
-
if (numRows <= 2 && numCols >= 3) {
|
|
3587
|
+
if (numRows <= 2 && numCols >= 3 && !nestedAttached) {
|
|
3332
3588
|
const rebuilt = normalizeUndersegmentedTable(irGrid, grid.colXs, textItems);
|
|
3333
3589
|
if (rebuilt) {
|
|
3334
3590
|
rebuiltUsed = true;
|
|
3335
|
-
finalGrid = rebuilt.map((row) => row.map((rawText) => {
|
|
3336
|
-
const cleaned = rawText.replace(/^[\s]*[-–—]\s*\d+\s*[-–—][\s]*$/gm, "").trim();
|
|
3337
|
-
return {
|
|
3338
|
-
text: cleaned.split("\n").map((line) => collapseEvenSpacing(line)).join("\n"),
|
|
3339
|
-
colSpan: 1,
|
|
3340
|
-
rowSpan: 1
|
|
3341
|
-
};
|
|
3342
|
-
}));
|
|
3591
|
+
finalGrid = rebuilt.map((row) => row.map((rawText) => ({ text: cleanCellText(rawText), colSpan: 1, rowSpan: 1 })));
|
|
3343
3592
|
finalRows = finalGrid.length;
|
|
3344
3593
|
}
|
|
3345
3594
|
}
|
|
@@ -3356,7 +3605,12 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3356
3605
|
};
|
|
3357
3606
|
const hasContent = finalGrid.some((row) => row.some((cell) => cell.text.trim() !== ""));
|
|
3358
3607
|
if (!hasContent) continue;
|
|
3359
|
-
if (
|
|
3608
|
+
if (grid.clipParent) {
|
|
3609
|
+
const nb = { page: pageNum, x: grid.bbox.x1, y: grid.bbox.y1, width: grid.bbox.x2 - grid.bbox.x1, height: grid.bbox.y2 - grid.bbox.y1 };
|
|
3610
|
+
pendingNested.push({ parent: grid.clipParent, block: { type: "table", table: irTable, pageNumber: pageNum, bbox: nb } });
|
|
3611
|
+
continue;
|
|
3612
|
+
}
|
|
3613
|
+
if (!grid.cells && isProseBoxGrid(grid, verticals, irTable)) {
|
|
3360
3614
|
for (const it of tableItems) usedItems.delete(it);
|
|
3361
3615
|
continue;
|
|
3362
3616
|
}
|
|
@@ -3367,7 +3621,7 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3367
3621
|
width: grid.bbox.x2 - grid.bbox.x1,
|
|
3368
3622
|
height: grid.bbox.y2 - grid.bbox.y1
|
|
3369
3623
|
};
|
|
3370
|
-
if (shouldDemoteTable(irTable)) {
|
|
3624
|
+
if (!grid.cells && shouldDemoteTable(irTable)) {
|
|
3371
3625
|
const demoted = demoteTableToText(irTable);
|
|
3372
3626
|
if (demoted) {
|
|
3373
3627
|
const text = numGridRows === 1 ? "\n" + demoted + "\n" : demoted;
|
|
@@ -3377,6 +3631,7 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3377
3631
|
}
|
|
3378
3632
|
blocks.push({ type: "table", table: irTable, pageNumber: pageNum, bbox: tableBbox });
|
|
3379
3633
|
}
|
|
3634
|
+
for (const p of pendingNested) blocks.push(p.block);
|
|
3380
3635
|
let remaining = items.filter((i) => !usedItems.has(i));
|
|
3381
3636
|
const groupSizes = [];
|
|
3382
3637
|
let finalTextBlocks = [];
|
|
@@ -3686,4 +3941,4 @@ export {
|
|
|
3686
3941
|
extractPageBlocksWithLines,
|
|
3687
3942
|
mergeCrossPageTables
|
|
3688
3943
|
};
|
|
3689
|
-
//# sourceMappingURL=chunk-
|
|
3944
|
+
//# sourceMappingURL=chunk-7XUXSDH5.js.map
|