kordoc 4.9.0 → 4.9.1

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 (122) hide show
  1. package/README.md +9 -0
  2. package/dist/{-GCDZVN36.js → -KIYHEVUW.js} +14 -8
  3. package/dist/{chunk-BK6ZFFZO.cjs → chunk-2ULV2DX4.cjs} +4 -4
  4. package/dist/chunk-2ULV2DX4.cjs.map +1 -0
  5. package/dist/{chunk-VVMXAB5N.js → chunk-3PY5YCJP.js} +2 -2
  6. package/dist/{chunk-5Y7WKVVP.cjs → chunk-4R73ASZF.cjs} +2 -2
  7. package/dist/chunk-4R73ASZF.cjs.map +1 -0
  8. package/dist/{chunk-CTOIJPOZ.js → chunk-55Q76S6S.js} +2 -2
  9. package/dist/{chunk-EPPJTZJJ.js → chunk-5CAKNM2K.js} +2 -2
  10. package/dist/{chunk-BANRDDJL.cjs → chunk-65TL66UD.cjs} +3 -3
  11. package/dist/chunk-65TL66UD.cjs.map +1 -0
  12. package/dist/{chunk-4ZHZL44G.cjs → chunk-D7EMDOX7.cjs} +6 -6
  13. package/dist/chunk-D7EMDOX7.cjs.map +1 -0
  14. package/dist/chunk-DCZVOIEO.cjs.map +1 -1
  15. package/dist/{chunk-XLARMJAD.js → chunk-GNRBCV4R.js} +3 -3
  16. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  17. package/dist/{chunk-4DEU3YJR.js → chunk-GU4NCNCT.js} +2 -2
  18. package/dist/{chunk-K4JVORUT.js → chunk-HFZIYAQQ.js} +2 -2
  19. package/dist/{chunk-YQ3EWPCN.js → chunk-HG7GXBVP.js} +2 -2
  20. package/dist/{chunk-ZL5R3O5Y.cjs → chunk-HOSNMNKU.cjs} +7 -7
  21. package/dist/chunk-HOSNMNKU.cjs.map +1 -0
  22. package/dist/{chunk-IJH3NEF3.js → chunk-INV3W43Y.js} +2 -2
  23. package/dist/{chunk-GLVZNMMN.js → chunk-JHXAQDXS.js} +272 -21
  24. package/dist/chunk-JHXAQDXS.js.map +1 -0
  25. package/dist/{chunk-MRFUIWOD.js → chunk-L27YEW3T.js} +3 -3
  26. package/dist/chunk-L5CDTOC3.cjs.map +1 -1
  27. package/dist/{chunk-L6VNNUV4.js → chunk-Q3IVAWOK.js} +3 -3
  28. package/dist/{chunk-MQKK34ID.js → chunk-SFSB3FAL.js} +2 -2
  29. package/dist/{chunk-SKTYYRUD.js → chunk-SGTGSV4A.js} +2 -2
  30. package/dist/{chunk-WBVORBGM.js → chunk-TC7EDYZD.js} +2 -2
  31. package/dist/{chunk-YZWSTDT7.js → chunk-TN6AALZG.js} +2 -2
  32. package/dist/{chunk-THB2RO2P.js → chunk-UIQWUYOJ.js} +3 -3
  33. package/dist/{chunk-KWKYWCPR.js → chunk-VGRIWMTQ.js} +2 -2
  34. package/dist/{chunk-PPA3BSEX.js → chunk-Z2SX4E7K.js} +2 -2
  35. package/dist/chunks-FB344JZT.js +10 -0
  36. package/dist/cli.js +47 -25
  37. package/dist/cli.js.map +1 -1
  38. package/dist/{formula-W6VEVOGF.js → formula-5DQQ4MFT.js} +4 -4
  39. package/dist/{formula-W35NSRS5.cjs → formula-I5D3UNLV.cjs} +9 -9
  40. package/dist/formula-I5D3UNLV.cjs.map +1 -0
  41. package/dist/{formula-IIF334U5.js → formula-S4O7SBN3.js} +3 -3
  42. package/dist/{image-ocr-ZR2HP4WG.cjs → image-ocr-BKUYR4WU.cjs} +11 -11
  43. package/dist/image-ocr-BKUYR4WU.cjs.map +1 -0
  44. package/dist/{image-ocr-4CF6B2ZP.js → image-ocr-LIH2E7WC.js} +5 -5
  45. package/dist/{image-ocr-KCH5UMWN.js → image-ocr-SQXFTNYR.js} +7 -7
  46. package/dist/index.cjs +439 -188
  47. package/dist/index.cjs.map +1 -1
  48. package/dist/index.d.cts +46 -1
  49. package/dist/index.d.ts +46 -1
  50. package/dist/index.js +268 -17
  51. package/dist/index.js.map +1 -1
  52. package/dist/mcp.js +19 -16
  53. package/dist/mcp.js.map +1 -1
  54. package/dist/{model-bundle-ZIHP5ULR.js → model-bundle-4JMY5E37.js} +5 -5
  55. package/dist/{models-Q7HDRZMF.js → models-D7X5YBWX.js} +5 -5
  56. package/dist/page-range-P7SDW6LR.cjs.map +1 -1
  57. package/dist/{parser-SPK4QG4F.js → parser-GHRXWFJN.js} +6 -6
  58. package/dist/{parser-O3X37357.js → parser-MY7JJISJ.js} +6 -6
  59. package/dist/{parser-7HS5FORY.cjs → parser-ZLHOAZAA.cjs} +26 -26
  60. package/dist/parser-ZLHOAZAA.cjs.map +1 -0
  61. package/dist/pdf-ocr-FESGFQYN.cjs +14 -0
  62. package/dist/pdf-ocr-FESGFQYN.cjs.map +1 -0
  63. package/dist/pdf-ocr-IEAXGG3D.js +13 -0
  64. package/dist/pdf-ocr-Z6CHIYEM.js +16 -0
  65. package/dist/{profile-io-PQSH3EPJ.js → profile-io-EAPI6M7O.js} +3 -3
  66. package/dist/{rasterize-NMCA7XRR.js → rasterize-UIDZAEWB.js} +2 -2
  67. package/dist/render-XL7ZVAHK.js +10 -0
  68. package/dist/seal-CY7EIWDJ.js +10 -0
  69. package/dist/{setup-CQ6SMNMA.js → setup-UHX3HHWY.js} +3 -3
  70. package/dist/{watch-4BOS6J6K.js → watch-23MV3PBX.js} +9 -9
  71. package/package.json +1 -1
  72. package/dist/chunk-4ZHZL44G.cjs.map +0 -1
  73. package/dist/chunk-5Y7WKVVP.cjs.map +0 -1
  74. package/dist/chunk-BANRDDJL.cjs.map +0 -1
  75. package/dist/chunk-BK6ZFFZO.cjs.map +0 -1
  76. package/dist/chunk-GLVZNMMN.js.map +0 -1
  77. package/dist/chunk-ZL5R3O5Y.cjs.map +0 -1
  78. package/dist/chunks-R6PFU6OR.js +0 -10
  79. package/dist/formula-W35NSRS5.cjs.map +0 -1
  80. package/dist/image-ocr-ZR2HP4WG.cjs.map +0 -1
  81. package/dist/parser-7HS5FORY.cjs.map +0 -1
  82. package/dist/pdf-ocr-4XUES6M5.js +0 -16
  83. package/dist/pdf-ocr-6D7OPO2X.cjs +0 -14
  84. package/dist/pdf-ocr-6D7OPO2X.cjs.map +0 -1
  85. package/dist/pdf-ocr-NICPW5HS.js +0 -13
  86. package/dist/render-MMAQI7DM.js +0 -10
  87. package/dist/seal-GWABZNEC.js +0 -10
  88. /package/dist/{-GCDZVN36.js.map → -KIYHEVUW.js.map} +0 -0
  89. /package/dist/{chunk-VVMXAB5N.js.map → chunk-3PY5YCJP.js.map} +0 -0
  90. /package/dist/{chunk-CTOIJPOZ.js.map → chunk-55Q76S6S.js.map} +0 -0
  91. /package/dist/{chunk-EPPJTZJJ.js.map → chunk-5CAKNM2K.js.map} +0 -0
  92. /package/dist/{chunk-XLARMJAD.js.map → chunk-GNRBCV4R.js.map} +0 -0
  93. /package/dist/{chunk-4DEU3YJR.js.map → chunk-GU4NCNCT.js.map} +0 -0
  94. /package/dist/{chunk-K4JVORUT.js.map → chunk-HFZIYAQQ.js.map} +0 -0
  95. /package/dist/{chunk-YQ3EWPCN.js.map → chunk-HG7GXBVP.js.map} +0 -0
  96. /package/dist/{chunk-IJH3NEF3.js.map → chunk-INV3W43Y.js.map} +0 -0
  97. /package/dist/{chunk-MRFUIWOD.js.map → chunk-L27YEW3T.js.map} +0 -0
  98. /package/dist/{chunk-L6VNNUV4.js.map → chunk-Q3IVAWOK.js.map} +0 -0
  99. /package/dist/{chunk-MQKK34ID.js.map → chunk-SFSB3FAL.js.map} +0 -0
  100. /package/dist/{chunk-SKTYYRUD.js.map → chunk-SGTGSV4A.js.map} +0 -0
  101. /package/dist/{chunk-WBVORBGM.js.map → chunk-TC7EDYZD.js.map} +0 -0
  102. /package/dist/{chunk-YZWSTDT7.js.map → chunk-TN6AALZG.js.map} +0 -0
  103. /package/dist/{chunk-THB2RO2P.js.map → chunk-UIQWUYOJ.js.map} +0 -0
  104. /package/dist/{chunk-KWKYWCPR.js.map → chunk-VGRIWMTQ.js.map} +0 -0
  105. /package/dist/{chunk-PPA3BSEX.js.map → chunk-Z2SX4E7K.js.map} +0 -0
  106. /package/dist/{chunks-R6PFU6OR.js.map → chunks-FB344JZT.js.map} +0 -0
  107. /package/dist/{formula-W6VEVOGF.js.map → formula-5DQQ4MFT.js.map} +0 -0
  108. /package/dist/{formula-IIF334U5.js.map → formula-S4O7SBN3.js.map} +0 -0
  109. /package/dist/{image-ocr-4CF6B2ZP.js.map → image-ocr-LIH2E7WC.js.map} +0 -0
  110. /package/dist/{image-ocr-KCH5UMWN.js.map → image-ocr-SQXFTNYR.js.map} +0 -0
  111. /package/dist/{model-bundle-ZIHP5ULR.js.map → model-bundle-4JMY5E37.js.map} +0 -0
  112. /package/dist/{models-Q7HDRZMF.js.map → models-D7X5YBWX.js.map} +0 -0
  113. /package/dist/{parser-SPK4QG4F.js.map → parser-GHRXWFJN.js.map} +0 -0
  114. /package/dist/{parser-O3X37357.js.map → parser-MY7JJISJ.js.map} +0 -0
  115. /package/dist/{pdf-ocr-4XUES6M5.js.map → pdf-ocr-IEAXGG3D.js.map} +0 -0
  116. /package/dist/{pdf-ocr-NICPW5HS.js.map → pdf-ocr-Z6CHIYEM.js.map} +0 -0
  117. /package/dist/{profile-io-PQSH3EPJ.js.map → profile-io-EAPI6M7O.js.map} +0 -0
  118. /package/dist/{rasterize-NMCA7XRR.js.map → rasterize-UIDZAEWB.js.map} +0 -0
  119. /package/dist/{render-MMAQI7DM.js.map → render-XL7ZVAHK.js.map} +0 -0
  120. /package/dist/{seal-GWABZNEC.js.map → seal-CY7EIWDJ.js.map} +0 -0
  121. /package/dist/{setup-CQ6SMNMA.js.map → setup-UHX3HHWY.js.map} +0 -0
  122. /package/dist/{watch-4BOS6J6K.js.map → watch-23MV3PBX.js.map} +0 -0
@@ -1,5 +1,5 @@
1
1
  // src/utils.ts
2
- var VERSION = true ? "4.9.0" : "0.0.0-dev";
2
+ var VERSION = true ? "4.9.1" : "0.0.0-dev";
3
3
  function toArrayBuffer(buf) {
4
4
  if (buf.byteOffset === 0 && buf.byteLength === buf.buffer.byteLength) {
5
5
  return buf.buffer;
@@ -121,4 +121,4 @@ export {
121
121
  safeMax,
122
122
  classifyError
123
123
  };
124
- //# sourceMappingURL=chunk-IJH3NEF3.js.map
124
+ //# sourceMappingURL=chunk-INV3W43Y.js.map
@@ -22,7 +22,7 @@ import {
22
22
  paraTextPureT,
23
23
  patchZipEntries,
24
24
  scanSectionXml
25
- } from "./chunk-L6VNNUV4.js";
25
+ } from "./chunk-Q3IVAWOK.js";
26
26
  import {
27
27
  MAX_COLS,
28
28
  MAX_ROWS,
@@ -32,14 +32,14 @@ import {
32
32
  dedupeRunningHeaders,
33
33
  flattenLayoutTables,
34
34
  mapPuaText
35
- } from "./chunk-YQ3EWPCN.js";
35
+ } from "./chunk-HG7GXBVP.js";
36
36
  import {
37
37
  SPACE_EM_FIXED,
38
38
  charWidthEm1000,
39
39
  fitRatioForFewerLines,
40
40
  measureTextWidth,
41
41
  simulateWrap
42
- } from "./chunk-THB2RO2P.js";
42
+ } from "./chunk-UIQWUYOJ.js";
43
43
  import {
44
44
  MAX_DECOMPRESS_SIZE,
45
45
  MAX_XML_DEPTH,
@@ -55,7 +55,7 @@ import {
55
55
  findChildByLocalName,
56
56
  localName,
57
57
  rawTextContent
58
- } from "./chunk-WBVORBGM.js";
58
+ } from "./chunk-TC7EDYZD.js";
59
59
  import {
60
60
  KordocError,
61
61
  classifyError,
@@ -67,7 +67,7 @@ import {
67
67
  sanitizeHref,
68
68
  stripDtd,
69
69
  toArrayBuffer
70
- } from "./chunk-VVMXAB5N.js";
70
+ } from "./chunk-3PY5YCJP.js";
71
71
 
72
72
  // src/index.ts
73
73
  import { readFile } from "fs/promises";
@@ -502,9 +502,9 @@ function decryptEntry(cipher, entry, startKey) {
502
502
  const decipher = createDecipheriv("aes-256-cbc", key, entry.iv);
503
503
  decipher.setAutoPadding(false);
504
504
  const raw = Buffer.concat([decipher.update(cipher), decipher.final()]);
505
- const plain = inflateRawSync(raw, { maxOutputLength: MAX_DECOMPRESS_SIZE });
506
- const sum = createHash("sha256").update(plain.subarray(0, Math.min(CHECKSUM_PREFIX_BYTES, plain.length))).digest();
507
- if (sum.length === entry.checksum.length && timingSafeEqual(sum, entry.checksum)) return plain;
505
+ const plain2 = inflateRawSync(raw, { maxOutputLength: MAX_DECOMPRESS_SIZE });
506
+ const sum = createHash("sha256").update(plain2.subarray(0, Math.min(CHECKSUM_PREFIX_BYTES, plain2.length))).digest();
507
+ if (sum.length === entry.checksum.length && timingSafeEqual(sum, entry.checksum)) return plain2;
508
508
  } catch {
509
509
  }
510
510
  }
@@ -520,13 +520,13 @@ async function decryptHwpxInPlace(zip, manifestXml, password) {
520
520
  if (!file) {
521
521
  throw new KordocError(`\uC554\uD638 \uBAA9\uB85D\uC5D0 \uC788\uB294 \uD30C\uC77C\uC774 \uBB38\uC11C\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4: ${entry.path}`);
522
522
  }
523
- const plain = decryptEntry(await file.async("nodebuffer"), entry, startKey);
524
- if (!plain) {
523
+ const plain2 = decryptEntry(await file.async("nodebuffer"), entry, startKey);
524
+ if (!plain2) {
525
525
  throw new KordocError("\uBE44\uBC00\uBC88\uD638\uAC00 \uC77C\uCE58\uD558\uC9C0 \uC54A\uAC70\uB098 \uC554\uD638\uD654 \uB370\uC774\uD130\uAC00 \uC190\uC0C1\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
526
526
  }
527
- decrypted.push({ path: entry.path, plain });
527
+ decrypted.push({ path: entry.path, plain: plain2 });
528
528
  }
529
- for (const { path, plain } of decrypted) zip.file(path, plain);
529
+ for (const { path, plain: plain2 } of decrypted) zip.file(path, plain2);
530
530
  zip.file("META-INF/manifest.xml", stripEncryptionData(manifestXml));
531
531
  return decrypted.length;
532
532
  }
@@ -21511,7 +21511,7 @@ function gaejosikSizes(bodyHeight, ov = {}) {
21511
21511
  }
21512
21512
  function gaejosikSpaceBefore(depth, bodyHeight) {
21513
21513
  const s = bodyHeight / 1500;
21514
- const ui = [3e3, 2e3, 1200, 600][Math.min(depth, 3)];
21514
+ const ui = [300, 0, 0, 0][Math.min(depth, 3)];
21515
21515
  return Math.round(ui * s);
21516
21516
  }
21517
21517
  function gaejosikLevelIndent(depth, bodyHeight, sizes = {}, bullet2 = "\u25CB") {
@@ -22028,6 +22028,7 @@ function buildPrvText(blocks) {
22028
22028
  }
22029
22029
  return lines.join("\n").slice(0, 1024);
22030
22030
  }
22031
+ var BUNIM_HEAD = /^붙\s*임(?:\s|:|$)/;
22031
22032
  function findMathDelim(s, from) {
22032
22033
  let i = s.indexOf("$$", from);
22033
22034
  while (i > 0) {
@@ -22043,9 +22044,11 @@ function parseMarkdownToBlocks(md2) {
22043
22044
  const blocks = [];
22044
22045
  let i = 0;
22045
22046
  const listStack = [];
22047
+ let inBunim = false;
22046
22048
  while (i < lines.length) {
22047
22049
  const line = lines[i];
22048
22050
  if (!line.trim()) {
22051
+ inBunim = false;
22049
22052
  i++;
22050
22053
  continue;
22051
22054
  }
@@ -22173,6 +22176,19 @@ function parseMarkdownToBlocks(md2) {
22173
22176
  if (joined.length) blocks.push({ type: "blockquote", text: joined.join("\n") });
22174
22177
  continue;
22175
22178
  }
22179
+ if (BUNIM_HEAD.test(line.trim())) inBunim = true;
22180
+ if (inBunim) {
22181
+ if (BUNIM_HEAD.test(line.trim())) {
22182
+ const prevBlock = blocks[blocks.length - 1];
22183
+ if (blocks.length && !(prevBlock.type === "paragraph" && !prevBlock.text)) {
22184
+ blocks.push({ type: "paragraph", text: "" });
22185
+ }
22186
+ }
22187
+ blocks.push({ type: "paragraph", text: line.replace(/\s+$/, "") });
22188
+ listStack.length = 0;
22189
+ i++;
22190
+ continue;
22191
+ }
22176
22192
  const listLine = line.replace(/^[\t ]+/, (ws) => ws.replace(/\t/g, " "));
22177
22193
  const listMatch = listLine.match(/^(\s*)([-*+]|\d+[.)]) (.+)$/);
22178
22194
  if (listMatch) {
@@ -22556,13 +22572,18 @@ ${base2.join("\n")}
22556
22572
  }
22557
22573
  const ls = gongmun.lineSpacing;
22558
22574
  const titleAlign = gongmun.centerTitle ? "CENTER" : "LEFT";
22559
- const h2Geom = gongmun.h2Marker !== "none" ? { spaceBefore: Math.round(gongmun.bodyHeight * 2), spaceAfter: 0, indent: -markerWidth(gongmun.h2Marker === "box" ? "\u25A1" : "1.", 1600) } : { spaceBefore: 600, spaceAfter: 150 };
22575
+ const h2MarkerWidth = markerWidth(gongmun.h2Marker === "box" ? "\u25A1" : "1.", 1600);
22576
+ const h2Geom = gongmun.h2Marker !== "none" ? { spaceBefore: Math.round(gongmun.bodyHeight * 2), spaceAfter: 0, indent: -h2MarkerWidth } : { spaceBefore: 600, spaceAfter: 150 };
22577
+ const h3Left = gongmun.h2Marker !== "none" ? h2MarkerWidth : 0;
22560
22578
  const base = [
22561
22579
  paraPr(0, { lineSpacing: ls, keepWord: true }),
22562
22580
  paraPr(1, { align: titleAlign, spaceBefore: 400, spaceAfter: 400, lineSpacing: ls, keepWord: true }),
22563
22581
  paraPr(2, { align: "LEFT", ...h2Geom, lineSpacing: ls, keepWord: true }),
22564
- paraPr(3, { align: "LEFT", spaceBefore: 400, spaceAfter: 100, lineSpacing: ls, keepWord: true }),
22565
- paraPr(4, { align: "LEFT", spaceBefore: 300, spaceAfter: 100, lineSpacing: ls, keepWord: true }),
22582
+ // h3·h4 소제목("가." "1)")은 h2(□) 대항목의 하위다 — 종전에는 left가 없어 h2 부호가
22583
+ // 내어쓰기로 왼쪽에 나간 뒤 소제목이 본문 경계에서 시작해, 실렌더상 소제목이 대항목보다
22584
+ // 왼쪽에 놓이며 계층이 사라졌다(실렌더 확인). h2 부호폭만큼 들여써 h2 제목 글자와 맞춘다.
22585
+ paraPr(3, { align: "LEFT", left: h3Left, spaceBefore: 400, spaceAfter: 100, lineSpacing: ls, keepWord: true }),
22586
+ paraPr(4, { align: "LEFT", left: h3Left + Math.round(gongmun.bodyHeight / 2), spaceBefore: 300, spaceAfter: 100, lineSpacing: ls, keepWord: true }),
22566
22587
  paraPr(5, { align: "LEFT", lineSpacing: 130, indent: 400, keepWord: true }),
22567
22588
  paraPr(6, { align: "LEFT", lineSpacing: ls, indent: 600, keepWord: true }),
22568
22589
  paraPr(7, { align: "LEFT", lineSpacing: ls, indent: 600, keepWord: true })
@@ -25269,8 +25290,8 @@ function renderHtmlTable(block, ctx) {
25269
25290
  ctx.opener.emitCarrier(ctx.paraXmls);
25270
25291
  return `<hp:p paraPrIDRef="${tableStyle && bfReg ? GONGMUN_RIGHT : 0}" styleIDRef="0"><hp:run charPrIDRef="0">${tbl2}</hp:run></hp:p>`;
25271
25292
  }
25272
- const plain = (block.text || "").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
25273
- return plain ? generateParagraph(plain) : "";
25293
+ const plain2 = (block.text || "").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
25294
+ return plain2 ? generateParagraph(plain2) : "";
25274
25295
  }
25275
25296
  function appendPostamble(blocks, ctx) {
25276
25297
  const { gongmun, dfIds, bfReg, tableStyle, paraXmls } = ctx;
@@ -26185,6 +26206,233 @@ function gongmunLintWarnings(text, limit = 10) {
26185
26206
  return shown;
26186
26207
  }
26187
26208
 
26209
+ // src/hwpx/munche-lint.ts
26210
+ function usesGaejosikMunche(preset) {
26211
+ const p = normalizeGongmunPreset(preset);
26212
+ return p === "gaejosik" || p === "report" || p === "plan";
26213
+ }
26214
+ var ITEM_MAX = 70;
26215
+ var CONCL_MAX = 60;
26216
+ var LEAD_MAX = 140;
26217
+ function classify(raw) {
26218
+ const indent = raw.length - raw.trimStart().length;
26219
+ const t = raw.trim();
26220
+ if (!t) return null;
26221
+ if (t.startsWith("#") || t.startsWith("|") || t.startsWith("![") || /^[-=*_]{3,}$/.test(t)) return null;
26222
+ if (t.startsWith(">")) return { kind: "lead", body: t.slice(1).trim() };
26223
+ if (/^(?:⇒|=>|➡|→)/.test(t)) return { kind: "concl", body: t.replace(/^(?:⇒|=>|➡|→)\s*/, "") };
26224
+ if (/^(?:※|\*\s)/.test(t)) return { kind: "note", body: t.replace(/^(?:※|\*)\s*/, "") };
26225
+ if (t.startsWith("\u25A1")) return { kind: "dae", body: t.slice(1).trim() };
26226
+ if (/^(?:○|❍|ㅇ|◦)/.test(t)) return { kind: "item", body: t.slice(1).trim() };
26227
+ const li = /^(?:[-•ㆍ·]|\d+[.)])\s+(.*)$/.exec(t);
26228
+ if (li) return { kind: indent >= 2 ? "sub" : "item", body: li[1].trim() };
26229
+ return { kind: "para", body: t };
26230
+ }
26231
+ function plain(s) {
26232
+ return s.replace(/!?\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/(\*\*|__|~~|`)/g, "").trim();
26233
+ }
26234
+ function stripQuoted(s) {
26235
+ return s.replace(/[“"'‘][^”"'’]{0,80}[”"'’]/g, "").replace(/\([^)]{0,80}\)/g, "");
26236
+ }
26237
+ var DA_ENDING = /[가-힣]다\.?$/;
26238
+ var DEONTIC = /(?:해야|하여야|되어야|돼야|필요가 있)\s*(?:한다|함|합니다|하겠음)\.?$|할 것\.?$/;
26239
+ var GEOSIDA = /것(?:이다|임)\.?$/;
26240
+ var LEAD_ENDING = /(?:하고자|하려|고자)\s*함\.?$/;
26241
+ var NOT_A_BUT = /(?:아니라|아닌|아니고|아니며)\s*,?\s*([가-힣]{1,12})/g;
26242
+ var ABSTRACT = [
26243
+ "\uC0AC\uB78C",
26244
+ "\uB9C8\uC74C",
26245
+ "\uBCF8\uC9C8",
26246
+ "\uC804\uD658",
26247
+ "\uD0DC\uB3C4",
26248
+ "\uBB38\uD654",
26249
+ "\uCCA0\uD559",
26250
+ "\uAC00\uCE58",
26251
+ "\uC815\uC2E0",
26252
+ "\uAD00\uACC4",
26253
+ "\uC2E0\uB8B0",
26254
+ "\uACFC\uC815",
26255
+ "\uC9C8\uBB38",
26256
+ "\uC774\uC57C\uAE30",
26257
+ "\uACBD\uD5D8",
26258
+ "\uC2DC\uAC04",
26259
+ "\uACF5\uAC04",
26260
+ "\uC5F0\uACB0",
26261
+ "\uBCC0\uD654",
26262
+ "\uBBF8\uB798",
26263
+ "\uC2DC\uC791",
26264
+ "\uC6A9\uAE30",
26265
+ "\uC758\uC9C0",
26266
+ "\uBC29\uBC95",
26267
+ "\uC790\uC138",
26268
+ "\uC758\uC2DD",
26269
+ "\uC5ED\uB7C9"
26270
+ ];
26271
+ var COUPLET = /[은는이가]\s*[^,]{2,15},\s*[^,]{2,15}[은는이가]\s*[^,]{2,15}$/;
26272
+ var DATE_KOREAN = /\d{4}년\s*\d{1,2}월/;
26273
+ function lintMuncheText(text) {
26274
+ const findings = [];
26275
+ const lines = text.split(/\r?\n/);
26276
+ let fenceMarker = null;
26277
+ let frontMatter = false;
26278
+ let leadBuf = [];
26279
+ const add = (line, kind, severity, rule, match, message, suggest) => {
26280
+ findings.push({ line, kind, severity, rule, match: match.slice(0, 60), message, suggest });
26281
+ };
26282
+ const flushLead = () => {
26283
+ if (!leadBuf.length) return;
26284
+ const block = leadBuf.map((l) => l.body).join(" ").trim();
26285
+ const at = leadBuf[0].line;
26286
+ leadBuf = [];
26287
+ if (block.length < 20) return;
26288
+ if (!LEAD_ENDING.test(block)) {
26289
+ add(
26290
+ at,
26291
+ "lead",
26292
+ "warning",
26293
+ "LEAD_ENDING",
26294
+ block,
26295
+ "\uB9AC\uB4DC\uBB38\uC740 '~\uD558\uACE0\uC790 \uD568.' \uD55C \uBB38\uC7A5",
26296
+ "[\uC218\uB2E8]\uD558\uACE0, [\uC218\uB2E8]\uD558\uC5EC [\uBAA9\uC801]\uD558\uACE0\uC790 \uD568."
26297
+ );
26298
+ }
26299
+ const sentences = (block.match(/\./g) ?? []).length;
26300
+ if (block.length > LEAD_MAX || sentences > 1) {
26301
+ add(
26302
+ at,
26303
+ "lead",
26304
+ "warning",
26305
+ "LEAD_LONG",
26306
+ block,
26307
+ `\uB9AC\uB4DC\uBB38 ${block.length}\uC790\xB7\uBB38\uC7A5 ${sentences}\uAC1C \u2014 \uC2E4\uCE21\uC740 \uD55C \uBB38\uC7A5 40~120\uC790`,
26308
+ "\uC218\uB2E8 \uB458\xB7\uBAA9\uC801 \uD558\uB098\uB85C \uC555\uCD95"
26309
+ );
26310
+ }
26311
+ };
26312
+ for (let i = 0; i < lines.length; i++) {
26313
+ const raw = lines[i];
26314
+ const no = i + 1;
26315
+ if (raw.trim() === "---" && (frontMatter || no <= 3)) {
26316
+ if (no <= 3 || frontMatter) frontMatter = !frontMatter;
26317
+ continue;
26318
+ }
26319
+ if (frontMatter) continue;
26320
+ const fence = raw.match(/^\s*(```+|~~~+)/);
26321
+ if (fence) {
26322
+ const kind = fence[1][0];
26323
+ if (fenceMarker === null) fenceMarker = kind;
26324
+ else if (kind === fenceMarker) fenceMarker = null;
26325
+ continue;
26326
+ }
26327
+ if (fenceMarker !== null) continue;
26328
+ const c = classify(raw);
26329
+ if (!c) {
26330
+ flushLead();
26331
+ continue;
26332
+ }
26333
+ if (c.kind === "lead") {
26334
+ leadBuf.push({ line: no, body: plain(c.body) });
26335
+ continue;
26336
+ }
26337
+ flushLead();
26338
+ const b = plain(c.body);
26339
+ if (!b) continue;
26340
+ const q = stripQuoted(b);
26341
+ if (c.kind === "item" || c.kind === "sub" || c.kind === "concl" || c.kind === "para") {
26342
+ if (DA_ENDING.test(q)) {
26343
+ add(
26344
+ no,
26345
+ c.kind,
26346
+ "error",
26347
+ "DA_ENDING",
26348
+ b,
26349
+ "'~\uB2E4' \uC11C\uC220\uD615 \uC885\uACB0 \u2014 \uC2E4\uCE21 0%(\uD56D\uBAA9 0/264)",
26350
+ "\uBA85\uC0AC\xB7\uBA85\uC0AC\uAD6C \uB610\uB294 '~\uD568/\uC788\uC74C'\uC73C\uB85C"
26351
+ );
26352
+ }
26353
+ if (GEOSIDA.test(q)) {
26354
+ add(no, c.kind, "warning", "GEOSIDA", b, "'~\uAC83\uC774\uB2E4/\uAC83\uC784' \u2014 \uC2E4\uCE21 1\uAC74\uBFD0", "\uBA85\uC0AC \uC885\uACB0\uB85C");
26355
+ }
26356
+ }
26357
+ if (DEONTIC.test(q)) {
26358
+ add(
26359
+ no,
26360
+ c.kind,
26361
+ "error",
26362
+ "DEONTIC",
26363
+ b,
26364
+ "'~\uD574\uC57C \uD55C\uB2E4' \uB2F9\uC704 \uC885\uACB0 \u2014 \uD310\uB2E8\uC740 \uBA85\uC0AC\uB85C \uB05D\uB9FA\uC74C",
26365
+ "\uC608) \u21D2 \uC9C0\uC5ED\uB9DE\uCDA4\uD615 \uBCF4\uAE09 \uD544\uC694"
26366
+ );
26367
+ }
26368
+ NOT_A_BUT.lastIndex = 0;
26369
+ for (const m of q.matchAll(NOT_A_BUT)) {
26370
+ const tail = m[1] ?? "";
26371
+ if (ABSTRACT.some((w) => tail.includes(w))) {
26372
+ add(
26373
+ no,
26374
+ c.kind,
26375
+ "error",
26376
+ "RHETORIC_CONTRAST",
26377
+ m[0].trim(),
26378
+ `'\uC544\uB2C8\uB77C ${tail}' \u2014 B\uAC00 \uCD94\uC0C1\uC5B4\xB7\uAC00\uCE58\uC5B4\uBA74 \uC218\uC0AC(\uC2E4\uCE21 0\uAC74)`,
26379
+ "\uB450 \uAD6C\uCCB4 \uC120\uD0DD\uC9C0\uB97C \uAC00\uB974\uB294 \uACBD\uC6B0\uB9CC \uD5C8\uC6A9"
26380
+ );
26381
+ } else {
26382
+ add(
26383
+ no,
26384
+ c.kind,
26385
+ "warning",
26386
+ "CONTRAST_CHECK",
26387
+ m[0].trim(),
26388
+ `'\uC544\uB2C8\uB77C ${tail}' \u2014 B\uAC00 \uAD6C\uCCB4 \uC120\uD0DD\uC9C0(\uC81C\uB3C4\xB7\uC7A5\uC18C\xB7\uC808\uCC28)\uC778\uC9C0 \uD655\uC778`
26389
+ );
26390
+ }
26391
+ }
26392
+ if (c.kind !== "note" && /[?!?!]/.test(q)) {
26393
+ add(no, c.kind, "error", "QUESTION_EXCLAIM", b, "\uBB3C\uC74C\uD45C\xB7\uB290\uB08C\uD45C \u2014 \uBCF8\uBB38 \uC2E4\uCE21 0\uAC74");
26394
+ }
26395
+ if ((c.kind === "item" || c.kind === "para" || c.kind === "dae") && COUPLET.test(q)) {
26396
+ add(no, c.kind, "warning", "COUPLET", b, "\uB300\uAD6C(\u5C0D\u53E5)\uB85C \uBCF4\uC784 \u2014 \uC2AC\uB85C\uAC74 \uBB38\uC7A5\uC740 \uC2E4\uCE21 0\uAC74", "\uBAA9\uD45C \uC218\uCE58\xB7\uBA85\uC0AC\uB85C");
26397
+ }
26398
+ if (c.kind === "item" && b.length > ITEM_MAX) {
26399
+ add(
26400
+ no,
26401
+ c.kind,
26402
+ "warning",
26403
+ "ITEM_LONG",
26404
+ b,
26405
+ `\uD56D\uBAA9 ${b.length}\uC790 \u2014 \uC2E4\uCE21 \uC911\uC559 31\uC790, 2\uC904 \uD55C\uACC4`,
26406
+ "\uADFC\uAC70\xB7\uC608\uC2DC\uB294 \uC138\uBD80(-)\uB85C \uB0B4\uB9BC"
26407
+ );
26408
+ }
26409
+ if (c.kind === "concl" && b.length > CONCL_MAX) {
26410
+ add(
26411
+ no,
26412
+ c.kind,
26413
+ "warning",
26414
+ "CONCL_LONG",
26415
+ b,
26416
+ `\uACB0\uB860 ${b.length}\uC790 \u2014 \uC2E4\uCE21 \uC911\uC559 30\uC790`,
26417
+ "\uD310\uB2E8 \uD558\uB098\uB9CC \uB0A8\uAE40"
26418
+ );
26419
+ }
26420
+ if (DATE_KOREAN.test(b)) {
26421
+ add(no, c.kind, "warning", "DATE_KOREAN", b, "\uC5F0\xB7\uC6D4\uC744 \uAE00\uC790\uB85C \uD45C\uAE30", "\uC608) 2026. 8. 22.");
26422
+ }
26423
+ }
26424
+ flushLead();
26425
+ return findings;
26426
+ }
26427
+ function muncheLintWarnings(text, limit = 10) {
26428
+ const findings = lintMuncheText(text);
26429
+ const shown = findings.slice(0, limit).map(
26430
+ (f) => `\uBB38\uCCB4 [${f.rule}] L${f.line} "${f.match}" \u2014 ${f.message}${f.suggest ? ` (${f.suggest})` : ""}`
26431
+ );
26432
+ if (findings.length > limit) shown.push(`\uBB38\uCCB4 \uACBD\uACE0 ${findings.length - limit}\uAC74 \uB354 \uC788\uC74C \u2014 kordoc lint --munche\uB85C \uC804\uCCB4 \uD655\uC778`);
26433
+ return shown;
26434
+ }
26435
+
26188
26436
  // src/roundtrip/patcher.ts
26189
26437
  import JSZip10 from "jszip";
26190
26438
 
@@ -28942,7 +29190,7 @@ async function dispatch(format, buffer, opts) {
28942
29190
  }
28943
29191
  async function parseImage(buffer, options) {
28944
29192
  try {
28945
- const { parseImageDocument } = await import("./image-ocr-KCH5UMWN.js");
29193
+ const { parseImageDocument } = await import("./image-ocr-SQXFTNYR.js");
28946
29194
  const { blocks, warnings } = await parseImageDocument(buffer, options);
28947
29195
  return {
28948
29196
  success: true,
@@ -29001,7 +29249,7 @@ async function parseHwp(buffer, options) {
29001
29249
  async function parsePdf(buffer, options) {
29002
29250
  let parsePdfDocument;
29003
29251
  try {
29004
- const mod = await import("./parser-SPK4QG4F.js");
29252
+ const mod = await import("./parser-GHRXWFJN.js");
29005
29253
  parsePdfDocument = mod.parsePdfDocument;
29006
29254
  } catch {
29007
29255
  return {
@@ -29127,6 +29375,9 @@ export {
29127
29375
  unknownFontWarnings,
29128
29376
  lintGongmunText,
29129
29377
  gongmunLintWarnings,
29378
+ usesGaejosikMunche,
29379
+ lintMuncheText,
29380
+ muncheLintWarnings,
29130
29381
  patchHwpx,
29131
29382
  patchHwp,
29132
29383
  validateHwpx,
@@ -29148,4 +29399,4 @@ export {
29148
29399
  parseHwpml,
29149
29400
  fillForm
29150
29401
  };
29151
- //# sourceMappingURL=chunk-GLVZNMMN.js.map
29402
+ //# sourceMappingURL=chunk-JHXAQDXS.js.map