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
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
blocksToPages,
|
|
5
5
|
encodePng,
|
|
6
6
|
escapeLiteralDollar
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-7KNGSQU7.js";
|
|
8
8
|
import {
|
|
9
9
|
hasRequestedPagesAfter,
|
|
10
10
|
parsePageRange
|
|
@@ -41,15 +41,18 @@ import {
|
|
|
41
41
|
ocrModelsCached,
|
|
42
42
|
refineDocumentStyleHeadings,
|
|
43
43
|
removeHeaderFooterBlocks,
|
|
44
|
+
startsNewItem,
|
|
44
45
|
trimTrailingEmptyTableCols,
|
|
45
46
|
wrapJoiner
|
|
46
|
-
} from "./chunk-
|
|
47
|
-
import
|
|
48
|
-
|
|
47
|
+
} from "./chunk-TXUKTOG2.js";
|
|
48
|
+
import {
|
|
49
|
+
stripScriptTags
|
|
50
|
+
} from "./chunk-3IB7LBHC.js";
|
|
51
|
+
import "./chunk-F4NRLLY4.js";
|
|
49
52
|
import {
|
|
50
53
|
KordocError,
|
|
51
54
|
sanitizeHref
|
|
52
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-MLIS253L.js";
|
|
53
56
|
|
|
54
57
|
// src/pdf/ocr-region-merge.ts
|
|
55
58
|
function mergeOcrImageRegions(blocks, page, regions, ocrBlocks) {
|
|
@@ -634,6 +637,40 @@ function ocrVectorOps(opList, paths) {
|
|
|
634
637
|
return { fnArray, argsArray };
|
|
635
638
|
}
|
|
636
639
|
|
|
640
|
+
// src/pdf/contact-table.ts
|
|
641
|
+
var CONTACT_HEAD = /^(?:담당\s*부서|<[^<>]+>)$/;
|
|
642
|
+
var CONTACT_ROLE = /^(?:책임자|담당자)$/;
|
|
643
|
+
var PERSON = /^(.+?)\s+([가-힣]{2,4})\s+(\([^()]*\d[^()]*\)|\S+@\S+)$/;
|
|
644
|
+
function splitContactTables(blocks) {
|
|
645
|
+
for (const b of blocks) {
|
|
646
|
+
const t = b.type === "table" ? b.table : void 0;
|
|
647
|
+
if (!t || t.cols !== 4 || t.rows < 2) continue;
|
|
648
|
+
const rows = t.cells;
|
|
649
|
+
if (!CONTACT_HEAD.test(rows[0][0].text.replace(/\s+/g, " ").trim())) continue;
|
|
650
|
+
const people = rows.map((r) => PERSON.exec(r[3].text.replace(/\s+/g, " ").trim()));
|
|
651
|
+
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;
|
|
652
|
+
const lead = [];
|
|
653
|
+
let ok = true;
|
|
654
|
+
for (const c of [0, 1]) {
|
|
655
|
+
const top = rows[0][c];
|
|
656
|
+
if (top.rowSpan === 1) {
|
|
657
|
+
lead.push(rows.map((r) => r[c].text));
|
|
658
|
+
continue;
|
|
659
|
+
}
|
|
660
|
+
const lines = top.text.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
661
|
+
if (top.rowSpan !== t.rows || lines.length > t.rows) {
|
|
662
|
+
ok = false;
|
|
663
|
+
break;
|
|
664
|
+
}
|
|
665
|
+
lead.push(rows.map((_, r) => lines[r] ?? ""));
|
|
666
|
+
}
|
|
667
|
+
if (!ok) continue;
|
|
668
|
+
const one = (text) => ({ text, colSpan: 1, rowSpan: 1 });
|
|
669
|
+
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])]);
|
|
670
|
+
t.cols = 6;
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
|
|
637
674
|
// src/pdf/table-parts.ts
|
|
638
675
|
var PART_COL_TOL = 1;
|
|
639
676
|
function anchorsOf(table) {
|
|
@@ -670,7 +707,7 @@ var indexOf = (coords, x) => {
|
|
|
670
707
|
};
|
|
671
708
|
var rowText = (anchors, r) => anchors.filter((a) => a.r === r).map((a) => a.cell.text.replace(/\s+/g, "")).join("|");
|
|
672
709
|
var hasText = (t) => t.replace(/\|/g, "") !== "";
|
|
673
|
-
function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom) {
|
|
710
|
+
function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom, lex) {
|
|
674
711
|
if (pcx.length !== prev.cols + 1 || ccx.length !== curr.cols + 1) return null;
|
|
675
712
|
const U = unionCoords(pcx, ccx);
|
|
676
713
|
const cols = U.length - 1;
|
|
@@ -726,13 +763,35 @@ function joinSplitParts(prev, pcx, curr, ccx, dx = 0, prevBottom) {
|
|
|
726
763
|
}
|
|
727
764
|
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]);
|
|
728
765
|
const table = { rows, cols, cells: grid, hasHeader: prev.hasHeader, ...prev.caption ? { caption: prev.caption } : {} };
|
|
729
|
-
|
|
730
|
-
if (rows > prev.rows && !split && prevBottom !== void 0
|
|
766
|
+
let split = rows > prev.rows && mergeSplitRow(table, owner, prev.rows, U);
|
|
767
|
+
if (rows > prev.rows && !split && prevBottom !== void 0 && mergeStraddlingCells(table, owner, prev.rows, prevBottom, lex)) split = mergeSplitRow(table, owner, prev.rows, U, true);
|
|
731
768
|
return { table, colXs: U, split, header: ca.filter((a) => a.r < skip && a.cell.text.trim()).length >= 2 };
|
|
732
769
|
}
|
|
733
|
-
function mergeStraddlingCells(table, owner, first, prevBottom) {
|
|
770
|
+
function mergeStraddlingCells(table, owner, first, prevBottom, lex) {
|
|
734
771
|
const last = first - 1;
|
|
735
|
-
|
|
772
|
+
const straddles = owner[first].some((o, c) => o !== null && o === owner[last][c]);
|
|
773
|
+
let firstNew = table.cols;
|
|
774
|
+
for (let c = 0; c < table.cols; c++) {
|
|
775
|
+
const d = owner[first][c];
|
|
776
|
+
if (d && d.r === first && d !== owner[last][c] && hasContent(table.cells[d.r][d.c])) {
|
|
777
|
+
firstNew = c;
|
|
778
|
+
break;
|
|
779
|
+
}
|
|
780
|
+
}
|
|
781
|
+
let midWord = false;
|
|
782
|
+
if (lex) for (let c = 0; c < table.cols && !midWord; ) {
|
|
783
|
+
const u = owner[last][c], d = owner[first][c];
|
|
784
|
+
if (!u) {
|
|
785
|
+
c++;
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
788
|
+
c = u.c + u.cs;
|
|
789
|
+
if (!d || d === u || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
|
|
790
|
+
if (u.r !== last || d.rs < 2) continue;
|
|
791
|
+
const tail = table.cells[u.r][u.c].text.trim().split(/\s+/).pop() ?? "", head = table.cells[first][d.c].text.trim().split(/\s+/)[0] ?? "";
|
|
792
|
+
if (/^[가-힣]{2,}$/.test(tail) && /^[가-힣]{2,}/.test(head) && lex.evidence2(tail, head) === "") midWord = true;
|
|
793
|
+
}
|
|
794
|
+
let merged = false;
|
|
736
795
|
for (let c = 0; c < table.cols; ) {
|
|
737
796
|
const u = owner[last][c], d = owner[first][c];
|
|
738
797
|
if (!u) {
|
|
@@ -740,18 +799,24 @@ function mergeStraddlingCells(table, owner, first, prevBottom) {
|
|
|
740
799
|
continue;
|
|
741
800
|
}
|
|
742
801
|
c = u.c + u.cs;
|
|
743
|
-
if (!d || d === u || u.r
|
|
802
|
+
if (!d || d === u || u.r + u.rs - 1 !== last || d.r !== first || d.c !== u.c || d.cs !== u.cs) continue;
|
|
744
803
|
const a = table.cells[u.r][u.c], b = table.cells[first][d.c];
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
804
|
+
if (!(u.rs >= 2 && u.c + u.cs <= firstNew && hasContent(a) && !hasContent(b))) {
|
|
805
|
+
if (!straddles && !midWord) continue;
|
|
806
|
+
if (u.r >= last && d.rs < 2) continue;
|
|
807
|
+
const U = CELL_LINES.get(a);
|
|
808
|
+
if (!U?.length || U.length > STRADDLE_MAX_LINES || !hasContent(b)) continue;
|
|
809
|
+
const lu = U[U.length - 1];
|
|
810
|
+
if (!midWord && lu.y - prevBottom > (u.r >= last ? STRADDLE_BOTTOM_ONE_ROW : STRADDLE_BOTTOM) * (lu.h || 10)) continue;
|
|
811
|
+
}
|
|
749
812
|
appendCell(a, b);
|
|
750
813
|
a.rowSpan = first + d.rs - u.r;
|
|
751
814
|
table.cells[first][d.c] = { text: "", colSpan: 1, rowSpan: 1 };
|
|
752
815
|
const grown = { ...u, rs: a.rowSpan };
|
|
753
816
|
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;
|
|
817
|
+
merged = true;
|
|
754
818
|
}
|
|
819
|
+
return merged;
|
|
755
820
|
}
|
|
756
821
|
var FULL_LINE_TOL = 1;
|
|
757
822
|
var FULL_LINE_MIN_FRAC = 0.5;
|
|
@@ -787,11 +852,21 @@ function continuesAcross(u, d, x1, x2) {
|
|
|
787
852
|
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;
|
|
788
853
|
return U.some(leftAligned) || D.some(leftAligned) || hanging;
|
|
789
854
|
}
|
|
790
|
-
|
|
855
|
+
var OUTLINE_HEAD = /^[□■]\s*\S/;
|
|
856
|
+
var OUTLINE_ITEM = /^[ㅇ○◦\-‐–·․‧※*]\s*\S/;
|
|
857
|
+
function outlineContinues(u, d) {
|
|
858
|
+
const U = u.text.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
859
|
+
const D = d.text.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
860
|
+
return U.length >= 2 && D.length >= 1 && U.some((l) => OUTLINE_HEAD.test(l)) && OUTLINE_ITEM.test(D[0]);
|
|
861
|
+
}
|
|
862
|
+
function lineEnded(c, x1, x2, next = "") {
|
|
791
863
|
const L = CELL_LINES.get(c);
|
|
792
864
|
if (!L || L.length !== 1) return false;
|
|
793
|
-
const l = L[0];
|
|
794
|
-
|
|
865
|
+
const l = L[0], h = l.h || 10;
|
|
866
|
+
const word = next.trim().split(/\s+/)[0] ?? "";
|
|
867
|
+
let units = 0;
|
|
868
|
+
for (const ch of word) units += /[가-힣\u3400-\u9fff]/.test(ch) ? 1 : 0.55;
|
|
869
|
+
return x2 - l.r - (l.l - x1) >= Math.max(LABEL_ROOM, units) * h;
|
|
795
870
|
}
|
|
796
871
|
function appendCell(a, b) {
|
|
797
872
|
if (a.blocks?.length || b.blocks?.length) {
|
|
@@ -801,7 +876,22 @@ function appendCell(a, b) {
|
|
|
801
876
|
if (b.text.trim()) a.text = a.text.trim() ? a.text + "\n" + b.text : b.text;
|
|
802
877
|
}
|
|
803
878
|
var hasContent = (cell) => !!cell.text.trim() || !!cell.blocks?.length || IMAGE_CELLS.has(cell);
|
|
804
|
-
|
|
879
|
+
var CLAUSE_OPEN_ENDING = /(?:하는|되는|하고|하며|하여|되어|되고|되며|이며|으며|어야|아야|여야)$/;
|
|
880
|
+
var batchim = (ch) => {
|
|
881
|
+
const k = ch.charCodeAt(0) - 44032;
|
|
882
|
+
return k >= 0 && k < 11172 && k % 28 !== 0;
|
|
883
|
+
};
|
|
884
|
+
function clauseContinues(u, d) {
|
|
885
|
+
const tail = u.text.trim().split(/\s+/).pop() ?? "", head = d.text.trim();
|
|
886
|
+
if (!/^[가-힣]{2,}$/.test(tail) || !/^[가-힣]/.test(head) || startsNewItem(u.text, head)) return false;
|
|
887
|
+
const last = tail[tail.length - 1], before = tail[tail.length - 2];
|
|
888
|
+
return last === "\uC744" && batchim(before) || last === "\uB97C" && !batchim(before) || CLAUSE_OPEN_ENDING.test(tail);
|
|
889
|
+
}
|
|
890
|
+
function outlineOnly(pairs, cell) {
|
|
891
|
+
const filled = pairs.filter(([, d]) => hasContent(d.cell));
|
|
892
|
+
return filled.length === 1 && outlineContinues(cell(filled[0][0]), cell(filled[0][1]));
|
|
893
|
+
}
|
|
894
|
+
function mergeSplitRow(table, owner, first, colXs, textOnly = false) {
|
|
805
895
|
const last = first - 1;
|
|
806
896
|
const pairs = [];
|
|
807
897
|
let carried = false;
|
|
@@ -819,12 +909,12 @@ function mergeSplitRow(table, owner, first, colXs) {
|
|
|
819
909
|
} else if (a.r === last && a.rs === 2) carried = true;
|
|
820
910
|
c = a.c + a.cs;
|
|
821
911
|
}
|
|
822
|
-
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));
|
|
912
|
+
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));
|
|
823
913
|
const cell = (a) => table.cells[a.r][a.c];
|
|
824
914
|
if (!carriedSplit) {
|
|
825
915
|
const norm = (c) => c.text.replace(/\s+/g, "");
|
|
826
|
-
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;
|
|
827
|
-
if (!pairs.some(([u, d]) => continuesAcross(cell(u), cell(d), colXs[u.c], colXs[u.c + u.cs]))) return false;
|
|
916
|
+
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;
|
|
917
|
+
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;
|
|
828
918
|
}
|
|
829
919
|
for (const [u, d] of pairs) appendCell(table.cells[u.r][u.c], table.cells[d.r][d.c]);
|
|
830
920
|
for (let r = 0; r < first; r++) for (let c = 0; c < table.cols; c++) {
|
|
@@ -871,8 +961,8 @@ function sameHeadShape(a, b) {
|
|
|
871
961
|
}
|
|
872
962
|
return tall;
|
|
873
963
|
}
|
|
874
|
-
function mergeCrossPageTables(blocks, pageHeights) {
|
|
875
|
-
mergeColumnFlow(blocks, pageHeights);
|
|
964
|
+
function mergeCrossPageTables(blocks, pageHeights, lex) {
|
|
965
|
+
mergeColumnFlow(blocks, pageHeights, lex);
|
|
876
966
|
for (let i = blocks.length - 2; i >= 0; i--) {
|
|
877
967
|
const prev = blocks[i];
|
|
878
968
|
if (prev.type !== "table" || !prev.table || !prev.bbox || !prev.pageNumber) continue;
|
|
@@ -881,7 +971,7 @@ function mergeCrossPageTables(blocks, pageHeights) {
|
|
|
881
971
|
const curr = blocks[j];
|
|
882
972
|
if (!curr || curr.type !== "table" || !curr.table || !curr.bbox || curr.pageNumber !== prev.pageNumber + 1) continue;
|
|
883
973
|
if (startsWithUnitRow(prev.table) && startsWithUnitRow(curr.table)) continue;
|
|
884
|
-
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;
|
|
974
|
+
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;
|
|
885
975
|
if (joined) {
|
|
886
976
|
placeJoined(blocks, i, j, joined);
|
|
887
977
|
continue;
|
|
@@ -925,7 +1015,7 @@ function mergeCrossPageTables(blocks, pageHeights) {
|
|
|
925
1015
|
if (blocks[i].type === "table" && t && EMPTY_PARTS.has(t)) blocks.splice(i, 1);
|
|
926
1016
|
}
|
|
927
1017
|
}
|
|
928
|
-
function mergeColumnFlow(blocks, pageHeights) {
|
|
1018
|
+
function mergeColumnFlow(blocks, pageHeights, lex) {
|
|
929
1019
|
if (!pageHeights) return;
|
|
930
1020
|
for (let i = 0; i < blocks.length; i++) {
|
|
931
1021
|
const L = blocks[i];
|
|
@@ -947,7 +1037,7 @@ function mergeColumnFlow(blocks, pageHeights) {
|
|
|
947
1037
|
const R = blocks[k];
|
|
948
1038
|
if (Math.abs(R.bbox.width - L.bbox.width) > Math.max(R.bbox.width, L.bbox.width) * NEIGHBOR_TABLE_EPSILON) continue;
|
|
949
1039
|
if (!looksContinued(L, R) || restartsTable(blocks, i, R.table, pageHeights)) continue;
|
|
950
|
-
const joined = joinClipParts(L, R, pageHeights);
|
|
1040
|
+
const joined = joinClipParts(L, R, pageHeights, lex);
|
|
951
1041
|
if (!joined) continue;
|
|
952
1042
|
const top = L.bbox.y + L.bbox.height;
|
|
953
1043
|
const at = Math.min(i, k);
|
|
@@ -956,12 +1046,12 @@ function mergeColumnFlow(blocks, pageHeights) {
|
|
|
956
1046
|
i = at - 1;
|
|
957
1047
|
}
|
|
958
1048
|
}
|
|
959
|
-
function joinClipParts(prev, curr, pageHeights) {
|
|
1049
|
+
function joinClipParts(prev, curr, pageHeights, lex) {
|
|
960
1050
|
const pt = prev.table, ct = curr.table;
|
|
961
1051
|
if (!CLIP_TABLES.has(pt) || !CLIP_TABLES.has(ct)) return null;
|
|
962
1052
|
const px = TABLE_COLXS.get(pt), cx = TABLE_COLXS.get(ct);
|
|
963
1053
|
if (!px || !cx) return null;
|
|
964
|
-
let xs = cx, shifted = false, dx = 0;
|
|
1054
|
+
let xs = cx, shifted = false, dx = 0, foreign = false;
|
|
965
1055
|
if (!shiftedSame(px, cx, false)) {
|
|
966
1056
|
if (!pageHeights?.get(prev.pageNumber) || !pageHeights?.get(curr.pageNumber)) return null;
|
|
967
1057
|
dx = px[px.length - 1] - cx[cx.length - 1];
|
|
@@ -970,19 +1060,29 @@ function joinClipParts(prev, curr, pageHeights) {
|
|
|
970
1060
|
shifted = true;
|
|
971
1061
|
} else dx = 0;
|
|
972
1062
|
if (!px.some((x) => Math.abs(x - xs[0]) <= CONTINUATION_COL_TOL)) return null;
|
|
1063
|
+
const inner = xs.slice(1, -1);
|
|
1064
|
+
foreign = inner.length > 0 && !inner.some((x) => px.some((p) => Math.abs(p - x) <= CONTINUATION_COL_TOL)) && headingRow(ct.cells[0] ?? []);
|
|
973
1065
|
}
|
|
974
|
-
const res = joinSplitParts(pt, px, ct, xs, dx, prev.bbox?.y);
|
|
975
|
-
if (!res || shifted && !res.split && !res.header) return null;
|
|
1066
|
+
const res = joinSplitParts(pt, px, ct, xs, dx, prev.bbox?.y, lex);
|
|
1067
|
+
if (!res || (shifted || foreign) && !res.split && !res.header) return null;
|
|
976
1068
|
TABLE_COLXS.set(res.table, res.colXs);
|
|
977
1069
|
CLIP_TABLES.add(res.table);
|
|
978
1070
|
return res.table;
|
|
979
1071
|
}
|
|
1072
|
+
function headingRow(row) {
|
|
1073
|
+
const heads = row.map((c) => c.text.replace(/\s+/g, "")).filter(Boolean);
|
|
1074
|
+
if (heads.length === 1) return heads[0].length <= 8 || /^[①-⑳❶-❿]/.test(heads[0]);
|
|
1075
|
+
return heads.length === 2 && /^(?:\d{1,2}|[ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ]+|[①-⑳❶-❿])$/.test(heads[0]);
|
|
1076
|
+
}
|
|
980
1077
|
var ANNEX_HEAD_RE = /^\s*[<\[(【]?\s*(?:붙\s*임|참\s*고|별\s*첨|별\s*지|별\s*표|첨\s*부|부\s*록)(?:\s*\d|\s*$|\s*[>\])】])|^\s*■/;
|
|
981
1078
|
function looksContinued(prev, curr, pageHeights) {
|
|
982
1079
|
const ph = pageHeights?.get(prev.pageNumber), ch = pageHeights?.get(curr.pageNumber);
|
|
983
1080
|
if (ph && ch && (prev.bbox.y > ph * PAGE_EDGE_BAND || curr.bbox.y + curr.bbox.height < ch * (1 - PAGE_EDGE_BAND))) return false;
|
|
984
|
-
const
|
|
985
|
-
|
|
1081
|
+
const firstRow = curr.table.cells[0] ?? [];
|
|
1082
|
+
const firstText = firstRow.find((c) => c.text.trim())?.text ?? "";
|
|
1083
|
+
if (!ANNEX_HEAD_RE.test(firstText)) return true;
|
|
1084
|
+
const filled = firstRow.map((c) => c.text.replace(/\s+/g, "")).filter(Boolean);
|
|
1085
|
+
return filled.length >= 2 && filled.every((t) => t === filled[0]);
|
|
986
1086
|
}
|
|
987
1087
|
function firstRowSig(t) {
|
|
988
1088
|
const x = TABLE_COLXS.get(t);
|
|
@@ -995,6 +1095,7 @@ function restartsTable(blocks, i, curr, pageHeights) {
|
|
|
995
1095
|
const head = blocks[chainHead(blocks, i, pageHeights)].table;
|
|
996
1096
|
if (cs.length === 1 && restartsTitledForm(head, curr)) return true;
|
|
997
1097
|
if (cs.length < RESTART_MIN_ANCHORS) return false;
|
|
1098
|
+
if (CONTACT_HEAD.test(cs[0].t) && cs.some((c) => CONTACT_ROLE.test(c.t))) return false;
|
|
998
1099
|
const hs = firstRowSig(head);
|
|
999
1100
|
if (!hs || hs.length !== cs.length) return false;
|
|
1000
1101
|
const dx = hs[hs.length - 1].x2 - cs[cs.length - 1].x2;
|
|
@@ -1841,6 +1942,52 @@ function restoreTrackedSpacing(items, fnArray, argsArray) {
|
|
|
1841
1942
|
}
|
|
1842
1943
|
return changed;
|
|
1843
1944
|
}
|
|
1945
|
+
function markSyntheticSpaces(items, fnArray, argsArray) {
|
|
1946
|
+
if (!items.some((it) => typeof it.str === "string" && it.str.length > 0 && !it.str.trim())) return;
|
|
1947
|
+
const streams = /* @__PURE__ */ new Map();
|
|
1948
|
+
const saved = [];
|
|
1949
|
+
let font = "";
|
|
1950
|
+
for (let i = 0; i < fnArray.length; i++) {
|
|
1951
|
+
const fn = fnArray[i];
|
|
1952
|
+
const args = argsArray[i];
|
|
1953
|
+
if (fn === OPS5.setFont) font = String(args[0]);
|
|
1954
|
+
else if (fn === OPS5.save || fn === OPS5.paintFormXObjectBegin) saved.push(font);
|
|
1955
|
+
else if (fn === OPS5.restore || fn === OPS5.paintFormXObjectEnd) font = saved.pop() ?? font;
|
|
1956
|
+
else if (fn === OPS5.showText) {
|
|
1957
|
+
let list = streams.get(font);
|
|
1958
|
+
if (!list) streams.set(font, list = []);
|
|
1959
|
+
for (const g2 of args[0]) {
|
|
1960
|
+
if (g2 && typeof g2 === "object" && typeof g2.unicode === "string") list.push(normalizeUnicode3(g2.unicode));
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
const cursor = /* @__PURE__ */ new Map();
|
|
1965
|
+
const failed = /* @__PURE__ */ new Set();
|
|
1966
|
+
const marks = [];
|
|
1967
|
+
for (const it of items) {
|
|
1968
|
+
const f = it.fontName ?? "";
|
|
1969
|
+
const glyphs = streams.get(f);
|
|
1970
|
+
if (!glyphs || failed.has(f) || typeof it.str !== "string" || !it.str) continue;
|
|
1971
|
+
let gi = cursor.get(f) ?? 0;
|
|
1972
|
+
if (!it.str.trim()) {
|
|
1973
|
+
if (gi < glyphs.length && /^\s+$/.test(glyphs[gi])) {
|
|
1974
|
+
while (gi < glyphs.length && /^\s+$/.test(glyphs[gi])) gi++;
|
|
1975
|
+
cursor.set(f, gi);
|
|
1976
|
+
} else marks.push(it);
|
|
1977
|
+
continue;
|
|
1978
|
+
}
|
|
1979
|
+
const want = it.str.replace(/\s+/g, "");
|
|
1980
|
+
while (gi < glyphs.length && /^\s*$/.test(glyphs[gi])) gi++;
|
|
1981
|
+
let got = "";
|
|
1982
|
+
while (gi < glyphs.length && got.length < want.length) got += glyphs[gi++].replace(/\s+/g, "");
|
|
1983
|
+
if (got !== want) {
|
|
1984
|
+
failed.add(f);
|
|
1985
|
+
continue;
|
|
1986
|
+
}
|
|
1987
|
+
cursor.set(f, gi);
|
|
1988
|
+
}
|
|
1989
|
+
for (const it of marks) if (!failed.has(it.fontName ?? "")) it.synthetic = true;
|
|
1990
|
+
}
|
|
1844
1991
|
|
|
1845
1992
|
// src/pdf/endnotes.ts
|
|
1846
1993
|
var NOTE_MARK = /^\s*(문\d{1,5}[))]|\d{1,5}\)|\(\d{1,5}\))/;
|
|
@@ -1978,6 +2125,7 @@ function orderTwoUpPage(blocks, pageWidth, pageHeight) {
|
|
|
1978
2125
|
var BAND = 0.12;
|
|
1979
2126
|
var MAX_CHARS = 10;
|
|
1980
2127
|
var MIN_REPEAT = 3;
|
|
2128
|
+
var RUN_GAP = 5;
|
|
1981
2129
|
function removeSideTabs(blocks, pageWidths) {
|
|
1982
2130
|
const edges = /* @__PURE__ */ new Map();
|
|
1983
2131
|
for (const b of blocks) {
|
|
@@ -2010,13 +2158,21 @@ function removeSideTabs(blocks, pageWidths) {
|
|
|
2010
2158
|
}
|
|
2011
2159
|
const running = /* @__PURE__ */ new Set();
|
|
2012
2160
|
for (const [k, ps] of pages) {
|
|
2013
|
-
const list = [...ps];
|
|
2014
|
-
|
|
2015
|
-
|
|
2161
|
+
const list = [...ps].sort((a, b) => a - b);
|
|
2162
|
+
let run = [];
|
|
2163
|
+
const flush = () => {
|
|
2164
|
+
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}`);
|
|
2165
|
+
run = [];
|
|
2166
|
+
};
|
|
2167
|
+
for (const p of list) {
|
|
2168
|
+
if (run.length && p - run[run.length - 1] > RUN_GAP) flush();
|
|
2169
|
+
run.push(p);
|
|
2170
|
+
}
|
|
2171
|
+
flush();
|
|
2016
2172
|
}
|
|
2017
2173
|
return running.size ? blocks.filter((b) => {
|
|
2018
2174
|
const k = key(b);
|
|
2019
|
-
return !k || !running.has(k);
|
|
2175
|
+
return !k || !running.has(`${b.pageNumber}\0${k}`);
|
|
2020
2176
|
}) : blocks;
|
|
2021
2177
|
}
|
|
2022
2178
|
|
|
@@ -2184,7 +2340,9 @@ function normalizeAraea(text) {
|
|
|
2184
2340
|
return text.replace(/(?<![\u1100-\u115F])\u119E/g, "\u318D");
|
|
2185
2341
|
}
|
|
2186
2342
|
var stripNoUnicodeGlyph = (text) => text.includes("\uF000") ? text.replace(/\uF000/g, "") : text;
|
|
2187
|
-
var
|
|
2343
|
+
var CHOSEONG_COMPAT = "\u3131\u3132\u3134\u3137\u3138\u3139\u3141\u3142\u3143\u3145\u3146\u3147\u3148\u3149\u314A\u314B\u314C\u314D\u314E";
|
|
2344
|
+
var normalizeLoneChoseong = (text) => /[\u1100-\u1112]/.test(text) ? text.replace(/[\u1100-\u1112](?![\u1160-\u11A7\uD7B0-\uD7C6])/g, (c) => CHOSEONG_COMPAT[c.charCodeAt(0) - 4352]) : text;
|
|
2345
|
+
var cleanChars = (text) => normalizeLoneChoseong(normalizeAraea(stripNoUnicodeGlyph(stripControlChars(text))));
|
|
2188
2346
|
function sanitizeBlockControlChars(blocks) {
|
|
2189
2347
|
for (const b of blocks) {
|
|
2190
2348
|
if (b.text) b.text = cleanChars(b.text);
|
|
@@ -2261,7 +2419,7 @@ function cleanPdfText(text, opts) {
|
|
|
2261
2419
|
}
|
|
2262
2420
|
const mark = /^(?:#{1,6}|-) /.exec(line)?.[0] ?? "";
|
|
2263
2421
|
return mark + collapseEvenSpacing(line.slice(mark.length), false);
|
|
2264
|
-
}).replace(/\\~\\~/g, "~~").replace(/~~~~/g, "").replace(/<u>\s*<\/u>/g, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
2422
|
+
}).replace(/\\~\\~/g, "~~").replace(/~~~~/g, "").replace(/<u>\s*<\/u>/g, "").replace(/<(sup|sub)>\s*<\/\1>/g, "").replace(/\n{3,}/g, "\n\n").trim();
|
|
2265
2423
|
}
|
|
2266
2424
|
function startsWithMarker(line) {
|
|
2267
2425
|
const t = line.trimStart();
|
|
@@ -2349,7 +2507,7 @@ function mergeLinkRuns(markdown) {
|
|
|
2349
2507
|
|
|
2350
2508
|
// src/pdf/formula-ocr.ts
|
|
2351
2509
|
async function applyFormulaOcr(buffer, blocks, pageFilter, effectivePageCount, warnings, _onProgress) {
|
|
2352
|
-
const formulaMod = await import("./formula-
|
|
2510
|
+
const formulaMod = await import("./formula-EPKLPDU7.js");
|
|
2353
2511
|
const { FormulaPipeline, ensureFormulaModels } = formulaMod;
|
|
2354
2512
|
await ensureFormulaModels((p) => {
|
|
2355
2513
|
if (p.phase === "download" && p.total) {
|
|
@@ -2489,42 +2647,15 @@ g.pdfjsWorker = pdfjsWorker;
|
|
|
2489
2647
|
import { getDocument, GlobalWorkerOptions, OPS as OPS6 } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
2490
2648
|
import { createRequire } from "module";
|
|
2491
2649
|
import { dirname, join } from "path";
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
for (const b of blocks) {
|
|
2499
|
-
const t = b.type === "table" ? b.table : void 0;
|
|
2500
|
-
if (!t || t.cols !== 4 || t.rows < 2) continue;
|
|
2501
|
-
const rows = t.cells;
|
|
2502
|
-
if (!HEAD.test(rows[0][0].text.replace(/\s+/g, " ").trim())) continue;
|
|
2503
|
-
const people = rows.map((r) => PERSON.exec(r[3].text.replace(/\s+/g, " ").trim()));
|
|
2504
|
-
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;
|
|
2505
|
-
const lead = [];
|
|
2506
|
-
let ok = true;
|
|
2507
|
-
for (const c of [0, 1]) {
|
|
2508
|
-
const top = rows[0][c];
|
|
2509
|
-
if (top.rowSpan === 1) {
|
|
2510
|
-
lead.push(rows.map((r) => r[c].text));
|
|
2511
|
-
continue;
|
|
2512
|
-
}
|
|
2513
|
-
const lines = top.text.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
2514
|
-
if (top.rowSpan !== t.rows || lines.length > t.rows) {
|
|
2515
|
-
ok = false;
|
|
2516
|
-
break;
|
|
2517
|
-
}
|
|
2518
|
-
lead.push(rows.map((_, r) => lines[r] ?? ""));
|
|
2519
|
-
}
|
|
2520
|
-
if (!ok) continue;
|
|
2521
|
-
const one = (text) => ({ text, colSpan: 1, rowSpan: 1 });
|
|
2522
|
-
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])]);
|
|
2523
|
-
t.cols = 6;
|
|
2650
|
+
function ocrImageRegions(regions, large, all) {
|
|
2651
|
+
if (all) return regions;
|
|
2652
|
+
const out = /* @__PURE__ */ new Map();
|
|
2653
|
+
for (const [p, rs] of regions) {
|
|
2654
|
+
const big = rs.filter((r) => large.has(r));
|
|
2655
|
+
if (big.length) out.set(p, big);
|
|
2524
2656
|
}
|
|
2657
|
+
return out;
|
|
2525
2658
|
}
|
|
2526
|
-
|
|
2527
|
-
// src/pdf/parser.ts
|
|
2528
2659
|
GlobalWorkerOptions.workerSrc = "";
|
|
2529
2660
|
var MAX_PAGES = 5e3;
|
|
2530
2661
|
var MAX_TOTAL_TEXT = 100 * 1024 * 1024;
|
|
@@ -2597,6 +2728,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2597
2728
|
const pagesWithLargeImage = /* @__PURE__ */ new Set();
|
|
2598
2729
|
const skippedImagePages = /* @__PURE__ */ new Map();
|
|
2599
2730
|
const uncoveredImageRegions = /* @__PURE__ */ new Map();
|
|
2731
|
+
const largeImageRegions = /* @__PURE__ */ new Set();
|
|
2600
2732
|
const imageState = createPdfImageState();
|
|
2601
2733
|
const extractedImages = [];
|
|
2602
2734
|
const pageImageBlocks = /* @__PURE__ */ new Map();
|
|
@@ -2628,6 +2760,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2628
2760
|
const differencesOf = (loadedName) => fontObj(loadedName)?.differences;
|
|
2629
2761
|
restoreNamedGlyphs(rawItems, rawOps.fnArray, rawOps.argsArray, differencesOf, (n) => fontObj(n)?.name);
|
|
2630
2762
|
restoreTrackedSpacing(rawItems, rawOps.fnArray, rawOps.argsArray);
|
|
2763
|
+
markSyntheticSpaces(rawItems, rawOps.fnArray, rawOps.argsArray);
|
|
2631
2764
|
const occluded = occludedTextItems(rawItems, rawOps.fnArray, rawOps.argsArray);
|
|
2632
2765
|
const items = normalizeItems(occluded.size ? rawItems.filter((it) => !occluded.has(it)) : rawItems);
|
|
2633
2766
|
const filtered = filterHiddenText(items, pageW, pageH, viewX1, viewY1);
|
|
@@ -2691,6 +2824,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2691
2824
|
const regions = uncoveredImageRegions.get(i) ?? [];
|
|
2692
2825
|
regions.push(r);
|
|
2693
2826
|
uncoveredImageRegions.set(i, regions);
|
|
2827
|
+
if (large) largeImageRegions.add(r);
|
|
2694
2828
|
}
|
|
2695
2829
|
}
|
|
2696
2830
|
}
|
|
@@ -2739,6 +2873,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2739
2873
|
const parsedPageCount = parsedPages || (pageFilter ? pageFilter.size : effectivePageCount);
|
|
2740
2874
|
const isImageBased = pageFilter?.size !== 0 && totalChars / Math.max(parsedPageCount, 1) < 10;
|
|
2741
2875
|
const ocrDone = /* @__PURE__ */ new Set();
|
|
2876
|
+
const ocrRegions = options?.ocr === true || autoOcr ? ocrImageRegions(uncoveredImageRegions, largeImageRegions, options?.ocr === true) : /* @__PURE__ */ new Map();
|
|
2742
2877
|
if (ocrBuffer) {
|
|
2743
2878
|
const inScope = (p) => !pageFilter || pageFilter.has(p);
|
|
2744
2879
|
const targets = /* @__PURE__ */ new Set();
|
|
@@ -2751,14 +2886,15 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2751
2886
|
if (autoOcr && pq.ocrReason !== "low_text" && pq.ocrReason !== "vector_text") continue;
|
|
2752
2887
|
targets.add(pq.page);
|
|
2753
2888
|
}
|
|
2754
|
-
|
|
2889
|
+
for (const p of ocrRegions.keys()) targets.add(p);
|
|
2755
2890
|
}
|
|
2756
2891
|
if (targets.size > 0) {
|
|
2757
2892
|
try {
|
|
2758
|
-
const { runPdfOcr } = await import("./pdf-ocr-
|
|
2893
|
+
const { runPdfOcr } = await import("./pdf-ocr-6DEE23IP.js");
|
|
2759
2894
|
const mode = typeof options?.ocr === "function" ? options.ocr : "builtin";
|
|
2760
|
-
const regionPages = new Map([...
|
|
2895
|
+
const regionPages = new Map([...ocrRegions].filter(([p]) => options?.ocr !== "force" && !isImageBased && !pageQuality.find((q) => q.page === p)?.needsOcr));
|
|
2761
2896
|
const ocrPageBlocks = await runPdfOcr(ocrBuffer, targets, mode, warnings, options?.onProgress, options?.tables !== false, vectorPageOps, regionPages);
|
|
2897
|
+
for (const obs of ocrPageBlocks.values()) stripScriptTags({ blocks: obs });
|
|
2762
2898
|
if (ocrPageBlocks.size > 0) {
|
|
2763
2899
|
const replacePages = /* @__PURE__ */ new Set();
|
|
2764
2900
|
for (const [p, obs] of ocrPageBlocks) {
|
|
@@ -2768,7 +2904,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2768
2904
|
ocrDone.add(p);
|
|
2769
2905
|
continue;
|
|
2770
2906
|
}
|
|
2771
|
-
const regions =
|
|
2907
|
+
const regions = ocrRegions.get(p);
|
|
2772
2908
|
if (!regions || mergeOcrImageRegions(blocks, p, regions, obs) === 0) continue;
|
|
2773
2909
|
ocrDone.add(p);
|
|
2774
2910
|
if (pageImageBlocks.get(p)?.length === 1) pageImageBlocks.delete(p);
|
|
@@ -2822,7 +2958,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2822
2958
|
}
|
|
2823
2959
|
}
|
|
2824
2960
|
if (options?.removeHeaderFooter !== false && parsedPageCount >= 3) {
|
|
2825
|
-
const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings);
|
|
2961
|
+
const removed = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks);
|
|
2826
2962
|
for (let ri = removed.length - 1; ri >= 0; ri--) {
|
|
2827
2963
|
blocks.splice(removed[ri], 1);
|
|
2828
2964
|
}
|
|
@@ -2833,7 +2969,11 @@ async function parsePdfDocument(buffer, options) {
|
|
|
2833
2969
|
}
|
|
2834
2970
|
}
|
|
2835
2971
|
mergeContinuedCells(blocks, pageHeights);
|
|
2836
|
-
mergeCrossPageTables(blocks, pageHeights);
|
|
2972
|
+
mergeCrossPageTables(blocks, pageHeights, wrapLexicon);
|
|
2973
|
+
if (options?.removeHeaderFooter !== false && parsedPageCount >= 3) {
|
|
2974
|
+
const boxes = removeHeaderFooterBlocks(blocks, pageHeights, warnings, noteMarks, true);
|
|
2975
|
+
for (let ri = boxes.length - 1; ri >= 0; ri--) blocks.splice(boxes[ri], 1);
|
|
2976
|
+
}
|
|
2837
2977
|
splitContactTables(blocks);
|
|
2838
2978
|
if (!options?.keepTrailingEmptyCols) trimTrailingEmptyTableCols(blocks);
|
|
2839
2979
|
joinPageBreakWraps(blocks, wrapLexicon);
|
|
@@ -2946,7 +3086,8 @@ export {
|
|
|
2946
3086
|
detectTableCaptions,
|
|
2947
3087
|
extractPdfMetadataOnly,
|
|
2948
3088
|
mergeCrossPageTables,
|
|
3089
|
+
ocrImageRegions,
|
|
2949
3090
|
parsePdfDocument,
|
|
2950
3091
|
removeHeaderFooterBlocks
|
|
2951
3092
|
};
|
|
2952
|
-
//# sourceMappingURL=parser-
|
|
3093
|
+
//# sourceMappingURL=parser-ZQM3664Z.js.map
|