kordoc 4.16.0 → 4.16.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 +344 -1135
- package/dist/{-VQNLLLPE.js → -4G6MA4X6.js} +11 -11
- package/dist/chunk-3IB7LBHC.js +57 -0
- package/dist/chunk-3IB7LBHC.js.map +1 -0
- package/dist/{chunk-6LMKQM7I.js → chunk-4VODJKFL.js} +3 -3
- package/dist/{chunk-UDX7TSOC.js → chunk-5KS5PWJR.js} +2 -2
- package/dist/chunk-62W7QCEX.cjs +57 -0
- package/dist/chunk-62W7QCEX.cjs.map +1 -0
- package/dist/{chunk-NNYF2AGC.js → chunk-7KNGSQU7.js} +4 -4
- package/dist/chunk-7KNGSQU7.js.map +1 -0
- package/dist/{chunk-DYENR3PX.js → chunk-AUWGDP4G.js} +2 -2
- package/dist/{chunk-H6KMTYYZ.cjs → chunk-CEIATRDW.cjs} +3 -3
- package/dist/{chunk-H6KMTYYZ.cjs.map → chunk-CEIATRDW.cjs.map} +1 -1
- package/dist/{chunk-N6TPODYL.js → chunk-DES2LGFZ.js} +2 -2
- package/dist/{chunk-PQRP4NSF.js → chunk-F4NRLLY4.js} +2 -2
- package/dist/{chunk-B5NEGP65.cjs → chunk-FKUDAIJI.cjs} +692 -33
- package/dist/chunk-FKUDAIJI.cjs.map +1 -0
- package/dist/{chunk-XWA625AN.js → chunk-FSDJLAOW.js} +3 -1
- package/dist/chunk-FSDJLAOW.js.map +1 -0
- package/dist/{chunk-PIMB2YNO.js → chunk-GO5IFOUF.js} +2 -2
- package/dist/{chunk-476OYHGZ.js → chunk-IQGIT2VX.js} +37 -7
- package/dist/chunk-IQGIT2VX.js.map +1 -0
- package/dist/chunk-J3IF6KGW.js +59 -0
- package/dist/chunk-J3IF6KGW.js.map +1 -0
- package/dist/{chunk-C75WE52C.js → chunk-JELRWAZC.js} +2 -2
- package/dist/{chunk-46DZF3RK.js → chunk-JFLAM3MM.js} +2 -2
- package/dist/{chunk-A3QDRMVD.js → chunk-KIOQ4N37.js} +2 -2
- package/dist/{chunk-TGD7UFHD.js → chunk-LEIAEWZ7.js} +4 -4
- package/dist/chunk-LEIAEWZ7.js.map +1 -0
- package/dist/{chunk-GOQBON77.js → chunk-MLIS253L.js} +2 -2
- package/dist/{chunk-JB5X5NNL.js → chunk-OXLPVQYK.js} +680 -21
- package/dist/chunk-OXLPVQYK.js.map +1 -0
- package/dist/{chunk-RC4C7Q33.js → chunk-P6ZDXTV6.js} +2 -2
- package/dist/{chunk-CB5XDCSL.js → chunk-QOCS7W7R.js} +5034 -4569
- package/dist/chunk-QOCS7W7R.js.map +1 -0
- package/dist/{chunk-3JWMDL3S.js → chunk-S2PL227Q.js} +2 -2
- package/dist/{chunk-HIVK5V27.js → chunk-SFEQYKYJ.js} +133 -110
- package/dist/chunk-SFEQYKYJ.js.map +1 -0
- package/dist/{chunk-NWODPYBD.cjs → chunk-STM3ORY7.cjs} +2 -2
- package/dist/{chunk-NWODPYBD.cjs.map → chunk-STM3ORY7.cjs.map} +1 -1
- package/dist/{chunk-43FKGDDO.js → chunk-TXUKTOG2.js} +213 -30
- package/dist/chunk-TXUKTOG2.js.map +1 -0
- package/dist/{chunk-XHOZB2WP.js → chunk-UTP2WCHS.js} +681 -22
- package/dist/chunk-UTP2WCHS.js.map +1 -0
- package/dist/{chunk-MH6MAL64.cjs → chunk-WDQTFAXY.cjs} +217 -114
- package/dist/chunk-WDQTFAXY.cjs.map +1 -0
- package/dist/{chunk-DRY3L5KQ.cjs → chunk-XTFN5WKS.cjs} +7 -7
- package/dist/chunk-XTFN5WKS.cjs.map +1 -0
- package/dist/chunks-NUNIKS2J.js +10 -0
- package/dist/cli.js +33 -30
- package/dist/cli.js.map +1 -1
- package/dist/{formula-FNQYHMIY.js → formula-EPKLPDU7.js} +3 -3
- package/dist/{formula-5775PTP2.js → formula-NARUOXRX.js} +4 -4
- package/dist/{formula-VEFKYXPB.cjs → formula-WIMV5TUX.cjs} +9 -9
- package/dist/{formula-VEFKYXPB.cjs.map → formula-WIMV5TUX.cjs.map} +1 -1
- package/dist/{image-ocr-PYZU4TO7.js → image-ocr-3WJ4QH3T.js} +8 -8
- package/dist/{image-ocr-YA2MQBRP.js → image-ocr-5BUJQ4TK.js} +6 -6
- package/dist/{image-ocr-6JZR734G.cjs → image-ocr-AXWXR6JV.cjs} +15 -15
- package/dist/{image-ocr-6JZR734G.cjs.map → image-ocr-AXWXR6JV.cjs.map} +1 -1
- package/dist/index.cjs +1900 -1406
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +24 -6
- package/dist/index.d.ts +24 -6
- package/dist/index.js +1282 -788
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +34 -28
- package/dist/mcp.js.map +1 -1
- package/dist/{model-bundle-O6J7ORVC.js → model-bundle-IMBW7D2Z.js} +5 -5
- package/dist/{models-YMOKZGCI.js → models-SY75IBOE.js} +5 -5
- package/dist/{parser-YAQV7FBO.cjs → parser-2LU4EVU3.cjs} +360 -219
- package/dist/parser-2LU4EVU3.cjs.map +1 -0
- package/dist/{parser-3B6I2XL7.js → parser-N6476XAC.js} +225 -84
- package/dist/parser-N6476XAC.js.map +1 -0
- package/dist/{parser-PXATL5DM.js → parser-ZQM3664Z.js} +222 -81
- package/dist/parser-ZQM3664Z.js.map +1 -0
- package/dist/pdf-ocr-6DEE23IP.js +15 -0
- package/dist/pdf-ocr-GHEJVPX2.cjs +16 -0
- package/dist/{pdf-ocr-T2JXQATA.cjs.map → pdf-ocr-GHEJVPX2.cjs.map} +1 -1
- package/dist/pdf-ocr-MQTWODVU.js +18 -0
- package/dist/{profile-io-ZTV2MKRT.js → profile-io-GJPKCYPT.js} +3 -3
- package/dist/{rasterize-MMUZ537K.js → rasterize-UOALJQDS.js} +3 -3
- package/dist/{redact-doc-S42XGV5D.js → redact-doc-22SYW3KH.js} +11 -11
- package/dist/{render-WCWPZKJ7.js → render-MJ4H3R23.js} +7 -7
- package/dist/seal-XWMRUTI4.js +10 -0
- package/dist/{setup-D35LKZCH.js → setup-2URYVUEO.js} +3 -3
- package/dist/visual-USPS4QRC.js +20 -0
- package/dist/{watch-AX64CIMN.js → watch-ALXZGTOB.js} +12 -12
- package/package.json +1 -1
- package/dist/chunk-43FKGDDO.js.map +0 -1
- package/dist/chunk-476OYHGZ.js.map +0 -1
- package/dist/chunk-B5NEGP65.cjs.map +0 -1
- package/dist/chunk-CB5XDCSL.js.map +0 -1
- package/dist/chunk-DRY3L5KQ.cjs.map +0 -1
- package/dist/chunk-HIVK5V27.js.map +0 -1
- package/dist/chunk-JB5X5NNL.js.map +0 -1
- package/dist/chunk-MH6MAL64.cjs.map +0 -1
- package/dist/chunk-NNYF2AGC.js.map +0 -1
- package/dist/chunk-QJERJZJ6.js +0 -11
- package/dist/chunk-QJERJZJ6.js.map +0 -1
- package/dist/chunk-TGD7UFHD.js.map +0 -1
- package/dist/chunk-UQ6TZDW6.js +0 -13
- package/dist/chunk-UQ6TZDW6.js.map +0 -1
- package/dist/chunk-XHOZB2WP.js.map +0 -1
- package/dist/chunk-XWA625AN.js.map +0 -1
- package/dist/chunk-ZY5K3LPM.cjs +0 -11
- package/dist/chunk-ZY5K3LPM.cjs.map +0 -1
- package/dist/chunks-JD25E5PM.js +0 -10
- package/dist/parser-3B6I2XL7.js.map +0 -1
- package/dist/parser-PXATL5DM.js.map +0 -1
- package/dist/parser-YAQV7FBO.cjs.map +0 -1
- package/dist/pdf-ocr-2TTO5PX2.js +0 -15
- package/dist/pdf-ocr-T2JXQATA.cjs +0 -16
- package/dist/pdf-ocr-WF2NQA6X.js +0 -18
- package/dist/seal-WHK4GOHR.js +0 -10
- package/dist/visual-WL4TDE5B.js +0 -20
- /package/dist/{-VQNLLLPE.js.map → -4G6MA4X6.js.map} +0 -0
- /package/dist/{chunk-6LMKQM7I.js.map → chunk-4VODJKFL.js.map} +0 -0
- /package/dist/{chunk-UDX7TSOC.js.map → chunk-5KS5PWJR.js.map} +0 -0
- /package/dist/{chunk-DYENR3PX.js.map → chunk-AUWGDP4G.js.map} +0 -0
- /package/dist/{chunk-N6TPODYL.js.map → chunk-DES2LGFZ.js.map} +0 -0
- /package/dist/{chunk-PQRP4NSF.js.map → chunk-F4NRLLY4.js.map} +0 -0
- /package/dist/{chunk-PIMB2YNO.js.map → chunk-GO5IFOUF.js.map} +0 -0
- /package/dist/{chunk-C75WE52C.js.map → chunk-JELRWAZC.js.map} +0 -0
- /package/dist/{chunk-46DZF3RK.js.map → chunk-JFLAM3MM.js.map} +0 -0
- /package/dist/{chunk-A3QDRMVD.js.map → chunk-KIOQ4N37.js.map} +0 -0
- /package/dist/{chunk-GOQBON77.js.map → chunk-MLIS253L.js.map} +0 -0
- /package/dist/{chunk-RC4C7Q33.js.map → chunk-P6ZDXTV6.js.map} +0 -0
- /package/dist/{chunk-3JWMDL3S.js.map → chunk-S2PL227Q.js.map} +0 -0
- /package/dist/{chunks-JD25E5PM.js.map → chunks-NUNIKS2J.js.map} +0 -0
- /package/dist/{formula-FNQYHMIY.js.map → formula-EPKLPDU7.js.map} +0 -0
- /package/dist/{formula-5775PTP2.js.map → formula-NARUOXRX.js.map} +0 -0
- /package/dist/{image-ocr-PYZU4TO7.js.map → image-ocr-3WJ4QH3T.js.map} +0 -0
- /package/dist/{image-ocr-YA2MQBRP.js.map → image-ocr-5BUJQ4TK.js.map} +0 -0
- /package/dist/{model-bundle-O6J7ORVC.js.map → model-bundle-IMBW7D2Z.js.map} +0 -0
- /package/dist/{models-YMOKZGCI.js.map → models-SY75IBOE.js.map} +0 -0
- /package/dist/{pdf-ocr-2TTO5PX2.js.map → pdf-ocr-6DEE23IP.js.map} +0 -0
- /package/dist/{pdf-ocr-WF2NQA6X.js.map → pdf-ocr-MQTWODVU.js.map} +0 -0
- /package/dist/{profile-io-ZTV2MKRT.js.map → profile-io-GJPKCYPT.js.map} +0 -0
- /package/dist/{rasterize-MMUZ537K.js.map → rasterize-UOALJQDS.js.map} +0 -0
- /package/dist/{redact-doc-S42XGV5D.js.map → redact-doc-22SYW3KH.js.map} +0 -0
- /package/dist/{render-WCWPZKJ7.js.map → render-MJ4H3R23.js.map} +0 -0
- /package/dist/{seal-WHK4GOHR.js.map → seal-XWMRUTI4.js.map} +0 -0
- /package/dist/{setup-D35LKZCH.js.map → setup-2URYVUEO.js.map} +0 -0
- /package/dist/{visual-WL4TDE5B.js.map → visual-USPS4QRC.js.map} +0 -0
- /package/dist/{watch-AX64CIMN.js.map → watch-ALXZGTOB.js.map} +0 -0
|
@@ -30,21 +30,24 @@ import {
|
|
|
30
30
|
normalizeItems,
|
|
31
31
|
refineDocumentStyleHeadings,
|
|
32
32
|
removeHeaderFooterBlocks,
|
|
33
|
+
startsNewItem,
|
|
33
34
|
trimTrailingEmptyTableCols,
|
|
34
35
|
wrapJoiner
|
|
35
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-SFEQYKYJ.js";
|
|
36
37
|
import {
|
|
37
38
|
ocrModelsCached
|
|
38
|
-
} from "./chunk-
|
|
39
|
-
import "./chunk-
|
|
40
|
-
import "./chunk-
|
|
39
|
+
} from "./chunk-DES2LGFZ.js";
|
|
40
|
+
import "./chunk-KIOQ4N37.js";
|
|
41
|
+
import "./chunk-JELRWAZC.js";
|
|
41
42
|
import {
|
|
42
43
|
blocksToPages
|
|
43
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-AUWGDP4G.js";
|
|
44
45
|
import {
|
|
45
46
|
encodePng
|
|
46
47
|
} from "./chunk-7FCNOKOR.js";
|
|
47
|
-
import
|
|
48
|
+
import {
|
|
49
|
+
stripScriptTags
|
|
50
|
+
} from "./chunk-J3IF6KGW.js";
|
|
48
51
|
import {
|
|
49
52
|
hasRequestedPagesAfter,
|
|
50
53
|
parsePageRange
|
|
@@ -53,11 +56,11 @@ import {
|
|
|
53
56
|
WINGDINGS,
|
|
54
57
|
blocksToMarkdown,
|
|
55
58
|
escapeLiteralDollar
|
|
56
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-LEIAEWZ7.js";
|
|
57
60
|
import {
|
|
58
61
|
KordocError,
|
|
59
62
|
sanitizeHref
|
|
60
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-P6ZDXTV6.js";
|
|
61
64
|
|
|
62
65
|
// src/pdf/ocr-region-merge.ts
|
|
63
66
|
function mergeOcrImageRegions(blocks, page, regions, ocrBlocks) {
|
|
@@ -642,6 +645,40 @@ function ocrVectorOps(opList, paths) {
|
|
|
642
645
|
return { fnArray, argsArray };
|
|
643
646
|
}
|
|
644
647
|
|
|
648
|
+
// src/pdf/contact-table.ts
|
|
649
|
+
var CONTACT_HEAD = /^(?:담당\s*부서|<[^<>]+>)$/;
|
|
650
|
+
var CONTACT_ROLE = /^(?:책임자|담당자)$/;
|
|
651
|
+
var PERSON = /^(.+?)\s+([가-힣]{2,4})\s+(\([^()]*\d[^()]*\)|\S+@\S+)$/;
|
|
652
|
+
function splitContactTables(blocks) {
|
|
653
|
+
for (const b of blocks) {
|
|
654
|
+
const t = b.type === "table" ? b.table : void 0;
|
|
655
|
+
if (!t || t.cols !== 4 || t.rows < 2) continue;
|
|
656
|
+
const rows = t.cells;
|
|
657
|
+
if (!CONTACT_HEAD.test(rows[0][0].text.replace(/\s+/g, " ").trim())) continue;
|
|
658
|
+
const people = rows.map((r) => PERSON.exec(r[3].text.replace(/\s+/g, " ").trim()));
|
|
659
|
+
if (people.some((p) => !p) || rows.some((r) => !CONTACT_ROLE.test(r[2].text.replace(/\s+/g, "")) || r[2].rowSpan !== 1 || r[3].rowSpan !== 1)) continue;
|
|
660
|
+
const lead = [];
|
|
661
|
+
let ok = true;
|
|
662
|
+
for (const c of [0, 1]) {
|
|
663
|
+
const top = rows[0][c];
|
|
664
|
+
if (top.rowSpan === 1) {
|
|
665
|
+
lead.push(rows.map((r) => r[c].text));
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
const lines = top.text.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
669
|
+
if (top.rowSpan !== t.rows || lines.length > t.rows) {
|
|
670
|
+
ok = false;
|
|
671
|
+
break;
|
|
672
|
+
}
|
|
673
|
+
lead.push(rows.map((_, r) => lines[r] ?? ""));
|
|
674
|
+
}
|
|
675
|
+
if (!ok) continue;
|
|
676
|
+
const one = (text) => ({ text, colSpan: 1, rowSpan: 1 });
|
|
677
|
+
t.cells = rows.map((r, i) => [one(lead[0][i]), one(lead[1][i]), one(r[2].text), one(people[i][1]), one(people[i][2]), one(people[i][3])]);
|
|
678
|
+
t.cols = 6;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
|
|
645
682
|
// src/pdf/table-parts.ts
|
|
646
683
|
var PART_COL_TOL = 1;
|
|
647
684
|
function anchorsOf(table) {
|
|
@@ -678,7 +715,7 @@ var indexOf = (coords, x) => {
|
|
|
678
715
|
};
|
|
679
716
|
var rowText = (anchors, r) => anchors.filter((a) => a.r === r).map((a) => a.cell.text.replace(/\s+/g, "")).join("|");
|
|
680
717
|
var hasText = (t) => t.replace(/\|/g, "") !== "";
|
|
681
|
-
function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom) {
|
|
718
|
+
function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom, lex) {
|
|
682
719
|
if (pcx.length !== prev.cols + 1 || ccx.length !== curr.cols + 1) return null;
|
|
683
720
|
const U = unionCoords(pcx, ccx);
|
|
684
721
|
const cols = U.length - 1;
|
|
@@ -734,13 +771,35 @@ function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom) {
|
|
|
734
771
|
}
|
|
735
772
|
for (let r = 0; r < rows; r++) for (let c = 0; c < cols; c++) if (owner[r][c] === null) FILLER_CELLS.add(grid[r][c]);
|
|
736
773
|
const table = { rows, cols, cells: grid, hasHeader: prev.hasHeader, ...prev.caption ? { caption: prev.caption } : {} };
|
|
737
|
-
|
|
738
|
-
if (rows > prev.rows && !split && prevBottom !== void 0
|
|
774
|
+
let split = rows > prev.rows && mergeSplitRow(table, owner, prev.rows, U);
|
|
775
|
+
if (rows > prev.rows && !split && prevBottom !== void 0 && mergeStraddlingCells(table, owner, prev.rows, prevBottom, lex)) split = mergeSplitRow(table, owner, prev.rows, U, true);
|
|
739
776
|
return { table, colXs: U, split, header: ca.filter((a) => a.r < skip && a.cell.text.trim()).length >= 2 };
|
|
740
777
|
}
|
|
741
|
-
function mergeStraddlingCells(table, owner, first, prevBottom) {
|
|
778
|
+
function mergeStraddlingCells(table, owner, first, prevBottom, lex) {
|
|
742
779
|
const last = first - 1;
|
|
743
|
-
|
|
780
|
+
const straddles = owner[first].some((o, c) => o !== null && o === owner[last][c]);
|
|
781
|
+
let firstNew = table.cols;
|
|
782
|
+
for (let c = 0; c < table.cols; c++) {
|
|
783
|
+
const d = owner[first][c];
|
|
784
|
+
if (d && d.r === first && d !== owner[last][c] && hasContent(table.cells[d.r][d.c])) {
|
|
785
|
+
firstNew = c;
|
|
786
|
+
break;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
let midWord = false;
|
|
790
|
+
if (lex) for (let c = 0; c < table.cols && !midWord; ) {
|
|
791
|
+
const u = owner[last][c], d = owner[first][c];
|
|
792
|
+
if (!u) {
|
|
793
|
+
c++;
|
|
794
|
+
continue;
|
|
795
|
+
}
|
|
796
|
+
c = u.c + u.cs;
|
|
797
|
+
if (!d || d === u || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
|
|
798
|
+
if (u.r !== last || d.rs < 2) continue;
|
|
799
|
+
const tail = table.cells[u.r][u.c].text.trim().split(/\s+/).pop() ?? "", head = table.cells[first][d.c].text.trim().split(/\s+/)[0] ?? "";
|
|
800
|
+
if (/^[가-힣]{2,}$/.test(tail) && /^[가-힣]{2,}/.test(head) && lex.evidence2(tail, head) === "") midWord = true;
|
|
801
|
+
}
|
|
802
|
+
let merged = false;
|
|
744
803
|
for (let c = 0; c < table.cols; ) {
|
|
745
804
|
const u = owner[last][c], d = owner[first][c];
|
|
746
805
|
if (!u) {
|
|
@@ -748,18 +807,24 @@ function mergeStraddlingCells(table, owner, first, prevBottom) {
|
|
|
748
807
|
continue;
|
|
749
808
|
}
|
|
750
809
|
c = u.c + u.cs;
|
|
751
|
-
if (!d || d === u || u.r
|
|
810
|
+
if (!d || d === u || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
|
|
752
811
|
const a = table.cells[u.r][u.c], b = table.cells[first][d.c];
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
812
|
+
if (!(u.rs >= 2 && u.c + u.cs <= firstNew && hasContent(a) && !hasContent(b))) {
|
|
813
|
+
if (!straddles && !midWord) continue;
|
|
814
|
+
if (u.r >= last && d.rs < 2) continue;
|
|
815
|
+
const U = CELL_LINES.get(a);
|
|
816
|
+
if (!U?.length || U.length > STRADDLE_MAX_LINES || !hasContent(b)) continue;
|
|
817
|
+
const lu = U[U.length - 1];
|
|
818
|
+
if (!midWord && lu.y - prevBottom > (u.r >= last ? STRADDLE_BOTTOM_ONE_ROW : STRADDLE_BOTTOM) * (lu.h || 10)) continue;
|
|
819
|
+
}
|
|
757
820
|
appendCell(a, b);
|
|
758
821
|
a.rowSpan = first + d.rs - u.r;
|
|
759
822
|
table.cells[first][d.c] = { text: "", colSpan: 1, rowSpan: 1 };
|
|
760
823
|
const grown = { ...u, rs: a.rowSpan };
|
|
761
824
|
for (let rr = u.r; rr < u.r + grown.rs; rr++) for (let dc = u.c; dc < u.c + u.cs; dc++) owner[rr][dc] = grown;
|
|
825
|
+
merged = true;
|
|
762
826
|
}
|
|
827
|
+
return merged;
|
|
763
828
|
}
|
|
764
829
|
var FULL_LINE_TOL = 1;
|
|
765
830
|
var FULL_LINE_MIN_FRAC = 0.5;
|
|
@@ -795,11 +860,21 @@ function continuesAcross(u, d, x1, x2) {
|
|
|
795
860
|
const hanging = U.length >= 2 && U.every((l) => maxR - l.r <= FULL_LINE_TOL * fs) && last.l - minL >= HANGING_MIN * fs && Math.abs(D[0].l - last.l) <= HANGING_TOL;
|
|
796
861
|
return U.some(leftAligned) || D.some(leftAligned) || hanging;
|
|
797
862
|
}
|
|
798
|
-
|
|
863
|
+
var OUTLINE_HEAD = /^[□■]\s*\S/;
|
|
864
|
+
var OUTLINE_ITEM = /^[ㅇ○◦\-‐–·․‧※*]\s*\S/;
|
|
865
|
+
function outlineContinues(u, d) {
|
|
866
|
+
const U = u.text.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
867
|
+
const D = d.text.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
868
|
+
return U.length >= 2 && D.length >= 1 && U.some((l) => OUTLINE_HEAD.test(l)) && OUTLINE_ITEM.test(D[0]);
|
|
869
|
+
}
|
|
870
|
+
function lineEnded(c, x1, x2, next = "") {
|
|
799
871
|
const L = CELL_LINES.get(c);
|
|
800
872
|
if (!L || L.length !== 1) return false;
|
|
801
|
-
const l = L[0];
|
|
802
|
-
|
|
873
|
+
const l = L[0], h = l.h || 10;
|
|
874
|
+
const word = next.trim().split(/\s+/)[0] ?? "";
|
|
875
|
+
let units = 0;
|
|
876
|
+
for (const ch of word) units += /[가-힣\u3400-\u9fff]/.test(ch) ? 1 : 0.55;
|
|
877
|
+
return x2 - l.r - (l.l - x1) >= Math.max(LABEL_ROOM, units) * h;
|
|
803
878
|
}
|
|
804
879
|
function appendCell(a, b) {
|
|
805
880
|
if (a.blocks?.length || b.blocks?.length) {
|
|
@@ -809,7 +884,22 @@ function appendCell(a, b) {
|
|
|
809
884
|
if (b.text.trim()) a.text = a.text.trim() ? a.text + "\n" + b.text : b.text;
|
|
810
885
|
}
|
|
811
886
|
var hasContent = (cell) => !!cell.text.trim() || !!cell.blocks?.length || IMAGE_CELLS.has(cell);
|
|
812
|
-
|
|
887
|
+
var CLAUSE_OPEN_ENDING = /(?:하는|되는|하고|하며|하여|되어|되고|되며|이며|으며|어야|아야|여야)$/;
|
|
888
|
+
var batchim = (ch) => {
|
|
889
|
+
const k = ch.charCodeAt(0) - 44032;
|
|
890
|
+
return k >= 0 && k < 11172 && k % 28 !== 0;
|
|
891
|
+
};
|
|
892
|
+
function clauseContinues(u, d) {
|
|
893
|
+
const tail = u.text.trim().split(/\s+/).pop() ?? "", head = d.text.trim();
|
|
894
|
+
if (!/^[가-힣]{2,}$/.test(tail) || !/^[가-힣]/.test(head) || startsNewItem(u.text, head)) return false;
|
|
895
|
+
const last = tail[tail.length - 1], before = tail[tail.length - 2];
|
|
896
|
+
return last === "\uC744" && batchim(before) || last === "\uB97C" && !batchim(before) || CLAUSE_OPEN_ENDING.test(tail);
|
|
897
|
+
}
|
|
898
|
+
function outlineOnly(pairs, cell) {
|
|
899
|
+
const filled = pairs.filter(([, d]) => hasContent(d.cell));
|
|
900
|
+
return filled.length === 1 && outlineContinues(cell(filled[0][0]), cell(filled[0][1]));
|
|
901
|
+
}
|
|
902
|
+
function mergeSplitRow(table, owner, first, colXs, textOnly = false) {
|
|
813
903
|
const last = first - 1;
|
|
814
904
|
const pairs = [];
|
|
815
905
|
let carried = false;
|
|
@@ -827,12 +917,12 @@ function mergeSplitRow(table, owner, first, colXs) {
|
|
|
827
917
|
} else if (a.r === last && a.rs === 2) carried = true;
|
|
828
918
|
c = a.c + a.cs;
|
|
829
919
|
}
|
|
830
|
-
const carriedSplit = carried && pairs.filter(([u, d]) => hasContent(u.cell) && hasContent(d.cell)).length <= 1 && !pairs.some(([u, d]) => !hasContent(u.cell) && hasContent(d.cell));
|
|
920
|
+
const carriedSplit = !textOnly && carried && pairs.filter(([u, d]) => hasContent(u.cell) && hasContent(d.cell)).length <= 1 && !pairs.some(([u, d]) => !hasContent(u.cell) && hasContent(d.cell));
|
|
831
921
|
const cell = (a) => table.cells[a.r][a.c];
|
|
832
922
|
if (!carriedSplit) {
|
|
833
923
|
const norm = (c) => c.text.replace(/\s+/g, "");
|
|
834
|
-
if (pairs.some(([u, d]) => hasContent(d.cell) && norm(cell(d)) !== norm(cell(u)) && lineEnded(cell(u), colXs[u.c], colXs[u.c + u.cs]))) return false;
|
|
835
|
-
if (!pairs.some(([u, d]) => continuesAcross(cell(u), cell(d), colXs[u.c], colXs[u.c + u.cs]))) return false;
|
|
924
|
+
if (pairs.some(([u, d]) => hasContent(d.cell) && norm(cell(d)) !== norm(cell(u)) && lineEnded(cell(u), colXs[u.c], colXs[u.c + u.cs], cell(d).text))) return false;
|
|
925
|
+
if (!outlineOnly(pairs, cell) && !pairs.some(([u, d]) => continuesAcross(cell(u), cell(d), colXs[u.c], colXs[u.c + u.cs])) && !pairs.some(([u, d]) => clauseContinues(cell(u), cell(d)))) return false;
|
|
836
926
|
}
|
|
837
927
|
for (const [u, d] of pairs) appendCell(table.cells[u.r][u.c], table.cells[d.r][d.c]);
|
|
838
928
|
for (let r = 0; r < first; r++) for (let c = 0; c < table.cols; c++) {
|
|
@@ -879,8 +969,8 @@ function sameHeadShape(a, b) {
|
|
|
879
969
|
}
|
|
880
970
|
return tall;
|
|
881
971
|
}
|
|
882
|
-
function mergeCrossPageTables(blocks, pageHeights) {
|
|
883
|
-
mergeColumnFlow(blocks, pageHeights);
|
|
972
|
+
function mergeCrossPageTables(blocks, pageHeights, lex) {
|
|
973
|
+
mergeColumnFlow(blocks, pageHeights, lex);
|
|
884
974
|
for (let i = blocks.length - 2; i >= 0; i--) {
|
|
885
975
|
const prev = blocks[i];
|
|
886
976
|
if (prev.type !== "table" || !prev.table || !prev.bbox || !prev.pageNumber) continue;
|
|
@@ -889,7 +979,7 @@ function mergeCrossPageTables(blocks, pageHeights) {
|
|
|
889
979
|
const curr = blocks[j];
|
|
890
980
|
if (!curr || curr.type !== "table" || !curr.table || !curr.bbox || curr.pageNumber !== prev.pageNumber + 1) continue;
|
|
891
981
|
if (startsWithUnitRow(prev.table) && startsWithUnitRow(curr.table)) continue;
|
|
892
|
-
const joined = j === i + 1 || blocks.slice(i + 1, j).every((b) => besideOwn(b, prev, curr) || insideTable(b, prev)) ? looksContinued(prev, curr, pageHeights) && !restartsTable(blocks, i, curr.table, pageHeights) ? joinClipParts(prev, curr, pageHeights) ?? false : null : null;
|
|
982
|
+
const joined = j === i + 1 || blocks.slice(i + 1, j).every((b) => besideOwn(b, prev, curr) || insideTable(b, prev)) ? looksContinued(prev, curr, pageHeights) && !restartsTable(blocks, i, curr.table, pageHeights) ? joinClipParts(prev, curr, pageHeights, lex) ?? false : null : null;
|
|
893
983
|
if (joined) {
|
|
894
984
|
placeJoined(blocks, i, j, joined);
|
|
895
985
|
continue;
|
|
@@ -933,7 +1023,7 @@ function mergeCrossPageTables(blocks, pageHeights) {
|
|
|
933
1023
|
if (blocks[i].type === "table" && t && EMPTY_PARTS.has(t)) blocks.splice(i, 1);
|
|
934
1024
|
}
|
|
935
1025
|
}
|
|
936
|
-
function mergeColumnFlow(blocks, pageHeights) {
|
|
1026
|
+
function mergeColumnFlow(blocks, pageHeights, lex) {
|
|
937
1027
|
if (!pageHeights) return;
|
|
938
1028
|
for (let i = 0; i < blocks.length; i++) {
|
|
939
1029
|
const L = blocks[i];
|
|
@@ -955,7 +1045,7 @@ function mergeColumnFlow(blocks, pageHeights) {
|
|
|
955
1045
|
const R = blocks[k];
|
|
956
1046
|
if (Math.abs(R.bbox.width - L.bbox.width) > Math.max(R.bbox.width, L.bbox.width) * NEIGHBOR_TABLE_EPSILON) continue;
|
|
957
1047
|
if (!looksContinued(L, R) || restartsTable(blocks, i, R.table, pageHeights)) continue;
|
|
958
|
-
const joined = joinClipParts(L, R, pageHeights);
|
|
1048
|
+
const joined = joinClipParts(L, R, pageHeights, lex);
|
|
959
1049
|
if (!joined) continue;
|
|
960
1050
|
const top = L.bbox.y + L.bbox.height;
|
|
961
1051
|
const at = Math.min(i, k);
|
|
@@ -964,12 +1054,12 @@ function mergeColumnFlow(blocks, pageHeights) {
|
|
|
964
1054
|
i = at - 1;
|
|
965
1055
|
}
|
|
966
1056
|
}
|
|
967
|
-
function joinClipParts(prev, curr, pageHeights) {
|
|
1057
|
+
function joinClipParts(prev, curr, pageHeights, lex) {
|
|
968
1058
|
const pt = prev.table, ct = curr.table;
|
|
969
1059
|
if (!CLIP_TABLES.has(pt) || !CLIP_TABLES.has(ct)) return null;
|
|
970
1060
|
const px = TABLE_COLXS.get(pt), cx = TABLE_COLXS.get(ct);
|
|
971
1061
|
if (!px || !cx) return null;
|
|
972
|
-
let xs = cx, shifted = false, dx = 0;
|
|
1062
|
+
let xs = cx, shifted = false, dx = 0, foreign = false;
|
|
973
1063
|
if (!shiftedSame(px, cx, false)) {
|
|
974
1064
|
if (!pageHeights?.get(prev.pageNumber) || !pageHeights?.get(curr.pageNumber)) return null;
|
|
975
1065
|
dx = px[px.length - 1] - cx[cx.length - 1];
|
|
@@ -978,19 +1068,29 @@ function joinClipParts(prev, curr, pageHeights) {
|
|
|
978
1068
|
shifted = true;
|
|
979
1069
|
} else dx = 0;
|
|
980
1070
|
if (!px.some((x) => Math.abs(x - xs[0]) <= CONTINUATION_COL_TOL)) return null;
|
|
1071
|
+
const inner = xs.slice(1, -1);
|
|
1072
|
+
foreign = inner.length > 0 && !inner.some((x) => px.some((p) => Math.abs(p - x) <= CONTINUATION_COL_TOL)) && headingRow(ct.cells[0] ?? []);
|
|
981
1073
|
}
|
|
982
|
-
const res = joinSplitParts(pt, px, ct, xs, dx, prev.bbox?.y);
|
|
983
|
-
if (!res || shifted && !res.split && !res.header) return null;
|
|
1074
|
+
const res = joinSplitParts(pt, px, ct, xs, dx, prev.bbox?.y, lex);
|
|
1075
|
+
if (!res || (shifted || foreign) && !res.split && !res.header) return null;
|
|
984
1076
|
TABLE_COLXS.set(res.table, res.colXs);
|
|
985
1077
|
CLIP_TABLES.add(res.table);
|
|
986
1078
|
return res.table;
|
|
987
1079
|
}
|
|
1080
|
+
function headingRow(row) {
|
|
1081
|
+
const heads = row.map((c) => c.text.replace(/\s+/g, "")).filter(Boolean);
|
|
1082
|
+
if (heads.length === 1) return heads[0].length <= 8 || /^[①-⑳❶-❿]/.test(heads[0]);
|
|
1083
|
+
return heads.length === 2 && /^(?:\d{1,2}|[ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ]+|[①-⑳❶-❿])$/.test(heads[0]);
|
|
1084
|
+
}
|
|
988
1085
|
var ANNEX_HEAD_RE = /^\s*[<\[(【]?\s*(?:붙\s*임|참\s*고|별\s*첨|별\s*지|별\s*표|첨\s*부|부\s*록)(?:\s*\d|\s*$|\s*[>\])】])|^\s*■/;
|
|
989
1086
|
function looksContinued(prev, curr, pageHeights) {
|
|
990
1087
|
const ph = pageHeights?.get(prev.pageNumber), ch = pageHeights?.get(curr.pageNumber);
|
|
991
1088
|
if (ph && ch && (prev.bbox.y > ph * PAGE_EDGE_BAND || curr.bbox.y + curr.bbox.height < ch * (1 - PAGE_EDGE_BAND))) return false;
|
|
992
|
-
const
|
|
993
|
-
|
|
1089
|
+
const firstRow = curr.table.cells[0] ?? [];
|
|
1090
|
+
const firstText = firstRow.find((c) => c.text.trim())?.text ?? "";
|
|
1091
|
+
if (!ANNEX_HEAD_RE.test(firstText)) return true;
|
|
1092
|
+
const filled = firstRow.map((c) => c.text.replace(/\s+/g, "")).filter(Boolean);
|
|
1093
|
+
return filled.length >= 2 && filled.every((t) => t === filled[0]);
|
|
994
1094
|
}
|
|
995
1095
|
function firstRowSig(t) {
|
|
996
1096
|
const x = TABLE_COLXS.get(t);
|
|
@@ -1003,6 +1103,7 @@ function restartsTable(blocks, i, curr, pageHeights) {
|
|
|
1003
1103
|
const head = blocks[chainHead(blocks, i, pageHeights)].table;
|
|
1004
1104
|
if (cs.length === 1 && restartsTitledForm(head, curr)) return true;
|
|
1005
1105
|
if (cs.length < RESTART_MIN_ANCHORS) return false;
|
|
1106
|
+
if (CONTACT_HEAD.test(cs[0].t) && cs.some((c) => CONTACT_ROLE.test(c.t))) return false;
|
|
1006
1107
|
const hs = firstRowSig(head);
|
|
1007
1108
|
if (!hs || hs.length !== cs.length) return false;
|
|
1008
1109
|
const dx = hs[hs.length - 1].x2 - cs[cs.length - 1].x2;
|
|
@@ -1849,6 +1950,52 @@ function restoreTrackedSpacing(items, fnArray, argsArray) {
|
|
|
1849
1950
|
}
|
|
1850
1951
|
return changed;
|
|
1851
1952
|
}
|
|
1953
|
+
function markSyntheticSpaces(items, fnArray, argsArray) {
|
|
1954
|
+
if (!items.some((it) => typeof it.str === "string" && it.str.length > 0 && !it.str.trim())) return;
|
|
1955
|
+
const streams = /* @__PURE__ */ new Map();
|
|
1956
|
+
const saved = [];
|
|
1957
|
+
let font = "";
|
|
1958
|
+
for (let i = 0; i < fnArray.length; i++) {
|
|
1959
|
+
const fn = fnArray[i];
|
|
1960
|
+
const args = argsArray[i];
|
|
1961
|
+
if (fn === OPS5.setFont) font = String(args[0]);
|
|
1962
|
+
else if (fn === OPS5.save || fn === OPS5.paintFormXObjectBegin) saved.push(font);
|
|
1963
|
+
else if (fn === OPS5.restore || fn === OPS5.paintFormXObjectEnd) font = saved.pop() ?? font;
|
|
1964
|
+
else if (fn === OPS5.showText) {
|
|
1965
|
+
let list = streams.get(font);
|
|
1966
|
+
if (!list) streams.set(font, list = []);
|
|
1967
|
+
for (const g2 of args[0]) {
|
|
1968
|
+
if (g2 && typeof g2 === "object" && typeof g2.unicode === "string") list.push(normalizeUnicode3(g2.unicode));
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
const cursor = /* @__PURE__ */ new Map();
|
|
1973
|
+
const failed = /* @__PURE__ */ new Set();
|
|
1974
|
+
const marks = [];
|
|
1975
|
+
for (const it of items) {
|
|
1976
|
+
const f = it.fontName ?? "";
|
|
1977
|
+
const glyphs = streams.get(f);
|
|
1978
|
+
if (!glyphs || failed.has(f) || typeof it.str !== "string" || !it.str) continue;
|
|
1979
|
+
let gi = cursor.get(f) ?? 0;
|
|
1980
|
+
if (!it.str.trim()) {
|
|
1981
|
+
if (gi < glyphs.length && /^\s+$/.test(glyphs[gi])) {
|
|
1982
|
+
while (gi < glyphs.length && /^\s+$/.test(glyphs[gi])) gi++;
|
|
1983
|
+
cursor.set(f, gi);
|
|
1984
|
+
} else marks.push(it);
|
|
1985
|
+
continue;
|
|
1986
|
+
}
|
|
1987
|
+
const want = it.str.replace(/\s+/g, "");
|
|
1988
|
+
while (gi < glyphs.length && /^\s*$/.test(glyphs[gi])) gi++;
|
|
1989
|
+
let got = "";
|
|
1990
|
+
while (gi < glyphs.length && got.length < want.length) got += glyphs[gi++].replace(/\s+/g, "");
|
|
1991
|
+
if (got !== want) {
|
|
1992
|
+
failed.add(f);
|
|
1993
|
+
continue;
|
|
1994
|
+
}
|
|
1995
|
+
cursor.set(f, gi);
|
|
1996
|
+
}
|
|
1997
|
+
for (const it of marks) if (!failed.has(it.fontName ?? "")) it.synthetic = true;
|
|
1998
|
+
}
|
|
1852
1999
|
|
|
1853
2000
|
// src/pdf/endnotes.ts
|
|
1854
2001
|
var NOTE_MARK = /^\s*(문\d{1,5}[))]|\d{1,5}\)|\(\d{1,5}\))/;
|
|
@@ -1986,6 +2133,7 @@ function orderTwoUpPage(blocks, pageWidth, pageHeight) {
|
|
|
1986
2133
|
var BAND = 0.12;
|
|
1987
2134
|
var MAX_CHARS = 10;
|
|
1988
2135
|
var MIN_REPEAT = 3;
|
|
2136
|
+
var RUN_GAP = 5;
|
|
1989
2137
|
function removeSideTabs(blocks, pageWidths) {
|
|
1990
2138
|
const edges = /* @__PURE__ */ new Map();
|
|
1991
2139
|
for (const b of blocks) {
|
|
@@ -2018,13 +2166,21 @@ function removeSideTabs(blocks, pageWidths) {
|
|
|
2018
2166
|
}
|
|
2019
2167
|
const running = /* @__PURE__ */ new Set();
|
|
2020
2168
|
for (const [k, ps] of pages) {
|
|
2021
|
-
const list = [...ps];
|
|
2022
|
-
|
|
2023
|
-
|
|
2169
|
+
const list = [...ps].sort((a, b) => a - b);
|
|
2170
|
+
let run = [];
|
|
2171
|
+
const flush = () => {
|
|
2172
|
+
if (run.length >= MIN_REPEAT && run.length >= (run[run.length - 1] - run[0] + 1) * 0.4) for (const p of run) running.add(`${p}\0${k}`);
|
|
2173
|
+
run = [];
|
|
2174
|
+
};
|
|
2175
|
+
for (const p of list) {
|
|
2176
|
+
if (run.length && p - run[run.length - 1] > RUN_GAP) flush();
|
|
2177
|
+
run.push(p);
|
|
2178
|
+
}
|
|
2179
|
+
flush();
|
|
2024
2180
|
}
|
|
2025
2181
|
return running.size ? blocks.filter((b) => {
|
|
2026
2182
|
const k = key(b);
|
|
2027
|
-
return !k || !running.has(k);
|
|
2183
|
+
return !k || !running.has(`${b.pageNumber}\0${k}`);
|
|
2028
2184
|
}) : blocks;
|
|
2029
2185
|
}
|
|
2030
2186
|
|
|
@@ -2192,7 +2348,9 @@ function normalizeAraea(text) {
|
|
|
2192
2348
|
return text.replace(/(?<![\u1100-\u115F])\u119E/g, "\u318D");
|
|
2193
2349
|
}
|
|
2194
2350
|
var stripNoUnicodeGlyph = (text) => text.includes("\uF000") ? text.replace(/\uF000/g, "") : text;
|
|
2195
|
-
var
|
|
2351
|
+
var CHOSEONG_COMPAT = "\u3131\u3132\u3134\u3137\u3138\u3139\u3141\u3142\u3143\u3145\u3146\u3147\u3148\u3149\u314A\u314B\u314C\u314D\u314E";
|
|
2352
|
+
var normalizeLoneChoseong = (text) => /[\u1100-\u1112]/.test(text) ? text.replace(/[\u1100-\u1112](?![\u1160-\u11A7\uD7B0-\uD7C6])/g, (c) => CHOSEONG_COMPAT[c.charCodeAt(0) - 4352]) : text;
|
|
2353
|
+
var cleanChars = (text) => normalizeLoneChoseong(normalizeAraea(stripNoUnicodeGlyph(stripControlChars(text))));
|
|
2196
2354
|
function sanitizeBlockControlChars(blocks) {
|
|
2197
2355
|
for (const b of blocks) {
|
|
2198
2356
|
if (b.text) b.text = cleanChars(b.text);
|
|
@@ -2269,7 +2427,7 @@ function cleanPdfText(text, opts) {
|
|
|
2269
2427
|
}
|
|
2270
2428
|
const mark = /^(?:#{1,6}|-) /.exec(line)?.[0] ?? "";
|
|
2271
2429
|
return mark + collapseEvenSpacing(line.slice(mark.length), false);
|
|
2272
|
-
}).replace(/\\~\\~/g, "~~").replace(/~~~~/g, "").replace(/<u>\s*<\/u>/g, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
2430
|
+
}).replace(/\\~\\~/g, "~~").replace(/~~~~/g, "").replace(/<u>\s*<\/u>/g, "").replace(/<(sup|sub)>\s*<\/\1>/g, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
2273
2431
|
}
|
|
2274
2432
|
function startsWithMarker(line) {
|
|
2275
2433
|
const t = line.trimStart();
|
|
@@ -2357,7 +2515,7 @@ function mergeLinkRuns(markdown) {
|
|
|
2357
2515
|
|
|
2358
2516
|
// src/pdf/formula-ocr.ts
|
|
2359
2517
|
async function applyFormulaOcr(buffer, blocks, pageFilter, effectivePageCount, warnings, _onProgress) {
|
|
2360
|
-
const formulaMod = await import("./formula-
|
|
2518
|
+
const formulaMod = await import("./formula-NARUOXRX.js");
|
|
2361
2519
|
const { FormulaPipeline, ensureFormulaModels } = formulaMod;
|
|
2362
2520
|
await ensureFormulaModels((p) => {
|
|
2363
2521
|
if (p.phase === "download" && p.total) {
|
|
@@ -2497,42 +2655,15 @@ g.pdfjsWorker = pdfjsWorker;
|
|
|
2497
2655
|
import { getDocument, GlobalWorkerOptions, OPS as OPS6 } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
2498
2656
|
import { createRequire } from "module";
|
|
2499
2657
|
import { dirname, join } from "path";
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
for (const b of blocks) {
|
|
2507
|
-
const t = b.type === "table" ? b.table : void 0;
|
|
2508
|
-
if (!t || t.cols !== 4 || t.rows < 2) continue;
|
|
2509
|
-
const rows = t.cells;
|
|
2510
|
-
if (!HEAD.test(rows[0][0].text.replace(/\s+/g, " ").trim())) continue;
|
|
2511
|
-
const people = rows.map((r) => PERSON.exec(r[3].text.replace(/\s+/g, " ").trim()));
|
|
2512
|
-
if (people.some((p) => !p) || rows.some((r) => !ROLE.test(r[2].text.replace(/\s+/g, "")) || r[2].rowSpan !== 1 || r[3].rowSpan !== 1)) continue;
|
|
2513
|
-
const lead = [];
|
|
2514
|
-
let ok = true;
|
|
2515
|
-
for (const c of [0, 1]) {
|
|
2516
|
-
const top = rows[0][c];
|
|
2517
|
-
if (top.rowSpan === 1) {
|
|
2518
|
-
lead.push(rows.map((r) => r[c].text));
|
|
2519
|
-
continue;
|
|
2520
|
-
}
|
|
2521
|
-
const lines = top.text.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
2522
|
-
if (top.rowSpan !== t.rows || lines.length > t.rows) {
|
|
2523
|
-
ok = false;
|
|
2524
|
-
break;
|
|
2525
|
-
}
|
|
2526
|
-
lead.push(rows.map((_, r) => lines[r] ?? ""));
|
|
2527
|
-
}
|
|
2528
|
-
if (!ok) continue;
|
|
2529
|
-
const one = (text) => ({ text, colSpan: 1, rowSpan: 1 });
|
|
2530
|
-
t.cells = rows.map((r, i) => [one(lead[0][i]), one(lead[1][i]), one(r[2].text), one(people[i][1]), one(people[i][2]), one(people[i][3])]);
|
|
2531
|
-
t.cols = 6;
|
|
2658
|
+
function ocrImageRegions(regions, large, all) {
|
|
2659
|
+
if (all) return regions;
|
|
2660
|
+
const out = /* @__PURE__ */ new Map();
|
|
2661
|
+
for (const [p, rs] of regions) {
|
|
2662
|
+
const big = rs.filter((r) => large.has(r));
|
|
2663
|
+
if (big.length) out.set(p, big);
|
|
2532
2664
|
}
|
|
2665
|
+
return out;
|
|
2533
2666
|
}
|
|
2534
|
-
|
|
2535
|
-
// src/pdf/parser.ts
|
|
2536
2667
|
GlobalWorkerOptions.workerSrc = "";
|
|
2537
2668
|
var MAX_PAGES = 5e3;
|
|
2538
2669
|
var MAX_TOTAL_TEXT = 100 * 1024 * 1024;
|
|
@@ -2605,6 +2736,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2605
2736
|
const pagesWithLargeImage = /* @__PURE__ */ new Set();
|
|
2606
2737
|
const skippedImagePages = /* @__PURE__ */ new Map();
|
|
2607
2738
|
const uncoveredImageRegions = /* @__PURE__ */ new Map();
|
|
2739
|
+
const largeImageRegions = /* @__PURE__ */ new Set();
|
|
2608
2740
|
const imageState = createPdfImageState();
|
|
2609
2741
|
const extractedImages = [];
|
|
2610
2742
|
const pageImageBlocks = /* @__PURE__ */ new Map();
|
|
@@ -2636,6 +2768,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2636
2768
|
const differencesOf = (loadedName) => fontObj(loadedName)?.differences;
|
|
2637
2769
|
restoreNamedGlyphs(rawItems, rawOps.fnArray, rawOps.argsArray, differencesOf, (n) => fontObj(n)?.name);
|
|
2638
2770
|
restoreTrackedSpacing(rawItems, rawOps.fnArray, rawOps.argsArray);
|
|
2771
|
+
markSyntheticSpaces(rawItems, rawOps.fnArray, rawOps.argsArray);
|
|
2639
2772
|
const occluded = occludedTextItems(rawItems, rawOps.fnArray, rawOps.argsArray);
|
|
2640
2773
|
const items = normalizeItems(occluded.size ? rawItems.filter((it) => !occluded.has(it)) : rawItems);
|
|
2641
2774
|
const filtered = filterHiddenText(items, pageW, pageH, viewX1, viewY1);
|
|
@@ -2699,6 +2832,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2699
2832
|
const regions = uncoveredImageRegions.get(i) ?? [];
|
|
2700
2833
|
regions.push(r);
|
|
2701
2834
|
uncoveredImageRegions.set(i, regions);
|
|
2835
|
+
if (large) largeImageRegions.add(r);
|
|
2702
2836
|
}
|
|
2703
2837
|
}
|
|
2704
2838
|
}
|
|
@@ -2747,6 +2881,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2747
2881
|
const parsedPageCount = parsedPages || (pageFilter ? pageFilter.size : effectivePageCount);
|
|
2748
2882
|
const isImageBased = pageFilter?.size !== 0 && totalChars / Math.max(parsedPageCount, 1) < 10;
|
|
2749
2883
|
const ocrDone = /* @__PURE__ */ new Set();
|
|
2884
|
+
const ocrRegions = options?.ocr === true || autoOcr ? ocrImageRegions(uncoveredImageRegions, largeImageRegions, options?.ocr === true) : /* @__PURE__ */ new Map();
|
|
2750
2885
|
if (ocrBuffer) {
|
|
2751
2886
|
const inScope = (p) => !pageFilter || pageFilter.has(p);
|
|
2752
2887
|
const targets = /* @__PURE__ */ new Set();
|
|
@@ -2759,14 +2894,15 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2759
2894
|
if (autoOcr && pq.ocrReason !== "low_text" && pq.ocrReason !== "vector_text") continue;
|
|
2760
2895
|
targets.add(pq.page);
|
|
2761
2896
|
}
|
|
2762
|
-
|
|
2897
|
+
for (const p of ocrRegions.keys()) targets.add(p);
|
|
2763
2898
|
}
|
|
2764
2899
|
if (targets.size > 0) {
|
|
2765
2900
|
try {
|
|
2766
|
-
const { runPdfOcr } = await import("./pdf-ocr-
|
|
2901
|
+
const { runPdfOcr } = await import("./pdf-ocr-MQTWODVU.js");
|
|
2767
2902
|
const mode = typeof options?.ocr === "function" ? options.ocr : "builtin";
|
|
2768
|
-
const regionPages = new Map([...
|
|
2903
|
+
const regionPages = new Map([...ocrRegions].filter(([p]) => options?.ocr !== "force" && !isImageBased && !pageQuality.find((q) => q.page === p)?.needsOcr));
|
|
2769
2904
|
const ocrPageBlocks = await runPdfOcr(ocrBuffer, targets, mode, warnings, options?.onProgress, options?.tables !== false, vectorPageOps, regionPages);
|
|
2905
|
+
for (const obs of ocrPageBlocks.values()) stripScriptTags({ blocks: obs });
|
|
2770
2906
|
if (ocrPageBlocks.size > 0) {
|
|
2771
2907
|
const replacePages = /* @__PURE__ */ new Set();
|
|
2772
2908
|
for (const [p, obs] of ocrPageBlocks) {
|
|
@@ -2776,7 +2912,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2776
2912
|
ocrDone.add(p);
|
|
2777
2913
|
continue;
|
|
2778
2914
|
}
|
|
2779
|
-
const regions =
|
|
2915
|
+
const regions = ocrRegions.get(p);
|
|
2780
2916
|
if (!regions || mergeOcrImageRegions(blocks, p, regions, obs) === 0) continue;
|
|
2781
2917
|
ocrDone.add(p);
|
|
2782
2918
|
if (pageImageBlocks.get(p)?.length === 1) pageImageBlocks.delete(p);
|
|
@@ -2830,7 +2966,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2830
2966
|
}
|
|
2831
2967
|
}
|
|
2832
2968
|
if (options?.removeHeaderFooter !== false && parsedPageCount >= 3) {
|
|
2833
|
-
const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings);
|
|
2969
|
+
const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks);
|
|
2834
2970
|
for (let ri = removed.length - 1; ri >= 0; ri--) {
|
|
2835
2971
|
blocks.splice(removed[ri], 1);
|
|
2836
2972
|
}
|
|
@@ -2841,7 +2977,11 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2841
2977
|
}
|
|
2842
2978
|
}
|
|
2843
2979
|
mergeContinuedCells(blocks, pageHeights);
|
|
2844
|
-
mergeCrossPageTables(blocks, pageHeights);
|
|
2980
|
+
mergeCrossPageTables(blocks, pageHeights, wrapLexicon);
|
|
2981
|
+
if (options?.removeHeaderFooter !== false && parsedPageCount >= 3) {
|
|
2982
|
+
const boxes = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks, true);
|
|
2983
|
+
for (let ri = boxes.length - 1; ri >= 0; ri--) blocks.splice(boxes[ri], 1);
|
|
2984
|
+
}
|
|
2845
2985
|
splitContactTables(blocks);
|
|
2846
2986
|
if (!options?.keepTrailingEmptyCols) trimTrailingEmptyTableCols(blocks);
|
|
2847
2987
|
joinPageBreakWraps(blocks, wrapLexicon);
|
|
@@ -2954,7 +3094,8 @@ export {
|
|
|
2954
3094
|
detectTableCaptions,
|
|
2955
3095
|
extractPdfMetadataOnly,
|
|
2956
3096
|
mergeCrossPageTables,
|
|
3097
|
+
ocrImageRegions,
|
|
2957
3098
|
parsePdfDocument,
|
|
2958
3099
|
removeHeaderFooterBlocks
|
|
2959
3100
|
};
|
|
2960
|
-
//# sourceMappingURL=parser-
|
|
3101
|
+
//# sourceMappingURL=parser-N6476XAC.js.map
|