kordoc 3.11.0 → 3.12.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/README.md +6 -0
- package/dist/{-QMW2GDWP.js → -OPZIF3QT.js} +5 -5
- package/dist/{chunk-RCSDSN5Y.cjs → chunk-2C5GCXPJ.cjs} +2 -2
- package/dist/{chunk-RCSDSN5Y.cjs.map → chunk-2C5GCXPJ.cjs.map} +1 -1
- package/dist/{chunk-SNSAZ7FA.js → chunk-7Z43WEML.js} +2 -2
- package/dist/{chunk-O27B5IRL.js → chunk-BUDM6ULT.js} +2 -2
- package/dist/{chunk-GETZFABK.js → chunk-ILR7GF3W.js} +2 -2
- package/dist/{chunk-D4JKKSSI.js → chunk-NGKIAZ6G.js} +2 -2
- package/dist/{chunk-TUBD3EEF.js → chunk-RUYSNNYZ.js} +5 -5
- package/dist/cli.js +7 -7
- package/dist/index.cjs +118 -118
- package/dist/index.js +2 -2
- package/dist/mcp.js +5 -5
- package/dist/{parser-3EARWV2H.js → parser-5FSEFR3R.js} +38 -4
- package/dist/parser-5FSEFR3R.js.map +1 -0
- package/dist/{parser-STGI5I5K.js → parser-AWEGMHHV.js} +37 -3
- package/dist/parser-AWEGMHHV.js.map +1 -0
- package/dist/{parser-X34HD2KQ.cjs → parser-PCTX7LGN.cjs} +49 -15
- package/dist/parser-PCTX7LGN.cjs.map +1 -0
- package/dist/render-ATQNKOT2.js +9 -0
- package/dist/{watch-KVYJ46S6.js → watch-Y7BAYXJE.js} +5 -5
- package/package.json +1 -1
- package/dist/parser-3EARWV2H.js.map +0 -1
- package/dist/parser-STGI5I5K.js.map +0 -1
- package/dist/parser-X34HD2KQ.cjs.map +0 -1
- package/dist/render-FPWZ6YNZ.js +0 -9
- /package/dist/{-QMW2GDWP.js.map → -OPZIF3QT.js.map} +0 -0
- /package/dist/{chunk-SNSAZ7FA.js.map → chunk-7Z43WEML.js.map} +0 -0
- /package/dist/{chunk-O27B5IRL.js.map → chunk-BUDM6ULT.js.map} +0 -0
- /package/dist/{chunk-GETZFABK.js.map → chunk-ILR7GF3W.js.map} +0 -0
- /package/dist/{chunk-D4JKKSSI.js.map → chunk-NGKIAZ6G.js.map} +0 -0
- /package/dist/{chunk-TUBD3EEF.js.map → chunk-RUYSNNYZ.js.map} +0 -0
- /package/dist/{render-FPWZ6YNZ.js.map → render-ATQNKOT2.js.map} +0 -0
- /package/dist/{watch-KVYJ46S6.js.map → watch-Y7BAYXJE.js.map} +0 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _chunk2C5GCXPJcjs = require('./chunk-2C5GCXPJ.cjs');
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
var _chunkDCZVOIEOcjs = require('./chunk-DCZVOIEO.cjs');
|
|
@@ -240,10 +240,40 @@ var EDGE_MIN_SPAN = 12;
|
|
|
240
240
|
var EDGE_INSET = 15;
|
|
241
241
|
var EDGE_NEAR = 10;
|
|
242
242
|
var EDGE_CONNECT_TOL = 5;
|
|
243
|
+
var CHAIN_Y_TOL = 1.5;
|
|
244
|
+
var CHAIN_GAP = 3;
|
|
245
|
+
function chainCollinearRules(horizontals) {
|
|
246
|
+
if (horizontals.length <= 1) return horizontals;
|
|
247
|
+
const sorted = [...horizontals].sort((a, b) => a.y1 - b.y1 || a.x1 - b.x1);
|
|
248
|
+
const rules = [];
|
|
249
|
+
let bandStart = 0;
|
|
250
|
+
const flushBand = (end) => {
|
|
251
|
+
const band = sorted.slice(bandStart, end).sort((a, b) => a.x1 - b.x1);
|
|
252
|
+
let cur = { ...band[0] };
|
|
253
|
+
for (let i = 1; i < band.length; i++) {
|
|
254
|
+
const seg = band[i];
|
|
255
|
+
if (seg.x1 - cur.x2 <= CHAIN_GAP) {
|
|
256
|
+
if (seg.x2 > cur.x2) cur.x2 = seg.x2;
|
|
257
|
+
if (seg.lineWidth > cur.lineWidth) cur.lineWidth = seg.lineWidth;
|
|
258
|
+
} else {
|
|
259
|
+
rules.push(cur);
|
|
260
|
+
cur = { ...seg };
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
rules.push(cur);
|
|
264
|
+
};
|
|
265
|
+
for (let i = 1; i <= sorted.length; i++) {
|
|
266
|
+
if (i === sorted.length || sorted[i].y1 - sorted[bandStart].y1 > CHAIN_Y_TOL) {
|
|
267
|
+
flushBand(i);
|
|
268
|
+
bandStart = i;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return rules;
|
|
272
|
+
}
|
|
243
273
|
function closeOpenTableEdges(horizontals, verticals) {
|
|
244
274
|
if (horizontals.length < EDGE_MIN_RULES) return verticals;
|
|
245
275
|
const groups = [];
|
|
246
|
-
for (const hl of horizontals) {
|
|
276
|
+
for (const hl of chainCollinearRules(horizontals)) {
|
|
247
277
|
let placed = false;
|
|
248
278
|
for (const g2 of groups) {
|
|
249
279
|
if (Math.abs(g2[0].x1 - hl.x1) <= EDGE_ALIGN_TOL && Math.abs(g2[0].x2 - hl.x2) <= EDGE_ALIGN_TOL) {
|
|
@@ -2056,14 +2086,14 @@ function isProseSpread(items) {
|
|
|
2056
2086
|
for (let i = 1; i < sorted.length; i++) {
|
|
2057
2087
|
gaps.push(sorted[i].x - (sorted[i - 1].x + sorted[i - 1].w));
|
|
2058
2088
|
}
|
|
2059
|
-
const maxGap =
|
|
2089
|
+
const maxGap = _chunk2C5GCXPJcjs.safeMax.call(void 0, gaps);
|
|
2060
2090
|
const avgLen = items.reduce((s, i) => s + i.text.length, 0) / items.length;
|
|
2061
2091
|
return maxGap < 40 && avgLen < 5;
|
|
2062
2092
|
}
|
|
2063
2093
|
function detectColumns(yLines) {
|
|
2064
2094
|
const allItems = yLines.flat();
|
|
2065
2095
|
if (allItems.length === 0) return null;
|
|
2066
|
-
const pageWidth =
|
|
2096
|
+
const pageWidth = _chunk2C5GCXPJcjs.safeMax.call(void 0, allItems.map((i) => i.x + i.w)) - _chunk2C5GCXPJcjs.safeMin.call(void 0, allItems.map((i) => i.x));
|
|
2067
2097
|
if (pageWidth < 100) return null;
|
|
2068
2098
|
let bigoLineIdx = -1;
|
|
2069
2099
|
for (let i = 0; i < yLines.length; i++) {
|
|
@@ -2285,9 +2315,9 @@ function detectHeadings(blocks, medianFontSize) {
|
|
|
2285
2315
|
if (/^\d+$/.test(text)) continue;
|
|
2286
2316
|
const ratio = block.style.fontSize / medianFontSize;
|
|
2287
2317
|
let level = 0;
|
|
2288
|
-
if (ratio >=
|
|
2289
|
-
else if (ratio >=
|
|
2290
|
-
else if (ratio >=
|
|
2318
|
+
if (ratio >= _chunk2C5GCXPJcjs.HEADING_RATIO_H1) level = 1;
|
|
2319
|
+
else if (ratio >= _chunk2C5GCXPJcjs.HEADING_RATIO_H2) level = 2;
|
|
2320
|
+
else if (ratio >= _chunk2C5GCXPJcjs.HEADING_RATIO_H3) level = 3;
|
|
2291
2321
|
if (level > 0) {
|
|
2292
2322
|
block.type = "heading";
|
|
2293
2323
|
block.level = level;
|
|
@@ -2298,6 +2328,10 @@ function detectHeadings(blocks, medianFontSize) {
|
|
|
2298
2328
|
function shouldDemoteTable(table) {
|
|
2299
2329
|
const allCells = table.cells.flatMap((row) => row.map((c) => c.text.trim())).filter(Boolean);
|
|
2300
2330
|
const allText = allCells.join(" ");
|
|
2331
|
+
if (table.rows >= 2 && table.cols >= 2 && table.cells[0].every((c) => {
|
|
2332
|
+
const t = c.text.trim();
|
|
2333
|
+
return t.length > 0 && t.length <= 12 && !/[□■◆○●▶ㅇ<>]/.test(t);
|
|
2334
|
+
}) && table.cells.slice(1).some((row) => row.some((c) => c.text.trim() !== ""))) return false;
|
|
2301
2335
|
if (table.rows <= 3 && table.cols <= 3) {
|
|
2302
2336
|
const totalCells2 = table.rows * table.cols;
|
|
2303
2337
|
const emptyCells2 = totalCells2 - allCells.length;
|
|
@@ -2807,7 +2841,7 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
2807
2841
|
}
|
|
2808
2842
|
if (remaining.length > 0) {
|
|
2809
2843
|
const allY = remaining.map((i) => i.y);
|
|
2810
|
-
const pageH =
|
|
2844
|
+
const pageH = _chunk2C5GCXPJcjs.safeMax.call(void 0, allY) - _chunk2C5GCXPJcjs.safeMin.call(void 0, allY);
|
|
2811
2845
|
const groups = xyCutOrder(remaining, Math.max(15, pageH * 0.03));
|
|
2812
2846
|
const textBlocks = [];
|
|
2813
2847
|
for (const group of groups) {
|
|
@@ -2983,7 +3017,7 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false) {
|
|
|
2983
3017
|
blocks.push({ type: "paragraph", text: tableText, pageNumber: pageNum, bbox, style: dominantStyle(items) });
|
|
2984
3018
|
} else {
|
|
2985
3019
|
const allY = items.map((i) => i.y);
|
|
2986
|
-
const pageHeight =
|
|
3020
|
+
const pageHeight = _chunk2C5GCXPJcjs.safeMax.call(void 0, allY) - _chunk2C5GCXPJcjs.safeMin.call(void 0, allY);
|
|
2987
3021
|
const gapThreshold = Math.max(15, pageHeight * 0.03);
|
|
2988
3022
|
const orderedGroups = proseCutX !== null ? splitTwoColumnProse(items, proseCutX) : xyCutOrder(items, gapThreshold);
|
|
2989
3023
|
for (const group of orderedGroups) {
|
|
@@ -3236,7 +3270,7 @@ async function loadPdfWithTimeout(buffer) {
|
|
|
3236
3270
|
new Promise((_, reject) => {
|
|
3237
3271
|
timer = setTimeout(() => {
|
|
3238
3272
|
loadingTask.destroy();
|
|
3239
|
-
reject(new (0,
|
|
3273
|
+
reject(new (0, _chunk2C5GCXPJcjs.KordocError)("PDF \uB85C\uB529 \uD0C0\uC784\uC544\uC6C3 (30\uCD08 \uCD08\uACFC)"));
|
|
3240
3274
|
}, PDF_LOAD_TIMEOUT_MS);
|
|
3241
3275
|
})
|
|
3242
3276
|
]);
|
|
@@ -3249,7 +3283,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3249
3283
|
const doc = await loadPdfWithTimeout(buffer);
|
|
3250
3284
|
try {
|
|
3251
3285
|
const pageCount = doc.numPages;
|
|
3252
|
-
if (pageCount === 0) throw new (0,
|
|
3286
|
+
if (pageCount === 0) throw new (0, _chunk2C5GCXPJcjs.KordocError)("PDF\uC5D0 \uD398\uC774\uC9C0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
3253
3287
|
const metadata = { pageCount };
|
|
3254
3288
|
await extractPdfMetadata(doc, metadata);
|
|
3255
3289
|
const blocks = [];
|
|
@@ -3309,11 +3343,11 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3309
3343
|
pageText += pageText ? "\n" + t : t;
|
|
3310
3344
|
}
|
|
3311
3345
|
pageQuality.push(computePageQuality(i, pageText));
|
|
3312
|
-
if (totalTextBytes > MAX_TOTAL_TEXT) throw new (0,
|
|
3346
|
+
if (totalTextBytes > MAX_TOTAL_TEXT) throw new (0, _chunk2C5GCXPJcjs.KordocError)("\uD14D\uC2A4\uD2B8 \uCD94\uCD9C \uD06C\uAE30 \uCD08\uACFC");
|
|
3313
3347
|
parsedPages++;
|
|
3314
3348
|
_optionalChain([options, 'optionalAccess', _36 => _36.onProgress, 'optionalCall', _37 => _37(parsedPages, totalTarget)]);
|
|
3315
3349
|
} catch (pageErr) {
|
|
3316
|
-
if (pageErr instanceof
|
|
3350
|
+
if (pageErr instanceof _chunk2C5GCXPJcjs.KordocError) throw pageErr;
|
|
3317
3351
|
warnings.push({ page: i, message: `\uD398\uC774\uC9C0 ${i} \uD30C\uC2F1 \uC2E4\uD328: ${pageErr instanceof Error ? pageErr.message : "\uC54C \uC218 \uC5C6\uB294 \uC624\uB958"}`, code: "PARTIAL_PARSE" });
|
|
3318
3352
|
}
|
|
3319
3353
|
}
|
|
@@ -3381,7 +3415,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3381
3415
|
detectKoreanListBlocks(blocks);
|
|
3382
3416
|
const outline = blocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
|
|
3383
3417
|
sanitizeBlockControlChars(blocks);
|
|
3384
|
-
let markdown = cleanPdfText(
|
|
3418
|
+
let markdown = cleanPdfText(_chunk2C5GCXPJcjs.blocksToMarkdown.call(void 0, blocks));
|
|
3385
3419
|
return {
|
|
3386
3420
|
markdown,
|
|
3387
3421
|
blocks,
|
|
@@ -3440,4 +3474,4 @@ async function extractPdfMetadataOnly(buffer) {
|
|
|
3440
3474
|
|
|
3441
3475
|
|
|
3442
3476
|
exports.cleanPdfText = cleanPdfText; exports.detectKoreanListBlocks = detectKoreanListBlocks; exports.detectTableCaptions = detectTableCaptions; exports.extractPdfMetadataOnly = extractPdfMetadataOnly; exports.mergeCrossPageTables = mergeCrossPageTables; exports.parsePdfDocument = parsePdfDocument; exports.removeHeaderFooterBlocks = removeHeaderFooterBlocks;
|
|
3443
|
-
//# sourceMappingURL=parser-
|
|
3477
|
+
//# sourceMappingURL=parser-PCTX7LGN.cjs.map
|