kordoc 4.21.19 → 4.21.21
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 +7 -5
- package/dist/{-FLYHAUQ6.js → -ZYF6HX4M.js} +11 -11
- package/dist/{chunk-TC6DQLYN.js → chunk-2ZGP7A5T.js} +2 -2
- package/dist/{chunk-4VM6BT4W.js → chunk-3TCF5HPP.js} +2 -2
- package/dist/{chunk-2DNJW2HO.cjs → chunk-57VNFMMS.cjs} +3 -3
- package/dist/{chunk-2DNJW2HO.cjs.map → chunk-57VNFMMS.cjs.map} +1 -1
- package/dist/{chunk-OON4IJU2.js → chunk-5HTFWUJE.js} +2 -2
- package/dist/{chunk-AQ5GIBBH.js → chunk-7YAJCXCD.js} +2 -2
- package/dist/{chunk-3O4YC67B.js → chunk-BC54LBST.js} +3 -3
- package/dist/{chunk-GK4QLKNT.js → chunk-BG6LUCQL.js} +2 -2
- package/dist/{chunk-SM42XSI3.js → chunk-CY4QM2KQ.js} +2 -2
- package/dist/{chunk-KLKV47XO.cjs → chunk-DTZIZ5PP.cjs} +13 -13
- package/dist/{chunk-KLKV47XO.cjs.map → chunk-DTZIZ5PP.cjs.map} +1 -1
- package/dist/{chunk-INZGI6PI.js → chunk-FBJVDBMO.js} +2 -2
- package/dist/{chunk-Z2OOYQ4I.js → chunk-FZMGF6XU.js} +2 -2
- package/dist/{chunk-JGGYLUGD.cjs → chunk-H2MS4VG3.cjs} +3 -3
- package/dist/{chunk-JGGYLUGD.cjs.map → chunk-H2MS4VG3.cjs.map} +1 -1
- package/dist/{chunk-3PCAJWGK.js → chunk-HWIW3WK2.js} +42 -3
- package/dist/{chunk-3PCAJWGK.js.map → chunk-HWIW3WK2.js.map} +1 -1
- package/dist/{chunk-F6N7CDB7.js → chunk-J5PBI3ZC.js} +3 -3
- package/dist/{chunk-DQ2YGTRS.js → chunk-KBV4WFZ6.js} +145 -123
- package/dist/chunk-KBV4WFZ6.js.map +1 -0
- package/dist/{chunk-YDIVY65W.js → chunk-KTLHADU4.js} +2 -2
- package/dist/{chunk-3KW2Q655.cjs → chunk-MCUX2Y2C.cjs} +2 -2
- package/dist/{chunk-3KW2Q655.cjs.map → chunk-MCUX2Y2C.cjs.map} +1 -1
- package/dist/{chunk-X6WXU4LA.js → chunk-PTF4NCFM.js} +2 -2
- package/dist/{chunk-46PYORID.js → chunk-QHNVH4TC.js} +6 -6
- package/dist/{chunk-RYRUQ73F.js → chunk-RBRHO7WL.js} +2 -2
- package/dist/{chunk-CLAIAXMX.js → chunk-T3DTTK23.js} +2 -2
- package/dist/{chunk-DZVZVZAD.cjs → chunk-T7PN5D4D.cjs} +6 -6
- package/dist/{chunk-DZVZVZAD.cjs.map → chunk-T7PN5D4D.cjs.map} +1 -1
- package/dist/{chunk-EYLEVRHT.cjs → chunk-TMUUDMDH.cjs} +274 -172
- package/dist/chunk-TMUUDMDH.cjs.map +1 -0
- package/dist/{chunk-VIFY6DJZ.js → chunk-TRO4CQHJ.js} +4 -4
- package/dist/{chunk-OWLDTF5Q.js → chunk-WGMYVRSA.js} +2 -2
- package/dist/{chunk-AMXIYV73.js → chunk-YHPJTLCA.js} +2 -2
- package/dist/{chunk-QWOZRYUA.js → chunk-YM3K3LCD.js} +450 -110
- package/dist/chunk-YM3K3LCD.js.map +1 -0
- package/dist/{chunk-Y5OSPKBU.js → chunk-YQZOPT3A.js} +225 -43
- package/dist/chunk-YQZOPT3A.js.map +1 -0
- package/dist/{chunk-UDODNSDU.js → chunk-ZZIQWSGC.js} +2 -2
- package/dist/chunks-MDMJRCJ7.js +10 -0
- package/dist/cli.js +30 -30
- package/dist/{formula-2YYGN7UE.js → formula-6XNIXZ5L.js} +3 -3
- package/dist/{formula-EKXCURKO.cjs → formula-A3I5VAP7.cjs} +9 -9
- package/dist/{formula-EKXCURKO.cjs.map → formula-A3I5VAP7.cjs.map} +1 -1
- package/dist/{formula-Z5UPXBQM.js → formula-P7M7IH2L.js} +4 -4
- package/dist/{image-ocr-23R7RVHP.js → image-ocr-3C6W3KZO.js} +6 -6
- package/dist/{image-ocr-IMLFZ2JC.js → image-ocr-ITNY454I.js} +9 -9
- package/dist/{image-ocr-TE76KKNV.cjs → image-ocr-UJRSQ2T3.cjs} +15 -15
- package/dist/{image-ocr-TE76KKNV.cjs.map → image-ocr-UJRSQ2T3.cjs.map} +1 -1
- package/dist/index.cjs +1064 -687
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +482 -105
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +22 -22
- package/dist/{model-bundle-GTSRH2DY.js → model-bundle-LAWQH75O.js} +5 -5
- package/dist/{models-2J3NS7G2.js → models-6QTD2CFM.js} +5 -5
- package/dist/{parse-worker-v2-VO5UY3MP.js → parse-worker-v2-FEPJG3ER.js} +12 -12
- package/dist/{parser-FXGAKPUI.js → parser-56I364YM.js} +16 -8
- package/dist/{parser-JVUZ7EEV.js.map → parser-56I364YM.js.map} +1 -1
- package/dist/{parser-JVUZ7EEV.js → parser-KFCY3NIN.js} +19 -11
- package/dist/{parser-FXGAKPUI.js.map → parser-KFCY3NIN.js.map} +1 -1
- package/dist/{parser-D5VMCDLG.cjs → parser-VKWUMUML.cjs} +142 -134
- package/dist/parser-VKWUMUML.cjs.map +1 -0
- package/dist/pdf-ocr-MME37BL4.js +18 -0
- package/dist/pdf-ocr-OKAHNEJA.cjs +19 -0
- package/dist/{pdf-ocr-YFNUYBYJ.cjs.map → pdf-ocr-OKAHNEJA.cjs.map} +1 -1
- package/dist/pdf-ocr-ZZ6AJL6Z.js +22 -0
- package/dist/{profile-io-ULK73H2G.js → profile-io-OCITHUQF.js} +3 -3
- package/dist/{rasterize-FG3NX3GA.js → rasterize-SFCG4YOI.js} +3 -3
- package/dist/{redact-doc-NMKTKG24.js → redact-doc-5SMPXIGG.js} +11 -11
- package/dist/{render-GQUUGPOJ.js → render-FGPG5A2N.js} +7 -7
- package/dist/seal-GA7NZDTG.js +10 -0
- package/dist/{setup-PRBHD7JI.js → setup-JQVYZO7I.js} +3 -3
- package/dist/visual-YMG644YW.js +20 -0
- package/dist/{watch-LFSXNO2B.js → watch-C77BUSP7.js} +12 -12
- package/package.json +1 -1
- package/dist/chunk-DQ2YGTRS.js.map +0 -1
- package/dist/chunk-EYLEVRHT.cjs.map +0 -1
- package/dist/chunk-QWOZRYUA.js.map +0 -1
- package/dist/chunk-Y5OSPKBU.js.map +0 -1
- package/dist/chunks-J46DCTUC.js +0 -10
- package/dist/parser-D5VMCDLG.cjs.map +0 -1
- package/dist/pdf-ocr-364WQ5TY.js +0 -18
- package/dist/pdf-ocr-4MZELYCR.js +0 -22
- package/dist/pdf-ocr-YFNUYBYJ.cjs +0 -19
- package/dist/seal-EVHTG5GH.js +0 -10
- package/dist/visual-TCIR6MOG.js +0 -20
- /package/dist/{-FLYHAUQ6.js.map → -ZYF6HX4M.js.map} +0 -0
- /package/dist/{chunk-TC6DQLYN.js.map → chunk-2ZGP7A5T.js.map} +0 -0
- /package/dist/{chunk-4VM6BT4W.js.map → chunk-3TCF5HPP.js.map} +0 -0
- /package/dist/{chunk-OON4IJU2.js.map → chunk-5HTFWUJE.js.map} +0 -0
- /package/dist/{chunk-AQ5GIBBH.js.map → chunk-7YAJCXCD.js.map} +0 -0
- /package/dist/{chunk-3O4YC67B.js.map → chunk-BC54LBST.js.map} +0 -0
- /package/dist/{chunk-GK4QLKNT.js.map → chunk-BG6LUCQL.js.map} +0 -0
- /package/dist/{chunk-SM42XSI3.js.map → chunk-CY4QM2KQ.js.map} +0 -0
- /package/dist/{chunk-INZGI6PI.js.map → chunk-FBJVDBMO.js.map} +0 -0
- /package/dist/{chunk-Z2OOYQ4I.js.map → chunk-FZMGF6XU.js.map} +0 -0
- /package/dist/{chunk-F6N7CDB7.js.map → chunk-J5PBI3ZC.js.map} +0 -0
- /package/dist/{chunk-YDIVY65W.js.map → chunk-KTLHADU4.js.map} +0 -0
- /package/dist/{chunk-X6WXU4LA.js.map → chunk-PTF4NCFM.js.map} +0 -0
- /package/dist/{chunk-46PYORID.js.map → chunk-QHNVH4TC.js.map} +0 -0
- /package/dist/{chunk-RYRUQ73F.js.map → chunk-RBRHO7WL.js.map} +0 -0
- /package/dist/{chunk-CLAIAXMX.js.map → chunk-T3DTTK23.js.map} +0 -0
- /package/dist/{chunk-VIFY6DJZ.js.map → chunk-TRO4CQHJ.js.map} +0 -0
- /package/dist/{chunk-OWLDTF5Q.js.map → chunk-WGMYVRSA.js.map} +0 -0
- /package/dist/{chunk-AMXIYV73.js.map → chunk-YHPJTLCA.js.map} +0 -0
- /package/dist/{chunk-UDODNSDU.js.map → chunk-ZZIQWSGC.js.map} +0 -0
- /package/dist/{chunks-J46DCTUC.js.map → chunks-MDMJRCJ7.js.map} +0 -0
- /package/dist/{formula-2YYGN7UE.js.map → formula-6XNIXZ5L.js.map} +0 -0
- /package/dist/{formula-Z5UPXBQM.js.map → formula-P7M7IH2L.js.map} +0 -0
- /package/dist/{image-ocr-23R7RVHP.js.map → image-ocr-3C6W3KZO.js.map} +0 -0
- /package/dist/{image-ocr-IMLFZ2JC.js.map → image-ocr-ITNY454I.js.map} +0 -0
- /package/dist/{model-bundle-GTSRH2DY.js.map → model-bundle-LAWQH75O.js.map} +0 -0
- /package/dist/{models-2J3NS7G2.js.map → models-6QTD2CFM.js.map} +0 -0
- /package/dist/{parse-worker-v2-VO5UY3MP.js.map → parse-worker-v2-FEPJG3ER.js.map} +0 -0
- /package/dist/{pdf-ocr-364WQ5TY.js.map → pdf-ocr-MME37BL4.js.map} +0 -0
- /package/dist/{pdf-ocr-4MZELYCR.js.map → pdf-ocr-ZZ6AJL6Z.js.map} +0 -0
- /package/dist/{profile-io-ULK73H2G.js.map → profile-io-OCITHUQF.js.map} +0 -0
- /package/dist/{rasterize-FG3NX3GA.js.map → rasterize-SFCG4YOI.js.map} +0 -0
- /package/dist/{redact-doc-NMKTKG24.js.map → redact-doc-5SMPXIGG.js.map} +0 -0
- /package/dist/{render-GQUUGPOJ.js.map → render-FGPG5A2N.js.map} +0 -0
- /package/dist/{seal-EVHTG5GH.js.map → seal-GA7NZDTG.js.map} +0 -0
- /package/dist/{setup-PRBHD7JI.js.map → setup-JQVYZO7I.js.map} +0 -0
- /package/dist/{visual-TCIR6MOG.js.map → visual-YMG644YW.js.map} +0 -0
- /package/dist/{watch-LFSXNO2B.js.map → watch-C77BUSP7.js.map} +0 -0
|
@@ -1,88 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
import {
|
|
2
3
|
CELL_EDGES,
|
|
3
4
|
HEADING_RATIO_H1,
|
|
4
5
|
HEADING_RATIO_H2,
|
|
5
6
|
HEADING_RATIO_H3,
|
|
6
7
|
tidyScriptTags
|
|
7
|
-
} from "./chunk-
|
|
8
|
-
import {
|
|
9
|
-
ensureModelsIn,
|
|
10
|
-
getModelsDir
|
|
11
|
-
} from "./chunk-INZGI6PI.js";
|
|
8
|
+
} from "./chunk-PTF4NCFM.js";
|
|
12
9
|
import {
|
|
13
10
|
safeMax,
|
|
14
11
|
safeMin
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
|
|
17
|
-
// src/ocr/models.ts
|
|
18
|
-
import { join } from "path";
|
|
19
|
-
import { stat } from "fs/promises";
|
|
20
|
-
var OCR_DET_MODEL = {
|
|
21
|
-
name: "PP-OCRv5 mobile det",
|
|
22
|
-
filename: "det.onnx",
|
|
23
|
-
url: "https://huggingface.co/PaddlePaddle/PP-OCRv5_mobile_det_onnx/resolve/main/inference.onnx",
|
|
24
|
-
sha256: "a431985659dc921974177a95adcfbb90fd9e51989a5e04d70d0b75f597b6e61d",
|
|
25
|
-
sizeMb: 5
|
|
26
|
-
};
|
|
27
|
-
var OCR_REC_MODEL = {
|
|
28
|
-
name: "PP-OCRv5 korean rec",
|
|
29
|
-
filename: "rec_korean.onnx",
|
|
30
|
-
url: "https://huggingface.co/PaddlePaddle/korean_PP-OCRv5_mobile_rec_onnx/resolve/main/inference.onnx",
|
|
31
|
-
sha256: "92f0b7785e64fc9090106a241cf4c1eb97472824558272751b88a2a4476d3a08",
|
|
32
|
-
sizeMb: 13
|
|
33
|
-
};
|
|
34
|
-
var OCR_REC_DICT = {
|
|
35
|
-
name: "PP-OCRv5 korean dict",
|
|
36
|
-
filename: "rec_korean.yml",
|
|
37
|
-
url: "https://huggingface.co/PaddlePaddle/korean_PP-OCRv5_mobile_rec_onnx/resolve/main/inference.yml",
|
|
38
|
-
sha256: "f757fa1c40e99edcf27e9cce879b93eb2a51fa46f5ef39095689b8c37dd75998",
|
|
39
|
-
sizeMb: 1
|
|
40
|
-
};
|
|
41
|
-
var ALL_OCR_MODELS = [OCR_DET_MODEL, OCR_REC_MODEL, OCR_REC_DICT];
|
|
42
|
-
function getOcrModelsDir() {
|
|
43
|
-
return getModelsDir("ppocr");
|
|
44
|
-
}
|
|
45
|
-
async function ensureOcrModels(onProgress) {
|
|
46
|
-
return ensureModelsIn(getOcrModelsDir(), ALL_OCR_MODELS, onProgress);
|
|
47
|
-
}
|
|
48
|
-
async function ocrModelsCached() {
|
|
49
|
-
const dir = getOcrModelsDir();
|
|
50
|
-
for (const spec of ALL_OCR_MODELS) {
|
|
51
|
-
try {
|
|
52
|
-
if (!(await stat(join(dir, spec.filename))).size) return false;
|
|
53
|
-
} catch {
|
|
54
|
-
return false;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
function parseCharacterDict(yml) {
|
|
60
|
-
const lines = yml.split("\n");
|
|
61
|
-
const chars = [];
|
|
62
|
-
let inDict = false;
|
|
63
|
-
let dictIndent = -1;
|
|
64
|
-
for (const line of lines) {
|
|
65
|
-
if (!inDict) {
|
|
66
|
-
const m2 = /^(\s*)character_dict:\s*$/.exec(line);
|
|
67
|
-
if (m2) {
|
|
68
|
-
inDict = true;
|
|
69
|
-
dictIndent = m2[1].length;
|
|
70
|
-
}
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
const m = /^(\s*)- (.*)$/.exec(line);
|
|
74
|
-
if (m && m[1].length >= dictIndent) {
|
|
75
|
-
let v = m[2];
|
|
76
|
-
if (v.length >= 2 && (v.startsWith("'") && v.endsWith("'") || v.startsWith('"') && v.endsWith('"'))) {
|
|
77
|
-
v = v.slice(1, -1).replace(/''/g, "'");
|
|
78
|
-
}
|
|
79
|
-
chars.push(v);
|
|
80
|
-
continue;
|
|
81
|
-
}
|
|
82
|
-
if (line.trim() !== "") break;
|
|
83
|
-
}
|
|
84
|
-
return chars;
|
|
85
|
-
}
|
|
12
|
+
} from "./chunk-FZMGF6XU.js";
|
|
86
13
|
|
|
87
14
|
// src/pdf/line-extract.ts
|
|
88
15
|
import { OPS } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
@@ -1944,7 +1871,7 @@ function dropGridsInside(lineGrids, clipGrids, containers = [], verticals = [])
|
|
|
1944
1871
|
const ga = area(g);
|
|
1945
1872
|
return ga > 0 && ix * iy / ga >= 0.5;
|
|
1946
1873
|
};
|
|
1947
|
-
const inside = (c, g) => c.x1 >= g.x1 -
|
|
1874
|
+
const inside = (c, g) => c.x1 >= g.x1 - 3 && c.x2 <= g.x2 + 3 && c.y1 >= g.y1 - 3 && c.y2 <= g.y2 + 3;
|
|
1948
1875
|
const stackedOnly = (g) => {
|
|
1949
1876
|
const stacked = clipGrids.filter((c) => inside(c.bbox, g.bbox)).sort((a, b) => a.bbox.y1 - b.bbox.y1);
|
|
1950
1877
|
if (stacked.length < 2 || g.colXs.length < 3 || stacked.reduce((s, c) => s + area(c.bbox), 0) < area(g.bbox) * 0.5) return false;
|
|
@@ -3415,6 +3342,49 @@ function isExamLayoutTable(table) {
|
|
|
3415
3342
|
return layout >= texts.length * 0.6;
|
|
3416
3343
|
}
|
|
3417
3344
|
|
|
3345
|
+
// src/pdf/cluster-cell-text.ts
|
|
3346
|
+
function clusterCellLines(items) {
|
|
3347
|
+
const hOf = (i) => i.h > 0 ? i.h : i.fontSize;
|
|
3348
|
+
const lines = [];
|
|
3349
|
+
for (const it of [...items].sort((a, b) => b.y - a.y || a.x - b.x)) {
|
|
3350
|
+
const bottom = it.y, top = it.y + hOf(it);
|
|
3351
|
+
const line = lines.find((l) => Math.min(l.top, top) - Math.max(l.bottom, bottom) >= Math.min(l.top - l.bottom, top - bottom) * 0.5);
|
|
3352
|
+
if (line) {
|
|
3353
|
+
line.items.push(it);
|
|
3354
|
+
line.bottom = Math.min(line.bottom, bottom);
|
|
3355
|
+
line.top = Math.max(line.top, top);
|
|
3356
|
+
} else lines.push({ bottom, top, items: [it] });
|
|
3357
|
+
}
|
|
3358
|
+
return lines.sort((a, b) => b.top - a.top).map(({ items: line }) => {
|
|
3359
|
+
line.sort((a, b) => a.x - b.x);
|
|
3360
|
+
let s = line[0].text;
|
|
3361
|
+
for (let i = 1; i < line.length; i++) {
|
|
3362
|
+
const gap = line[i].x - (line[i - 1].x + line[i - 1].w);
|
|
3363
|
+
const fs = (line[i].fontSize + line[i - 1].fontSize) / 2;
|
|
3364
|
+
s += (!isCjkLatinAutospace(line[i - 1].text, line[i].text, gap, fs) && (line[i].hasSpaceBefore && gap >= fs * 0.05 || gap > spaceGapThreshold(fs)) ? " " : "") + line[i].text;
|
|
3365
|
+
}
|
|
3366
|
+
const last = line.reduce((a, b) => b.x + b.w > a.x + a.w ? b : a);
|
|
3367
|
+
return {
|
|
3368
|
+
text: s,
|
|
3369
|
+
left: line[0].x,
|
|
3370
|
+
right: last.x + last.w,
|
|
3371
|
+
fontSize: line[0].fontSize,
|
|
3372
|
+
spaceAfter: last.spaceAfter,
|
|
3373
|
+
firstCharW: line[0].w / Math.max(1, [...line[0].text.replace(/<\/?u>|~~/g, "")].length)
|
|
3374
|
+
};
|
|
3375
|
+
});
|
|
3376
|
+
}
|
|
3377
|
+
var WRAP_INDENT_MAX = 3;
|
|
3378
|
+
function joinClusterCellLines(lines, box, lex) {
|
|
3379
|
+
let out = lines[0]?.text ?? "";
|
|
3380
|
+
for (let i = 1; i < lines.length; i++) {
|
|
3381
|
+
const a = lines[i - 1], b = lines[i];
|
|
3382
|
+
const join = !a.spaceAfter && cellLineWraps(box, box.x1, a.right, a.fontSize, b.firstCharW) && a.left - box.x1 <= WRAP_INDENT_MAX * a.fontSize && b.left - box.x1 <= WRAP_INDENT_MAX * b.fontSize && /<\/u>$/.test(a.text) === /^<u>/.test(b.text) && !startsNewItem(out, b.text) && wrapJoiner(out, b.text, lex, false) === "";
|
|
3383
|
+
out += (join ? "" : " ") + b.text;
|
|
3384
|
+
}
|
|
3385
|
+
return out;
|
|
3386
|
+
}
|
|
3387
|
+
|
|
3418
3388
|
// src/pdf/cluster-detector.ts
|
|
3419
3389
|
var Y_TOL = 3;
|
|
3420
3390
|
var COL_CLUSTER_TOL = 15;
|
|
@@ -3423,7 +3393,7 @@ var MIN_COLS = 2;
|
|
|
3423
3393
|
var MIN_GAP_FACTOR = 2;
|
|
3424
3394
|
var MIN_GAP_ABSOLUTE = 20;
|
|
3425
3395
|
var MIN_COL_FILL_RATIO = 0.4;
|
|
3426
|
-
function detectClusterTables(items, pageNum, rejected) {
|
|
3396
|
+
function detectClusterTables(items, pageNum, rejected, lex) {
|
|
3427
3397
|
const tab = sideTabGlyphs(items);
|
|
3428
3398
|
if (tab.size) items = items.filter((i) => !tab.has(i));
|
|
3429
3399
|
if (items.length < MIN_ROWS * MIN_COLS) return [];
|
|
@@ -3444,7 +3414,7 @@ function detectClusterTables(items, pageNum, rejected) {
|
|
|
3444
3414
|
const mergedRows = mergeMultiLineRows(headerAndBelow, columns);
|
|
3445
3415
|
const tableRegions = findTableRegionsByHeader(mergedRows, columns, headerItems);
|
|
3446
3416
|
for (const region of tableRegions) {
|
|
3447
|
-
const table = buildClusterTable(region.rows, columns, pageNum);
|
|
3417
|
+
const table = buildClusterTable(region.rows, columns, pageNum, lex);
|
|
3448
3418
|
if (table) {
|
|
3449
3419
|
expandUsedItems(table.usedItems, originMap);
|
|
3450
3420
|
results.push(table);
|
|
@@ -3459,8 +3429,8 @@ function detectClusterTables(items, pageNum, rejected) {
|
|
|
3459
3429
|
const tableRegions = findTableRegions(rows, columns);
|
|
3460
3430
|
for (const region of tableRegions) {
|
|
3461
3431
|
const own = extractColumnClusters(region.rows.filter((row) => hasSuspiciousGaps(row)));
|
|
3462
|
-
const ownTable = own.length >= MIN_COLS && own.length < columns.length ? buildClusterTable(mergeMultiLineRows(region.rows, own), own, pageNum) : null;
|
|
3463
|
-
const table = ownTable && ownTable.table.cells.every((row, r) => row.every((cell) => (r === 0 || cell.colSpan >= ownTable.table.cols || cell.text.trim().length <= 30) && !/\p{Co}/u.test(cell.text))) ? ownTable : buildClusterTable(mergeMultiLineRows(region.rows, columns), columns, pageNum);
|
|
3432
|
+
const ownTable = own.length >= MIN_COLS && own.length < columns.length ? buildClusterTable(mergeMultiLineRows(region.rows, own), own, pageNum, lex) : null;
|
|
3433
|
+
const table = ownTable && ownTable.table.cells.every((row, r) => row.every((cell) => (r === 0 || cell.colSpan >= ownTable.table.cols || cell.text.trim().length <= 30) && !/\p{Co}/u.test(cell.text))) ? ownTable : buildClusterTable(mergeMultiLineRows(region.rows, columns), columns, pageNum, lex);
|
|
3464
3434
|
if (table) {
|
|
3465
3435
|
expandUsedItems(table.usedItems, originMap);
|
|
3466
3436
|
results.push(table);
|
|
@@ -4157,7 +4127,7 @@ function assignRowItems(items, columns, numCols, headerFace) {
|
|
|
4157
4127
|
}
|
|
4158
4128
|
return result;
|
|
4159
4129
|
}
|
|
4160
|
-
function buildClusterTable(rows, columns, pageNum) {
|
|
4130
|
+
function buildClusterTable(rows, columns, pageNum, lex) {
|
|
4161
4131
|
const numCols = columns.length;
|
|
4162
4132
|
const numRows = rows.length;
|
|
4163
4133
|
if (numRows < MIN_ROWS || numCols < MIN_COLS) return null;
|
|
@@ -4166,6 +4136,7 @@ function buildClusterTable(rows, columns, pageNum) {
|
|
|
4166
4136
|
() => Array.from({ length: numCols }, () => ({ text: "", colSpan: 1, rowSpan: 1 }))
|
|
4167
4137
|
);
|
|
4168
4138
|
const usedItems = /* @__PURE__ */ new Set();
|
|
4139
|
+
const lines = cells.map((row) => row.map(() => []));
|
|
4169
4140
|
const headFaces = new Set(rows[0]?.items.map((i) => i.fontName));
|
|
4170
4141
|
const headerFace = headFaces.size === 1 && rows.slice(1).every((row) => row.items.every((i) => !headFaces.has(i.fontName))) ? [...headFaces][0] : void 0;
|
|
4171
4142
|
for (let r = 0; r < numRows; r++) {
|
|
@@ -4177,12 +4148,18 @@ function buildClusterTable(rows, columns, pageNum) {
|
|
|
4177
4148
|
}
|
|
4178
4149
|
const assignments = assignRowItems(row.items, columns, numCols, r === 0 ? headerFace : void 0);
|
|
4179
4150
|
for (const { col, items } of assignments) {
|
|
4180
|
-
const
|
|
4181
|
-
|
|
4182
|
-
|
|
4151
|
+
const cell = lines[r][col];
|
|
4152
|
+
if (cell.length) cell[cell.length - 1].spaceAfter = true;
|
|
4153
|
+
cell.push(...clusterCellLines(items));
|
|
4183
4154
|
for (const item of items) usedItems.add(item);
|
|
4184
4155
|
}
|
|
4185
4156
|
}
|
|
4157
|
+
const boxes = columns.map((_, c) => {
|
|
4158
|
+
const col = lines.flatMap((row) => row[c]);
|
|
4159
|
+
return { x1: Math.min(...col.map((l) => l.left)), x2: Math.max(...col.map((l) => l.right)) };
|
|
4160
|
+
});
|
|
4161
|
+
const textOf = (r, c) => joinClusterCellLines(lines[r][c], boxes[c], lex);
|
|
4162
|
+
for (let r = 0; r < numRows; r++) for (let c = 0; c < numCols; c++) if (lines[r][c].length) cells[r][c].text = textOf(r, c);
|
|
4186
4163
|
let emptyRows = 0;
|
|
4187
4164
|
for (const row of cells) {
|
|
4188
4165
|
if (row.every((c) => c.text === "")) emptyRows++;
|
|
@@ -4202,9 +4179,9 @@ function buildClusterTable(rows, columns, pageNum) {
|
|
|
4202
4179
|
if (cells[pr].some((c) => c.text.trim())) {
|
|
4203
4180
|
if (cells[pr][0].colSpan > 1) break;
|
|
4204
4181
|
for (let c = 0; c < numCols; c++) {
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4182
|
+
if (!cells[r][c].text.trim()) continue;
|
|
4183
|
+
lines[pr][c].push(...lines[r][c]);
|
|
4184
|
+
cells[pr][c].text = textOf(pr, c);
|
|
4208
4185
|
}
|
|
4209
4186
|
for (let c = 0; c < numCols; c++) cells[r][c].text = "";
|
|
4210
4187
|
break;
|
|
@@ -4251,29 +4228,6 @@ function buildClusterTable(rows, columns, pageNum) {
|
|
|
4251
4228
|
usedItems
|
|
4252
4229
|
};
|
|
4253
4230
|
}
|
|
4254
|
-
function joinCellItems(items) {
|
|
4255
|
-
const hOf = (i) => i.h > 0 ? i.h : i.fontSize;
|
|
4256
|
-
const lines = [];
|
|
4257
|
-
for (const it of [...items].sort((a, b) => b.y - a.y || a.x - b.x)) {
|
|
4258
|
-
const bottom = it.y, top = it.y + hOf(it);
|
|
4259
|
-
const line = lines.find((l) => Math.min(l.top, top) - Math.max(l.bottom, bottom) >= Math.min(l.top - l.bottom, top - bottom) * 0.5);
|
|
4260
|
-
if (line) {
|
|
4261
|
-
line.items.push(it);
|
|
4262
|
-
line.bottom = Math.min(line.bottom, bottom);
|
|
4263
|
-
line.top = Math.max(line.top, top);
|
|
4264
|
-
} else lines.push({ bottom, top, items: [it] });
|
|
4265
|
-
}
|
|
4266
|
-
return lines.sort((a, b) => b.top - a.top).map(({ items: line }) => {
|
|
4267
|
-
line.sort((a, b) => a.x - b.x);
|
|
4268
|
-
let s = line[0].text;
|
|
4269
|
-
for (let i = 1; i < line.length; i++) {
|
|
4270
|
-
const gap = line[i].x - (line[i - 1].x + line[i - 1].w);
|
|
4271
|
-
const fs = (line[i].fontSize + line[i - 1].fontSize) / 2;
|
|
4272
|
-
s += (!isCjkLatinAutospace(line[i - 1].text, line[i].text, gap, fs) && (line[i].hasSpaceBefore && gap >= fs * 0.05 || gap > spaceGapThreshold(fs)) ? " " : "") + line[i].text;
|
|
4273
|
-
}
|
|
4274
|
-
return s;
|
|
4275
|
-
}).join(" ");
|
|
4276
|
-
}
|
|
4277
4231
|
|
|
4278
4232
|
// src/pdf/page-regions.ts
|
|
4279
4233
|
function splitTwoColumnProse(items, cutX) {
|
|
@@ -5717,6 +5671,20 @@ function detectSpecialKoreanTables(blocks) {
|
|
|
5717
5671
|
flushKvTable();
|
|
5718
5672
|
return result;
|
|
5719
5673
|
}
|
|
5674
|
+
function tracksPages(occ) {
|
|
5675
|
+
const nums = occ.map((o) => [...o.text.matchAll(/\d+/g)].map((m) => +m[0]));
|
|
5676
|
+
if (!nums.length || nums.some((n) => n.length !== nums[0].length)) return false;
|
|
5677
|
+
return nums[0].some((_, j) => new Set(occ.map((o, k) => o.page - nums[k][j])).size === 1);
|
|
5678
|
+
}
|
|
5679
|
+
function looseVaryingNumber(occ) {
|
|
5680
|
+
const nums = occ.map((o) => [...o.text.matchAll(/\d+/g)]);
|
|
5681
|
+
if (!nums.length || nums.some((n) => n.length !== nums[0].length)) return false;
|
|
5682
|
+
const loose = (text, m) => !/\p{L}/u.test(text[m.index - 1] ?? " ") && !/\p{L}/u.test(text[m.index + m[0].length] ?? " ");
|
|
5683
|
+
for (let j = 0; j < nums[0].length; j++) {
|
|
5684
|
+
if (new Set(nums.map((n) => n[j][0])).size > 1 && occ.every((o, k) => loose(o.text, nums[k][j]))) return true;
|
|
5685
|
+
}
|
|
5686
|
+
return false;
|
|
5687
|
+
}
|
|
5720
5688
|
function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables = false, context = []) {
|
|
5721
5689
|
if (context.length && !tables) {
|
|
5722
5690
|
const removed = removeHeaderFooterBlocks([...blocks, ...context], pageHeights, [], notes).filter((index) => index < blocks.length);
|
|
@@ -5746,6 +5714,7 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
|
|
|
5746
5714
|
const patternCount = /* @__PURE__ */ new Map();
|
|
5747
5715
|
const patternPages = /* @__PURE__ */ new Map();
|
|
5748
5716
|
const patternNumbers = /* @__PURE__ */ new Map();
|
|
5717
|
+
const patternOcc = /* @__PURE__ */ new Map();
|
|
5749
5718
|
for (const e of entries) {
|
|
5750
5719
|
const norm = e.text.replace(/\d+/g, "#");
|
|
5751
5720
|
patternCount.set(norm, (patternCount.get(norm) || 0) + 1);
|
|
@@ -5755,13 +5724,18 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
|
|
|
5755
5724
|
const pages = patternPages.get(norm) || /* @__PURE__ */ new Set();
|
|
5756
5725
|
pages.add(e.page);
|
|
5757
5726
|
patternPages.set(norm, pages);
|
|
5727
|
+
patternOcc.set(norm, [...patternOcc.get(norm) ?? [], e]);
|
|
5758
5728
|
}
|
|
5759
5729
|
const repeatedPatterns = /* @__PURE__ */ new Set();
|
|
5760
5730
|
for (const [p, count] of patternCount) {
|
|
5761
5731
|
const pages = [...patternPages.get(p) ?? []];
|
|
5762
5732
|
const span2 = pages.length ? Math.max(...pages) - Math.min(...pages) + 1 : 0;
|
|
5763
|
-
const
|
|
5764
|
-
|
|
5733
|
+
const varying = !tables && (patternNumbers.get(p)?.size ?? 0) > 1;
|
|
5734
|
+
const occ = patternOcc.get(p) ?? [];
|
|
5735
|
+
const dense = pages.length >= span2 * 0.4;
|
|
5736
|
+
const loose = looseVaryingNumber(occ) && (entries === bottomEntries || dense || tracksPages(occ));
|
|
5737
|
+
const pageNumbered = varying && (loose || dense && new Set(occ.map((o) => o.text)).size * 2 <= occ.length);
|
|
5738
|
+
if (count >= MIN_REPEAT2 && pages.length >= MIN_REPEAT2 && (varying ? pageNumbered : dense)) {
|
|
5765
5739
|
repeatedPatterns.add(p);
|
|
5766
5740
|
}
|
|
5767
5741
|
}
|
|
@@ -5799,6 +5773,59 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
|
|
|
5799
5773
|
}
|
|
5800
5774
|
return [...removeSet].sort((a, b) => a - b);
|
|
5801
5775
|
}
|
|
5776
|
+
function runningLinePatterns(removed, pageHeights) {
|
|
5777
|
+
const occ = /* @__PURE__ */ new Map();
|
|
5778
|
+
for (const b of removed) {
|
|
5779
|
+
const ph = b.bbox && b.pageNumber ? pageHeights.get(b.bbox.page) || pageHeights.get(b.pageNumber) : void 0;
|
|
5780
|
+
const key = b.text ? runningKey(b.text) : "";
|
|
5781
|
+
if (!ph || !b.bbox || !b.pageNumber || !/\p{L}/u.test(key) || ph - b.bbox.y <= ph * 0.5) continue;
|
|
5782
|
+
(occ.get(key) ?? occ.set(key, []).get(key)).push({ page: b.pageNumber, nums: (b.text.match(/\d+/g) ?? []).join(",") });
|
|
5783
|
+
}
|
|
5784
|
+
const out = /* @__PURE__ */ new Map();
|
|
5785
|
+
for (const [key, list] of occ) {
|
|
5786
|
+
if (!pageNumberAtEnd(key)) continue;
|
|
5787
|
+
const offsets = new Set(list.map((o) => o.page - +o.nums));
|
|
5788
|
+
if (offsets.size === 1) out.set(key, [...offsets][0]);
|
|
5789
|
+
}
|
|
5790
|
+
return out;
|
|
5791
|
+
}
|
|
5792
|
+
var runningKey = (s) => s.replace(/\d+/g, "#").replace(/\s+/g, " ").trim();
|
|
5793
|
+
var pageNumberAtEnd = (key) => (key.match(/#/g) ?? []).length === 1 && /#\s*[)\]]?$/.test(key);
|
|
5794
|
+
function stripAbsorbedRunningLines(blocks, pageHeights, running) {
|
|
5795
|
+
if (!running.size) return blocks;
|
|
5796
|
+
const matches = (line, page) => {
|
|
5797
|
+
const offset = running.get(runningKey(line));
|
|
5798
|
+
return offset !== void 0 && page - +(line.match(/\d+/g) ?? []).pop() === offset;
|
|
5799
|
+
};
|
|
5800
|
+
const out = [];
|
|
5801
|
+
for (const b of blocks) {
|
|
5802
|
+
const ph = b.bbox && b.pageNumber ? pageHeights.get(b.bbox.page) || pageHeights.get(b.pageNumber) : void 0;
|
|
5803
|
+
if (!ph || !b.bbox || !b.pageNumber || b.bbox.y > ph * 0.12) {
|
|
5804
|
+
out.push(b);
|
|
5805
|
+
continue;
|
|
5806
|
+
}
|
|
5807
|
+
if (b.type === "paragraph" && b.text) {
|
|
5808
|
+
const lines = b.text.split("\n");
|
|
5809
|
+
let hi = lines.length;
|
|
5810
|
+
while (hi > 0 && !lines[hi - 1].trim()) hi--;
|
|
5811
|
+
if (hi > 0 && matches(lines[hi - 1], b.pageNumber)) {
|
|
5812
|
+
const text = lines.slice(0, hi - 1).join("\n").trim();
|
|
5813
|
+
if (!text) continue;
|
|
5814
|
+
b.text = text;
|
|
5815
|
+
}
|
|
5816
|
+
} else if (b.type === "table" && b.table && b.table.cells.length) {
|
|
5817
|
+
const t = b.table, last = t.cells.length - 1;
|
|
5818
|
+
if (matches(t.cells[last].map((c) => c.text.trim()).filter(Boolean).join(" "), b.pageNumber) && !t.cells.slice(0, last).some((row, i) => row.some((c) => i + (c.rowSpan || 1) - 1 >= last))) {
|
|
5819
|
+
t.cells.pop();
|
|
5820
|
+
if (!t.cells.length) continue;
|
|
5821
|
+
t.rows = t.cells.length;
|
|
5822
|
+
t.hasHeader = t.hasHeader && t.rows > 1;
|
|
5823
|
+
}
|
|
5824
|
+
}
|
|
5825
|
+
out.push(b);
|
|
5826
|
+
}
|
|
5827
|
+
return out;
|
|
5828
|
+
}
|
|
5802
5829
|
|
|
5803
5830
|
// src/pdf/table-meta.ts
|
|
5804
5831
|
var CLIP_TABLES = /* @__PURE__ */ new WeakSet();
|
|
@@ -8274,7 +8301,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
|
|
|
8274
8301
|
spaceAfter: i.spaceAfter
|
|
8275
8302
|
}));
|
|
8276
8303
|
const proseColumns = findTwoColumnProseCutX(clusterItems) !== null || detectPersistentColumnGutter(remaining.map((i) => ({ x: i.x, y: i.y, w: i.w, h: i.h > 0 ? i.h : i.fontSize }))) !== null;
|
|
8277
|
-
const clusterResults = (proseColumns ? [] : detectClusterTables(clusterItems, pageNum)).filter((cr) => {
|
|
8304
|
+
const clusterResults = (proseColumns ? [] : detectClusterTables(clusterItems, pageNum, void 0, lex)).filter((cr) => {
|
|
8278
8305
|
const b = cr.bbox;
|
|
8279
8306
|
const overlapX = (x) => Math.min(x.x + x.width, b.x + b.width) - Math.max(x.x, b.x);
|
|
8280
8307
|
return !blocks.some((x) => x.bbox && x.bbox.y >= b.y - 2 && x.bbox.y + x.bbox.height <= b.y + b.height + 2 && (x.type === "paragraph" ? (x.text?.match(/\p{L}/gu)?.length ?? 0) >= 10 && overlapX(x.bbox) >= 0.8 * b.width : x.type === "table" && !ocrPage && x.table?.cols === cr.table.cols && overlapX(x.bbox) >= 0.5 * Math.min(x.bbox.width, b.width)));
|
|
@@ -8626,7 +8653,7 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false, detectTable
|
|
|
8626
8653
|
if (regions) return regions.flatMap((region) => extractPageBlocksFallback(region, pageNum, false, detectTables, lex));
|
|
8627
8654
|
}
|
|
8628
8655
|
const rejected = { prose: 0 };
|
|
8629
|
-
const clusterResults = detectTables ? detectClusterTables(clusterItems, pageNum, rejected) : [];
|
|
8656
|
+
const clusterResults = detectTables ? detectClusterTables(clusterItems, pageNum, rejected, lex) : [];
|
|
8630
8657
|
if (clusterResults.length > 0) {
|
|
8631
8658
|
const ciToIdx = /* @__PURE__ */ new Map();
|
|
8632
8659
|
for (let ci = 0; ci < clusterItems.length; ci++) ciToIdx.set(clusterItems[ci], ci);
|
|
@@ -8811,13 +8838,6 @@ function rowParagraphs(block) {
|
|
|
8811
8838
|
}
|
|
8812
8839
|
|
|
8813
8840
|
export {
|
|
8814
|
-
OCR_DET_MODEL,
|
|
8815
|
-
OCR_REC_MODEL,
|
|
8816
|
-
OCR_REC_DICT,
|
|
8817
|
-
getOcrModelsDir,
|
|
8818
|
-
ensureOcrModels,
|
|
8819
|
-
ocrModelsCached,
|
|
8820
|
-
parseCharacterDict,
|
|
8821
8841
|
extractLines,
|
|
8822
8842
|
extractImageRegions,
|
|
8823
8843
|
filterHiddenText,
|
|
@@ -8847,6 +8867,8 @@ export {
|
|
|
8847
8867
|
detectTableCaptions,
|
|
8848
8868
|
detectKoreanListBlocks,
|
|
8849
8869
|
removeHeaderFooterBlocks,
|
|
8870
|
+
runningLinePatterns,
|
|
8871
|
+
stripAbsorbedRunningLines,
|
|
8850
8872
|
CLIP_TABLES,
|
|
8851
8873
|
FRAME_TITLE_BLOCKS,
|
|
8852
8874
|
TABLE_COLXS,
|
|
@@ -8869,4 +8891,4 @@ export {
|
|
|
8869
8891
|
UNRULED_REGION_TABLES,
|
|
8870
8892
|
mergeOcrImageRegions
|
|
8871
8893
|
};
|
|
8872
|
-
//# sourceMappingURL=chunk-
|
|
8894
|
+
//# sourceMappingURL=chunk-KBV4WFZ6.js.map
|