kordoc 3.8.2 → 3.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/{-FEHSMPVO.js → -F5IXBLQQ.js} +3 -3
- package/dist/{chunk-553VTUVP.js → chunk-7J73IGMK.js} +2 -2
- package/dist/{chunk-DP37KF2X.js → chunk-B27QMVL7.js} +39 -4
- package/dist/chunk-B27QMVL7.js.map +1 -0
- package/dist/{chunk-JHZUFBUV.js → chunk-KIWKBRCJ.js} +2 -2
- package/dist/{chunk-YBPNKFJW.cjs → chunk-XL6O3VAY.cjs} +2 -2
- package/dist/{chunk-YBPNKFJW.cjs.map → chunk-XL6O3VAY.cjs.map} +1 -1
- package/dist/cli.js +4 -4
- package/dist/index.cjs +251 -216
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +38 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +3 -3
- package/dist/{parser-KNQDRLZQ.js → parser-6GP535ZB.js} +153 -7
- package/dist/parser-6GP535ZB.js.map +1 -0
- package/dist/{parser-NR2TYGO3.js → parser-TM3AS25T.js} +153 -7
- package/dist/parser-TM3AS25T.js.map +1 -0
- package/dist/{parser-NS4ZPD7B.cjs → parser-WWKYMRGJ.cjs} +177 -31
- package/dist/parser-WWKYMRGJ.cjs.map +1 -0
- package/dist/{watch-XCWADLPU.js → watch-HETTZ7BO.js} +3 -3
- package/package.json +2 -1
- package/dist/chunk-DP37KF2X.js.map +0 -1
- package/dist/parser-KNQDRLZQ.js.map +0 -1
- package/dist/parser-NR2TYGO3.js.map +0 -1
- package/dist/parser-NS4ZPD7B.cjs.map +0 -1
- /package/dist/{-FEHSMPVO.js.map → -F5IXBLQQ.js.map} +0 -0
- /package/dist/{chunk-553VTUVP.js.map → chunk-7J73IGMK.js.map} +0 -0
- /package/dist/{chunk-JHZUFBUV.js.map → chunk-KIWKBRCJ.js.map} +0 -0
- /package/dist/{watch-XCWADLPU.js.map → watch-HETTZ7BO.js.map} +0 -0
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
blocksToMarkdown,
|
|
7
7
|
safeMax,
|
|
8
8
|
safeMin
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-7J73IGMK.js";
|
|
10
10
|
import {
|
|
11
11
|
parsePageRange
|
|
12
12
|
} from "./chunk-GE43BE46.js";
|
|
@@ -1262,7 +1262,106 @@ function detectClusterTables(items, pageNum) {
|
|
|
1262
1262
|
}
|
|
1263
1263
|
}
|
|
1264
1264
|
}
|
|
1265
|
-
return results;
|
|
1265
|
+
return results.filter((r) => !isTwoColumnProse(r));
|
|
1266
|
+
}
|
|
1267
|
+
function isTwoColumnProse(r) {
|
|
1268
|
+
const t = r.table;
|
|
1269
|
+
if (t.rows < 8) return false;
|
|
1270
|
+
const dense = [];
|
|
1271
|
+
for (let c = 0; c < t.cols; c++) {
|
|
1272
|
+
const filled = t.cells.filter((row) => row[c]?.text.trim()).length;
|
|
1273
|
+
if (filled / t.rows >= 0.3) dense.push(c);
|
|
1274
|
+
}
|
|
1275
|
+
if (dense.length !== 2) return false;
|
|
1276
|
+
for (const c of dense) {
|
|
1277
|
+
const lens = t.cells.map((row) => row[c]?.text.replace(/\s+/g, "").length ?? 0).filter((n) => n > 0);
|
|
1278
|
+
const avg = lens.reduce((s, v) => s + v, 0) / (lens.length || 1);
|
|
1279
|
+
if (avg < 12) return false;
|
|
1280
|
+
}
|
|
1281
|
+
return findTwoColumnProseCutX([...r.usedItems]) !== null;
|
|
1282
|
+
}
|
|
1283
|
+
function findTwoColumnProseCutX(items) {
|
|
1284
|
+
const lines = groupByBaseline(items);
|
|
1285
|
+
if (lines.length < 8) return null;
|
|
1286
|
+
let minX = Infinity;
|
|
1287
|
+
let maxX = -Infinity;
|
|
1288
|
+
for (const i of items) {
|
|
1289
|
+
if (i.x < minX) minX = i.x;
|
|
1290
|
+
if (i.x + i.w > maxX) maxX = i.x + i.w;
|
|
1291
|
+
}
|
|
1292
|
+
if (!Number.isFinite(maxX - minX)) return null;
|
|
1293
|
+
if (maxX - minX < 100) return null;
|
|
1294
|
+
const lo = minX + (maxX - minX) * 0.3;
|
|
1295
|
+
const hi = minX + (maxX - minX) * 0.7;
|
|
1296
|
+
const step = Math.max(2, (hi - lo) / 400);
|
|
1297
|
+
let cutX = 0;
|
|
1298
|
+
let bestCover = Infinity;
|
|
1299
|
+
for (let x = lo; x <= hi; x += step) {
|
|
1300
|
+
let cover = 0;
|
|
1301
|
+
for (const line of lines) {
|
|
1302
|
+
if (line.items.some((i) => i.x < x && i.x + i.w > x)) cover++;
|
|
1303
|
+
}
|
|
1304
|
+
if (cover < bestCover) {
|
|
1305
|
+
bestCover = cover;
|
|
1306
|
+
cutX = x;
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
if (bestCover / lines.length > 0.15) return null;
|
|
1310
|
+
const left = [];
|
|
1311
|
+
const right = [];
|
|
1312
|
+
let twoSide = 0;
|
|
1313
|
+
for (const line of lines) {
|
|
1314
|
+
let hasL = false;
|
|
1315
|
+
let hasR = false;
|
|
1316
|
+
for (const i of line.items) {
|
|
1317
|
+
if (i.x + i.w <= cutX) {
|
|
1318
|
+
left.push(i);
|
|
1319
|
+
hasL = true;
|
|
1320
|
+
} else if (i.x >= cutX) {
|
|
1321
|
+
right.push(i);
|
|
1322
|
+
hasR = true;
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
if (hasL && hasR) twoSide++;
|
|
1326
|
+
}
|
|
1327
|
+
if (twoSide / lines.length < 0.55) return null;
|
|
1328
|
+
if (left.length < 5 || right.length < 5) return null;
|
|
1329
|
+
const allText = items.map((i) => i.text).join("").replace(/\s+/g, "");
|
|
1330
|
+
const digits = (allText.match(/[\d,.%△—-]/g) || []).length;
|
|
1331
|
+
if (allText.length === 0 || digits / allText.length > 0.15) return null;
|
|
1332
|
+
const stats = [left, right].map((side) => {
|
|
1333
|
+
let sMinX = Infinity;
|
|
1334
|
+
let sMaxR = -Infinity;
|
|
1335
|
+
let fsSum = 0;
|
|
1336
|
+
const rowEnds = /* @__PURE__ */ new Map();
|
|
1337
|
+
const rowLens = /* @__PURE__ */ new Map();
|
|
1338
|
+
const rowFirst = /* @__PURE__ */ new Map();
|
|
1339
|
+
for (const i of side) {
|
|
1340
|
+
if (i.x < sMinX) sMinX = i.x;
|
|
1341
|
+
const rgt = i.x + i.w;
|
|
1342
|
+
if (rgt > sMaxR) sMaxR = rgt;
|
|
1343
|
+
fsSum += i.fontSize;
|
|
1344
|
+
const key = Math.round(i.y / 4);
|
|
1345
|
+
rowEnds.set(key, Math.max(rowEnds.get(key) ?? -Infinity, rgt));
|
|
1346
|
+
rowLens.set(key, (rowLens.get(key) ?? 0) + i.text.replace(/\s+/g, "").length);
|
|
1347
|
+
const f = rowFirst.get(key);
|
|
1348
|
+
if (!f || i.x < f.x) rowFirst.set(key, i);
|
|
1349
|
+
}
|
|
1350
|
+
const ends = [...rowEnds.values()].sort((a, b) => a - b);
|
|
1351
|
+
const p85 = ends[Math.floor(ends.length * 0.85)] ?? sMaxR;
|
|
1352
|
+
const fs = fsSum / side.length;
|
|
1353
|
+
const justified = ends.filter((e) => Math.abs(e - p85) <= fs).length / ends.length;
|
|
1354
|
+
const lens = [...rowLens.values()];
|
|
1355
|
+
const avgLen = lens.reduce((s, v) => s + v, 0) / (lens.length || 1);
|
|
1356
|
+
const markers = [...rowFirst.values()].filter((i) => /^[•▪◦‣∙·\-–—□■◇◆▶※*]/.test(i.text)).length;
|
|
1357
|
+
return { width: sMaxR - sMinX, justified, avgLen, markerRatio: markers / (rowFirst.size || 1) };
|
|
1358
|
+
});
|
|
1359
|
+
if (stats.some((s) => s.avgLen < 12)) return null;
|
|
1360
|
+
if (stats.some((s) => s.markerRatio > 0.1)) return null;
|
|
1361
|
+
const widthSym = Math.min(stats[0].width, stats[1].width) / Math.max(stats[0].width, stats[1].width);
|
|
1362
|
+
if (widthSym < 0.6) return null;
|
|
1363
|
+
if (Math.min(stats[0].justified, stats[1].justified) < 0.55) return null;
|
|
1364
|
+
return cutX;
|
|
1266
1365
|
}
|
|
1267
1366
|
function mergeEvenSpacedClusters(items) {
|
|
1268
1367
|
const originMap = /* @__PURE__ */ new Map();
|
|
@@ -2459,7 +2558,7 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
|
|
|
2459
2558
|
if (grids.length > 0) {
|
|
2460
2559
|
return extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals);
|
|
2461
2560
|
}
|
|
2462
|
-
return extractPageBlocksFallback(items, pageNum);
|
|
2561
|
+
return extractPageBlocksFallback(items, pageNum, true);
|
|
2463
2562
|
}
|
|
2464
2563
|
var STRIKE_MAX_THICKNESS = 2;
|
|
2465
2564
|
var STRIKE_MAX_THICKNESS_RATIO = 0.25;
|
|
@@ -2704,7 +2803,53 @@ function mergeAdjacentTableBlocks(blocks) {
|
|
|
2704
2803
|
}
|
|
2705
2804
|
return result;
|
|
2706
2805
|
}
|
|
2707
|
-
function
|
|
2806
|
+
function splitTwoColumnProse(items, cutX) {
|
|
2807
|
+
const left = [];
|
|
2808
|
+
const right = [];
|
|
2809
|
+
const cross = [];
|
|
2810
|
+
for (const i of items) {
|
|
2811
|
+
if (i.x + i.w <= cutX) left.push(i);
|
|
2812
|
+
else if (i.x >= cutX) right.push(i);
|
|
2813
|
+
else cross.push(i);
|
|
2814
|
+
}
|
|
2815
|
+
if (cross.length === 0) {
|
|
2816
|
+
return [left, right].filter((g2) => g2.length > 0);
|
|
2817
|
+
}
|
|
2818
|
+
cross.sort((a, b) => b.y - a.y);
|
|
2819
|
+
const crossLines = [];
|
|
2820
|
+
for (const c of cross) {
|
|
2821
|
+
const last = crossLines[crossLines.length - 1];
|
|
2822
|
+
if (last && Math.abs(last[0].y - c.y) <= 3) last.push(c);
|
|
2823
|
+
else crossLines.push([c]);
|
|
2824
|
+
}
|
|
2825
|
+
const bandItem = (arr) => arr.filter((i) => {
|
|
2826
|
+
for (const cl of crossLines) {
|
|
2827
|
+
if (Math.abs(cl[0].y - i.y) <= 3) {
|
|
2828
|
+
cl.push(i);
|
|
2829
|
+
return false;
|
|
2830
|
+
}
|
|
2831
|
+
}
|
|
2832
|
+
return true;
|
|
2833
|
+
});
|
|
2834
|
+
const leftRest = bandItem(left);
|
|
2835
|
+
const rightRest = bandItem(right);
|
|
2836
|
+
const boundYs = crossLines.map((cl) => cl[0].y);
|
|
2837
|
+
const bandOf = (y) => {
|
|
2838
|
+
let k = 0;
|
|
2839
|
+
while (k < boundYs.length && y < boundYs[k]) k++;
|
|
2840
|
+
return k;
|
|
2841
|
+
};
|
|
2842
|
+
const groups = [];
|
|
2843
|
+
for (let k = 0; k <= crossLines.length; k++) {
|
|
2844
|
+
const L = leftRest.filter((i) => bandOf(i.y) === k);
|
|
2845
|
+
const R = rightRest.filter((i) => bandOf(i.y) === k);
|
|
2846
|
+
if (L.length > 0) groups.push(L);
|
|
2847
|
+
if (R.length > 0) groups.push(R);
|
|
2848
|
+
if (k < crossLines.length) groups.push(crossLines[k]);
|
|
2849
|
+
}
|
|
2850
|
+
return groups;
|
|
2851
|
+
}
|
|
2852
|
+
function extractPageBlocksFallback(items, pageNum, fullPage = false) {
|
|
2708
2853
|
if (items.length === 0) return [];
|
|
2709
2854
|
const blocks = [];
|
|
2710
2855
|
const clusterItems = items.map((i) => ({
|
|
@@ -2745,8 +2890,9 @@ function extractPageBlocksFallback(items, pageNum) {
|
|
|
2745
2890
|
return by - ay;
|
|
2746
2891
|
});
|
|
2747
2892
|
} else {
|
|
2893
|
+
const proseCutX = fullPage ? findTwoColumnProseCutX(items) : null;
|
|
2748
2894
|
const allYLines = mergeSuperscriptLines(groupByY(items));
|
|
2749
|
-
const columns = detectColumns(allYLines);
|
|
2895
|
+
const columns = proseCutX !== null ? null : detectColumns(allYLines);
|
|
2750
2896
|
if (columns && columns.length >= 3) {
|
|
2751
2897
|
const tableText = extractWithColumns(allYLines, columns);
|
|
2752
2898
|
const bbox = computeBBox(items, pageNum);
|
|
@@ -2755,7 +2901,7 @@ function extractPageBlocksFallback(items, pageNum) {
|
|
|
2755
2901
|
const allY = items.map((i) => i.y);
|
|
2756
2902
|
const pageHeight = safeMax(allY) - safeMin(allY);
|
|
2757
2903
|
const gapThreshold = Math.max(15, pageHeight * 0.03);
|
|
2758
|
-
const orderedGroups = xyCutOrder(items, gapThreshold);
|
|
2904
|
+
const orderedGroups = proseCutX !== null ? splitTwoColumnProse(items, proseCutX) : xyCutOrder(items, gapThreshold);
|
|
2759
2905
|
for (const group of orderedGroups) {
|
|
2760
2906
|
if (group.length === 0) continue;
|
|
2761
2907
|
const yLines = mergeSuperscriptLines(groupByY(group));
|
|
@@ -3210,4 +3356,4 @@ export {
|
|
|
3210
3356
|
parsePdfDocument,
|
|
3211
3357
|
removeHeaderFooterBlocks
|
|
3212
3358
|
};
|
|
3213
|
-
//# sourceMappingURL=parser-
|
|
3359
|
+
//# sourceMappingURL=parser-TM3AS25T.js.map
|