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,15 +1,88 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
1
|
import {
|
|
3
2
|
CELL_EDGES,
|
|
4
3
|
HEADING_RATIO_H1,
|
|
5
4
|
HEADING_RATIO_H2,
|
|
6
5
|
HEADING_RATIO_H3,
|
|
7
6
|
tidyScriptTags
|
|
8
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-KTLHADU4.js";
|
|
8
|
+
import {
|
|
9
|
+
ensureModelsIn,
|
|
10
|
+
getModelsDir
|
|
11
|
+
} from "./chunk-FBJVDBMO.js";
|
|
9
12
|
import {
|
|
10
13
|
safeMax,
|
|
11
14
|
safeMin
|
|
12
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-ZZIQWSGC.js";
|
|
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
|
+
}
|
|
13
86
|
|
|
14
87
|
// src/pdf/line-extract.ts
|
|
15
88
|
import { OPS } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
@@ -1871,7 +1944,7 @@ function dropGridsInside(lineGrids, clipGrids, containers = [], verticals = [])
|
|
|
1871
1944
|
const ga = area(g);
|
|
1872
1945
|
return ga > 0 && ix * iy / ga >= 0.5;
|
|
1873
1946
|
};
|
|
1874
|
-
const inside = (c, g) => c.x1 >= g.x1 -
|
|
1947
|
+
const inside = (c, g) => c.x1 >= g.x1 - 3 && c.x2 <= g.x2 + 3 && c.y1 >= g.y1 - 3 && c.y2 <= g.y2 + 3;
|
|
1875
1948
|
const stackedOnly = (g) => {
|
|
1876
1949
|
const stacked = clipGrids.filter((c) => inside(c.bbox, g.bbox)).sort((a, b) => a.bbox.y1 - b.bbox.y1);
|
|
1877
1950
|
if (stacked.length < 2 || g.colXs.length < 3 || stacked.reduce((s, c) => s + area(c.bbox), 0) < area(g.bbox) * 0.5) return false;
|
|
@@ -3342,6 +3415,49 @@ function isExamLayoutTable(table) {
|
|
|
3342
3415
|
return layout >= texts.length * 0.6;
|
|
3343
3416
|
}
|
|
3344
3417
|
|
|
3418
|
+
// src/pdf/cluster-cell-text.ts
|
|
3419
|
+
function clusterCellLines(items) {
|
|
3420
|
+
const hOf = (i) => i.h > 0 ? i.h : i.fontSize;
|
|
3421
|
+
const lines = [];
|
|
3422
|
+
for (const it of [...items].sort((a, b) => b.y - a.y || a.x - b.x)) {
|
|
3423
|
+
const bottom = it.y, top = it.y + hOf(it);
|
|
3424
|
+
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);
|
|
3425
|
+
if (line) {
|
|
3426
|
+
line.items.push(it);
|
|
3427
|
+
line.bottom = Math.min(line.bottom, bottom);
|
|
3428
|
+
line.top = Math.max(line.top, top);
|
|
3429
|
+
} else lines.push({ bottom, top, items: [it] });
|
|
3430
|
+
}
|
|
3431
|
+
return lines.sort((a, b) => b.top - a.top).map(({ items: line }) => {
|
|
3432
|
+
line.sort((a, b) => a.x - b.x);
|
|
3433
|
+
let s = line[0].text;
|
|
3434
|
+
for (let i = 1; i < line.length; i++) {
|
|
3435
|
+
const gap = line[i].x - (line[i - 1].x + line[i - 1].w);
|
|
3436
|
+
const fs = (line[i].fontSize + line[i - 1].fontSize) / 2;
|
|
3437
|
+
s += (!isCjkLatinAutospace(line[i - 1].text, line[i].text, gap, fs) && (line[i].hasSpaceBefore && gap >= fs * 0.05 || gap > spaceGapThreshold(fs)) ? " " : "") + line[i].text;
|
|
3438
|
+
}
|
|
3439
|
+
const last = line.reduce((a, b) => b.x + b.w > a.x + a.w ? b : a);
|
|
3440
|
+
return {
|
|
3441
|
+
text: s,
|
|
3442
|
+
left: line[0].x,
|
|
3443
|
+
right: last.x + last.w,
|
|
3444
|
+
fontSize: line[0].fontSize,
|
|
3445
|
+
spaceAfter: last.spaceAfter,
|
|
3446
|
+
firstCharW: line[0].w / Math.max(1, [...line[0].text.replace(/<\/?u>|~~/g, "")].length)
|
|
3447
|
+
};
|
|
3448
|
+
});
|
|
3449
|
+
}
|
|
3450
|
+
var WRAP_INDENT_MAX = 3;
|
|
3451
|
+
function joinClusterCellLines(lines, box, lex) {
|
|
3452
|
+
let out = lines[0]?.text ?? "";
|
|
3453
|
+
for (let i = 1; i < lines.length; i++) {
|
|
3454
|
+
const a = lines[i - 1], b = lines[i];
|
|
3455
|
+
const join2 = !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) === "";
|
|
3456
|
+
out += (join2 ? "" : " ") + b.text;
|
|
3457
|
+
}
|
|
3458
|
+
return out;
|
|
3459
|
+
}
|
|
3460
|
+
|
|
3345
3461
|
// src/pdf/cluster-detector.ts
|
|
3346
3462
|
var Y_TOL = 3;
|
|
3347
3463
|
var COL_CLUSTER_TOL = 15;
|
|
@@ -3350,7 +3466,7 @@ var MIN_COLS = 2;
|
|
|
3350
3466
|
var MIN_GAP_FACTOR = 2;
|
|
3351
3467
|
var MIN_GAP_ABSOLUTE = 20;
|
|
3352
3468
|
var MIN_COL_FILL_RATIO = 0.4;
|
|
3353
|
-
function detectClusterTables(items, pageNum, rejected) {
|
|
3469
|
+
function detectClusterTables(items, pageNum, rejected, lex) {
|
|
3354
3470
|
const tab = sideTabGlyphs(items);
|
|
3355
3471
|
if (tab.size) items = items.filter((i) => !tab.has(i));
|
|
3356
3472
|
if (items.length < MIN_ROWS * MIN_COLS) return [];
|
|
@@ -3371,7 +3487,7 @@ function detectClusterTables(items, pageNum, rejected) {
|
|
|
3371
3487
|
const mergedRows = mergeMultiLineRows(headerAndBelow, columns);
|
|
3372
3488
|
const tableRegions = findTableRegionsByHeader(mergedRows, columns, headerItems);
|
|
3373
3489
|
for (const region of tableRegions) {
|
|
3374
|
-
const table = buildClusterTable(region.rows, columns, pageNum);
|
|
3490
|
+
const table = buildClusterTable(region.rows, columns, pageNum, lex);
|
|
3375
3491
|
if (table) {
|
|
3376
3492
|
expandUsedItems(table.usedItems, originMap);
|
|
3377
3493
|
results.push(table);
|
|
@@ -3386,8 +3502,8 @@ function detectClusterTables(items, pageNum, rejected) {
|
|
|
3386
3502
|
const tableRegions = findTableRegions(rows, columns);
|
|
3387
3503
|
for (const region of tableRegions) {
|
|
3388
3504
|
const own = extractColumnClusters(region.rows.filter((row) => hasSuspiciousGaps(row)));
|
|
3389
|
-
const ownTable = own.length >= MIN_COLS && own.length < columns.length ? buildClusterTable(mergeMultiLineRows(region.rows, own), own, pageNum) : null;
|
|
3390
|
-
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);
|
|
3505
|
+
const ownTable = own.length >= MIN_COLS && own.length < columns.length ? buildClusterTable(mergeMultiLineRows(region.rows, own), own, pageNum, lex) : null;
|
|
3506
|
+
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);
|
|
3391
3507
|
if (table) {
|
|
3392
3508
|
expandUsedItems(table.usedItems, originMap);
|
|
3393
3509
|
results.push(table);
|
|
@@ -4084,7 +4200,7 @@ function assignRowItems(items, columns, numCols, headerFace) {
|
|
|
4084
4200
|
}
|
|
4085
4201
|
return result;
|
|
4086
4202
|
}
|
|
4087
|
-
function buildClusterTable(rows, columns, pageNum) {
|
|
4203
|
+
function buildClusterTable(rows, columns, pageNum, lex) {
|
|
4088
4204
|
const numCols = columns.length;
|
|
4089
4205
|
const numRows = rows.length;
|
|
4090
4206
|
if (numRows < MIN_ROWS || numCols < MIN_COLS) return null;
|
|
@@ -4093,6 +4209,7 @@ function buildClusterTable(rows, columns, pageNum) {
|
|
|
4093
4209
|
() => Array.from({ length: numCols }, () => ({ text: "", colSpan: 1, rowSpan: 1 }))
|
|
4094
4210
|
);
|
|
4095
4211
|
const usedItems = /* @__PURE__ */ new Set();
|
|
4212
|
+
const lines = cells.map((row) => row.map(() => []));
|
|
4096
4213
|
const headFaces = new Set(rows[0]?.items.map((i) => i.fontName));
|
|
4097
4214
|
const headerFace = headFaces.size === 1 && rows.slice(1).every((row) => row.items.every((i) => !headFaces.has(i.fontName))) ? [...headFaces][0] : void 0;
|
|
4098
4215
|
for (let r = 0; r < numRows; r++) {
|
|
@@ -4104,12 +4221,18 @@ function buildClusterTable(rows, columns, pageNum) {
|
|
|
4104
4221
|
}
|
|
4105
4222
|
const assignments = assignRowItems(row.items, columns, numCols, r === 0 ? headerFace : void 0);
|
|
4106
4223
|
for (const { col, items } of assignments) {
|
|
4107
|
-
const
|
|
4108
|
-
|
|
4109
|
-
|
|
4224
|
+
const cell = lines[r][col];
|
|
4225
|
+
if (cell.length) cell[cell.length - 1].spaceAfter = true;
|
|
4226
|
+
cell.push(...clusterCellLines(items));
|
|
4110
4227
|
for (const item of items) usedItems.add(item);
|
|
4111
4228
|
}
|
|
4112
4229
|
}
|
|
4230
|
+
const boxes = columns.map((_, c) => {
|
|
4231
|
+
const col = lines.flatMap((row) => row[c]);
|
|
4232
|
+
return { x1: Math.min(...col.map((l) => l.left)), x2: Math.max(...col.map((l) => l.right)) };
|
|
4233
|
+
});
|
|
4234
|
+
const textOf = (r, c) => joinClusterCellLines(lines[r][c], boxes[c], lex);
|
|
4235
|
+
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);
|
|
4113
4236
|
let emptyRows = 0;
|
|
4114
4237
|
for (const row of cells) {
|
|
4115
4238
|
if (row.every((c) => c.text === "")) emptyRows++;
|
|
@@ -4129,9 +4252,9 @@ function buildClusterTable(rows, columns, pageNum) {
|
|
|
4129
4252
|
if (cells[pr].some((c) => c.text.trim())) {
|
|
4130
4253
|
if (cells[pr][0].colSpan > 1) break;
|
|
4131
4254
|
for (let c = 0; c < numCols; c++) {
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4255
|
+
if (!cells[r][c].text.trim()) continue;
|
|
4256
|
+
lines[pr][c].push(...lines[r][c]);
|
|
4257
|
+
cells[pr][c].text = textOf(pr, c);
|
|
4135
4258
|
}
|
|
4136
4259
|
for (let c = 0; c < numCols; c++) cells[r][c].text = "";
|
|
4137
4260
|
break;
|
|
@@ -4178,29 +4301,6 @@ function buildClusterTable(rows, columns, pageNum) {
|
|
|
4178
4301
|
usedItems
|
|
4179
4302
|
};
|
|
4180
4303
|
}
|
|
4181
|
-
function joinCellItems(items) {
|
|
4182
|
-
const hOf = (i) => i.h > 0 ? i.h : i.fontSize;
|
|
4183
|
-
const lines = [];
|
|
4184
|
-
for (const it of [...items].sort((a, b) => b.y - a.y || a.x - b.x)) {
|
|
4185
|
-
const bottom = it.y, top = it.y + hOf(it);
|
|
4186
|
-
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);
|
|
4187
|
-
if (line) {
|
|
4188
|
-
line.items.push(it);
|
|
4189
|
-
line.bottom = Math.min(line.bottom, bottom);
|
|
4190
|
-
line.top = Math.max(line.top, top);
|
|
4191
|
-
} else lines.push({ bottom, top, items: [it] });
|
|
4192
|
-
}
|
|
4193
|
-
return lines.sort((a, b) => b.top - a.top).map(({ items: line }) => {
|
|
4194
|
-
line.sort((a, b) => a.x - b.x);
|
|
4195
|
-
let s = line[0].text;
|
|
4196
|
-
for (let i = 1; i < line.length; i++) {
|
|
4197
|
-
const gap = line[i].x - (line[i - 1].x + line[i - 1].w);
|
|
4198
|
-
const fs = (line[i].fontSize + line[i - 1].fontSize) / 2;
|
|
4199
|
-
s += (!isCjkLatinAutospace(line[i - 1].text, line[i].text, gap, fs) && (line[i].hasSpaceBefore && gap >= fs * 0.05 || gap > spaceGapThreshold(fs)) ? " " : "") + line[i].text;
|
|
4200
|
-
}
|
|
4201
|
-
return s;
|
|
4202
|
-
}).join(" ");
|
|
4203
|
-
}
|
|
4204
4304
|
|
|
4205
4305
|
// src/pdf/page-regions.ts
|
|
4206
4306
|
function splitTwoColumnProse(items, cutX) {
|
|
@@ -5644,6 +5744,20 @@ function detectSpecialKoreanTables(blocks) {
|
|
|
5644
5744
|
flushKvTable();
|
|
5645
5745
|
return result;
|
|
5646
5746
|
}
|
|
5747
|
+
function tracksPages(occ) {
|
|
5748
|
+
const nums = occ.map((o) => [...o.text.matchAll(/\d+/g)].map((m) => +m[0]));
|
|
5749
|
+
if (!nums.length || nums.some((n) => n.length !== nums[0].length)) return false;
|
|
5750
|
+
return nums[0].some((_, j) => new Set(occ.map((o, k) => o.page - nums[k][j])).size === 1);
|
|
5751
|
+
}
|
|
5752
|
+
function looseVaryingNumber(occ) {
|
|
5753
|
+
const nums = occ.map((o) => [...o.text.matchAll(/\d+/g)]);
|
|
5754
|
+
if (!nums.length || nums.some((n) => n.length !== nums[0].length)) return false;
|
|
5755
|
+
const loose = (text, m) => !/\p{L}/u.test(text[m.index - 1] ?? " ") && !/\p{L}/u.test(text[m.index + m[0].length] ?? " ");
|
|
5756
|
+
for (let j = 0; j < nums[0].length; j++) {
|
|
5757
|
+
if (new Set(nums.map((n) => n[j][0])).size > 1 && occ.every((o, k) => loose(o.text, nums[k][j]))) return true;
|
|
5758
|
+
}
|
|
5759
|
+
return false;
|
|
5760
|
+
}
|
|
5647
5761
|
function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables = false, context = []) {
|
|
5648
5762
|
if (context.length && !tables) {
|
|
5649
5763
|
const removed = removeHeaderFooterBlocks([...blocks, ...context], pageHeights, [], notes).filter((index) => index < blocks.length);
|
|
@@ -5673,6 +5787,7 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
|
|
|
5673
5787
|
const patternCount = /* @__PURE__ */ new Map();
|
|
5674
5788
|
const patternPages = /* @__PURE__ */ new Map();
|
|
5675
5789
|
const patternNumbers = /* @__PURE__ */ new Map();
|
|
5790
|
+
const patternOcc = /* @__PURE__ */ new Map();
|
|
5676
5791
|
for (const e of entries) {
|
|
5677
5792
|
const norm = e.text.replace(/\d+/g, "#");
|
|
5678
5793
|
patternCount.set(norm, (patternCount.get(norm) || 0) + 1);
|
|
@@ -5682,13 +5797,18 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
|
|
|
5682
5797
|
const pages = patternPages.get(norm) || /* @__PURE__ */ new Set();
|
|
5683
5798
|
pages.add(e.page);
|
|
5684
5799
|
patternPages.set(norm, pages);
|
|
5800
|
+
patternOcc.set(norm, [...patternOcc.get(norm) ?? [], e]);
|
|
5685
5801
|
}
|
|
5686
5802
|
const repeatedPatterns = /* @__PURE__ */ new Set();
|
|
5687
5803
|
for (const [p, count] of patternCount) {
|
|
5688
5804
|
const pages = [...patternPages.get(p) ?? []];
|
|
5689
5805
|
const span2 = pages.length ? Math.max(...pages) - Math.min(...pages) + 1 : 0;
|
|
5690
|
-
const
|
|
5691
|
-
|
|
5806
|
+
const varying = !tables && (patternNumbers.get(p)?.size ?? 0) > 1;
|
|
5807
|
+
const occ = patternOcc.get(p) ?? [];
|
|
5808
|
+
const dense = pages.length >= span2 * 0.4;
|
|
5809
|
+
const loose = looseVaryingNumber(occ) && (entries === bottomEntries || dense || tracksPages(occ));
|
|
5810
|
+
const pageNumbered = varying && (loose || dense && new Set(occ.map((o) => o.text)).size * 2 <= occ.length);
|
|
5811
|
+
if (count >= MIN_REPEAT2 && pages.length >= MIN_REPEAT2 && (varying ? pageNumbered : dense)) {
|
|
5692
5812
|
repeatedPatterns.add(p);
|
|
5693
5813
|
}
|
|
5694
5814
|
}
|
|
@@ -5726,6 +5846,59 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings, notes, tables =
|
|
|
5726
5846
|
}
|
|
5727
5847
|
return [...removeSet].sort((a, b) => a - b);
|
|
5728
5848
|
}
|
|
5849
|
+
function runningLinePatterns(removed, pageHeights) {
|
|
5850
|
+
const occ = /* @__PURE__ */ new Map();
|
|
5851
|
+
for (const b of removed) {
|
|
5852
|
+
const ph = b.bbox && b.pageNumber ? pageHeights.get(b.bbox.page) || pageHeights.get(b.pageNumber) : void 0;
|
|
5853
|
+
const key = b.text ? runningKey(b.text) : "";
|
|
5854
|
+
if (!ph || !b.bbox || !b.pageNumber || !/\p{L}/u.test(key) || ph - b.bbox.y <= ph * 0.5) continue;
|
|
5855
|
+
(occ.get(key) ?? occ.set(key, []).get(key)).push({ page: b.pageNumber, nums: (b.text.match(/\d+/g) ?? []).join(",") });
|
|
5856
|
+
}
|
|
5857
|
+
const out = /* @__PURE__ */ new Map();
|
|
5858
|
+
for (const [key, list] of occ) {
|
|
5859
|
+
if (!pageNumberAtEnd(key)) continue;
|
|
5860
|
+
const offsets = new Set(list.map((o) => o.page - +o.nums));
|
|
5861
|
+
if (offsets.size === 1) out.set(key, [...offsets][0]);
|
|
5862
|
+
}
|
|
5863
|
+
return out;
|
|
5864
|
+
}
|
|
5865
|
+
var runningKey = (s) => s.replace(/\d+/g, "#").replace(/\s+/g, " ").trim();
|
|
5866
|
+
var pageNumberAtEnd = (key) => (key.match(/#/g) ?? []).length === 1 && /#\s*[)\]]?$/.test(key);
|
|
5867
|
+
function stripAbsorbedRunningLines(blocks, pageHeights, running) {
|
|
5868
|
+
if (!running.size) return blocks;
|
|
5869
|
+
const matches = (line, page) => {
|
|
5870
|
+
const offset = running.get(runningKey(line));
|
|
5871
|
+
return offset !== void 0 && page - +(line.match(/\d+/g) ?? []).pop() === offset;
|
|
5872
|
+
};
|
|
5873
|
+
const out = [];
|
|
5874
|
+
for (const b of blocks) {
|
|
5875
|
+
const ph = b.bbox && b.pageNumber ? pageHeights.get(b.bbox.page) || pageHeights.get(b.pageNumber) : void 0;
|
|
5876
|
+
if (!ph || !b.bbox || !b.pageNumber || b.bbox.y > ph * 0.12) {
|
|
5877
|
+
out.push(b);
|
|
5878
|
+
continue;
|
|
5879
|
+
}
|
|
5880
|
+
if (b.type === "paragraph" && b.text) {
|
|
5881
|
+
const lines = b.text.split("\n");
|
|
5882
|
+
let hi = lines.length;
|
|
5883
|
+
while (hi > 0 && !lines[hi - 1].trim()) hi--;
|
|
5884
|
+
if (hi > 0 && matches(lines[hi - 1], b.pageNumber)) {
|
|
5885
|
+
const text = lines.slice(0, hi - 1).join("\n").trim();
|
|
5886
|
+
if (!text) continue;
|
|
5887
|
+
b.text = text;
|
|
5888
|
+
}
|
|
5889
|
+
} else if (b.type === "table" && b.table && b.table.cells.length) {
|
|
5890
|
+
const t = b.table, last = t.cells.length - 1;
|
|
5891
|
+
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))) {
|
|
5892
|
+
t.cells.pop();
|
|
5893
|
+
if (!t.cells.length) continue;
|
|
5894
|
+
t.rows = t.cells.length;
|
|
5895
|
+
t.hasHeader = t.hasHeader && t.rows > 1;
|
|
5896
|
+
}
|
|
5897
|
+
}
|
|
5898
|
+
out.push(b);
|
|
5899
|
+
}
|
|
5900
|
+
return out;
|
|
5901
|
+
}
|
|
5729
5902
|
|
|
5730
5903
|
// src/pdf/table-meta.ts
|
|
5731
5904
|
var CLIP_TABLES = /* @__PURE__ */ new WeakSet();
|
|
@@ -8201,7 +8374,7 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
|
|
|
8201
8374
|
spaceAfter: i.spaceAfter
|
|
8202
8375
|
}));
|
|
8203
8376
|
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;
|
|
8204
|
-
const clusterResults = (proseColumns ? [] : detectClusterTables(clusterItems, pageNum)).filter((cr) => {
|
|
8377
|
+
const clusterResults = (proseColumns ? [] : detectClusterTables(clusterItems, pageNum, void 0, lex)).filter((cr) => {
|
|
8205
8378
|
const b = cr.bbox;
|
|
8206
8379
|
const overlapX = (x) => Math.min(x.x + x.width, b.x + b.width) - Math.max(x.x, b.x);
|
|
8207
8380
|
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)));
|
|
@@ -8553,7 +8726,7 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false, detectTable
|
|
|
8553
8726
|
if (regions) return regions.flatMap((region) => extractPageBlocksFallback(region, pageNum, false, detectTables, lex));
|
|
8554
8727
|
}
|
|
8555
8728
|
const rejected = { prose: 0 };
|
|
8556
|
-
const clusterResults = detectTables ? detectClusterTables(clusterItems, pageNum, rejected) : [];
|
|
8729
|
+
const clusterResults = detectTables ? detectClusterTables(clusterItems, pageNum, rejected, lex) : [];
|
|
8557
8730
|
if (clusterResults.length > 0) {
|
|
8558
8731
|
const ciToIdx = /* @__PURE__ */ new Map();
|
|
8559
8732
|
for (let ci = 0; ci < clusterItems.length; ci++) ciToIdx.set(clusterItems[ci], ci);
|
|
@@ -8738,6 +8911,13 @@ function rowParagraphs(block) {
|
|
|
8738
8911
|
}
|
|
8739
8912
|
|
|
8740
8913
|
export {
|
|
8914
|
+
OCR_DET_MODEL,
|
|
8915
|
+
OCR_REC_MODEL,
|
|
8916
|
+
OCR_REC_DICT,
|
|
8917
|
+
getOcrModelsDir,
|
|
8918
|
+
ensureOcrModels,
|
|
8919
|
+
ocrModelsCached,
|
|
8920
|
+
parseCharacterDict,
|
|
8741
8921
|
extractLines,
|
|
8742
8922
|
extractImageRegions,
|
|
8743
8923
|
filterHiddenText,
|
|
@@ -8767,6 +8947,8 @@ export {
|
|
|
8767
8947
|
detectTableCaptions,
|
|
8768
8948
|
detectKoreanListBlocks,
|
|
8769
8949
|
removeHeaderFooterBlocks,
|
|
8950
|
+
runningLinePatterns,
|
|
8951
|
+
stripAbsorbedRunningLines,
|
|
8770
8952
|
CLIP_TABLES,
|
|
8771
8953
|
FRAME_TITLE_BLOCKS,
|
|
8772
8954
|
TABLE_COLXS,
|
|
@@ -8789,4 +8971,4 @@ export {
|
|
|
8789
8971
|
UNRULED_REGION_TABLES,
|
|
8790
8972
|
mergeOcrImageRegions
|
|
8791
8973
|
};
|
|
8792
|
-
//# sourceMappingURL=chunk-
|
|
8974
|
+
//# sourceMappingURL=chunk-YQZOPT3A.js.map
|