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