kordoc 3.10.1 → 3.11.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/{-LPEXY73L.js → -QMW2GDWP.js} +5 -5
- package/dist/{chunk-I6CX2RK4.js → chunk-D4JKKSSI.js} +2 -2
- package/dist/{chunk-UR34PYAC.js → chunk-GETZFABK.js} +2 -2
- package/dist/{chunk-YXEE3DEQ.js → chunk-O27B5IRL.js} +2 -2
- package/dist/{chunk-7UXZTZBJ.cjs → chunk-RCSDSN5Y.cjs} +2 -2
- package/dist/{chunk-7UXZTZBJ.cjs.map → chunk-RCSDSN5Y.cjs.map} +1 -1
- package/dist/{chunk-GFS4QWB6.js → chunk-SNSAZ7FA.js} +2 -2
- package/dist/{chunk-RMGYE4LT.js → chunk-TUBD3EEF.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-LJOS7VZM.js → parser-3EARWV2H.js} +84 -3
- package/dist/parser-3EARWV2H.js.map +1 -0
- package/dist/{parser-664URIIW.js → parser-STGI5I5K.js} +83 -2
- package/dist/parser-STGI5I5K.js.map +1 -0
- package/dist/{parser-AT22HMF5.cjs → parser-X34HD2KQ.cjs} +95 -14
- package/dist/parser-X34HD2KQ.cjs.map +1 -0
- package/dist/render-FPWZ6YNZ.js +9 -0
- package/dist/{watch-CZF6NA2V.js → watch-KVYJ46S6.js} +5 -5
- package/package.json +1 -1
- package/dist/parser-664URIIW.js.map +0 -1
- package/dist/parser-AT22HMF5.cjs.map +0 -1
- package/dist/parser-LJOS7VZM.js.map +0 -1
- package/dist/render-XWOEGE3U.js +0 -9
- /package/dist/{-LPEXY73L.js.map → -QMW2GDWP.js.map} +0 -0
- /package/dist/{chunk-I6CX2RK4.js.map → chunk-D4JKKSSI.js.map} +0 -0
- /package/dist/{chunk-UR34PYAC.js.map → chunk-GETZFABK.js.map} +0 -0
- /package/dist/{chunk-YXEE3DEQ.js.map → chunk-O27B5IRL.js.map} +0 -0
- /package/dist/{chunk-GFS4QWB6.js.map → chunk-SNSAZ7FA.js.map} +0 -0
- /package/dist/{chunk-RMGYE4LT.js.map → chunk-TUBD3EEF.js.map} +0 -0
- /package/dist/{render-XWOEGE3U.js.map → render-FPWZ6YNZ.js.map} +0 -0
- /package/dist/{watch-CZF6NA2V.js.map → watch-KVYJ46S6.js.map} +0 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _chunkRCSDSN5Ycjs = require('./chunk-RCSDSN5Y.cjs');
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
var _chunkDCZVOIEOcjs = require('./chunk-DCZVOIEO.cjs');
|
|
@@ -201,10 +201,90 @@ function classifyAndAdd(seg, lineWidth, horizontals, verticals) {
|
|
|
201
201
|
function preprocessLines(horizontals, verticals) {
|
|
202
202
|
let h = horizontals.filter((l) => l.lineWidth <= MAX_LINE_WIDTH);
|
|
203
203
|
let v = verticals.filter((l) => l.lineWidth <= MAX_LINE_WIDTH);
|
|
204
|
+
h = dropShadingStacks(h, "h");
|
|
205
|
+
v = dropShadingStacks(v, "v");
|
|
204
206
|
h = mergeParallelLines(h, "h");
|
|
205
207
|
v = mergeParallelLines(v, "v");
|
|
206
208
|
return { horizontals: h, verticals: v };
|
|
207
209
|
}
|
|
210
|
+
var STACK_GAP = 2;
|
|
211
|
+
var STACK_MIN_LINES = 6;
|
|
212
|
+
function dropShadingStacks(lines, dir) {
|
|
213
|
+
if (lines.length < STACK_MIN_LINES) return lines;
|
|
214
|
+
const groups = /* @__PURE__ */ new Map();
|
|
215
|
+
for (const l of lines) {
|
|
216
|
+
const key = dir === "h" ? `${Math.round(l.x1)}:${Math.round(l.x2)}` : `${Math.round(l.y1)}:${Math.round(l.y2)}`;
|
|
217
|
+
const arr = groups.get(key);
|
|
218
|
+
if (arr) arr.push(l);
|
|
219
|
+
else groups.set(key, [l]);
|
|
220
|
+
}
|
|
221
|
+
const dropped = /* @__PURE__ */ new Set();
|
|
222
|
+
for (const group of groups.values()) {
|
|
223
|
+
if (group.length < STACK_MIN_LINES) continue;
|
|
224
|
+
group.sort((a, b) => dir === "h" ? a.y1 - b.y1 : a.x1 - b.x1);
|
|
225
|
+
let runStart = 0;
|
|
226
|
+
for (let i = 1; i <= group.length; i++) {
|
|
227
|
+
const gap = i < group.length ? dir === "h" ? group[i].y1 - group[i - 1].y1 : group[i].x1 - group[i - 1].x1 : Infinity;
|
|
228
|
+
if (gap < STACK_GAP) continue;
|
|
229
|
+
if (i - runStart >= STACK_MIN_LINES) {
|
|
230
|
+
for (let j = runStart; j < i; j++) dropped.add(group[j]);
|
|
231
|
+
}
|
|
232
|
+
runStart = i;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return dropped.size ? lines.filter((l) => !dropped.has(l)) : lines;
|
|
236
|
+
}
|
|
237
|
+
var EDGE_ALIGN_TOL = 3;
|
|
238
|
+
var EDGE_MIN_RULES = 3;
|
|
239
|
+
var EDGE_MIN_SPAN = 12;
|
|
240
|
+
var EDGE_INSET = 15;
|
|
241
|
+
var EDGE_NEAR = 10;
|
|
242
|
+
var EDGE_CONNECT_TOL = 5;
|
|
243
|
+
function closeOpenTableEdges(horizontals, verticals) {
|
|
244
|
+
if (horizontals.length < EDGE_MIN_RULES) return verticals;
|
|
245
|
+
const groups = [];
|
|
246
|
+
for (const hl of horizontals) {
|
|
247
|
+
let placed = false;
|
|
248
|
+
for (const g2 of groups) {
|
|
249
|
+
if (Math.abs(g2[0].x1 - hl.x1) <= EDGE_ALIGN_TOL && Math.abs(g2[0].x2 - hl.x2) <= EDGE_ALIGN_TOL) {
|
|
250
|
+
g2.push(hl);
|
|
251
|
+
placed = true;
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (!placed) groups.push([hl]);
|
|
256
|
+
}
|
|
257
|
+
const synthesized = [];
|
|
258
|
+
for (const g2 of groups) {
|
|
259
|
+
if (g2.length < EDGE_MIN_RULES) continue;
|
|
260
|
+
let yMin = Infinity, yMax = -Infinity, x1 = 0, x2 = 0;
|
|
261
|
+
for (const hl of g2) {
|
|
262
|
+
if (hl.y1 < yMin) yMin = hl.y1;
|
|
263
|
+
if (hl.y1 > yMax) yMax = hl.y1;
|
|
264
|
+
x1 += hl.x1;
|
|
265
|
+
x2 += hl.x2;
|
|
266
|
+
}
|
|
267
|
+
x1 /= g2.length;
|
|
268
|
+
x2 /= g2.length;
|
|
269
|
+
if (yMax - yMin < EDGE_MIN_SPAN) continue;
|
|
270
|
+
const crossCount = (v) => {
|
|
271
|
+
let n = 0;
|
|
272
|
+
for (const hl of g2) {
|
|
273
|
+
if (v.x1 >= hl.x1 - EDGE_CONNECT_TOL && v.x1 <= hl.x2 + EDGE_CONNECT_TOL && hl.y1 >= v.y1 - EDGE_CONNECT_TOL && hl.y1 <= v.y2 + EDGE_CONNECT_TOL) n++;
|
|
274
|
+
}
|
|
275
|
+
return n;
|
|
276
|
+
};
|
|
277
|
+
const hasInterior = verticals.some((v) => v.x1 > x1 + EDGE_INSET && v.x1 < x2 - EDGE_INSET && crossCount(v) >= 2);
|
|
278
|
+
if (!hasInterior) continue;
|
|
279
|
+
for (const edgeX of [x1, x2]) {
|
|
280
|
+
const closed = verticals.some((v) => Math.abs(v.x1 - edgeX) <= EDGE_NEAR && v.y1 <= yMax + EDGE_CONNECT_TOL && v.y2 >= yMin - EDGE_CONNECT_TOL);
|
|
281
|
+
if (!closed) {
|
|
282
|
+
synthesized.push({ x1: edgeX, y1: yMin, x2: edgeX, y2: yMax, lineWidth: 0.5 });
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return synthesized.length ? [...verticals, ...synthesized] : verticals;
|
|
287
|
+
}
|
|
208
288
|
function mergeParallelLines(lines, dir) {
|
|
209
289
|
if (lines.length <= 1) return lines;
|
|
210
290
|
const sorted = [...lines].sort((a, b) => {
|
|
@@ -1976,14 +2056,14 @@ function isProseSpread(items) {
|
|
|
1976
2056
|
for (let i = 1; i < sorted.length; i++) {
|
|
1977
2057
|
gaps.push(sorted[i].x - (sorted[i - 1].x + sorted[i - 1].w));
|
|
1978
2058
|
}
|
|
1979
|
-
const maxGap =
|
|
2059
|
+
const maxGap = _chunkRCSDSN5Ycjs.safeMax.call(void 0, gaps);
|
|
1980
2060
|
const avgLen = items.reduce((s, i) => s + i.text.length, 0) / items.length;
|
|
1981
2061
|
return maxGap < 40 && avgLen < 5;
|
|
1982
2062
|
}
|
|
1983
2063
|
function detectColumns(yLines) {
|
|
1984
2064
|
const allItems = yLines.flat();
|
|
1985
2065
|
if (allItems.length === 0) return null;
|
|
1986
|
-
const pageWidth =
|
|
2066
|
+
const pageWidth = _chunkRCSDSN5Ycjs.safeMax.call(void 0, allItems.map((i) => i.x + i.w)) - _chunkRCSDSN5Ycjs.safeMin.call(void 0, allItems.map((i) => i.x));
|
|
1987
2067
|
if (pageWidth < 100) return null;
|
|
1988
2068
|
let bigoLineIdx = -1;
|
|
1989
2069
|
for (let i = 0; i < yLines.length; i++) {
|
|
@@ -2205,9 +2285,9 @@ function detectHeadings(blocks, medianFontSize) {
|
|
|
2205
2285
|
if (/^\d+$/.test(text)) continue;
|
|
2206
2286
|
const ratio = block.style.fontSize / medianFontSize;
|
|
2207
2287
|
let level = 0;
|
|
2208
|
-
if (ratio >=
|
|
2209
|
-
else if (ratio >=
|
|
2210
|
-
else if (ratio >=
|
|
2288
|
+
if (ratio >= _chunkRCSDSN5Ycjs.HEADING_RATIO_H1) level = 1;
|
|
2289
|
+
else if (ratio >= _chunkRCSDSN5Ycjs.HEADING_RATIO_H2) level = 2;
|
|
2290
|
+
else if (ratio >= _chunkRCSDSN5Ycjs.HEADING_RATIO_H3) level = 3;
|
|
2211
2291
|
if (level > 0) {
|
|
2212
2292
|
block.type = "heading";
|
|
2213
2293
|
block.level = level;
|
|
@@ -2555,6 +2635,7 @@ function extractPageBlocksWithLines(items, pageNum, opList, pageWidth, pageHeigh
|
|
|
2555
2635
|
let { horizontals, verticals } = extractLines(opList.fnArray, opList.argsArray);
|
|
2556
2636
|
({ horizontals, verticals } = filterPageBorderLines(horizontals, verticals, pageWidth, pageHeight));
|
|
2557
2637
|
({ horizontals, verticals } = preprocessLines(horizontals, verticals));
|
|
2638
|
+
verticals = closeOpenTableEdges(horizontals, verticals);
|
|
2558
2639
|
markStrikethroughItems(items, horizontals);
|
|
2559
2640
|
wrapStrikethroughRuns(items);
|
|
2560
2641
|
const grids = buildTableGrids(horizontals, verticals);
|
|
@@ -2726,7 +2807,7 @@ function extractBlocksWithGrids(items, pageNum, grids, horizontals, verticals) {
|
|
|
2726
2807
|
}
|
|
2727
2808
|
if (remaining.length > 0) {
|
|
2728
2809
|
const allY = remaining.map((i) => i.y);
|
|
2729
|
-
const pageH =
|
|
2810
|
+
const pageH = _chunkRCSDSN5Ycjs.safeMax.call(void 0, allY) - _chunkRCSDSN5Ycjs.safeMin.call(void 0, allY);
|
|
2730
2811
|
const groups = xyCutOrder(remaining, Math.max(15, pageH * 0.03));
|
|
2731
2812
|
const textBlocks = [];
|
|
2732
2813
|
for (const group of groups) {
|
|
@@ -2902,7 +2983,7 @@ function extractPageBlocksFallback(items, pageNum, fullPage = false) {
|
|
|
2902
2983
|
blocks.push({ type: "paragraph", text: tableText, pageNumber: pageNum, bbox, style: dominantStyle(items) });
|
|
2903
2984
|
} else {
|
|
2904
2985
|
const allY = items.map((i) => i.y);
|
|
2905
|
-
const pageHeight =
|
|
2986
|
+
const pageHeight = _chunkRCSDSN5Ycjs.safeMax.call(void 0, allY) - _chunkRCSDSN5Ycjs.safeMin.call(void 0, allY);
|
|
2906
2987
|
const gapThreshold = Math.max(15, pageHeight * 0.03);
|
|
2907
2988
|
const orderedGroups = proseCutX !== null ? splitTwoColumnProse(items, proseCutX) : xyCutOrder(items, gapThreshold);
|
|
2908
2989
|
for (const group of orderedGroups) {
|
|
@@ -3155,7 +3236,7 @@ async function loadPdfWithTimeout(buffer) {
|
|
|
3155
3236
|
new Promise((_, reject) => {
|
|
3156
3237
|
timer = setTimeout(() => {
|
|
3157
3238
|
loadingTask.destroy();
|
|
3158
|
-
reject(new (0,
|
|
3239
|
+
reject(new (0, _chunkRCSDSN5Ycjs.KordocError)("PDF \uB85C\uB529 \uD0C0\uC784\uC544\uC6C3 (30\uCD08 \uCD08\uACFC)"));
|
|
3159
3240
|
}, PDF_LOAD_TIMEOUT_MS);
|
|
3160
3241
|
})
|
|
3161
3242
|
]);
|
|
@@ -3168,7 +3249,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3168
3249
|
const doc = await loadPdfWithTimeout(buffer);
|
|
3169
3250
|
try {
|
|
3170
3251
|
const pageCount = doc.numPages;
|
|
3171
|
-
if (pageCount === 0) throw new (0,
|
|
3252
|
+
if (pageCount === 0) throw new (0, _chunkRCSDSN5Ycjs.KordocError)("PDF\uC5D0 \uD398\uC774\uC9C0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
3172
3253
|
const metadata = { pageCount };
|
|
3173
3254
|
await extractPdfMetadata(doc, metadata);
|
|
3174
3255
|
const blocks = [];
|
|
@@ -3228,11 +3309,11 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3228
3309
|
pageText += pageText ? "\n" + t : t;
|
|
3229
3310
|
}
|
|
3230
3311
|
pageQuality.push(computePageQuality(i, pageText));
|
|
3231
|
-
if (totalTextBytes > MAX_TOTAL_TEXT) throw new (0,
|
|
3312
|
+
if (totalTextBytes > MAX_TOTAL_TEXT) throw new (0, _chunkRCSDSN5Ycjs.KordocError)("\uD14D\uC2A4\uD2B8 \uCD94\uCD9C \uD06C\uAE30 \uCD08\uACFC");
|
|
3232
3313
|
parsedPages++;
|
|
3233
3314
|
_optionalChain([options, 'optionalAccess', _36 => _36.onProgress, 'optionalCall', _37 => _37(parsedPages, totalTarget)]);
|
|
3234
3315
|
} catch (pageErr) {
|
|
3235
|
-
if (pageErr instanceof
|
|
3316
|
+
if (pageErr instanceof _chunkRCSDSN5Ycjs.KordocError) throw pageErr;
|
|
3236
3317
|
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" });
|
|
3237
3318
|
}
|
|
3238
3319
|
}
|
|
@@ -3300,7 +3381,7 @@ async function parsePdfDocument(buffer, options) {
|
|
|
3300
3381
|
detectKoreanListBlocks(blocks);
|
|
3301
3382
|
const outline = blocks.filter((b) => b.type === "heading" && b.level && b.text).map((b) => ({ level: b.level, text: b.text, pageNumber: b.pageNumber }));
|
|
3302
3383
|
sanitizeBlockControlChars(blocks);
|
|
3303
|
-
let markdown = cleanPdfText(
|
|
3384
|
+
let markdown = cleanPdfText(_chunkRCSDSN5Ycjs.blocksToMarkdown.call(void 0, blocks));
|
|
3304
3385
|
return {
|
|
3305
3386
|
markdown,
|
|
3306
3387
|
blocks,
|
|
@@ -3359,4 +3440,4 @@ async function extractPdfMetadataOnly(buffer) {
|
|
|
3359
3440
|
|
|
3360
3441
|
|
|
3361
3442
|
exports.cleanPdfText = cleanPdfText; exports.detectKoreanListBlocks = detectKoreanListBlocks; exports.detectTableCaptions = detectTableCaptions; exports.extractPdfMetadataOnly = extractPdfMetadataOnly; exports.mergeCrossPageTables = mergeCrossPageTables; exports.parsePdfDocument = parsePdfDocument; exports.removeHeaderFooterBlocks = removeHeaderFooterBlocks;
|
|
3362
|
-
//# sourceMappingURL=parser-
|
|
3443
|
+
//# sourceMappingURL=parser-X34HD2KQ.cjs.map
|