kordoc 4.17.1 → 4.17.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 +3 -0
- package/dist/{-UNMTWAEI.js → -2UA2JHVA.js} +10 -10
- package/dist/{chunk-B4PUQ4FP.js → chunk-2XHXABCX.js} +2 -2
- package/dist/{chunk-MPAN6S5O.js → chunk-3N272C5L.js} +243 -114
- package/dist/chunk-3N272C5L.js.map +1 -0
- package/dist/{chunk-EULS3PDF.js → chunk-4HRJISJF.js} +3 -3
- package/dist/{chunk-KBIQGGNY.js → chunk-4TSYMJDL.js} +242 -113
- package/dist/chunk-4TSYMJDL.js.map +1 -0
- package/dist/{chunk-3M2BMQJY.js → chunk-5JZEY5IL.js} +119 -77
- package/dist/chunk-5JZEY5IL.js.map +1 -0
- package/dist/{chunk-5FCLQVT5.cjs → chunk-6DOCSYEM.cjs} +113 -71
- package/dist/chunk-6DOCSYEM.cjs.map +1 -0
- package/dist/{chunk-N6MPDM55.js → chunk-6OCKAXIS.js} +2 -2
- package/dist/{chunk-QXNQ2HNB.js → chunk-A2W2JQ3S.js} +2 -2
- package/dist/{chunk-66YTQ3NQ.js → chunk-C4MVZXB5.js} +2 -2
- package/dist/{chunk-GYHY2YLV.js → chunk-FGL4IGOT.js} +4 -4
- package/dist/{chunk-BEJYCCDN.cjs → chunk-GPC72VSF.cjs} +6 -6
- package/dist/chunk-GPC72VSF.cjs.map +1 -0
- package/dist/chunk-GS7T56RP.cjs.map +1 -1
- package/dist/{chunk-FMP4POMD.js → chunk-GYTL6WT3.js} +3 -3
- package/dist/{chunk-4NH45EEB.cjs → chunk-HAW2VL62.cjs} +12 -12
- package/dist/chunk-HAW2VL62.cjs.map +1 -0
- package/dist/chunk-J55UQC5H.cjs.map +1 -1
- package/dist/{chunk-ELNYQRBN.js → chunk-JY2NBFIG.js} +14 -12
- package/dist/chunk-JY2NBFIG.js.map +1 -0
- package/dist/{chunk-BQAJHAWR.js → chunk-KQIYC2ZU.js} +2 -2
- package/dist/{chunk-GRHSVGSB.cjs → chunk-KZVQK5NS.cjs} +2 -2
- package/dist/chunk-KZVQK5NS.cjs.map +1 -0
- package/dist/{chunk-AUFO5LVN.js → chunk-MDCTITUG.js} +2 -2
- package/dist/{chunk-OVSCNCT6.js → chunk-O4CB7D2Q.js} +2 -2
- package/dist/{chunk-3J3BJIOZ.js → chunk-SDRKHEVT.js} +2 -2
- package/dist/{chunk-HAPCN7BD.js → chunk-VU26WGE5.js} +37 -15
- package/dist/chunk-VU26WGE5.js.map +1 -0
- package/dist/{chunk-BHUYJBSQ.js → chunk-WJLICIYV.js} +2 -2
- package/dist/{chunk-ZRXQDJPM.cjs → chunk-WWMKIHF7.cjs} +336 -207
- package/dist/chunk-WWMKIHF7.cjs.map +1 -0
- package/dist/{chunk-MY6Q2HFW.js → chunk-XZA6X34R.js} +121 -77
- package/dist/chunk-XZA6X34R.js.map +1 -0
- package/dist/{chunk-4CSY3QUO.js → chunk-YGKC6E6A.js} +2 -2
- package/dist/chunk-YIANW5QX.cjs.map +1 -1
- package/dist/{chunk-E6TJNN2U.js → chunk-ZDX5PIWR.js} +2 -2
- package/dist/chunks-EBWJR55V.js +10 -0
- package/dist/cli.js +25 -25
- package/dist/{formula-K7UF5MBF.cjs → formula-5RETDCIC.cjs} +9 -9
- package/dist/formula-5RETDCIC.cjs.map +1 -0
- package/dist/{formula-VH545WNH.js → formula-MBLN2DG4.js} +4 -4
- package/dist/{formula-3GB47YTH.js → formula-QZZDW5GW.js} +3 -3
- package/dist/{image-ocr-6AKQWAU2.js → image-ocr-CJSO3QSR.js} +7 -7
- package/dist/{image-ocr-VJFZCFAI.js → image-ocr-EREKAS47.js} +5 -5
- package/dist/{image-ocr-ZPQTFYSK.cjs → image-ocr-PSPVRLB5.cjs} +14 -14
- package/dist/image-ocr-PSPVRLB5.cjs.map +1 -0
- package/dist/index.cjs +612 -588
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +41 -17
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +21 -21
- package/dist/{model-bundle-P2XOZ76Q.js → model-bundle-MA4MMCRJ.js} +5 -5
- package/dist/{models-GPHBC2YJ.js → models-SEJ7LNSN.js} +5 -5
- package/dist/page-range-QHHFTL7X.cjs.map +1 -1
- package/dist/{parser-YIIRSBZS.js → parser-M5WHRX25.js} +40 -22
- package/dist/parser-M5WHRX25.js.map +1 -0
- package/dist/{parser-6SPYH3RU.cjs → parser-QILYPWSI.cjs} +211 -193
- package/dist/parser-QILYPWSI.cjs.map +1 -0
- package/dist/{parser-BVUFTU2O.js → parser-VH3F4EQU.js} +37 -19
- package/dist/parser-VH3F4EQU.js.map +1 -0
- package/dist/pdf-ocr-3SZUM3CN.cjs +16 -0
- package/dist/pdf-ocr-3SZUM3CN.cjs.map +1 -0
- package/dist/pdf-ocr-QB2TB5W5.js +18 -0
- package/dist/pdf-ocr-XC33L43D.js +15 -0
- package/dist/{profile-io-GU45HTYP.js → profile-io-5YB627EO.js} +3 -3
- package/dist/{rasterize-OWHFWG6R.js → rasterize-V2XHHS2I.js} +3 -3
- package/dist/{redact-doc-YTP6AAUP.js → redact-doc-5MK5L5IQ.js} +10 -10
- package/dist/{render-525LXDMV.js → render-SYZMHYK6.js} +6 -6
- package/dist/seal-IPKIQHYB.js +10 -0
- package/dist/{setup-NOXZLS7G.js → setup-ZPLJENSK.js} +3 -3
- package/dist/visual-RTTGNOAE.js +20 -0
- package/dist/{watch-NDRTCLVT.js → watch-FNWHVKK3.js} +11 -11
- package/package.json +1 -1
- package/dist/chunk-3M2BMQJY.js.map +0 -1
- package/dist/chunk-4NH45EEB.cjs.map +0 -1
- package/dist/chunk-5FCLQVT5.cjs.map +0 -1
- package/dist/chunk-BEJYCCDN.cjs.map +0 -1
- package/dist/chunk-ELNYQRBN.js.map +0 -1
- package/dist/chunk-GRHSVGSB.cjs.map +0 -1
- package/dist/chunk-HAPCN7BD.js.map +0 -1
- package/dist/chunk-KBIQGGNY.js.map +0 -1
- package/dist/chunk-MPAN6S5O.js.map +0 -1
- package/dist/chunk-MY6Q2HFW.js.map +0 -1
- package/dist/chunk-ZRXQDJPM.cjs.map +0 -1
- package/dist/chunks-P5Y7V73K.js +0 -10
- package/dist/formula-K7UF5MBF.cjs.map +0 -1
- package/dist/image-ocr-ZPQTFYSK.cjs.map +0 -1
- package/dist/parser-6SPYH3RU.cjs.map +0 -1
- package/dist/parser-BVUFTU2O.js.map +0 -1
- package/dist/parser-YIIRSBZS.js.map +0 -1
- package/dist/pdf-ocr-5YBMXW54.js +0 -18
- package/dist/pdf-ocr-EAVNHK3V.js +0 -15
- package/dist/pdf-ocr-J5GB5BW6.cjs +0 -16
- package/dist/pdf-ocr-J5GB5BW6.cjs.map +0 -1
- package/dist/seal-S4KJGZUI.js +0 -10
- package/dist/visual-AU3NH6EO.js +0 -20
- /package/dist/{-UNMTWAEI.js.map → -2UA2JHVA.js.map} +0 -0
- /package/dist/{chunk-B4PUQ4FP.js.map → chunk-2XHXABCX.js.map} +0 -0
- /package/dist/{chunk-EULS3PDF.js.map → chunk-4HRJISJF.js.map} +0 -0
- /package/dist/{chunk-N6MPDM55.js.map → chunk-6OCKAXIS.js.map} +0 -0
- /package/dist/{chunk-QXNQ2HNB.js.map → chunk-A2W2JQ3S.js.map} +0 -0
- /package/dist/{chunk-66YTQ3NQ.js.map → chunk-C4MVZXB5.js.map} +0 -0
- /package/dist/{chunk-GYHY2YLV.js.map → chunk-FGL4IGOT.js.map} +0 -0
- /package/dist/{chunk-FMP4POMD.js.map → chunk-GYTL6WT3.js.map} +0 -0
- /package/dist/{chunk-BQAJHAWR.js.map → chunk-KQIYC2ZU.js.map} +0 -0
- /package/dist/{chunk-AUFO5LVN.js.map → chunk-MDCTITUG.js.map} +0 -0
- /package/dist/{chunk-OVSCNCT6.js.map → chunk-O4CB7D2Q.js.map} +0 -0
- /package/dist/{chunk-3J3BJIOZ.js.map → chunk-SDRKHEVT.js.map} +0 -0
- /package/dist/{chunk-BHUYJBSQ.js.map → chunk-WJLICIYV.js.map} +0 -0
- /package/dist/{chunk-4CSY3QUO.js.map → chunk-YGKC6E6A.js.map} +0 -0
- /package/dist/{chunk-E6TJNN2U.js.map → chunk-ZDX5PIWR.js.map} +0 -0
- /package/dist/{chunks-P5Y7V73K.js.map → chunks-EBWJR55V.js.map} +0 -0
- /package/dist/{formula-VH545WNH.js.map → formula-MBLN2DG4.js.map} +0 -0
- /package/dist/{formula-3GB47YTH.js.map → formula-QZZDW5GW.js.map} +0 -0
- /package/dist/{image-ocr-6AKQWAU2.js.map → image-ocr-CJSO3QSR.js.map} +0 -0
- /package/dist/{image-ocr-VJFZCFAI.js.map → image-ocr-EREKAS47.js.map} +0 -0
- /package/dist/{model-bundle-P2XOZ76Q.js.map → model-bundle-MA4MMCRJ.js.map} +0 -0
- /package/dist/{models-GPHBC2YJ.js.map → models-SEJ7LNSN.js.map} +0 -0
- /package/dist/{pdf-ocr-5YBMXW54.js.map → pdf-ocr-QB2TB5W5.js.map} +0 -0
- /package/dist/{pdf-ocr-EAVNHK3V.js.map → pdf-ocr-XC33L43D.js.map} +0 -0
- /package/dist/{profile-io-GU45HTYP.js.map → profile-io-5YB627EO.js.map} +0 -0
- /package/dist/{rasterize-OWHFWG6R.js.map → rasterize-V2XHHS2I.js.map} +0 -0
- /package/dist/{redact-doc-YTP6AAUP.js.map → redact-doc-5MK5L5IQ.js.map} +0 -0
- /package/dist/{render-525LXDMV.js.map → render-SYZMHYK6.js.map} +0 -0
- /package/dist/{seal-S4KJGZUI.js.map → seal-IPKIQHYB.js.map} +0 -0
- /package/dist/{setup-NOXZLS7G.js.map → setup-ZPLJENSK.js.map} +0 -0
- /package/dist/{visual-AU3NH6EO.js.map → visual-RTTGNOAE.js.map} +0 -0
- /package/dist/{watch-NDRTCLVT.js.map → watch-FNWHVKK3.js.map} +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
parseRenderStyles
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2XHXABCX.js";
|
|
5
5
|
import {
|
|
6
6
|
KordocError,
|
|
7
7
|
precheckZipSize
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-A2W2JQ3S.js";
|
|
9
9
|
|
|
10
10
|
// src/form/seal.ts
|
|
11
11
|
import JSZip from "jszip";
|
|
@@ -1057,4 +1057,4 @@ export {
|
|
|
1057
1057
|
patchZipEntries,
|
|
1058
1058
|
placeSealHwpx
|
|
1059
1059
|
};
|
|
1060
|
-
//# sourceMappingURL=chunk-
|
|
1060
|
+
//# sourceMappingURL=chunk-4HRJISJF.js.map
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
safeMax,
|
|
11
11
|
safeMin
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-A2W2JQ3S.js";
|
|
13
13
|
|
|
14
14
|
// src/pdf/line-extract.ts
|
|
15
15
|
import { OPS } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
@@ -655,19 +655,34 @@ function multiplyTransform(m, t) {
|
|
|
655
655
|
m[1] * t[4] + m[3] * t[5] + m[5]
|
|
656
656
|
];
|
|
657
657
|
}
|
|
658
|
-
function
|
|
658
|
+
function transformedRect(ctm, x, y, w, h) {
|
|
659
|
+
const corners = [[x, y], [x + w, y], [x, y + h], [x + w, y + h]];
|
|
660
|
+
const xs = corners.map(([u, v]) => ctm[0] * u + ctm[2] * v + ctm[4]);
|
|
661
|
+
const ys = corners.map(([u, v]) => ctm[1] * u + ctm[3] * v + ctm[5]);
|
|
662
|
+
return { x1: Math.min(...xs), y1: Math.min(...ys), x2: Math.max(...xs), y2: Math.max(...ys) };
|
|
663
|
+
}
|
|
664
|
+
function intersect(a, b) {
|
|
665
|
+
return b ? { x1: Math.max(a.x1, b.x1), y1: Math.max(a.y1, b.y1), x2: Math.min(a.x2, b.x2), y2: Math.min(a.y2, b.y2) } : a;
|
|
666
|
+
}
|
|
667
|
+
function extractImageRegions(fnArray, argsArray, respectClip = false) {
|
|
659
668
|
const regions = [];
|
|
660
669
|
let ctm = [1, 0, 0, 1, 0, 0];
|
|
670
|
+
let clip = null;
|
|
661
671
|
const stack = [];
|
|
672
|
+
let pathRect;
|
|
673
|
+
let pendingClip = false;
|
|
662
674
|
for (let i = 0; i < fnArray.length; i++) {
|
|
663
675
|
const op = fnArray[i];
|
|
664
676
|
switch (op) {
|
|
665
677
|
case OPS2.save:
|
|
666
|
-
stack.push(ctm);
|
|
678
|
+
stack.push({ ctm, clip });
|
|
667
679
|
break;
|
|
668
|
-
case OPS2.restore:
|
|
669
|
-
|
|
680
|
+
case OPS2.restore: {
|
|
681
|
+
const state = stack.pop();
|
|
682
|
+
ctm = state?.ctm ?? [1, 0, 0, 1, 0, 0];
|
|
683
|
+
clip = state?.clip ?? null;
|
|
670
684
|
break;
|
|
685
|
+
}
|
|
671
686
|
case OPS2.transform: {
|
|
672
687
|
const t = argsArray[i];
|
|
673
688
|
if (Array.isArray(t) && t.length >= 6) ctm = multiplyTransform(ctm, t);
|
|
@@ -675,28 +690,44 @@ function extractImageRegions(fnArray, argsArray) {
|
|
|
675
690
|
}
|
|
676
691
|
// Form XObject 는 /Matrix 공간에서 그린다 — pdfjs 인자 [matrix, bbox], End 에서 복원 (line-extract.ts 와 같음)
|
|
677
692
|
case OPS2.paintFormXObjectBegin: {
|
|
678
|
-
stack.push(ctm);
|
|
693
|
+
stack.push({ ctm, clip });
|
|
679
694
|
const m = argsArray[i]?.[0];
|
|
680
695
|
if (Array.isArray(m) && m.length >= 6) ctm = multiplyTransform(ctm, m);
|
|
681
696
|
break;
|
|
682
697
|
}
|
|
683
|
-
case OPS2.paintFormXObjectEnd:
|
|
684
|
-
|
|
698
|
+
case OPS2.paintFormXObjectEnd: {
|
|
699
|
+
const state = stack.pop();
|
|
700
|
+
ctm = state?.ctm ?? [1, 0, 0, 1, 0, 0];
|
|
701
|
+
clip = state?.clip ?? null;
|
|
702
|
+
break;
|
|
703
|
+
}
|
|
704
|
+
case OPS2.constructPath: {
|
|
705
|
+
const [ops, coords] = argsArray[i];
|
|
706
|
+
pathRect = pathRect === void 0 && ops?.length === 1 && ops[0] === OPS2.rectangle && coords?.length >= 4 ? transformedRect(ctm, coords[0], coords[1], coords[2], coords[3]) : null;
|
|
707
|
+
break;
|
|
708
|
+
}
|
|
709
|
+
case OPS2.clip:
|
|
710
|
+
case OPS2.eoClip:
|
|
711
|
+
pendingClip = true;
|
|
712
|
+
break;
|
|
713
|
+
case OPS2.endPath:
|
|
714
|
+
case OPS2.stroke:
|
|
715
|
+
case OPS2.closeStroke:
|
|
716
|
+
case OPS2.fill:
|
|
717
|
+
case OPS2.eoFill:
|
|
718
|
+
case OPS2.fillStroke:
|
|
719
|
+
case OPS2.eoFillStroke:
|
|
720
|
+
case OPS2.closeFillStroke:
|
|
721
|
+
case OPS2.closeEOFillStroke:
|
|
722
|
+
if (respectClip && pendingClip && pathRect) clip = intersect(pathRect, clip);
|
|
723
|
+
pathRect = void 0;
|
|
724
|
+
pendingClip = false;
|
|
685
725
|
break;
|
|
686
726
|
case OPS2.paintImageXObject:
|
|
687
727
|
case OPS2.paintInlineImageXObject:
|
|
688
728
|
case OPS2.paintImageMaskXObject:
|
|
689
729
|
case OPS2.paintImageXObjectRepeat: {
|
|
690
|
-
const
|
|
691
|
-
let x1 = Infinity, y1 = Infinity, x2 = -Infinity, y2 = -Infinity;
|
|
692
|
-
for (const [u, v] of corners) {
|
|
693
|
-
const x = ctm[0] * u + ctm[2] * v + ctm[4];
|
|
694
|
-
const y = ctm[1] * u + ctm[3] * v + ctm[5];
|
|
695
|
-
if (x < x1) x1 = x;
|
|
696
|
-
if (x > x2) x2 = x;
|
|
697
|
-
if (y < y1) y1 = y;
|
|
698
|
-
if (y > y2) y2 = y;
|
|
699
|
-
}
|
|
730
|
+
const { x1, y1, x2, y2 } = intersect(transformedRect(ctm, 0, 0, 1, 1), clip);
|
|
700
731
|
if (x2 - x1 > 0 && y2 - y1 > 0) regions.push({ x1, y1, x2, y2 });
|
|
701
732
|
break;
|
|
702
733
|
}
|
|
@@ -2205,6 +2236,10 @@ function cellLineFills(box, contentLeft, cellRight, lineRight, fontSize) {
|
|
|
2205
2236
|
// src/pdf/cell-text.ts
|
|
2206
2237
|
var REGION_LABELS = /* @__PURE__ */ new Set(["\uC11C\uC6B8", "\uBD80\uC0B0", "\uB300\uAD6C", "\uC778\uCC9C", "\uAD11\uC8FC", "\uB300\uC804", "\uC6B8\uC0B0", "\uC138\uC885", "\uACBD\uAE30", "\uAC15\uC6D0", "\uCDA9\uBD81", "\uCDA9\uB0A8", "\uC804\uBD81", "\uC804\uB0A8", "\uACBD\uBD81", "\uACBD\uB0A8", "\uC81C\uC8FC", "\uC804\uAD6D"]);
|
|
2207
2238
|
var CELL_PADDING = 2;
|
|
2239
|
+
function cleanCellText(text) {
|
|
2240
|
+
const stripped = text.replace(/^[\s]*[-–—]\s*\d+\s*[-–—][\s]*$/gm, "").trim();
|
|
2241
|
+
return stripped.split("\n").map((line) => collapseEvenSpacing(line)).join("\n");
|
|
2242
|
+
}
|
|
2208
2243
|
var SPACE_GAP_RATIO = 0.17;
|
|
2209
2244
|
function spaceGapThreshold(fontSize) {
|
|
2210
2245
|
return Math.max(fontSize * SPACE_GAP_RATIO, 1);
|
|
@@ -2214,11 +2249,12 @@ function mapTextToCells(items, cells) {
|
|
|
2214
2249
|
for (const cell of cells) {
|
|
2215
2250
|
result.set(cell, []);
|
|
2216
2251
|
}
|
|
2252
|
+
const candidates = items.length * cells.length >= 5e3 ? cellBandLookup(cells) : () => cells;
|
|
2217
2253
|
for (const item of items) {
|
|
2218
2254
|
const pad = CELL_PADDING;
|
|
2219
2255
|
let bestCell = null;
|
|
2220
2256
|
let bestScore = 0;
|
|
2221
|
-
for (const cell of
|
|
2257
|
+
for (const cell of candidates(item.y - pad, item.y + (item.h || item.fontSize) + pad)) {
|
|
2222
2258
|
const ix1 = Math.max(item.x, cell.bbox.x1 - pad);
|
|
2223
2259
|
const ix2 = Math.min(item.x + item.w, cell.bbox.x2 + pad);
|
|
2224
2260
|
const iy1 = Math.max(item.y, cell.bbox.y1 - pad);
|
|
@@ -2239,6 +2275,39 @@ function mapTextToCells(items, cells) {
|
|
|
2239
2275
|
keepWordsInOneCell(result);
|
|
2240
2276
|
return result;
|
|
2241
2277
|
}
|
|
2278
|
+
function cellBandLookup(cells) {
|
|
2279
|
+
const sorted = cells.map((cell, index) => ({ cell, index })).sort((a, b) => a.cell.bbox.y1 - b.cell.bbox.y1);
|
|
2280
|
+
const build = (start, end) => {
|
|
2281
|
+
let lo = Infinity, hi = -Infinity;
|
|
2282
|
+
for (let i = start; i < end; i++) {
|
|
2283
|
+
lo = Math.min(lo, sorted[i].cell.bbox.y1);
|
|
2284
|
+
hi = Math.max(hi, sorted[i].cell.bbox.y2);
|
|
2285
|
+
}
|
|
2286
|
+
const band = { start, end, lo, hi };
|
|
2287
|
+
if (end - start > 8) {
|
|
2288
|
+
const mid = start + end >> 1;
|
|
2289
|
+
band.left = build(start, mid);
|
|
2290
|
+
band.right = build(mid, end);
|
|
2291
|
+
}
|
|
2292
|
+
return band;
|
|
2293
|
+
};
|
|
2294
|
+
const root = build(0, sorted.length);
|
|
2295
|
+
return (lo, hi) => {
|
|
2296
|
+
const found = [];
|
|
2297
|
+
const visit = (band) => {
|
|
2298
|
+
if (band.hi <= lo || band.lo >= hi) return;
|
|
2299
|
+
if (band.left && band.right) {
|
|
2300
|
+
visit(band.left);
|
|
2301
|
+
visit(band.right);
|
|
2302
|
+
} else for (let i = band.start; i < band.end; i++) {
|
|
2303
|
+
const entry = sorted[i];
|
|
2304
|
+
if (entry.cell.bbox.y2 > lo && entry.cell.bbox.y1 < hi) found.push(entry);
|
|
2305
|
+
}
|
|
2306
|
+
};
|
|
2307
|
+
visit(root);
|
|
2308
|
+
return found.sort((a, b) => a.index - b.index).map((entry) => entry.cell);
|
|
2309
|
+
};
|
|
2310
|
+
}
|
|
2242
2311
|
function keepWordsInOneCell(result) {
|
|
2243
2312
|
const owner = /* @__PURE__ */ new Map();
|
|
2244
2313
|
for (const [cell, arr] of result) for (const it of arr) owner.set(it, cell);
|
|
@@ -2294,9 +2363,8 @@ function cellTextToString(items, wrap) {
|
|
|
2294
2363
|
}
|
|
2295
2364
|
}
|
|
2296
2365
|
lines.push(curLine);
|
|
2297
|
-
const merged = mergeSuperscriptRows(lines);
|
|
2298
|
-
const textLines = merged.map((
|
|
2299
|
-
const s = sortLineByX(line);
|
|
2366
|
+
const merged = mergeSuperscriptRows(lines).map((line) => sortLineByX(line));
|
|
2367
|
+
const textLines = merged.map((s) => {
|
|
2300
2368
|
if (s.length === 1) return s[0].text;
|
|
2301
2369
|
if (s.length === 2 && /^[가-힣]$/.test(s[0].text) && /^[가-힣]$/.test(s[1].text) && !!wrap?.lex && (wrap.lex.isWord(s[0].text + s[1].text) || wrap.lex.evidence(s[0].text, s[1].text) === "" || REGION_LABELS.has(s[0].text + s[1].text)) && s[1].x - (s[0].x + s[0].w) >= Math.max(s[0].fontSize, s[1].fontSize) * 1.5 && s[1].x + s[1].w - s[0].x >= wrap.box.x2 - wrap.box.x1 - Math.max(s[0].fontSize, s[1].fontSize) * 2) return s[0].text + s[1].text;
|
|
2302
2370
|
const evenSpaced = detectEvenSpacedItems(s, true);
|
|
@@ -2320,16 +2388,16 @@ function cellTextToString(items, wrap) {
|
|
|
2320
2388
|
}
|
|
2321
2389
|
return result;
|
|
2322
2390
|
});
|
|
2323
|
-
const scripted = (s) => tagScripts(s, merged
|
|
2391
|
+
const scripted = (s) => tagScripts(s, merged);
|
|
2324
2392
|
if (!wrap) return scripted(mergeCellTextLines(textLines));
|
|
2325
2393
|
let contentLeft = Infinity;
|
|
2326
2394
|
for (const it of items) if (it.x < contentLeft) contentLeft = it.x;
|
|
2327
|
-
const lineEnds = merged.map((
|
|
2328
|
-
const s = sortLineByX(line);
|
|
2395
|
+
const lineEnds = merged.map((s) => {
|
|
2329
2396
|
let right = -Infinity;
|
|
2330
2397
|
for (const it of s) if (it.x + it.w > right) right = it.x + it.w;
|
|
2331
2398
|
const first = s[0];
|
|
2332
|
-
|
|
2399
|
+
const visible = first.text.replace(/<\/?u>|~~/g, "");
|
|
2400
|
+
return { right, fontSize: first.fontSize, firstCharW: first.w / Math.max(1, [...visible].length) };
|
|
2333
2401
|
});
|
|
2334
2402
|
let cellRight = -Infinity;
|
|
2335
2403
|
for (const e of lineEnds) if (e.right > cellRight) cellRight = e.right;
|
|
@@ -2373,15 +2441,16 @@ function mergeSuperscriptRows(lines) {
|
|
|
2373
2441
|
function detectEvenSpacedItems(items, cellLine = false) {
|
|
2374
2442
|
const result = new Array(items.length).fill(false);
|
|
2375
2443
|
if (items.length < 3) return result;
|
|
2376
|
-
|
|
2377
|
-
|
|
2444
|
+
const visible = items.map((it) => it.text.replace(/<\/?u>|~~/g, ""));
|
|
2445
|
+
if (cellLine && visible.every((text) => /^[가-힣]$/.test(text)) && items.slice(1).every((it) => !it.hasSpaceBefore || it.syntheticSpace) && items.slice(1).every((it, k) => it.x - (items[k].x + items[k].w) >= it.fontSize * 0.1)) {
|
|
2446
|
+
markEvenRun(items, visible, result, 0, items.length);
|
|
2378
2447
|
if (result.some(Boolean)) return result;
|
|
2379
2448
|
}
|
|
2380
2449
|
let runStart = -1;
|
|
2381
2450
|
for (let i = 0; i < items.length; i++) {
|
|
2382
|
-
const isShortKorean = /^[가-힣]{1}$/.test(
|
|
2451
|
+
const isShortKorean = /^[가-힣]{1}$/.test(visible[i]) || /^[\d]{1}$/.test(visible[i]);
|
|
2383
2452
|
if (isShortKorean && runStart >= 0 && items[i].hasSpaceBefore) {
|
|
2384
|
-
if (i - runStart >= 3) markEvenRun(items, result, runStart, i);
|
|
2453
|
+
if (i - runStart >= 3) markEvenRun(items, visible, result, runStart, i);
|
|
2385
2454
|
runStart = i;
|
|
2386
2455
|
continue;
|
|
2387
2456
|
}
|
|
@@ -2389,7 +2458,7 @@ function detectEvenSpacedItems(items, cellLine = false) {
|
|
|
2389
2458
|
const gap = items[i].x - (items[i - 1].x + items[i - 1].w);
|
|
2390
2459
|
const maxRunGap = Math.max(items[i].fontSize * 3, 30);
|
|
2391
2460
|
if (gap > maxRunGap) {
|
|
2392
|
-
if (i - runStart >= 3) markEvenRun(items, result, runStart, i);
|
|
2461
|
+
if (i - runStart >= 3) markEvenRun(items, visible, result, runStart, i);
|
|
2393
2462
|
runStart = i;
|
|
2394
2463
|
continue;
|
|
2395
2464
|
}
|
|
@@ -2398,19 +2467,19 @@ function detectEvenSpacedItems(items, cellLine = false) {
|
|
|
2398
2467
|
if (runStart < 0) runStart = i;
|
|
2399
2468
|
} else {
|
|
2400
2469
|
if (runStart >= 0 && i - runStart >= 3) {
|
|
2401
|
-
markEvenRun(items, result, runStart, i);
|
|
2470
|
+
markEvenRun(items, visible, result, runStart, i);
|
|
2402
2471
|
}
|
|
2403
2472
|
runStart = -1;
|
|
2404
2473
|
}
|
|
2405
2474
|
}
|
|
2406
2475
|
if (runStart >= 0 && items.length - runStart >= 3) {
|
|
2407
|
-
markEvenRun(items, result, runStart, items.length);
|
|
2476
|
+
markEvenRun(items, visible, result, runStart, items.length);
|
|
2408
2477
|
}
|
|
2409
2478
|
return result;
|
|
2410
2479
|
}
|
|
2411
|
-
function markEvenRun(items, result, start, end) {
|
|
2480
|
+
function markEvenRun(items, visible, result, start, end) {
|
|
2412
2481
|
let dateOnly = true;
|
|
2413
|
-
for (let i = start; i < end; i++) if (!/^[년월일시분초]$/.test(
|
|
2482
|
+
for (let i = start; i < end; i++) if (!/^[년월일시분초]$/.test(visible[i])) {
|
|
2414
2483
|
dateOnly = false;
|
|
2415
2484
|
break;
|
|
2416
2485
|
}
|
|
@@ -2632,14 +2701,20 @@ function filterHiddenText(items, pageWidth, pageHeight, originX = 0, originY = 0
|
|
|
2632
2701
|
return { visible, hiddenCount };
|
|
2633
2702
|
}
|
|
2634
2703
|
function collapseEvenSpacing(text, whole = true) {
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2704
|
+
if (whole) {
|
|
2705
|
+
const tokens = text.split(" ");
|
|
2706
|
+
const visible = tokens.map((t) => t.replace(/<\/?u>|~~/g, ""));
|
|
2707
|
+
const singleCharCount = visible.filter((t) => t.length === 1).length;
|
|
2708
|
+
if (tokens.length >= 3 && singleCharCount / tokens.length >= 0.7 && !isDateUnitBlank(visible)) return tokens.join("");
|
|
2639
2709
|
}
|
|
2640
2710
|
return text.replace(
|
|
2641
2711
|
/(?<![^\s>])[가-힣](?: [가-힣\d]){2,}(?![^\s<])/g,
|
|
2642
|
-
(match) =>
|
|
2712
|
+
(match, offset) => {
|
|
2713
|
+
const before = text.slice(0, offset).replace(/(?:<\/?u>|~~)+$/, "");
|
|
2714
|
+
const after = text.slice(offset + match.length).replace(/^(?:<\/?u>|~~)+/, "");
|
|
2715
|
+
if (/\S$/.test(before) || /^\S/.test(after)) return match;
|
|
2716
|
+
return isDateUnitBlank(match.split(" ")) ? match : match.replace(/ /g, "");
|
|
2717
|
+
}
|
|
2643
2718
|
);
|
|
2644
2719
|
}
|
|
2645
2720
|
function isDateUnitBlank(tokens) {
|
|
@@ -5002,27 +5077,6 @@ function splitEdgeSpannedColumns(items, gapThreshold, depth) {
|
|
|
5002
5077
|
];
|
|
5003
5078
|
}
|
|
5004
5079
|
|
|
5005
|
-
// src/pdf/blank-fills.ts
|
|
5006
|
-
var FILL_EDGE_GAP = 6;
|
|
5007
|
-
var FILL_MAX_THICKNESS = 2;
|
|
5008
|
-
function fillBlanks(items, horizontals, verticals = []) {
|
|
5009
|
-
const widened = /* @__PURE__ */ new Map();
|
|
5010
|
-
const used = /* @__PURE__ */ new Set();
|
|
5011
|
-
for (const h of horizontals) {
|
|
5012
|
-
if (h.lineWidth > FILL_MAX_THICKNESS || Math.abs(h.y1 - h.y2) > 1) continue;
|
|
5013
|
-
const x1 = Math.min(h.x1, h.x2), x2 = Math.max(h.x1, h.x2);
|
|
5014
|
-
const row = items.filter((i) => i.y >= h.y1 && i.y - h.y1 <= Math.max(3, i.fontSize * 0.5));
|
|
5015
|
-
const left = row.find((i) => i.x + i.w <= x1 + 1 && x1 - (i.x + i.w) <= FILL_EDGE_GAP);
|
|
5016
|
-
const right = row.find((i) => i.x >= x2 - 1 && i.x - x2 <= FILL_EDGE_GAP);
|
|
5017
|
-
if (!left || !right || widened.has(left) || row.some((i) => i.x < x2 && i.x + i.w > x1) || x2 - x1 < 2 * left.fontSize) continue;
|
|
5018
|
-
if (verticals.some((v) => (Math.abs(v.x1 - x1) <= 3 || Math.abs(v.x1 - x2) <= 3) && Math.min(v.y1, v.y2) - 3 <= h.y1 && Math.max(v.y1, v.y2) + 3 >= h.y1)) continue;
|
|
5019
|
-
widened.set(left, { ...left, text: left.text.trimEnd() + " ", w: x2 - left.x });
|
|
5020
|
-
used.add(h);
|
|
5021
|
-
}
|
|
5022
|
-
if (!used.size) return { items, horizontals };
|
|
5023
|
-
return { items: items.map((i) => widened.get(i) ?? i), horizontals: horizontals.filter((h) => !used.has(h)) };
|
|
5024
|
-
}
|
|
5025
|
-
|
|
5026
5080
|
// src/pdf/two-column.ts
|
|
5027
5081
|
var GUTTER_SCAN_LO = 0.3;
|
|
5028
5082
|
var GUTTER_SCAN_HI = 0.7;
|
|
@@ -5257,6 +5311,55 @@ function orderByPanels(units, rectOf, gutters) {
|
|
|
5257
5311
|
return ordered;
|
|
5258
5312
|
}
|
|
5259
5313
|
|
|
5314
|
+
// src/pdf/image-panels.ts
|
|
5315
|
+
function splitImagePanels(items, figures) {
|
|
5316
|
+
if (figures.length === 0) return null;
|
|
5317
|
+
const rects = items.map((i) => ({ x: i.x, y: i.y, w: i.w, h: i.h > 0 ? i.h : i.fontSize }));
|
|
5318
|
+
const cuts = detectPanelGutters([...rects, ...figures]);
|
|
5319
|
+
if (!cuts || cuts.length !== 2 || items.some((i) => cuts.some((x) => i.x < x && i.x + i.w > x))) return null;
|
|
5320
|
+
const groups = [
|
|
5321
|
+
items.filter((i) => i.x + i.w <= cuts[0]),
|
|
5322
|
+
items.filter((i) => i.x >= cuts[0] && i.x + i.w <= cuts[1]),
|
|
5323
|
+
items.filter((i) => i.x >= cuts[1])
|
|
5324
|
+
];
|
|
5325
|
+
const rows = groupByY(items);
|
|
5326
|
+
const sharedRows = rows.filter((row) => new Set(row.map((i) => i.x >= cuts[1] ? 2 : i.x >= cuts[0] ? 1 : 0)).size === 3).length;
|
|
5327
|
+
if (sharedRows / Math.min(...groups.map((group) => groupByY(group).length)) > 0.65) return null;
|
|
5328
|
+
for (const row of rows) {
|
|
5329
|
+
const ordered = [...row].sort((a, b) => a.x - b.x);
|
|
5330
|
+
let start = ordered[0].x, end = start + ordered[0].w, height = ordered[0].h || ordered[0].fontSize;
|
|
5331
|
+
for (const i of ordered.slice(1)) {
|
|
5332
|
+
const h = i.h || i.fontSize;
|
|
5333
|
+
if (i.x - end > Math.max(height, h) * 2) start = i.x;
|
|
5334
|
+
end = Math.max(end, i.x + i.w);
|
|
5335
|
+
height = h;
|
|
5336
|
+
if (cuts.some((x) => start < x && end > x)) return null;
|
|
5337
|
+
}
|
|
5338
|
+
}
|
|
5339
|
+
return groups;
|
|
5340
|
+
}
|
|
5341
|
+
|
|
5342
|
+
// src/pdf/blank-fills.ts
|
|
5343
|
+
var FILL_EDGE_GAP = 6;
|
|
5344
|
+
var FILL_MAX_THICKNESS = 2;
|
|
5345
|
+
function fillBlanks(items, horizontals, verticals = []) {
|
|
5346
|
+
const widened = /* @__PURE__ */ new Map();
|
|
5347
|
+
const used = /* @__PURE__ */ new Set();
|
|
5348
|
+
for (const h of horizontals) {
|
|
5349
|
+
if (h.lineWidth > FILL_MAX_THICKNESS || Math.abs(h.y1 - h.y2) > 1) continue;
|
|
5350
|
+
const x1 = Math.min(h.x1, h.x2), x2 = Math.max(h.x1, h.x2);
|
|
5351
|
+
const row = items.filter((i) => i.y >= h.y1 && i.y - h.y1 <= Math.max(3, i.fontSize * 0.5));
|
|
5352
|
+
const left = row.find((i) => i.x + i.w <= x1 + 1 && x1 - (i.x + i.w) <= FILL_EDGE_GAP);
|
|
5353
|
+
const right = row.find((i) => i.x >= x2 - 1 && i.x - x2 <= FILL_EDGE_GAP);
|
|
5354
|
+
if (!left || !right || widened.has(left) || row.some((i) => i.x < x2 && i.x + i.w > x1) || x2 - x1 < 2 * left.fontSize) continue;
|
|
5355
|
+
if (verticals.some((v) => (Math.abs(v.x1 - x1) <= 3 || Math.abs(v.x1 - x2) <= 3) && Math.min(v.y1, v.y2) - 3 <= h.y1 && Math.max(v.y1, v.y2) + 3 >= h.y1)) continue;
|
|
5356
|
+
widened.set(left, { ...left, text: left.text.trimEnd() + " ", w: x2 - left.x });
|
|
5357
|
+
used.add(h);
|
|
5358
|
+
}
|
|
5359
|
+
if (!used.size) return { items, horizontals };
|
|
5360
|
+
return { items: items.map((i) => widened.get(i) ?? i), horizontals: horizontals.filter((h) => !used.has(h)) };
|
|
5361
|
+
}
|
|
5362
|
+
|
|
5260
5363
|
// src/pdf/columns.ts
|
|
5261
5364
|
function isProseSpread(items) {
|
|
5262
5365
|
if (items.length < 3) return false;
|
|
@@ -5502,8 +5605,8 @@ function markUnderlineItems(items, horizontals, verticals) {
|
|
|
5502
5605
|
if (items.length === 0 || horizontals.length === 0) return underlines;
|
|
5503
5606
|
for (const line of horizontals) {
|
|
5504
5607
|
if (line.lineWidth > UNDER_MAX_THICKNESS) continue;
|
|
5505
|
-
|
|
5506
|
-
if (isRepeatedSpanRule(line, horizontals)) continue;
|
|
5608
|
+
const enclosed = insideTallCell(line, verticals, 0);
|
|
5609
|
+
if (!enclosed && (touchesVertical(line, verticals) || isRepeatedSpanRule(line, horizontals))) continue;
|
|
5507
5610
|
const matches = [];
|
|
5508
5611
|
for (const item of items) {
|
|
5509
5612
|
const h = item.h > 0 ? item.h : item.fontSize;
|
|
@@ -5522,10 +5625,12 @@ function markUnderlineItems(items, horizontals, verticals) {
|
|
|
5522
5625
|
maxH = Math.max(maxH, m.h > 0 ? m.h : m.fontSize);
|
|
5523
5626
|
covered += m.w;
|
|
5524
5627
|
}
|
|
5628
|
+
const inset = enclosed && insideTallCell(line, verticals, maxH);
|
|
5629
|
+
if (enclosed && !inset && (touchesVertical(line, verticals) || isRepeatedSpanRule(line, horizontals))) continue;
|
|
5525
5630
|
const pad = Math.max(maxH * UNDER_OWNER_PAD_EM, UNDER_OWNER_PAD_MIN_PT);
|
|
5526
5631
|
if (line.x1 < x1 - pad || line.x2 > x2 + pad) continue;
|
|
5527
5632
|
if (covered < (line.x2 - line.x1) * UNDER_MIN_COVERAGE) continue;
|
|
5528
|
-
if (hasBoxTopPair(line, maxH, horizontals)) continue;
|
|
5633
|
+
if (hasBoxTopPair(line, maxH, horizontals, inset ? items : void 0)) continue;
|
|
5529
5634
|
matches.sort((a, b) => a.x - b.x);
|
|
5530
5635
|
let hole = false;
|
|
5531
5636
|
for (let i = 1; i < matches.length; i++) {
|
|
@@ -5540,6 +5645,18 @@ function markUnderlineItems(items, horizontals, verticals) {
|
|
|
5540
5645
|
}
|
|
5541
5646
|
return underlines;
|
|
5542
5647
|
}
|
|
5648
|
+
function insideTallCell(line, verticals, em) {
|
|
5649
|
+
let left = false, right = false;
|
|
5650
|
+
for (const v of verticals) {
|
|
5651
|
+
const lo = Math.min(v.y1, v.y2), hi = Math.max(v.y1, v.y2);
|
|
5652
|
+
if (lo > line.y1 || hi < line.y1) continue;
|
|
5653
|
+
if (v.x1 >= line.x1 - 0.5 && v.x1 <= line.x2 + 0.5) return false;
|
|
5654
|
+
if (hi - lo <= em * UNDER_BOX_PAIR_MAX_EM) continue;
|
|
5655
|
+
if (v.x1 < line.x1 - 0.5) left = true;
|
|
5656
|
+
if (v.x1 > line.x2 + 0.5) right = true;
|
|
5657
|
+
}
|
|
5658
|
+
return left && right;
|
|
5659
|
+
}
|
|
5543
5660
|
function touchesVertical(line, verticals) {
|
|
5544
5661
|
for (const v of verticals) {
|
|
5545
5662
|
if (v.x1 < line.x1 - UNDER_GRID_EPS || v.x1 > line.x2 + UNDER_GRID_EPS) continue;
|
|
@@ -5548,7 +5665,7 @@ function touchesVertical(line, verticals) {
|
|
|
5548
5665
|
}
|
|
5549
5666
|
return false;
|
|
5550
5667
|
}
|
|
5551
|
-
function hasBoxTopPair(line, maxH, horizontals) {
|
|
5668
|
+
function hasBoxTopPair(line, maxH, horizontals, cellItems) {
|
|
5552
5669
|
const w = line.x2 - line.x1;
|
|
5553
5670
|
if (w <= 0) return false;
|
|
5554
5671
|
for (const o of horizontals) {
|
|
@@ -5558,7 +5675,13 @@ function hasBoxTopPair(line, maxH, horizontals) {
|
|
|
5558
5675
|
const ow = o.x2 - o.x1;
|
|
5559
5676
|
if (ow <= 0) continue;
|
|
5560
5677
|
const overlap2 = Math.min(line.x2, o.x2) - Math.max(line.x1, o.x1);
|
|
5561
|
-
if (overlap2 / Math.max(w, ow)
|
|
5678
|
+
if (overlap2 / Math.max(w, ow) < UNDER_BOX_PAIR_OVERLAP) continue;
|
|
5679
|
+
const covered = cellItems?.reduce((sum, item) => {
|
|
5680
|
+
const below = item.y - o.y1;
|
|
5681
|
+
if (below < 0.5 || below > 3 || !item.text.trim()) return sum;
|
|
5682
|
+
return sum + Math.max(0, Math.min(o.x2, item.x + item.w) - Math.max(o.x1, item.x));
|
|
5683
|
+
}, 0) ?? 0;
|
|
5684
|
+
if (covered < ow * UNDER_MIN_COVERAGE) return true;
|
|
5562
5685
|
}
|
|
5563
5686
|
return false;
|
|
5564
5687
|
}
|
|
@@ -5639,21 +5762,21 @@ function rules(lines, dir) {
|
|
|
5639
5762
|
const sorted = [...lines].sort((a, b) => dir === "h" ? a.y1 - b.y1 : a.x1 - b.x1);
|
|
5640
5763
|
return { dir, pos: sorted.map((l) => dir === "h" ? l.y1 : l.x1), lines: sorted };
|
|
5641
5764
|
}
|
|
5642
|
-
function seen(r, at, a1, a2) {
|
|
5765
|
+
function seen(r, at, a1, a2, near = EDGE_NEAR2) {
|
|
5643
5766
|
const len = a2 - a1;
|
|
5644
5767
|
if (len <= 0) return false;
|
|
5645
|
-
const covered = coverage(r, at, a1, a2);
|
|
5768
|
+
const covered = coverage(r, at, a1, a2, near);
|
|
5646
5769
|
return covered >= len * EDGE_COVER && len - covered <= EDGE_SLACK;
|
|
5647
5770
|
}
|
|
5648
|
-
function coverage(r, at, a1, a2) {
|
|
5771
|
+
function coverage(r, at, a1, a2, near) {
|
|
5649
5772
|
let i = 0, j = r.pos.length;
|
|
5650
5773
|
while (i < j) {
|
|
5651
5774
|
const m = i + j >> 1;
|
|
5652
|
-
if (r.pos[m] < at -
|
|
5775
|
+
if (r.pos[m] < at - near) i = m + 1;
|
|
5653
5776
|
else j = m;
|
|
5654
5777
|
}
|
|
5655
5778
|
const spans = [];
|
|
5656
|
-
for (; i < r.pos.length && r.pos[i] <= at +
|
|
5779
|
+
for (; i < r.pos.length && r.pos[i] <= at + near; i++) {
|
|
5657
5780
|
const l = r.lines[i];
|
|
5658
5781
|
const l1 = r.dir === "h" ? Math.min(l.x1, l.x2) : Math.min(l.y1, l.y2), l2 = r.dir === "h" ? Math.max(l.x1, l.x2) : Math.max(l.y1, l.y2);
|
|
5659
5782
|
const lo = Math.max(a1, l1), hi = Math.min(a2, l2);
|
|
@@ -5673,10 +5796,10 @@ function coverage(r, at, a1, a2) {
|
|
|
5673
5796
|
}
|
|
5674
5797
|
return covered + e - s;
|
|
5675
5798
|
}
|
|
5676
|
-
function edgesOf(box, h, v) {
|
|
5799
|
+
function edgesOf(box, h, v, hNear = EDGE_NEAR2) {
|
|
5677
5800
|
return {
|
|
5678
|
-
t: seen(h, box.y2, box.x1, box.x2),
|
|
5679
|
-
b: seen(h, box.y1, box.x1, box.x2),
|
|
5801
|
+
t: seen(h, box.y2, box.x1, box.x2, hNear),
|
|
5802
|
+
b: seen(h, box.y1, box.x1, box.x2, hNear),
|
|
5680
5803
|
l: seen(v, box.x1, box.y1, box.y2),
|
|
5681
5804
|
r: seen(v, box.x2, box.y1, box.y2)
|
|
5682
5805
|
};
|
|
@@ -5685,7 +5808,10 @@ function recordClipCellEdges(grids, horizontals, verticals, nonRules) {
|
|
|
5685
5808
|
if (!grids.some((g) => g.cells)) return;
|
|
5686
5809
|
const h = rules(nonRules?.size ? horizontals.filter((l) => !nonRules.has(l)) : horizontals, "h");
|
|
5687
5810
|
const v = rules(nonRules?.size ? verticals.filter((l) => !nonRules.has(l)) : verticals, "v");
|
|
5688
|
-
for (const g of grids) for (const c of g.cells ?? [])
|
|
5811
|
+
for (const g of grids) for (const c of g.cells ?? []) {
|
|
5812
|
+
const near = c.filler ? Math.min(EDGE_NEAR2, (c.bbox.y2 - c.bbox.y1) / 3) : EDGE_NEAR2;
|
|
5813
|
+
CLIP_CELL_EDGES.set(c, edgesOf(c.bbox, h, v, near));
|
|
5814
|
+
}
|
|
5689
5815
|
}
|
|
5690
5816
|
function takeClipCellEdges(from, to) {
|
|
5691
5817
|
const e = CLIP_CELL_EDGES.get(from);
|
|
@@ -5697,6 +5823,36 @@ function joinCellEdges(a, b) {
|
|
|
5697
5823
|
CELL_EDGES.set(a, { t: u.t, b: d.b, l: u.l || d.l, r: u.r || d.r });
|
|
5698
5824
|
}
|
|
5699
5825
|
|
|
5826
|
+
// src/pdf/table-unit-row.ts
|
|
5827
|
+
var UNIT = /^\s*\(\s*단위\s*[::]/;
|
|
5828
|
+
function rebuildUnitLine(items, grid) {
|
|
5829
|
+
const nearby = items.filter((item) => item.y >= grid.bbox.y2 && item.y - grid.bbox.y2 <= 18 && item.x >= grid.bbox.x1 - 3 && item.x + item.w <= grid.bbox.x2 + 3);
|
|
5830
|
+
for (const y of [...new Set(nearby.map((item) => Math.round(item.y)))].sort((a, b) => a - b)) {
|
|
5831
|
+
const line = nearby.filter((item) => Math.abs(item.y - y) <= 1).sort((a, b) => a.x - b.x);
|
|
5832
|
+
if (UNIT.test(line.map((item) => item.text).join(""))) return line;
|
|
5833
|
+
}
|
|
5834
|
+
return [];
|
|
5835
|
+
}
|
|
5836
|
+
function prependUnitRow(cells, cols, line, usedItems) {
|
|
5837
|
+
const text = cleanCellText(line.map((item) => item.text).join(""));
|
|
5838
|
+
cells.unshift(Array.from({ length: cols }, (_, c) => ({ text: c === 0 ? text : "", colSpan: c === 0 ? cols : 1, rowSpan: 1 })));
|
|
5839
|
+
for (const cell of cells[0]) CELL_EDGES.set(cell, NO_EDGES);
|
|
5840
|
+
for (const item of line) usedItems.add(item);
|
|
5841
|
+
}
|
|
5842
|
+
function attachUnitRow(items, grid, cells, cols, usedItems) {
|
|
5843
|
+
const all = cells.flat();
|
|
5844
|
+
if (all.filter((c) => c.text.trim()).length * 2 < all.length || UNIT.test(cells[0]?.[0]?.text ?? "")) return false;
|
|
5845
|
+
const above = items.filter((it) => !usedItems.has(it) && it.y >= grid.bbox.y2 && it.y - grid.bbox.y2 <= 8 && it.x >= grid.bbox.x1 - 3 && it.x + it.w <= grid.bbox.x2 + 3);
|
|
5846
|
+
let nearest = Infinity;
|
|
5847
|
+
for (const it of above) nearest = Math.min(nearest, it.y);
|
|
5848
|
+
const line = above.filter((it) => Math.abs(it.y - nearest) <= 1).sort((a, b) => a.x - b.x);
|
|
5849
|
+
const text = line.map((it) => it.text).join("");
|
|
5850
|
+
const inset = line.length ? grid.bbox.x2 - (line[line.length - 1].x + line[line.length - 1].w) : 0;
|
|
5851
|
+
if (!line.length || !UNIT.test(text) || inset < 4.6 || inset > 5.6) return false;
|
|
5852
|
+
prependUnitRow(cells, cols, line, usedItems);
|
|
5853
|
+
return true;
|
|
5854
|
+
}
|
|
5855
|
+
|
|
5700
5856
|
// src/pdf/page-frame.ts
|
|
5701
5857
|
function isPageFrameGrid(grid, cells, pageWidth, pageHeight, items = []) {
|
|
5702
5858
|
const b = grid.bbox;
|
|
@@ -6421,8 +6577,9 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
|
|
|
6421
6577
|
const lineGrids = detectTables ? buildTableGrids(horizontals, verticals) : [];
|
|
6422
6578
|
const tableClipGrids = dropHeadBandClipGrids(dropInsetClipGrids(dropShadingClipGrids(clipGrids, lineGrids, extracted.fillRects, verticals), lineGrids), lineGrids);
|
|
6423
6579
|
const grids = [...tableClipGrids, ...dropGridsInside(lineGrids, tableClipGrids, clipResult.containers)];
|
|
6580
|
+
const figures = () => extractImageRegions(opList.fnArray, opList.argsArray, true).filter((r) => r.x2 - r.x1 >= 40 && r.y2 - r.y1 >= 40).map((r) => ({ x: r.x1, y: r.y1, w: r.x2 - r.x1, h: r.y2 - r.y1 }));
|
|
6424
6581
|
if (grids.length === 1 && grids[0].rowYs.length === 2 && grids[0].colXs.length === 2 && grids[0].bbox.x2 - grids[0].bbox.x1 > pageWidth * 1.2 && grids[0].bbox.y2 - grids[0].bbox.y1 > pageHeight * 1.2) {
|
|
6425
|
-
return extractPageBlocksFallback(items, pageNum, true, detectTables, lex);
|
|
6582
|
+
return extractPageBlocksFallback(items, pageNum, true, detectTables, lex, figures());
|
|
6426
6583
|
}
|
|
6427
6584
|
const ruled = detectTables && clipGrids.length === 0 ? detectRuledBandTables(horizontals, verticals, items, pageNum) : [];
|
|
6428
6585
|
if (detectTables && clipGrids.length === 0 && ruled.length === 0 && lineGrids.length === 0) ruled.push(...detectTextBoxTables(extracted.hiddenBoxes, items, pageNum));
|
|
@@ -6431,7 +6588,7 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
|
|
|
6431
6588
|
return extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, horizontals, verticals, imageRegions, lex, ruled, rawRules);
|
|
6432
6589
|
}
|
|
6433
6590
|
if (detectTables && stackedTableBands(items)) {
|
|
6434
|
-
return extractPageBlocksFallback(items, pageNum, true, detectTables, lex);
|
|
6591
|
+
return extractPageBlocksFallback(items, pageNum, true, detectTables, lex, figures());
|
|
6435
6592
|
}
|
|
6436
6593
|
const sidebar = splitSidebarTitleRegion(items);
|
|
6437
6594
|
if (sidebar && grids.every((grid) => grid.rowYs.length === 2 && grid.colXs.length === 2 && !items.some((item) => item.x + item.w / 2 >= grid.bbox.x1 && item.x + item.w / 2 <= grid.bbox.x2 && item.y + item.h / 2 >= grid.bbox.y1 && item.y + item.h / 2 <= grid.bbox.y2))) {
|
|
@@ -6441,8 +6598,7 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
|
|
|
6441
6598
|
const imageRegions = extractImageRegions(opList.fnArray, opList.argsArray).filter((r) => r.x2 - r.x1 >= 8 && r.y2 - r.y1 >= 8);
|
|
6442
6599
|
return extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, horizontals, verticals, imageRegions, lex, [], rawRules);
|
|
6443
6600
|
}
|
|
6444
|
-
|
|
6445
|
-
return extractPageBlocksFallback(items, pageNum, true, detectTables, lex, figures);
|
|
6601
|
+
return extractPageBlocksFallback(items, pageNum, true, detectTables, lex, figures());
|
|
6446
6602
|
}
|
|
6447
6603
|
var STRIKE_MAX_THICKNESS = 2;
|
|
6448
6604
|
var STRIKE_MAX_THICKNESS_RATIO = 0.25;
|
|
@@ -6545,10 +6701,6 @@ function isSparseProseGrid(table) {
|
|
|
6545
6701
|
const prose = filled.filter((t) => t.length >= 60 && /[.!?。]/.test(t)).reduce((n, t) => n + t.length, 0);
|
|
6546
6702
|
return prose >= chars * 0.6;
|
|
6547
6703
|
}
|
|
6548
|
-
function cleanCellText(text) {
|
|
6549
|
-
const stripped = text.replace(/^[\s]*[-–—]\s*\d+\s*[-–—][\s]*$/gm, "").trim();
|
|
6550
|
-
return stripped.split("\n").map((line) => collapseEvenSpacing(line)).join("\n");
|
|
6551
|
-
}
|
|
6552
6704
|
var FRAME_RECT_TOL = 1.5;
|
|
6553
6705
|
function takePendingNested(pending, cellBox, clipCell) {
|
|
6554
6706
|
const out = [];
|
|
@@ -6661,25 +6813,13 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
|
|
|
6661
6813
|
markImageCell(irGrid[cell.row][cell.col]);
|
|
6662
6814
|
}
|
|
6663
6815
|
if (cell.filler && !cellItems.length) FILLER_CELLS.add(irGrid[cell.row][cell.col]);
|
|
6664
|
-
if (
|
|
6816
|
+
if (cellItems.length) recordCellLines(irGrid[cell.row][cell.col], cellItems);
|
|
6665
6817
|
takeClipCellEdges(cell, irGrid[cell.row][cell.col]);
|
|
6666
6818
|
}
|
|
6667
6819
|
let finalGrid = irGrid;
|
|
6668
6820
|
let finalRows = numRows;
|
|
6669
6821
|
let rebuiltUsed = false;
|
|
6670
|
-
|
|
6671
|
-
let unitText = "";
|
|
6672
|
-
if (!grid.cells && numRows >= 3 && numRows <= 5 && numCols >= 3) {
|
|
6673
|
-
const nearby = items.filter((item) => item.y >= grid.bbox.y2 && item.y - grid.bbox.y2 <= 18 && item.x >= grid.bbox.x1 - 3 && item.x + item.w <= grid.bbox.x2 + 3);
|
|
6674
|
-
for (const y of [...new Set(nearby.map((item) => Math.round(item.y)))].sort((a, b) => a - b)) {
|
|
6675
|
-
const line = nearby.filter((item) => Math.abs(item.y - y) <= 1).sort((a, b) => a.x - b.x);
|
|
6676
|
-
const text = line.map((item) => item.text).join("");
|
|
6677
|
-
if (!/^\s*\(\s*단위\s*[::]/.test(text)) continue;
|
|
6678
|
-
unitLine = line;
|
|
6679
|
-
unitText = text;
|
|
6680
|
-
break;
|
|
6681
|
-
}
|
|
6682
|
-
}
|
|
6822
|
+
const unitLine = !grid.cells && numRows >= 3 && numRows <= 5 && numCols >= 3 ? rebuildUnitLine(items, grid) : [];
|
|
6683
6823
|
if (!grid.cells && numRows <= 5 && numCols >= 3 && !nestedAttached && (numRows <= 2 || unitLine.length > 0)) {
|
|
6684
6824
|
const rebuilt = normalizeUndersegmentedTable(irGrid, grid.colXs, textItems, grid.rowYs);
|
|
6685
6825
|
if (rebuilt) {
|
|
@@ -6694,23 +6834,10 @@ function extractBlocksWithGrids(items, pageNum, pageWidth, pageHeight, grids, ho
|
|
|
6694
6834
|
}
|
|
6695
6835
|
}
|
|
6696
6836
|
if (unitLine.length > 0 && rebuiltUsed && !/^\s*\(\s*단위\s*[::]/.test(finalGrid[0]?.[0]?.text ?? "")) {
|
|
6697
|
-
finalGrid
|
|
6837
|
+
prependUnitRow(finalGrid, numCols, unitLine, usedItems);
|
|
6698
6838
|
finalRows++;
|
|
6699
|
-
for (const item of unitLine) usedItems.add(item);
|
|
6700
|
-
}
|
|
6701
|
-
const filledCells = finalGrid.flat().filter((c) => c.text.trim()).length;
|
|
6702
|
-
if (!rebuiltUsed && filledCells * 2 >= finalGrid.flat().length && !/^\s*\(\s*단위\s*[::]/.test(finalGrid[0]?.[0]?.text ?? "")) {
|
|
6703
|
-
const above = items.filter((it) => !usedItems.has(it) && it.y >= grid.bbox.y2 && it.y - grid.bbox.y2 <= 8 && it.x >= grid.bbox.x1 - 3 && it.x + it.w <= grid.bbox.x2 + 3);
|
|
6704
|
-
const line = above.filter((it) => Math.abs(it.y - Math.min(...above.map((a) => a.y))) <= 1).sort((a, b) => a.x - b.x);
|
|
6705
|
-
const text = line.map((it) => it.text).join("");
|
|
6706
|
-
const inset = line.length ? grid.bbox.x2 - (line[line.length - 1].x + line[line.length - 1].w) : 0;
|
|
6707
|
-
if (line.length && /^\s*\(\s*단위\s*[::]/.test(text) && inset >= 4.6 && inset <= 5.6) {
|
|
6708
|
-
finalGrid.unshift(Array.from({ length: numCols }, (_, c) => ({ text: c === 0 ? cleanCellText(text) : "", colSpan: c === 0 ? numCols : 1, rowSpan: 1 })));
|
|
6709
|
-
if (grid.cells) for (const u of finalGrid[0]) CELL_EDGES.set(u, NO_EDGES);
|
|
6710
|
-
finalRows++;
|
|
6711
|
-
for (const item of line) usedItems.add(item);
|
|
6712
|
-
}
|
|
6713
6839
|
}
|
|
6840
|
+
if (!rebuiltUsed && attachUnitRow(items, grid, finalGrid, numCols, usedItems)) finalRows++;
|
|
6714
6841
|
let semanticOneColumn = false;
|
|
6715
6842
|
if (!grid.cells && numCols === 1 && numGridRows >= 2) {
|
|
6716
6843
|
const populatedRows = finalGrid.filter((row) => row[0]?.text.trim());
|
|
@@ -7159,6 +7286,8 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false, detectTable
|
|
|
7159
7286
|
syntheticSpace: i.syntheticSpace
|
|
7160
7287
|
}));
|
|
7161
7288
|
const textRects = items.map((i) => ({ x: i.x, y: i.y, w: i.w, h: i.h > 0 ? i.h : i.fontSize }));
|
|
7289
|
+
const imagePanels = fullPage ? splitImagePanels(items, figures) : null;
|
|
7290
|
+
if (imagePanels) return imagePanels.flatMap((group) => extractPageBlocksFallback(group, pageNum, false, detectTables, lex));
|
|
7162
7291
|
const earlyProseCut = fullPage && detectTables ? findTwoColumnProseCutX(clusterItems) ?? persistentGutter(textRects) ?? (figures.length > 0 ? detectColumnGutter([...textRects, ...figures]) : null) : null;
|
|
7163
7292
|
if (earlyProseCut !== null) {
|
|
7164
7293
|
const band = topTableBand(items);
|
|
@@ -7275,4 +7404,4 @@ export {
|
|
|
7275
7404
|
joinCellEdges,
|
|
7276
7405
|
extractPageBlocksWithLines
|
|
7277
7406
|
};
|
|
7278
|
-
//# sourceMappingURL=chunk-
|
|
7407
|
+
//# sourceMappingURL=chunk-4TSYMJDL.js.map
|