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.
Files changed (34) hide show
  1. package/README.md +6 -0
  2. package/dist/{-LPEXY73L.js → -QMW2GDWP.js} +5 -5
  3. package/dist/{chunk-I6CX2RK4.js → chunk-D4JKKSSI.js} +2 -2
  4. package/dist/{chunk-UR34PYAC.js → chunk-GETZFABK.js} +2 -2
  5. package/dist/{chunk-YXEE3DEQ.js → chunk-O27B5IRL.js} +2 -2
  6. package/dist/{chunk-7UXZTZBJ.cjs → chunk-RCSDSN5Y.cjs} +2 -2
  7. package/dist/{chunk-7UXZTZBJ.cjs.map → chunk-RCSDSN5Y.cjs.map} +1 -1
  8. package/dist/{chunk-GFS4QWB6.js → chunk-SNSAZ7FA.js} +2 -2
  9. package/dist/{chunk-RMGYE4LT.js → chunk-TUBD3EEF.js} +5 -5
  10. package/dist/cli.js +7 -7
  11. package/dist/index.cjs +118 -118
  12. package/dist/index.js +2 -2
  13. package/dist/mcp.js +5 -5
  14. package/dist/{parser-LJOS7VZM.js → parser-3EARWV2H.js} +84 -3
  15. package/dist/parser-3EARWV2H.js.map +1 -0
  16. package/dist/{parser-664URIIW.js → parser-STGI5I5K.js} +83 -2
  17. package/dist/parser-STGI5I5K.js.map +1 -0
  18. package/dist/{parser-AT22HMF5.cjs → parser-X34HD2KQ.cjs} +95 -14
  19. package/dist/parser-X34HD2KQ.cjs.map +1 -0
  20. package/dist/render-FPWZ6YNZ.js +9 -0
  21. package/dist/{watch-CZF6NA2V.js → watch-KVYJ46S6.js} +5 -5
  22. package/package.json +1 -1
  23. package/dist/parser-664URIIW.js.map +0 -1
  24. package/dist/parser-AT22HMF5.cjs.map +0 -1
  25. package/dist/parser-LJOS7VZM.js.map +0 -1
  26. package/dist/render-XWOEGE3U.js +0 -9
  27. /package/dist/{-LPEXY73L.js.map → -QMW2GDWP.js.map} +0 -0
  28. /package/dist/{chunk-I6CX2RK4.js.map → chunk-D4JKKSSI.js.map} +0 -0
  29. /package/dist/{chunk-UR34PYAC.js.map → chunk-GETZFABK.js.map} +0 -0
  30. /package/dist/{chunk-YXEE3DEQ.js.map → chunk-O27B5IRL.js.map} +0 -0
  31. /package/dist/{chunk-GFS4QWB6.js.map → chunk-SNSAZ7FA.js.map} +0 -0
  32. /package/dist/{chunk-RMGYE4LT.js.map → chunk-TUBD3EEF.js.map} +0 -0
  33. /package/dist/{render-XWOEGE3U.js.map → render-FPWZ6YNZ.js.map} +0 -0
  34. /package/dist/{watch-CZF6NA2V.js.map → watch-KVYJ46S6.js.map} +0 -0
@@ -6,7 +6,7 @@
6
6
 
7
7
 
8
8
 
9
- var _chunk7UXZTZBJcjs = require('./chunk-7UXZTZBJ.cjs');
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 = _chunk7UXZTZBJcjs.safeMax.call(void 0, gaps);
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 = _chunk7UXZTZBJcjs.safeMax.call(void 0, allItems.map((i) => i.x + i.w)) - _chunk7UXZTZBJcjs.safeMin.call(void 0, allItems.map((i) => i.x));
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 >= _chunk7UXZTZBJcjs.HEADING_RATIO_H1) level = 1;
2209
- else if (ratio >= _chunk7UXZTZBJcjs.HEADING_RATIO_H2) level = 2;
2210
- else if (ratio >= _chunk7UXZTZBJcjs.HEADING_RATIO_H3) level = 3;
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 = _chunk7UXZTZBJcjs.safeMax.call(void 0, allY) - _chunk7UXZTZBJcjs.safeMin.call(void 0, allY);
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 = _chunk7UXZTZBJcjs.safeMax.call(void 0, allY) - _chunk7UXZTZBJcjs.safeMin.call(void 0, allY);
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, _chunk7UXZTZBJcjs.KordocError)("PDF \uB85C\uB529 \uD0C0\uC784\uC544\uC6C3 (30\uCD08 \uCD08\uACFC)"));
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, _chunk7UXZTZBJcjs.KordocError)("PDF\uC5D0 \uD398\uC774\uC9C0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.");
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, _chunk7UXZTZBJcjs.KordocError)("\uD14D\uC2A4\uD2B8 \uCD94\uCD9C \uD06C\uAE30 \uCD08\uACFC");
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 _chunk7UXZTZBJcjs.KordocError) throw pageErr;
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(_chunk7UXZTZBJcjs.blocksToMarkdown.call(void 0, blocks));
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-AT22HMF5.cjs.map
3443
+ //# sourceMappingURL=parser-X34HD2KQ.cjs.map