kordoc 4.0.7 → 4.1.0
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/LICENSE +21 -21
- package/README.md +837 -806
- package/dist/{-6HWEFXVV.js → -AS4IABL2.js} +24 -11
- package/dist/{chunk-BKWHX3RC.js → chunk-37HJHCPA.js} +24 -15
- package/dist/chunk-37HJHCPA.js.map +1 -0
- package/dist/{chunk-U25XGCNH.cjs → chunk-37VKMUST.cjs} +174 -25
- package/dist/chunk-37VKMUST.cjs.map +1 -0
- package/dist/{chunk-5OKHAJ62.js → chunk-4KI23VHA.js} +162 -13
- package/dist/chunk-4KI23VHA.js.map +1 -0
- package/dist/{chunk-6GBLFQMA.js → chunk-5RPYBC2Q.js} +1 -1
- package/dist/chunk-5RPYBC2Q.js.map +1 -0
- package/dist/{chunk-NGSHDBQR.js → chunk-AX2R5Q2N.js} +7 -4
- package/dist/chunk-AX2R5Q2N.js.map +1 -0
- package/dist/{chunk-X34YWRL5.cjs → chunk-DCZVOIEO.cjs} +1 -1
- package/dist/chunk-DCZVOIEO.cjs.map +1 -0
- package/dist/chunk-DZIXKL7E.js +145 -0
- package/dist/chunk-DZIXKL7E.js.map +1 -0
- package/dist/chunk-F2ZU3IZG.js +82 -0
- package/dist/chunk-F2ZU3IZG.js.map +1 -0
- package/dist/{chunk-AIQ3ISQU.js → chunk-GE43BE46.js} +1 -1
- package/dist/chunk-GE43BE46.js.map +1 -0
- package/dist/{chunk-Q7EN4EUJ.js → chunk-GQVSHGG4.js} +12 -4
- package/dist/chunk-GQVSHGG4.js.map +1 -0
- package/dist/chunk-GS7T56RP.cjs.map +1 -1
- package/dist/{chunk-TJJTLM76.js → chunk-L2XQQTOY.js} +1422 -1121
- package/dist/chunk-L2XQQTOY.js.map +1 -0
- package/dist/{chunk-3TBUDJDE.js → chunk-MOL7MDBG.js} +1 -1
- package/dist/chunk-MOL7MDBG.js.map +1 -0
- package/dist/{chunk-CNM75ZSX.js → chunk-O5VS7RIR.js} +2 -2
- package/dist/chunk-O5VS7RIR.js.map +1 -0
- package/dist/{chunk-2SN3CKME.js → chunk-SSTK6IKK.js} +18 -21
- package/dist/chunk-SSTK6IKK.js.map +1 -0
- package/dist/chunk-UOO7LSDG.js +152 -0
- package/dist/chunk-UOO7LSDG.js.map +1 -0
- package/dist/{chunk-ONXVBURQ.js → chunk-WO52HVQJ.js} +2 -2
- package/dist/chunk-WO52HVQJ.js.map +1 -0
- package/dist/{chunk-CFQLK3LM.js → chunk-YOO6ET6M.js} +7 -3
- package/dist/chunk-YOO6ET6M.js.map +1 -0
- package/dist/chunks-WVMGF7JL.js +10 -0
- package/dist/cli.js +173 -38
- package/dist/cli.js.map +1 -1
- package/dist/{detect-NTR2FUEG.js → detect-YEZX2XCF.js} +2 -2
- package/dist/{formula-ZYUDQHD3.cjs → formula-5NKVS2LR.cjs} +1 -1
- package/dist/formula-5NKVS2LR.cjs.map +1 -0
- package/dist/{formula-KOQV353G.js → formula-JCNF43NE.js} +1 -1
- package/dist/formula-JCNF43NE.js.map +1 -0
- package/dist/{formula-MEDGYQXS.js → formula-RXVSQPXI.js} +1 -1
- package/dist/formula-RXVSQPXI.js.map +1 -0
- package/dist/index.cjs +1932 -1397
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +106 -2
- package/dist/index.d.ts +106 -2
- package/dist/index.js +1626 -1091
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +275 -67
- package/dist/mcp.js.map +1 -1
- package/dist/page-range-737B4EZW.js +8 -0
- package/dist/page-range-LNMXJU6W.js +7 -0
- package/dist/page-range-P7SDW6LR.cjs +8 -0
- package/dist/page-range-P7SDW6LR.cjs.map +1 -0
- package/dist/{parser-E6U5TNAU.cjs → parser-N4A7UGDK.cjs} +314 -56
- package/dist/parser-N4A7UGDK.cjs.map +1 -0
- package/dist/{parser-5EHWYJMC.js → parser-PEOYBXBO.js} +287 -27
- package/dist/parser-PEOYBXBO.js.map +1 -0
- package/dist/{parser-UGB3NIVH.js → parser-XX4QTDFQ.js} +283 -25
- package/dist/parser-XX4QTDFQ.js.map +1 -0
- package/dist/{profile-io-CAKRPQRD.js → profile-io-PLDQFPJA.js} +3 -3
- package/dist/{provider-5K7O3Z2O.cjs → provider-4FAYHJ6N.cjs} +3 -3
- package/dist/provider-4FAYHJ6N.cjs.map +1 -0
- package/dist/{provider-H4WWSPOV.js → provider-C6IOGIS5.js} +3 -3
- package/dist/provider-C6IOGIS5.js.map +1 -0
- package/dist/{provider-7H4CPZYS.js → provider-UIBW2MIH.js} +3 -3
- package/dist/provider-UIBW2MIH.js.map +1 -0
- package/dist/rasterize-WWNQLKYW.js +40 -0
- package/dist/rasterize-WWNQLKYW.js.map +1 -0
- package/dist/redact-7ILEAUTS.js +12 -0
- package/dist/render-T7S6H6AN.js +10 -0
- package/dist/render-T7S6H6AN.js.map +1 -0
- package/dist/seal-7PTL6MXH.js +10 -0
- package/dist/seal-7PTL6MXH.js.map +1 -0
- package/dist/{setup-QSJ2INNS.js → setup-Q2PRE7UA.js} +5 -3
- package/dist/setup-Q2PRE7UA.js.map +1 -0
- package/dist/{watch-RMX427YR.js → watch-SFHXZALC.js} +78 -24
- package/dist/watch-SFHXZALC.js.map +1 -0
- package/package.json +97 -97
- package/dist/chunk-2SN3CKME.js.map +0 -1
- package/dist/chunk-3TBUDJDE.js.map +0 -1
- package/dist/chunk-5OKHAJ62.js.map +0 -1
- package/dist/chunk-6GBLFQMA.js.map +0 -1
- package/dist/chunk-AIQ3ISQU.js.map +0 -1
- package/dist/chunk-BKWHX3RC.js.map +0 -1
- package/dist/chunk-CFQLK3LM.js.map +0 -1
- package/dist/chunk-CNM75ZSX.js.map +0 -1
- package/dist/chunk-NGSHDBQR.js.map +0 -1
- package/dist/chunk-ONXVBURQ.js.map +0 -1
- package/dist/chunk-Q7EN4EUJ.js.map +0 -1
- package/dist/chunk-TJJTLM76.js.map +0 -1
- package/dist/chunk-U25XGCNH.cjs.map +0 -1
- package/dist/chunk-X34YWRL5.cjs.map +0 -1
- package/dist/formula-KOQV353G.js.map +0 -1
- package/dist/formula-MEDGYQXS.js.map +0 -1
- package/dist/formula-ZYUDQHD3.cjs.map +0 -1
- package/dist/page-range-CIRRJPXJ.js +0 -7
- package/dist/page-range-OF5I4PQY.js +0 -8
- package/dist/page-range-TPIRSA3J.cjs +0 -8
- package/dist/page-range-TPIRSA3J.cjs.map +0 -1
- package/dist/parser-5EHWYJMC.js.map +0 -1
- package/dist/parser-E6U5TNAU.cjs.map +0 -1
- package/dist/parser-UGB3NIVH.js.map +0 -1
- package/dist/provider-5K7O3Z2O.cjs.map +0 -1
- package/dist/provider-7H4CPZYS.js.map +0 -1
- package/dist/provider-H4WWSPOV.js.map +0 -1
- package/dist/render-P6663O4I.js +0 -10
- package/dist/seal-7PPTXKKV.js +0 -10
- package/dist/setup-QSJ2INNS.js.map +0 -1
- package/dist/watch-RMX427YR.js.map +0 -1
- /package/dist/{-6HWEFXVV.js.map → -AS4IABL2.js.map} +0 -0
- /package/dist/{detect-NTR2FUEG.js.map → chunks-WVMGF7JL.js.map} +0 -0
- /package/dist/{page-range-CIRRJPXJ.js.map → detect-YEZX2XCF.js.map} +0 -0
- /package/dist/{page-range-OF5I4PQY.js.map → page-range-737B4EZW.js.map} +0 -0
- /package/dist/{profile-io-CAKRPQRD.js.map → page-range-LNMXJU6W.js.map} +0 -0
- /package/dist/{render-P6663O4I.js.map → profile-io-PLDQFPJA.js.map} +0 -0
- /package/dist/{seal-7PPTXKKV.js.map → redact-7ILEAUTS.js.map} +0 -0
|
@@ -3,16 +3,19 @@ import {
|
|
|
3
3
|
HEADING_RATIO_H1,
|
|
4
4
|
HEADING_RATIO_H2,
|
|
5
5
|
HEADING_RATIO_H3,
|
|
6
|
-
|
|
7
|
-
} from "./chunk-
|
|
6
|
+
encodePng
|
|
7
|
+
} from "./chunk-UOO7LSDG.js";
|
|
8
8
|
import {
|
|
9
9
|
parsePageRange
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-MOL7MDBG.js";
|
|
11
|
+
import {
|
|
12
|
+
blocksToMarkdown
|
|
13
|
+
} from "./chunk-SSTK6IKK.js";
|
|
11
14
|
import {
|
|
12
15
|
KordocError,
|
|
13
16
|
safeMax,
|
|
14
17
|
safeMin
|
|
15
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-O5VS7RIR.js";
|
|
16
19
|
|
|
17
20
|
// src/pdf/line-extract.ts
|
|
18
21
|
import { OPS } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
@@ -580,6 +583,18 @@ function buildVertices(horizontals, verticals) {
|
|
|
580
583
|
}
|
|
581
584
|
function mergeVertices(vertices) {
|
|
582
585
|
if (vertices.length <= 1) return vertices;
|
|
586
|
+
let maxRadiusAll = 1;
|
|
587
|
+
for (const v of vertices) {
|
|
588
|
+
if (v.radius > maxRadiusAll) maxRadiusAll = v.radius;
|
|
589
|
+
}
|
|
590
|
+
const cell = Math.max(VERTEX_MERGE_FACTOR * maxRadiusAll, 1);
|
|
591
|
+
const buckets = /* @__PURE__ */ new Map();
|
|
592
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
593
|
+
const key = Math.floor(vertices[i].x / cell) + "," + Math.floor(vertices[i].y / cell);
|
|
594
|
+
const arr = buckets.get(key);
|
|
595
|
+
if (arr) arr.push(i);
|
|
596
|
+
else buckets.set(key, [i]);
|
|
597
|
+
}
|
|
583
598
|
const merged = [];
|
|
584
599
|
const used = new Array(vertices.length).fill(false);
|
|
585
600
|
for (let i = 0; i < vertices.length; i++) {
|
|
@@ -587,7 +602,20 @@ function mergeVertices(vertices) {
|
|
|
587
602
|
let sumX = vertices[i].x, sumY = vertices[i].y;
|
|
588
603
|
let maxRadius = vertices[i].radius;
|
|
589
604
|
let count = 1;
|
|
590
|
-
|
|
605
|
+
const cx = Math.floor(vertices[i].x / cell);
|
|
606
|
+
const cy = Math.floor(vertices[i].y / cell);
|
|
607
|
+
const candidates = [];
|
|
608
|
+
for (let dx = -1; dx <= 1; dx++) {
|
|
609
|
+
for (let dy = -1; dy <= 1; dy++) {
|
|
610
|
+
const arr = buckets.get(cx + dx + "," + (cy + dy));
|
|
611
|
+
if (!arr) continue;
|
|
612
|
+
for (const j of arr) {
|
|
613
|
+
if (j > i && !used[j]) candidates.push(j);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
candidates.sort((a, b) => a - b);
|
|
618
|
+
for (const j of candidates) {
|
|
591
619
|
if (used[j]) continue;
|
|
592
620
|
const mergeTol = VERTEX_MERGE_FACTOR * Math.max(maxRadius, vertices[j].radius);
|
|
593
621
|
if (Math.abs(vertices[i].x - vertices[j].x) <= mergeTol && Math.abs(vertices[i].y - vertices[j].y) <= mergeTol) {
|
|
@@ -814,6 +842,7 @@ function splitStackedGroup(group) {
|
|
|
814
842
|
}
|
|
815
843
|
return bands.filter((b) => b.length > 0);
|
|
816
844
|
}
|
|
845
|
+
var GROUP_BUCKET_CELL = 100;
|
|
817
846
|
function groupConnectedLines(lines) {
|
|
818
847
|
const parent = lines.map((_, i) => i);
|
|
819
848
|
function find(x) {
|
|
@@ -827,10 +856,34 @@ function groupConnectedLines(lines) {
|
|
|
827
856
|
const ra = find(a), rb = find(b);
|
|
828
857
|
if (ra !== rb) parent[ra] = rb;
|
|
829
858
|
}
|
|
859
|
+
const cellMap = /* @__PURE__ */ new Map();
|
|
830
860
|
for (let i = 0; i < lines.length; i++) {
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
861
|
+
const l = lines[i];
|
|
862
|
+
const cx1 = Math.floor((Math.min(l.x1, l.x2) - CONNECT_TOL) / GROUP_BUCKET_CELL);
|
|
863
|
+
const cx2 = Math.floor((Math.max(l.x1, l.x2) + CONNECT_TOL) / GROUP_BUCKET_CELL);
|
|
864
|
+
const cy1 = Math.floor((Math.min(l.y1, l.y2) - CONNECT_TOL) / GROUP_BUCKET_CELL);
|
|
865
|
+
const cy2 = Math.floor((Math.max(l.y1, l.y2) + CONNECT_TOL) / GROUP_BUCKET_CELL);
|
|
866
|
+
for (let cx = cx1; cx <= cx2; cx++) {
|
|
867
|
+
for (let cy = cy1; cy <= cy2; cy++) {
|
|
868
|
+
const key = cx + "," + cy;
|
|
869
|
+
const arr = cellMap.get(key);
|
|
870
|
+
if (arr) arr.push(i);
|
|
871
|
+
else cellMap.set(key, [i]);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
const tested = /* @__PURE__ */ new Set();
|
|
876
|
+
for (const arr of cellMap.values()) {
|
|
877
|
+
for (let a = 0; a < arr.length; a++) {
|
|
878
|
+
for (let b = a + 1; b < arr.length; b++) {
|
|
879
|
+
const i = Math.min(arr[a], arr[b]);
|
|
880
|
+
const j = Math.max(arr[a], arr[b]);
|
|
881
|
+
const key = i * lines.length + j;
|
|
882
|
+
if (tested.has(key)) continue;
|
|
883
|
+
tested.add(key);
|
|
884
|
+
if (linesIntersect(lines[i], lines[j])) {
|
|
885
|
+
union(i, j);
|
|
886
|
+
}
|
|
834
887
|
}
|
|
835
888
|
}
|
|
836
889
|
}
|
|
@@ -1223,6 +1276,172 @@ function normalizeUndersegmentedTable(originalCells, colXs, items) {
|
|
|
1223
1276
|
return rebuilt;
|
|
1224
1277
|
}
|
|
1225
1278
|
|
|
1279
|
+
// src/pdf/image-extract.ts
|
|
1280
|
+
import { OPS as OPS3, ImageKind } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
1281
|
+
var IMAGE_RESOLVE_TIMEOUT_MS = 5e3;
|
|
1282
|
+
function resolveImgData(page, objId) {
|
|
1283
|
+
const store = objId.startsWith("g_") ? page.commonObjs : page.objs;
|
|
1284
|
+
return new Promise((resolve) => {
|
|
1285
|
+
let done = false;
|
|
1286
|
+
const timer = setTimeout(() => {
|
|
1287
|
+
if (!done) {
|
|
1288
|
+
done = true;
|
|
1289
|
+
resolve(null);
|
|
1290
|
+
}
|
|
1291
|
+
}, IMAGE_RESOLVE_TIMEOUT_MS);
|
|
1292
|
+
try {
|
|
1293
|
+
store.get(objId, (data) => {
|
|
1294
|
+
if (!done) {
|
|
1295
|
+
done = true;
|
|
1296
|
+
clearTimeout(timer);
|
|
1297
|
+
resolve(data ?? null);
|
|
1298
|
+
}
|
|
1299
|
+
});
|
|
1300
|
+
} catch {
|
|
1301
|
+
if (!done) {
|
|
1302
|
+
done = true;
|
|
1303
|
+
clearTimeout(timer);
|
|
1304
|
+
resolve(null);
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
});
|
|
1308
|
+
}
|
|
1309
|
+
var MIN_DIM = 8;
|
|
1310
|
+
var MAX_PIXELS = 36e6;
|
|
1311
|
+
var MAX_IMAGES_PER_DOC = 200;
|
|
1312
|
+
var MAX_TOTAL_IMAGE_BYTES = 128 * 1024 * 1024;
|
|
1313
|
+
function createPdfImageState() {
|
|
1314
|
+
return { imageIndex: 0, totalBytes: 0, seen: /* @__PURE__ */ new Map(), capWarned: false };
|
|
1315
|
+
}
|
|
1316
|
+
function fnv1a(data) {
|
|
1317
|
+
let h = 2166136261;
|
|
1318
|
+
for (let i = 0; i < data.length; i++) {
|
|
1319
|
+
h ^= data[i];
|
|
1320
|
+
h = Math.imul(h, 16777619);
|
|
1321
|
+
}
|
|
1322
|
+
return h >>> 0;
|
|
1323
|
+
}
|
|
1324
|
+
function toRgba(img) {
|
|
1325
|
+
const { width: w, height: h, kind, data } = img;
|
|
1326
|
+
if (!data || !w || !h) return null;
|
|
1327
|
+
const rgba = new Uint8Array(w * h * 4);
|
|
1328
|
+
if (kind === ImageKind.RGBA_32BPP) {
|
|
1329
|
+
if (data.length < w * h * 4) return null;
|
|
1330
|
+
rgba.set(data.subarray(0, w * h * 4));
|
|
1331
|
+
return rgba;
|
|
1332
|
+
}
|
|
1333
|
+
if (kind === ImageKind.RGB_24BPP) {
|
|
1334
|
+
if (data.length < w * h * 3) return null;
|
|
1335
|
+
for (let i = 0, s = 0, d = 0; i < w * h; i++, s += 3, d += 4) {
|
|
1336
|
+
rgba[d] = data[s];
|
|
1337
|
+
rgba[d + 1] = data[s + 1];
|
|
1338
|
+
rgba[d + 2] = data[s + 2];
|
|
1339
|
+
rgba[d + 3] = 255;
|
|
1340
|
+
}
|
|
1341
|
+
return rgba;
|
|
1342
|
+
}
|
|
1343
|
+
if (kind === ImageKind.GRAYSCALE_1BPP) {
|
|
1344
|
+
const stride = w + 7 >> 3;
|
|
1345
|
+
if (data.length < stride * h) return null;
|
|
1346
|
+
for (let y = 0; y < h; y++) {
|
|
1347
|
+
for (let x = 0; x < w; x++) {
|
|
1348
|
+
const bit = data[y * stride + (x >> 3)] >> 7 - (x & 7) & 1;
|
|
1349
|
+
const v = bit ? 255 : 0;
|
|
1350
|
+
const d = (y * w + x) * 4;
|
|
1351
|
+
rgba[d] = v;
|
|
1352
|
+
rgba[d + 1] = v;
|
|
1353
|
+
rgba[d + 2] = v;
|
|
1354
|
+
rgba[d + 3] = 255;
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
return rgba;
|
|
1358
|
+
}
|
|
1359
|
+
return null;
|
|
1360
|
+
}
|
|
1361
|
+
async function extractPageImages(page, fnArray, argsArray, pageNumber, state, warnings) {
|
|
1362
|
+
const blocks = [];
|
|
1363
|
+
const images = [];
|
|
1364
|
+
const pageSeenIds = /* @__PURE__ */ new Set();
|
|
1365
|
+
for (let i = 0; i < fnArray.length; i++) {
|
|
1366
|
+
const op = fnArray[i];
|
|
1367
|
+
let imgData = null;
|
|
1368
|
+
let dedupeId = null;
|
|
1369
|
+
if (op === OPS3.paintImageXObject || op === OPS3.paintImageXObjectRepeat) {
|
|
1370
|
+
const objId = argsArray[i]?.[0];
|
|
1371
|
+
if (typeof objId !== "string" || pageSeenIds.has(objId)) continue;
|
|
1372
|
+
pageSeenIds.add(objId);
|
|
1373
|
+
dedupeId = objId;
|
|
1374
|
+
} else if (op !== OPS3.paintInlineImageXObject) {
|
|
1375
|
+
continue;
|
|
1376
|
+
}
|
|
1377
|
+
if (state.imageIndex >= MAX_IMAGES_PER_DOC || state.totalBytes >= MAX_TOTAL_IMAGE_BYTES) {
|
|
1378
|
+
if (!state.capWarned) {
|
|
1379
|
+
state.capWarned = true;
|
|
1380
|
+
warnings.push({ page: pageNumber, message: `\uC774\uBBF8\uC9C0 \uCD94\uCD9C \uC0C1\uD55C \uB3C4\uB2EC (${MAX_IMAGES_PER_DOC}\uAC1C/128MB) \u2014 \uC774\uD6C4 \uC774\uBBF8\uC9C0 \uC0DD\uB7B5`, code: "SKIPPED_IMAGE" });
|
|
1381
|
+
}
|
|
1382
|
+
continue;
|
|
1383
|
+
}
|
|
1384
|
+
if (dedupeId) {
|
|
1385
|
+
imgData = await resolveImgData(page, dedupeId);
|
|
1386
|
+
} else {
|
|
1387
|
+
imgData = argsArray[i]?.[0];
|
|
1388
|
+
}
|
|
1389
|
+
if (!imgData?.data || !imgData.width || !imgData.height) continue;
|
|
1390
|
+
const { width: w, height: h } = imgData;
|
|
1391
|
+
if (w < MIN_DIM || h < MIN_DIM) continue;
|
|
1392
|
+
if (w * h > MAX_PIXELS) {
|
|
1393
|
+
warnings.push({ page: pageNumber, message: `\uC774\uBBF8\uC9C0 \uD06C\uAE30 \uCD08\uACFC\uB85C \uCD94\uCD9C \uC0DD\uB7B5 (${w}\xD7${h})`, code: "SKIPPED_IMAGE" });
|
|
1394
|
+
continue;
|
|
1395
|
+
}
|
|
1396
|
+
const hash = `${w}x${h}k${imgData.kind ?? "?"}h${fnv1a(imgData.data)}${dedupeId ? "" : "inline"}`;
|
|
1397
|
+
if (state.seen.has(hash)) continue;
|
|
1398
|
+
const rgba = toRgba(imgData);
|
|
1399
|
+
if (!rgba) continue;
|
|
1400
|
+
const png = encodePng(w, h, rgba);
|
|
1401
|
+
state.imageIndex++;
|
|
1402
|
+
state.totalBytes += png.length;
|
|
1403
|
+
const filename = `image_${String(state.imageIndex).padStart(3, "0")}.png`;
|
|
1404
|
+
state.seen.set(hash, filename);
|
|
1405
|
+
images.push({ filename, data: png, mimeType: "image/png" });
|
|
1406
|
+
blocks.push({ type: "image", text: filename, pageNumber });
|
|
1407
|
+
}
|
|
1408
|
+
return { blocks, images };
|
|
1409
|
+
}
|
|
1410
|
+
function injectPageImageBlocks(blocks, pageImages) {
|
|
1411
|
+
if (pageImages.size === 0) return;
|
|
1412
|
+
const lastIndexForPage = /* @__PURE__ */ new Map();
|
|
1413
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
1414
|
+
const p = blocks[i].pageNumber;
|
|
1415
|
+
if (p !== void 0) lastIndexForPage.set(p, i);
|
|
1416
|
+
}
|
|
1417
|
+
const pageAtIndex = /* @__PURE__ */ new Map();
|
|
1418
|
+
for (const [p, last] of lastIndexForPage) pageAtIndex.set(last, p);
|
|
1419
|
+
const result = [];
|
|
1420
|
+
const injected = /* @__PURE__ */ new Set();
|
|
1421
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
1422
|
+
result.push(blocks[i]);
|
|
1423
|
+
const p = pageAtIndex.get(i);
|
|
1424
|
+
if (p !== void 0 && pageImages.has(p)) {
|
|
1425
|
+
result.push(...pageImages.get(p));
|
|
1426
|
+
injected.add(p);
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
for (const p of [...pageImages.keys()].sort((a, b) => a - b)) {
|
|
1430
|
+
if (injected.has(p)) continue;
|
|
1431
|
+
let at = result.length;
|
|
1432
|
+
for (let i = 0; i < result.length; i++) {
|
|
1433
|
+
const bp = result[i].pageNumber;
|
|
1434
|
+
if (bp !== void 0 && bp > p) {
|
|
1435
|
+
at = i;
|
|
1436
|
+
break;
|
|
1437
|
+
}
|
|
1438
|
+
}
|
|
1439
|
+
result.splice(at, 0, ...pageImages.get(p));
|
|
1440
|
+
}
|
|
1441
|
+
blocks.length = 0;
|
|
1442
|
+
blocks.push(...result);
|
|
1443
|
+
}
|
|
1444
|
+
|
|
1226
1445
|
// src/pdf/quality.ts
|
|
1227
1446
|
var RARE_JONG = /* @__PURE__ */ new Set([3, 5, 6, 9, 10, 11, 12, 13, 14, 15, 18, 24, 25, 26]);
|
|
1228
1447
|
var MOJIBAKE_MIN_HANGUL = 30;
|
|
@@ -2518,11 +2737,12 @@ function buildGridTable(lines, columns) {
|
|
|
2518
2737
|
if (filledCells < totalCells * 0.35 || merged.length < 2 || merged.length <= 3 && numCols >= 7) {
|
|
2519
2738
|
return merged.map((r) => r.filter((c) => c).join(" ")).join("\n");
|
|
2520
2739
|
}
|
|
2740
|
+
const escCell = (c) => c.replace(/\t/g, " ").replace(/\|/g, "\\|");
|
|
2521
2741
|
const md = [];
|
|
2522
|
-
md.push("| " + merged[0].join(" | ") + " |");
|
|
2742
|
+
md.push("| " + merged[0].map(escCell).join(" | ") + " |");
|
|
2523
2743
|
md.push("| " + merged[0].map(() => "---").join(" | ") + " |");
|
|
2524
2744
|
for (let r = 1; r < merged.length; r++) {
|
|
2525
|
-
md.push("| " + merged[r].join(" | ") + " |");
|
|
2745
|
+
md.push("| " + merged[r].map(escCell).join(" | ") + " |");
|
|
2526
2746
|
}
|
|
2527
2747
|
return md.join("\n");
|
|
2528
2748
|
}
|
|
@@ -2702,6 +2922,7 @@ function detectKoreanListBlocks(blocks) {
|
|
|
2702
2922
|
}
|
|
2703
2923
|
let familyStack = [];
|
|
2704
2924
|
let lastTopLevelList = null;
|
|
2925
|
+
let prevListIdx = -2;
|
|
2705
2926
|
const toRemove = /* @__PURE__ */ new Set();
|
|
2706
2927
|
for (let i = 0; i < blocks.length; i++) {
|
|
2707
2928
|
const b = blocks[i];
|
|
@@ -2730,7 +2951,7 @@ function detectKoreanListBlocks(blocks) {
|
|
|
2730
2951
|
if (depth === 0) {
|
|
2731
2952
|
blocks[i] = listBlock;
|
|
2732
2953
|
lastTopLevelList = listBlock;
|
|
2733
|
-
} else if (lastTopLevelList) {
|
|
2954
|
+
} else if (lastTopLevelList && i === prevListIdx + 1) {
|
|
2734
2955
|
if (!lastTopLevelList.children) lastTopLevelList.children = [];
|
|
2735
2956
|
lastTopLevelList.children.push(listBlock);
|
|
2736
2957
|
toRemove.add(i);
|
|
@@ -2738,6 +2959,7 @@ function detectKoreanListBlocks(blocks) {
|
|
|
2738
2959
|
blocks[i] = listBlock;
|
|
2739
2960
|
lastTopLevelList = listBlock;
|
|
2740
2961
|
}
|
|
2962
|
+
prevListIdx = i;
|
|
2741
2963
|
}
|
|
2742
2964
|
if (toRemove.size > 0) {
|
|
2743
2965
|
const sorted = [...toRemove].sort((a, b) => b - a);
|
|
@@ -2863,8 +3085,8 @@ function removeHeaderFooterBlocks(blocks, pageHeights, warnings) {
|
|
|
2863
3085
|
const blockTop = ph - (b.bbox.y + b.bbox.height);
|
|
2864
3086
|
const blockBottom = ph - b.bbox.y;
|
|
2865
3087
|
const entry = { blockIdx: bi, page: b.pageNumber, text: b.text.trim() };
|
|
2866
|
-
if (blockBottom <= ph * ZONE_RATIO)
|
|
2867
|
-
else if (blockTop >= ph * (1 - ZONE_RATIO))
|
|
3088
|
+
if (blockBottom <= ph * ZONE_RATIO) topEntries.push(entry);
|
|
3089
|
+
else if (blockTop >= ph * (1 - ZONE_RATIO)) bottomEntries.push(entry);
|
|
2868
3090
|
}
|
|
2869
3091
|
const removeSet = /* @__PURE__ */ new Set();
|
|
2870
3092
|
for (const entries of [topEntries, bottomEntries]) {
|
|
@@ -3037,6 +3259,8 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3037
3259
|
hasSpaceBefore: i.hasSpaceBefore
|
|
3038
3260
|
}));
|
|
3039
3261
|
const cellTextMap = mapTextToCells(textItems, cells);
|
|
3262
|
+
const assignedItems = /* @__PURE__ */ new Set();
|
|
3263
|
+
for (const arr of cellTextMap.values()) for (const it of arr) assignedItems.add(it);
|
|
3040
3264
|
const numRows = grid.rowYs.length - 1;
|
|
3041
3265
|
const numCols = grid.colXs.length - 1;
|
|
3042
3266
|
const irGrid = Array.from(
|
|
@@ -3056,9 +3280,11 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3056
3280
|
}
|
|
3057
3281
|
let finalGrid = irGrid;
|
|
3058
3282
|
let finalRows = numRows;
|
|
3283
|
+
let rebuiltUsed = false;
|
|
3059
3284
|
if (numRows <= 2 && numCols >= 3) {
|
|
3060
3285
|
const rebuilt = normalizeUndersegmentedTable(irGrid, grid.colXs, textItems);
|
|
3061
3286
|
if (rebuilt) {
|
|
3287
|
+
rebuiltUsed = true;
|
|
3062
3288
|
finalGrid = rebuilt.map((row) => row.map((rawText) => {
|
|
3063
3289
|
const cleaned = rawText.replace(/^[\s]*[-–—]\s*\d+\s*[-–—][\s]*$/gm, "").trim();
|
|
3064
3290
|
return {
|
|
@@ -3070,6 +3296,11 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3070
3296
|
finalRows = finalGrid.length;
|
|
3071
3297
|
}
|
|
3072
3298
|
}
|
|
3299
|
+
if (!rebuiltUsed) {
|
|
3300
|
+
for (let ti = 0; ti < textItems.length; ti++) {
|
|
3301
|
+
if (!assignedItems.has(textItems[ti])) usedItems.delete(tableItems[ti]);
|
|
3302
|
+
}
|
|
3303
|
+
}
|
|
3073
3304
|
const irTable = {
|
|
3074
3305
|
rows: finalRows,
|
|
3075
3306
|
cols: numCols,
|
|
@@ -3126,6 +3357,8 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3126
3357
|
}
|
|
3127
3358
|
remaining = remaining.filter((_, idx) => !usedClusterIndices.has(idx));
|
|
3128
3359
|
}
|
|
3360
|
+
const groupSizes = [];
|
|
3361
|
+
let finalTextBlocks = [];
|
|
3129
3362
|
if (remaining.length > 0) {
|
|
3130
3363
|
const allY = remaining.map((i) => i.y);
|
|
3131
3364
|
const pageH = safeMax(allY) - safeMin(allY);
|
|
@@ -3135,16 +3368,28 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
3135
3368
|
if (group.length === 0) continue;
|
|
3136
3369
|
const groupBlocks = extractPageBlocksFallback(group, pageNum);
|
|
3137
3370
|
for (const b of groupBlocks) textBlocks.push(b);
|
|
3371
|
+
groupSizes.push(groupBlocks.length);
|
|
3138
3372
|
}
|
|
3139
|
-
|
|
3140
|
-
for (const b of finalTextBlocks) blocks.push(b);
|
|
3373
|
+
finalTextBlocks = detectListBlocks(textBlocks);
|
|
3141
3374
|
}
|
|
3142
|
-
blocks.
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3375
|
+
const units = blocks.map((b) => [b]);
|
|
3376
|
+
let off = 0;
|
|
3377
|
+
for (const size of groupSizes) {
|
|
3378
|
+
const unit = finalTextBlocks.slice(off, off + size);
|
|
3379
|
+
off += size;
|
|
3380
|
+
if (unit.length > 0) units.push(unit);
|
|
3381
|
+
}
|
|
3382
|
+
const unitTopY = (u) => {
|
|
3383
|
+
let top = 0;
|
|
3384
|
+
for (const b of u) {
|
|
3385
|
+
if (b.bbox && b.bbox.y + b.bbox.height > top) top = b.bbox.y + b.bbox.height;
|
|
3386
|
+
}
|
|
3387
|
+
return top;
|
|
3388
|
+
};
|
|
3389
|
+
units.sort((a, b) => unitTopY(b) - unitTopY(a));
|
|
3390
|
+
const ordered = [];
|
|
3391
|
+
for (const u of units) for (const b of u) ordered.push(b);
|
|
3392
|
+
return mergeAdjacentTableBlocks(ordered);
|
|
3148
3393
|
}
|
|
3149
3394
|
return mergeAdjacentTableBlocks(blocks);
|
|
3150
3395
|
}
|
|
@@ -3390,7 +3635,7 @@ function mergeKoreanLines(text) {
|
|
|
3390
3635
|
|
|
3391
3636
|
// src/pdf/formula-ocr.ts
|
|
3392
3637
|
async function applyFormulaOcr(buffer, blocks, pageFilter, effectivePageCount, warnings, _onProgress) {
|
|
3393
|
-
const formulaMod = await import("./formula-
|
|
3638
|
+
const formulaMod = await import("./formula-JCNF43NE.js");
|
|
3394
3639
|
const { FormulaPipeline, ensureFormulaModels } = formulaMod;
|
|
3395
3640
|
await ensureFormulaModels((p) => {
|
|
3396
3641
|
if (p.phase === "download" && p.total) {
|
|
@@ -3585,6 +3830,9 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3585
3830
|
const pageHeights = /* @__PURE__ */ new Map();
|
|
3586
3831
|
const pagesWithLargeImage = /* @__PURE__ */ new Set();
|
|
3587
3832
|
const skippedImagePages = /* @__PURE__ */ new Map();
|
|
3833
|
+
const imageState = createPdfImageState();
|
|
3834
|
+
const extractedImages = [];
|
|
3835
|
+
const pageImageBlocks = /* @__PURE__ */ new Map();
|
|
3588
3836
|
let parsedPages = 0;
|
|
3589
3837
|
for (let i = 1; i <= effectivePageCount; i++) {
|
|
3590
3838
|
if (pageFilter && !pageFilter.has(i)) continue;
|
|
@@ -3622,9 +3870,19 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3622
3870
|
}
|
|
3623
3871
|
const pageBlocks = extractPageBlocksWithLines(visible, i, opList, viewport.width, viewport.height);
|
|
3624
3872
|
for (const b of pageBlocks) blocks.push(b);
|
|
3873
|
+
try {
|
|
3874
|
+
const { blocks: imgBlocks, images: pageImages } = await extractPageImages(page, opList.fnArray, opList.argsArray, i, imageState, warnings);
|
|
3875
|
+
if (imgBlocks.length > 0) pageImageBlocks.set(i, imgBlocks);
|
|
3876
|
+
extractedImages.push(...pageImages);
|
|
3877
|
+
} catch {
|
|
3878
|
+
}
|
|
3625
3879
|
let pageText = "";
|
|
3626
3880
|
for (const b of pageBlocks) {
|
|
3627
|
-
|
|
3881
|
+
let t = b.text || "";
|
|
3882
|
+
if (b.type === "table" && b.table) {
|
|
3883
|
+
const cellText = b.table.cells.map((row) => row.map((c) => c.text).join(" ")).join("\n");
|
|
3884
|
+
t = t ? t + "\n" + cellText : cellText;
|
|
3885
|
+
}
|
|
3628
3886
|
totalChars += t.replace(/\s/g, "").length;
|
|
3629
3887
|
totalTextBytes += t.length * 2;
|
|
3630
3888
|
pageText += pageText ? "\n" + t : t;
|
|
@@ -3643,11 +3901,11 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3643
3901
|
if (totalChars / Math.max(parsedPageCount, 1) < 10) {
|
|
3644
3902
|
if (options?.ocr) {
|
|
3645
3903
|
try {
|
|
3646
|
-
const { ocrPages } = await import("./provider-
|
|
3904
|
+
const { ocrPages } = await import("./provider-UIBW2MIH.js");
|
|
3647
3905
|
const ocrBlocks = await ocrPages(doc, options.ocr, pageFilter, effectivePageCount);
|
|
3648
3906
|
if (ocrBlocks.length > 0) {
|
|
3649
3907
|
const ocrMarkdown = ocrBlocks.map((b) => b.text || "").filter(Boolean).join("\n\n");
|
|
3650
|
-
return { markdown: ocrMarkdown, blocks: ocrBlocks, metadata, warnings, isImageBased: true, pageQuality, qualitySummary: summarizeDocumentQuality(pageQuality) };
|
|
3908
|
+
return { markdown: ocrMarkdown, blocks: ocrBlocks, metadata, warnings, isImageBased: true, pageQuality, qualitySummary: summarizeDocumentQuality(pageQuality), images: extractedImages.length > 0 ? extractedImages : void 0 };
|
|
3651
3909
|
}
|
|
3652
3910
|
} catch {
|
|
3653
3911
|
}
|
|
@@ -3684,6 +3942,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3684
3942
|
}
|
|
3685
3943
|
}
|
|
3686
3944
|
mergeCrossPageTables(blocks);
|
|
3945
|
+
injectPageImageBlocks(blocks, pageImageBlocks);
|
|
3687
3946
|
if (options?.formulaOcr && formulaBuffer) {
|
|
3688
3947
|
try {
|
|
3689
3948
|
await applyFormulaOcr(formulaBuffer, blocks, pageFilter, effectivePageCount, warnings, options.onProgress);
|
|
@@ -3712,7 +3971,8 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3712
3971
|
warnings: warnings.length > 0 ? warnings : void 0,
|
|
3713
3972
|
isImageBased: isImageBased || void 0,
|
|
3714
3973
|
pageQuality,
|
|
3715
|
-
qualitySummary: summarizeDocumentQuality(pageQuality)
|
|
3974
|
+
qualitySummary: summarizeDocumentQuality(pageQuality),
|
|
3975
|
+
images: extractedImages.length > 0 ? extractedImages : void 0
|
|
3716
3976
|
};
|
|
3717
3977
|
} finally {
|
|
3718
3978
|
await doc.destroy().catch(() => {
|
|
@@ -3762,4 +4022,4 @@ export {
|
|
|
3762
4022
|
parsePdfDocument,
|
|
3763
4023
|
removeHeaderFooterBlocks
|
|
3764
4024
|
};
|
|
3765
|
-
//# sourceMappingURL=parser-
|
|
4025
|
+
//# sourceMappingURL=parser-PEOYBXBO.js.map
|