kordoc 4.4.1 → 4.6.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 (184) hide show
  1. package/LICENSE +21 -21
  2. package/NOTICE +176 -176
  3. package/README.md +958 -942
  4. package/THIRD_PARTY/apache-2.0.LICENSE +201 -201
  5. package/THIRD_PARTY/claw-hwp.LICENSE +21 -21
  6. package/THIRD_PARTY/hml-equation-parser.LICENSE +201 -201
  7. package/THIRD_PARTY/hml-equation-parser.txt +35 -35
  8. package/THIRD_PARTY/opendataloader-pdf.txt +32 -32
  9. package/THIRD_PARTY/pix2text.txt +17 -17
  10. package/THIRD_PARTY/rhwp-forms.txt +35 -35
  11. package/dist/{-7X4H77Z7.js → -DEVLQKIT.js} +12 -12
  12. package/dist/{chunk-TGAWXMXB.js → chunk-2CABQYTT.js} +23 -12
  13. package/dist/chunk-2CABQYTT.js.map +1 -0
  14. package/dist/{chunk-5A2TGIN7.js → chunk-2CENWSAW.js} +10 -10
  15. package/dist/chunk-2CENWSAW.js.map +1 -0
  16. package/dist/{chunk-3H5X63BQ.js → chunk-3FFPHTXD.js} +1 -1
  17. package/dist/chunk-3FFPHTXD.js.map +1 -0
  18. package/dist/{chunk-MOL7MDBG.js → chunk-3TBUDJDE.js} +1 -1
  19. package/dist/chunk-3TBUDJDE.js.map +1 -0
  20. package/dist/{chunk-5RPYBC2Q.js → chunk-6GBLFQMA.js} +1 -1
  21. package/dist/chunk-6GBLFQMA.js.map +1 -0
  22. package/dist/{chunk-GZDOWYJM.js → chunk-6XPXIG57.js} +2 -2
  23. package/dist/chunk-6XPXIG57.js.map +1 -0
  24. package/dist/{chunk-2352RXHG.js → chunk-7BTO44Q7.js} +337 -87
  25. package/dist/chunk-7BTO44Q7.js.map +1 -0
  26. package/dist/{chunk-GE43BE46.js → chunk-AIQ3ISQU.js} +1 -1
  27. package/dist/chunk-AIQ3ISQU.js.map +1 -0
  28. package/dist/{chunk-GC7WBHAN.cjs → chunk-CARNWWGI.cjs} +4 -4
  29. package/dist/chunk-CARNWWGI.cjs.map +1 -0
  30. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  31. package/dist/{chunk-FR65WNLF.cjs → chunk-HPRGVU6A.cjs} +25 -14
  32. package/dist/chunk-HPRGVU6A.cjs.map +1 -0
  33. package/dist/{chunk-3DX6VJGH.cjs → chunk-I42DND3B.cjs} +17 -17
  34. package/dist/chunk-I42DND3B.cjs.map +1 -0
  35. package/dist/{chunk-SMPEZINI.js → chunk-IBVMJIHR.js} +2 -2
  36. package/dist/chunk-IBVMJIHR.js.map +1 -0
  37. package/dist/{chunk-UA53AA7R.js → chunk-IHK5LCYX.js} +2 -2
  38. package/dist/chunk-IHK5LCYX.js.map +1 -0
  39. package/dist/{chunk-JGHQFUKI.js → chunk-KC63W72C.js} +2 -2
  40. package/dist/chunk-KC63W72C.js.map +1 -0
  41. package/dist/{chunk-NUGTEPKT.js → chunk-KQOTL4WI.js} +2 -2
  42. package/dist/chunk-KQOTL4WI.js.map +1 -0
  43. package/dist/{chunk-ZV5OKQ3Z.cjs → chunk-MGGU3ZRK.cjs} +1 -1
  44. package/dist/chunk-MGGU3ZRK.cjs.map +1 -0
  45. package/dist/{chunk-AYM6UHFX.js → chunk-MSMSHU2F.js} +23 -12
  46. package/dist/chunk-MSMSHU2F.js.map +1 -0
  47. package/dist/{chunk-DZIXKL7E.js → chunk-O5EK52TG.js} +1 -1
  48. package/dist/chunk-O5EK52TG.js.map +1 -0
  49. package/dist/{chunk-IPOVUGXD.js → chunk-OPL22SYF.js} +3 -3
  50. package/dist/chunk-OPL22SYF.js.map +1 -0
  51. package/dist/{chunk-HGSO2H44.js → chunk-PQDNCWAZ.js} +11 -11
  52. package/dist/chunk-PQDNCWAZ.js.map +1 -0
  53. package/dist/{chunk-A73RMJ6B.js → chunk-PSAHY5XW.js} +1 -1
  54. package/dist/chunk-PSAHY5XW.js.map +1 -0
  55. package/dist/{chunk-T25FBUMN.js → chunk-UGKXJA3W.js} +4 -3
  56. package/dist/chunk-UGKXJA3W.js.map +1 -0
  57. package/dist/{chunk-5PXCA3DN.js → chunk-UQ4NSK66.js} +3 -3
  58. package/dist/chunk-UQ4NSK66.js.map +1 -0
  59. package/dist/{chunk-7MDLAKVO.js → chunk-VNEV6VKD.js} +2 -2
  60. package/dist/chunk-VNEV6VKD.js.map +1 -0
  61. package/dist/{chunk-7FCNOKOR.js → chunk-W34QSJFF.js} +1 -1
  62. package/dist/chunk-W34QSJFF.js.map +1 -0
  63. package/dist/{chunk-7BIVNIK5.cjs → chunk-WX7WQTOT.cjs} +4 -3
  64. package/dist/chunk-WX7WQTOT.cjs.map +1 -0
  65. package/dist/{chunk-DCZVOIEO.cjs → chunk-X34YWRL5.cjs} +1 -1
  66. package/dist/chunk-X34YWRL5.cjs.map +1 -0
  67. package/dist/{chunk-UAFSPWU7.js → chunk-YNJDNP44.js} +1 -1
  68. package/dist/chunk-YNJDNP44.js.map +1 -0
  69. package/dist/{chunk-WA7XLWZW.js → chunk-ZYQ5X6PG.js} +4 -3
  70. package/dist/chunk-ZYQ5X6PG.js.map +1 -0
  71. package/dist/chunks-Y2VE2WCJ.js +10 -0
  72. package/dist/cli.js +91 -31
  73. package/dist/cli.js.map +1 -1
  74. package/dist/{formula-JLYS73QL.js → formula-ETB6MESN.js} +2 -2
  75. package/dist/formula-ETB6MESN.js.map +1 -0
  76. package/dist/{formula-LIVQSCMM.js → formula-KW4NI5IO.js} +2 -2
  77. package/dist/formula-KW4NI5IO.js.map +1 -0
  78. package/dist/{formula-CG4S7TWO.cjs → formula-WKGP3D3Y.cjs} +8 -8
  79. package/dist/formula-WKGP3D3Y.cjs.map +1 -0
  80. package/dist/{image-ocr-AHHY42OI.js → image-ocr-C6U7YHRC.js} +15 -7
  81. package/dist/image-ocr-C6U7YHRC.js.map +1 -0
  82. package/dist/{image-ocr-K4XCRBTY.js → image-ocr-YIBJCOUQ.js} +17 -9
  83. package/dist/image-ocr-YIBJCOUQ.js.map +1 -0
  84. package/dist/{image-ocr-VCXLT5Q6.cjs → image-ocr-YID6TDN5.cjs} +20 -12
  85. package/dist/image-ocr-YID6TDN5.cjs.map +1 -0
  86. package/dist/index.cjs +676 -426
  87. package/dist/index.cjs.map +1 -1
  88. package/dist/index.d.cts +55 -3
  89. package/dist/index.d.ts +55 -3
  90. package/dist/index.js +331 -81
  91. package/dist/index.js.map +1 -1
  92. package/dist/mcp.js +61 -28
  93. package/dist/mcp.js.map +1 -1
  94. package/dist/{models-6SIKLKRH.js → models-6VMAVZR6.js} +3 -3
  95. package/dist/page-range-CIRRJPXJ.js +7 -0
  96. package/dist/page-range-OF5I4PQY.js +8 -0
  97. package/dist/page-range-TPIRSA3J.cjs +8 -0
  98. package/dist/page-range-TPIRSA3J.cjs.map +1 -0
  99. package/dist/{parser-ABYM2MVN.cjs → parser-EYCVDUJA.cjs} +33 -33
  100. package/dist/parser-EYCVDUJA.cjs.map +1 -0
  101. package/dist/{parser-I3ELUUOG.js → parser-GFXZV2VJ.js} +11 -11
  102. package/dist/parser-GFXZV2VJ.js.map +1 -0
  103. package/dist/{parser-IPVY56U3.js → parser-SHM3JEH6.js} +9 -9
  104. package/dist/parser-SHM3JEH6.js.map +1 -0
  105. package/dist/pdf-ocr-TMAWPOHC.cjs +13 -0
  106. package/dist/pdf-ocr-TMAWPOHC.cjs.map +1 -0
  107. package/dist/pdf-ocr-UKFYODLP.js +15 -0
  108. package/dist/pdf-ocr-ZG4UVUIT.js +12 -0
  109. package/dist/{profile-io-YADU6SKH.js → profile-io-FQZNNA3O.js} +3 -3
  110. package/dist/{rasterize-YV5VDSQX.js → rasterize-QGKFNTXO.js} +2 -2
  111. package/dist/rasterize-QGKFNTXO.js.map +1 -0
  112. package/dist/{redact-7ILEAUTS.js → redact-W5K3ILQH.js} +2 -2
  113. package/dist/render-YFIWQYVB.js +10 -0
  114. package/dist/seal-GZ7NDWLR.js +10 -0
  115. package/dist/{setup-GUQT5ELJ.js → setup-I4I75QJU.js} +1 -1
  116. package/dist/setup-I4I75QJU.js.map +1 -0
  117. package/dist/{watch-5K2ZERXI.js → watch-OIVXH2RN.js} +12 -12
  118. package/dist/watch-OIVXH2RN.js.map +1 -0
  119. package/package.json +103 -103
  120. package/templates//352/260/204/354/235/264/352/270/260/354/225/210/353/254/270_/354/230/210/354/213/234/352/260/222.json +9 -9
  121. package/templates//354/235/274/353/260/230/352/270/260/354/225/210/353/254/270_/354/230/210/354/213/234/352/260/222.json +24 -24
  122. package/dist/chunk-2352RXHG.js.map +0 -1
  123. package/dist/chunk-3DX6VJGH.cjs.map +0 -1
  124. package/dist/chunk-3H5X63BQ.js.map +0 -1
  125. package/dist/chunk-5A2TGIN7.js.map +0 -1
  126. package/dist/chunk-5PXCA3DN.js.map +0 -1
  127. package/dist/chunk-5RPYBC2Q.js.map +0 -1
  128. package/dist/chunk-7BIVNIK5.cjs.map +0 -1
  129. package/dist/chunk-7FCNOKOR.js.map +0 -1
  130. package/dist/chunk-7MDLAKVO.js.map +0 -1
  131. package/dist/chunk-A73RMJ6B.js.map +0 -1
  132. package/dist/chunk-AYM6UHFX.js.map +0 -1
  133. package/dist/chunk-DCZVOIEO.cjs.map +0 -1
  134. package/dist/chunk-DZIXKL7E.js.map +0 -1
  135. package/dist/chunk-FR65WNLF.cjs.map +0 -1
  136. package/dist/chunk-GC7WBHAN.cjs.map +0 -1
  137. package/dist/chunk-GE43BE46.js.map +0 -1
  138. package/dist/chunk-GZDOWYJM.js.map +0 -1
  139. package/dist/chunk-HGSO2H44.js.map +0 -1
  140. package/dist/chunk-IPOVUGXD.js.map +0 -1
  141. package/dist/chunk-JGHQFUKI.js.map +0 -1
  142. package/dist/chunk-MOL7MDBG.js.map +0 -1
  143. package/dist/chunk-NUGTEPKT.js.map +0 -1
  144. package/dist/chunk-SMPEZINI.js.map +0 -1
  145. package/dist/chunk-T25FBUMN.js.map +0 -1
  146. package/dist/chunk-TGAWXMXB.js.map +0 -1
  147. package/dist/chunk-UA53AA7R.js.map +0 -1
  148. package/dist/chunk-UAFSPWU7.js.map +0 -1
  149. package/dist/chunk-WA7XLWZW.js.map +0 -1
  150. package/dist/chunk-ZV5OKQ3Z.cjs.map +0 -1
  151. package/dist/chunks-FMZK4QHL.js +0 -10
  152. package/dist/formula-CG4S7TWO.cjs.map +0 -1
  153. package/dist/formula-JLYS73QL.js.map +0 -1
  154. package/dist/formula-LIVQSCMM.js.map +0 -1
  155. package/dist/image-ocr-AHHY42OI.js.map +0 -1
  156. package/dist/image-ocr-K4XCRBTY.js.map +0 -1
  157. package/dist/image-ocr-VCXLT5Q6.cjs.map +0 -1
  158. package/dist/page-range-737B4EZW.js +0 -8
  159. package/dist/page-range-LNMXJU6W.js +0 -7
  160. package/dist/page-range-P7SDW6LR.cjs +0 -8
  161. package/dist/page-range-P7SDW6LR.cjs.map +0 -1
  162. package/dist/parser-ABYM2MVN.cjs.map +0 -1
  163. package/dist/parser-I3ELUUOG.js.map +0 -1
  164. package/dist/parser-IPVY56U3.js.map +0 -1
  165. package/dist/pdf-ocr-EL3VSWWY.js +0 -12
  166. package/dist/pdf-ocr-FVLKQNAT.js +0 -15
  167. package/dist/pdf-ocr-VQ3QWXGE.cjs +0 -13
  168. package/dist/pdf-ocr-VQ3QWXGE.cjs.map +0 -1
  169. package/dist/rasterize-YV5VDSQX.js.map +0 -1
  170. package/dist/render-K6M3P24X.js +0 -10
  171. package/dist/seal-YW3U5BCY.js +0 -10
  172. package/dist/setup-GUQT5ELJ.js.map +0 -1
  173. package/dist/watch-5K2ZERXI.js.map +0 -1
  174. /package/dist/{-7X4H77Z7.js.map → -DEVLQKIT.js.map} +0 -0
  175. /package/dist/{chunks-FMZK4QHL.js.map → chunks-Y2VE2WCJ.js.map} +0 -0
  176. /package/dist/{models-6SIKLKRH.js.map → models-6VMAVZR6.js.map} +0 -0
  177. /package/dist/{page-range-737B4EZW.js.map → page-range-CIRRJPXJ.js.map} +0 -0
  178. /package/dist/{page-range-LNMXJU6W.js.map → page-range-OF5I4PQY.js.map} +0 -0
  179. /package/dist/{pdf-ocr-EL3VSWWY.js.map → pdf-ocr-UKFYODLP.js.map} +0 -0
  180. /package/dist/{pdf-ocr-FVLKQNAT.js.map → pdf-ocr-ZG4UVUIT.js.map} +0 -0
  181. /package/dist/{profile-io-YADU6SKH.js.map → profile-io-FQZNNA3O.js.map} +0 -0
  182. /package/dist/{redact-7ILEAUTS.js.map → redact-W5K3ILQH.js.map} +0 -0
  183. /package/dist/{render-K6M3P24X.js.map → render-YFIWQYVB.js.map} +0 -0
  184. /package/dist/{seal-YW3U5BCY.js.map → seal-GZ7NDWLR.js.map} +0 -0
@@ -1,15 +1,15 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  inlineImagesIntoMarkdown
4
- } from "./chunk-7FCNOKOR.js";
4
+ } from "./chunk-W34QSJFF.js";
5
5
  import {
6
6
  HEADING_RATIO_H1,
7
7
  HEADING_RATIO_H2,
8
8
  HEADING_RATIO_H3
9
- } from "./chunk-A73RMJ6B.js";
9
+ } from "./chunk-PSAHY5XW.js";
10
10
  import {
11
11
  parsePageRange
12
- } from "./chunk-MOL7MDBG.js";
12
+ } from "./chunk-3TBUDJDE.js";
13
13
  import {
14
14
  allLinesegRemovalSplices,
15
15
  applySplices,
@@ -22,7 +22,7 @@ import {
22
22
  paraTextPureT,
23
23
  patchZipEntries,
24
24
  scanSectionXml
25
- } from "./chunk-IPOVUGXD.js";
25
+ } from "./chunk-OPL22SYF.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-SMPEZINI.js";
35
+ } from "./chunk-IBVMJIHR.js";
36
36
  import {
37
37
  SPACE_EM_FIXED,
38
38
  charWidthEm1000,
39
39
  fitRatioForFewerLines,
40
40
  measureTextWidth,
41
41
  simulateWrap
42
- } from "./chunk-5PXCA3DN.js";
42
+ } from "./chunk-UQ4NSK66.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-JGHQFUKI.js";
58
+ } from "./chunk-KC63W72C.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-WA7XLWZW.js";
70
+ } from "./chunk-ZYQ5X6PG.js";
71
71
 
72
72
  // src/index.ts
73
73
  import { readFile } from "fs/promises";
@@ -17858,7 +17858,7 @@ async function parseXlsxDocument(buffer, options) {
17858
17858
  }
17859
17859
  let pageFilter = null;
17860
17860
  if (options?.pages) {
17861
- const { parsePageRange: parsePageRange2 } = await import("./page-range-737B4EZW.js");
17861
+ const { parsePageRange: parsePageRange2 } = await import("./page-range-OF5I4PQY.js");
17862
17862
  pageFilter = parsePageRange2(options.pages, sheets.length);
17863
17863
  }
17864
17864
  const blocks = [];
@@ -18558,7 +18558,7 @@ async function parseXlsDocument(buffer, options) {
18558
18558
  const totalSheets = Math.min(globals.sheets.length, MAX_SHEETS2);
18559
18559
  let pageFilter = null;
18560
18560
  if (options?.pages) {
18561
- const { parsePageRange: parsePageRange2 } = await import("./page-range-737B4EZW.js");
18561
+ const { parsePageRange: parsePageRange2 } = await import("./page-range-OF5I4PQY.js");
18562
18562
  pageFilter = parsePageRange2(options.pages, totalSheets);
18563
18563
  }
18564
18564
  const allBlocks = [];
@@ -21654,6 +21654,26 @@ function charVariantBase(richAssets, isGongmun = true) {
21654
21654
  var GONGMUN_BODY_RATIO = 95;
21655
21655
 
21656
21656
  // src/hwpx/md-runs.ts
21657
+ var HYPERLINK_FIELDID = 627600491;
21658
+ var FIELD_ID_BASE = 18e8;
21659
+ var FOOTNOTE_INST_BASE = 185e7;
21660
+ var inlineDoc = null;
21661
+ function beginInlineDoc(footnotes) {
21662
+ inlineDoc = { footnotes, fieldSeq: 0, noteSeq: 0, inNote: false };
21663
+ }
21664
+ function endInlineDoc() {
21665
+ inlineDoc = null;
21666
+ }
21667
+ function extractFootnoteDefs(md2) {
21668
+ const defs = /* @__PURE__ */ new Map();
21669
+ const out = md2.replace(/\r\n?/g, "\n").split("\n").filter((line) => {
21670
+ const m = /^\[\^([^\]\s]+)\]:\s?(.*)$/.exec(line);
21671
+ if (!m) return true;
21672
+ defs.set(m[1], m[2].trim());
21673
+ return false;
21674
+ }).join("\n");
21675
+ return { md: defs.size > 0 ? out : md2, defs };
21676
+ }
21657
21677
  function buildPrvText(blocks) {
21658
21678
  const lines = [];
21659
21679
  let bytes = 0;
@@ -21845,12 +21865,49 @@ function parseInlineMarkdown(text) {
21845
21865
  return `\0${literals.length - 1}\0`;
21846
21866
  });
21847
21867
  text = text.replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1");
21848
- text = text.replace(/\[([^\]]*)\]\(([^)]*)\)/g, (_, t, u) => t || u);
21849
21868
  text = text.replace(/~~([^~]+)~~/g, "$1");
21869
+ let spans;
21870
+ if (inlineDoc) {
21871
+ spans = [];
21872
+ const re = /\[\^([^\]\s]+)\]|\[([^\]]*)\]\(([^)]*)\)/g;
21873
+ let last = 0;
21874
+ for (const m of text.matchAll(re)) {
21875
+ const idx = m.index;
21876
+ if (idx > last) spans.push(...emphasisSpans(text.slice(last, idx)));
21877
+ if (m[1] !== void 0) {
21878
+ const def = inlineDoc.inNote ? void 0 : inlineDoc.footnotes.get(m[1]);
21879
+ if (def !== void 0) spans.push({ text: "", bold: false, italic: false, code: false, note: def });
21880
+ else spans.push(...emphasisSpans(m[0]));
21881
+ } else {
21882
+ const anchor = m[2] || m[3];
21883
+ const href = sanitizeHref(m[3].trim()) ?? void 0;
21884
+ const sub = emphasisSpans(anchor);
21885
+ if (href) for (const s of sub) s.href = href;
21886
+ spans.push(...sub);
21887
+ }
21888
+ last = idx + m[0].length;
21889
+ }
21890
+ if (last < text.length) spans.push(...emphasisSpans(text.slice(last)));
21891
+ if (spans.length === 0) spans.push({ text, bold: false, italic: false, code: false });
21892
+ } else {
21893
+ text = text.replace(/\[([^\]]*)\]\(([^)]*)\)/g, (_, t, u) => t || u);
21894
+ spans = emphasisSpans(text);
21895
+ if (spans.length === 0) spans.push({ text, bold: false, italic: false, code: false });
21896
+ }
21897
+ for (const span of spans) {
21898
+ if (!span.text.includes("\0")) continue;
21899
+ span.text = span.text.replace(/\x00(\d+)\x00/g, (_, i) => {
21900
+ const c = literals[+i] ?? "";
21901
+ return span.code ? "\\" + c : c;
21902
+ });
21903
+ }
21904
+ return spans;
21905
+ }
21906
+ var INLINE_REGEX = /(`[^`]+`|\*{3}(?:[^*]|\*(?!\*\*))+\*{3}|\*{2}(?:[^*]|\*(?!\*))+\*{2}|\*(?:[^*]|\*{2}(?:[^*]|\*(?!\*))+\*{2})+\*|(?<![^\s\p{P}\p{S}\x00])(?<!_)_{2}(?=\S)[^_]+(?<=\S)_{2}(?!_)(?![^\s\p{P}\p{S}\x00])|(?<![^\s\p{P}\p{S}\x00])(?<!_)_(?=\S)[^_]+(?<=\S)_(?!_)(?![^\s\p{P}\p{S}\x00]))/gu;
21907
+ function emphasisSpans(text, depth = 0) {
21850
21908
  const spans = [];
21851
- const regex = /(`[^`]+`|\*{3}[^*]+\*{3}|\*{2}[^*]+\*{2}|\*[^*]+\*|(?<![^\s\p{P}\p{S}\x00])(?<!_)_{2}(?=\S)[^_]+(?<=\S)_{2}(?!_)(?![^\s\p{P}\p{S}\x00])|(?<![^\s\p{P}\p{S}\x00])(?<!_)_(?=\S)[^_]+(?<=\S)_(?!_)(?![^\s\p{P}\p{S}\x00]))/gu;
21852
21909
  let lastIdx = 0;
21853
- for (const match of text.matchAll(regex)) {
21910
+ for (const match of text.matchAll(INLINE_REGEX)) {
21854
21911
  const idx = match.index;
21855
21912
  if (idx > lastIdx) {
21856
21913
  spans.push({ text: text.slice(lastIdx, idx), bold: false, italic: false, code: false });
@@ -21858,28 +21915,34 @@ function parseInlineMarkdown(text) {
21858
21915
  const raw = match[0];
21859
21916
  if (raw.startsWith("`")) {
21860
21917
  spans.push({ text: raw.slice(1, -1), bold: false, italic: false, code: true });
21861
- } else if (raw.startsWith("***") || raw.startsWith("___")) {
21862
- spans.push({ text: raw.slice(3, -3), bold: true, italic: true, code: false });
21863
- } else if (raw.startsWith("**") || raw.startsWith("__")) {
21864
- spans.push({ text: raw.slice(2, -2), bold: true, italic: false, code: false });
21865
21918
  } else {
21866
- spans.push({ text: raw.slice(1, -1), bold: false, italic: true, code: false });
21919
+ let inner;
21920
+ let bold = false;
21921
+ let italic = false;
21922
+ if (raw.startsWith("***") || raw.startsWith("___")) {
21923
+ inner = raw.slice(3, -3);
21924
+ bold = true;
21925
+ italic = true;
21926
+ } else if (raw.startsWith("**") || raw.startsWith("__")) {
21927
+ inner = raw.slice(2, -2);
21928
+ bold = true;
21929
+ } else {
21930
+ inner = raw.slice(1, -1);
21931
+ italic = true;
21932
+ }
21933
+ if (depth < 3 && /[`*_]/.test(inner)) {
21934
+ for (const child of emphasisSpans(inner, depth + 1)) {
21935
+ spans.push(child.code ? child : { ...child, bold: child.bold || bold, italic: child.italic || italic });
21936
+ }
21937
+ } else {
21938
+ spans.push({ text: inner, bold, italic, code: false });
21939
+ }
21867
21940
  }
21868
21941
  lastIdx = idx + raw.length;
21869
21942
  }
21870
21943
  if (lastIdx < text.length) {
21871
21944
  spans.push({ text: text.slice(lastIdx), bold: false, italic: false, code: false });
21872
21945
  }
21873
- if (spans.length === 0) {
21874
- spans.push({ text, bold: false, italic: false, code: false });
21875
- }
21876
- for (const span of spans) {
21877
- if (!span.text.includes("\0")) continue;
21878
- span.text = span.text.replace(/\x00(\d+)\x00/g, (_, i) => {
21879
- const c = literals[+i] ?? "";
21880
- return span.code ? "\\" + c : c;
21881
- });
21882
- }
21883
21946
  return spans;
21884
21947
  }
21885
21948
  function spanToCharPrId(span) {
@@ -21889,13 +21952,54 @@ function spanToCharPrId(span) {
21889
21952
  if (span.italic) return CHAR_ITALIC;
21890
21953
  return CHAR_NORMAL;
21891
21954
  }
21955
+ function hyperlinkBeginXml(fid, href) {
21956
+ const cmd = escapeXml(href.replace(/:/g, "\\:"));
21957
+ const path = escapeXml(href);
21958
+ return `<hp:ctrl><hp:fieldBegin id="${fid}" type="HYPERLINK" name="" editable="0" dirty="0" zorder="-1" fieldid="${HYPERLINK_FIELDID}"><hp:parameters cnt="6" name=""><hp:integerParam name="Prop">0</hp:integerParam><hp:stringParam name="Command">${cmd};1;0;0</hp:stringParam><hp:stringParam name="Path">${path}</hp:stringParam><hp:stringParam name="Category">HWPHYPERLINK_TYPE_URL</hp:stringParam><hp:stringParam name="TargetType">HWPHYPERLINK_TARGET_BOOKMARK</hp:stringParam><hp:stringParam name="DocOpenType">HWPHYPERLINK_JUMP_CURRENTTAB</hp:stringParam></hp:parameters></hp:fieldBegin></hp:ctrl>`;
21959
+ }
21960
+ function footnoteXml(note, mapCharId) {
21961
+ const d = inlineDoc;
21962
+ const n = ++d.noteSeq;
21963
+ d.inNote = true;
21964
+ let body;
21965
+ try {
21966
+ body = generateRuns(note, CHAR_NORMAL, mapCharId);
21967
+ } finally {
21968
+ d.inNote = false;
21969
+ }
21970
+ return `<hp:ctrl><hp:footNote number="${n}" suffixChar="41" instId="${FOOTNOTE_INST_BASE + n}"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0"><hp:p paraPrIDRef="0" styleIDRef="0">${body}</hp:p></hp:subList></hp:footNote></hp:ctrl>`;
21971
+ }
21892
21972
  function generateRuns(text, defaultCharPr = CHAR_NORMAL, mapCharId) {
21893
21973
  const spans = parseInlineMarkdown(text);
21894
- return spans.map((span) => {
21895
- let charId = span.code || span.bold || span.italic ? spanToCharPrId(span) : defaultCharPr;
21896
- if (mapCharId) charId = mapCharId(charId);
21897
- return `<hp:run charPrIDRef="${charId}"><hp:t>${escapeXml(span.text)}</hp:t></hp:run>`;
21898
- }).join("");
21974
+ const mapped = (id) => mapCharId ? mapCharId(id) : id;
21975
+ const out = [];
21976
+ let openHref = null;
21977
+ let openFid = 0;
21978
+ const closeField = () => {
21979
+ if (openHref === null) return;
21980
+ out.push(`<hp:run charPrIDRef="${mapped(defaultCharPr)}"><hp:ctrl><hp:fieldEnd beginIDRef="${openFid}" fieldid="${HYPERLINK_FIELDID}"/></hp:ctrl></hp:run>`);
21981
+ openHref = null;
21982
+ };
21983
+ for (const span of spans) {
21984
+ if (span.note !== void 0 && inlineDoc) {
21985
+ closeField();
21986
+ out.push(`<hp:run charPrIDRef="${mapped(defaultCharPr)}">${footnoteXml(span.note, mapCharId)}</hp:run>`);
21987
+ continue;
21988
+ }
21989
+ const href = inlineDoc ? span.href ?? null : null;
21990
+ if (href !== openHref) {
21991
+ closeField();
21992
+ if (href !== null) {
21993
+ openFid = FIELD_ID_BASE + ++inlineDoc.fieldSeq;
21994
+ openHref = href;
21995
+ out.push(`<hp:run charPrIDRef="${mapped(defaultCharPr)}">${hyperlinkBeginXml(openFid, href)}</hp:run>`);
21996
+ }
21997
+ }
21998
+ const charId = span.code || span.bold || span.italic ? spanToCharPrId(span) : defaultCharPr;
21999
+ out.push(`<hp:run charPrIDRef="${mapped(charId)}"><hp:t>${escapeXml(span.text)}</hp:t></hp:run>`);
22000
+ }
22001
+ closeField();
22002
+ return out.join("");
21899
22003
  }
21900
22004
  function generateParagraph(text, paraPrId = PARA_NORMAL, charPrId = CHAR_NORMAL, mapCharId, styleId = 0) {
21901
22005
  if (paraPrId === PARA_CODE) {
@@ -21905,6 +22009,56 @@ function generateParagraph(text, paraPrId = PARA_NORMAL, charPrId = CHAR_NORMAL,
21905
22009
  return `<hp:p paraPrIDRef="${paraPrId}" styleIDRef="${styleId}">${runs}</hp:p>`;
21906
22010
  }
21907
22011
 
22012
+ // src/hwpx/gen-page.ts
22013
+ var PAPER_MM = {
22014
+ A4: [210, 297],
22015
+ A3: [297, 420],
22016
+ B4: [257, 364],
22017
+ B5: [182, 257],
22018
+ Letter: [215.9, 279.4]
22019
+ };
22020
+ function resolvePage(opts) {
22021
+ if (!opts) return null;
22022
+ const { size, orientation, columns, header, footer } = opts;
22023
+ if (size === void 0 && orientation === void 0 && columns === void 0 && header === void 0 && footer === void 0) return null;
22024
+ let wMm = 210, hMm = 297;
22025
+ if (size !== void 0) {
22026
+ if (typeof size === "string") {
22027
+ const preset = PAPER_MM[size];
22028
+ if (!preset) throw new Error(`\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC6A9\uC9C0 \uD504\uB9AC\uC14B: ${size} (A4\xB7A3\xB7B4\xB7B5\xB7Letter)`);
22029
+ [wMm, hMm] = preset;
22030
+ } else {
22031
+ if (!(size.widthMm > 0) || !(size.heightMm > 0) || size.widthMm > 1e3 || size.heightMm > 1e3) {
22032
+ throw new Error(`\uC6A9\uC9C0 \uCE58\uC218\uB294 0~1000mm \uBC94\uC704\uC5EC\uC57C \uD569\uB2C8\uB2E4: ${size.widthMm}\xD7${size.heightMm}`);
22033
+ }
22034
+ wMm = size.widthMm;
22035
+ hMm = size.heightMm;
22036
+ }
22037
+ }
22038
+ const cols = columns ?? 1;
22039
+ if (!Number.isInteger(cols) || cols < 1 || cols > 8) {
22040
+ throw new Error(`\uB2E4\uB2E8 \uAC1C\uC218\uB294 1~8 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4: ${columns}`);
22041
+ }
22042
+ const paperHU = (mm) => Math.floor(mm * 7200 / 25.4);
22043
+ return {
22044
+ widthHU: size === void 0 ? A4_W_HU : paperHU(wMm),
22045
+ heightHU: size === void 0 ? A4_H_HU : paperHU(hMm),
22046
+ // 실측: 용지 치수는 방향과 무관하게 유지, 방향은 landscape 속성만 바뀐다
22047
+ landscape: orientation === "landscape" ? "NARROWLY" : "WIDELY",
22048
+ columns: cols,
22049
+ header: header?.trim() ? header.trim() : null,
22050
+ footer: footer?.trim() ? footer.trim() : null
22051
+ };
22052
+ }
22053
+ function columnColPrXml(columns) {
22054
+ const gap = columns > 1 ? 2268 : 0;
22055
+ return `<hp:ctrl><hp:colPr id="" type="NEWSPAPER" layout="LEFT" colCount="${columns}" sameSz="1" sameGap="${gap}"/></hp:ctrl>`;
22056
+ }
22057
+ function headerFooterCtrl(tag, text, id, mapCharId) {
22058
+ const runs = generateRuns(text, void 0, mapCharId);
22059
+ return `<hp:ctrl><hp:${tag} id="${id}" applyPageType="BOTH"><hp:subList id="" textDirection="HORIZONTAL" lineWrap="BREAK" vertAlign="TOP" linkListIDRef="0" linkListNextIDRef="0" textWidth="0" textHeight="0" hasTextRef="0" hasNumRef="0"><hp:p paraPrIDRef="0" styleIDRef="0">${runs}</hp:p></hp:subList></hp:${tag}></hp:ctrl>`;
22060
+ }
22061
+
21908
22062
  // src/hwpx/gen-header.ts
21909
22063
  function generateContainerXml() {
21910
22064
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
@@ -23495,15 +23649,65 @@ var IMAGE_EXT_MIME = {
23495
23649
  tif: "image/tiff",
23496
23650
  tiff: "image/tiff"
23497
23651
  };
23652
+ function sniffImage(b) {
23653
+ if (b.length >= 8 && b[0] === 137 && b[1] === 80 && b[2] === 78 && b[3] === 71) return { mime: "image/png", ext: "png" };
23654
+ if (b.length >= 3 && b[0] === 255 && b[1] === 216 && b[2] === 255) return { mime: "image/jpeg", ext: "jpg" };
23655
+ if (b.length >= 6 && b[0] === 71 && b[1] === 73 && b[2] === 70) return { mime: "image/gif", ext: "gif" };
23656
+ if (b.length >= 2 && b[0] === 66 && b[1] === 77) return { mime: "image/bmp", ext: "bmp" };
23657
+ return null;
23658
+ }
23659
+ function probeImageSize(b) {
23660
+ const dv = new DataView(b.buffer, b.byteOffset, b.byteLength);
23661
+ try {
23662
+ if (b[0] === 137 && b[1] === 80) {
23663
+ return { w: dv.getUint32(16), h: dv.getUint32(20) };
23664
+ }
23665
+ if (b[0] === 255 && b[1] === 216) {
23666
+ let i = 2;
23667
+ while (i + 9 < b.length) {
23668
+ if (b[i] !== 255) {
23669
+ i++;
23670
+ continue;
23671
+ }
23672
+ const marker = b[i + 1];
23673
+ if (marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204) {
23674
+ return { w: dv.getUint16(i + 7), h: dv.getUint16(i + 5) };
23675
+ }
23676
+ i += 2 + dv.getUint16(i + 2);
23677
+ }
23678
+ return null;
23679
+ }
23680
+ if (b[0] === 71 && b[1] === 73) {
23681
+ return { w: dv.getUint16(6, true), h: dv.getUint16(8, true) };
23682
+ }
23683
+ if (b[0] === 66 && b[1] === 77) {
23684
+ return { w: dv.getUint32(18, true), h: Math.abs(dv.getInt32(22, true)) };
23685
+ }
23686
+ } catch {
23687
+ }
23688
+ return null;
23689
+ }
23690
+ var PX_TO_HU = 75;
23691
+ var MAX_IMG_W_HU = 48189;
23498
23692
  var ImageRegistry = class {
23693
+ /** @param supplied url → 실데이터 바이트 (markdownToHwpx images 옵션) */
23694
+ constructor(supplied) {
23695
+ this.supplied = supplied;
23696
+ }
23499
23697
  byUrl = /* @__PURE__ */ new Map();
23500
23698
  ids = /* @__PURE__ */ new Set();
23501
23699
  parts = [];
23502
23700
  picSeq = 0;
23701
+ binSeq = 0;
23503
23702
  /** url 등록(중복 시 기존 파트) — 수용 불가면 null */
23504
23703
  take(url) {
23505
23704
  const cached = this.byUrl.get(url);
23506
23705
  if (cached !== void 0) return cached;
23706
+ const real = this.takeReal(url);
23707
+ if (real) {
23708
+ this.byUrl.set(url, real);
23709
+ return real;
23710
+ }
23507
23711
  let part = null;
23508
23712
  const m = /^([A-Za-z0-9._-]+)\.([A-Za-z0-9]+)$/.exec(url);
23509
23713
  const mime = m ? IMAGE_EXT_MIME[m[2].toLowerCase()] : void 0;
@@ -23523,6 +23727,41 @@ var ImageRegistry = class {
23523
23727
  this.byUrl.set(url, part);
23524
23728
  return part;
23525
23729
  }
23730
+ /** 실데이터 등록 — images 맵 바이트·data: URI. 포맷 미상(webp 등)은 null → placeholder 폴백 */
23731
+ takeReal(url) {
23732
+ let bytes = this.supplied?.get(url);
23733
+ if (!bytes && url.startsWith("data:")) {
23734
+ const m = /^data:image\/[a-z+]+;base64,([A-Za-z0-9+/=\s]+)$/i.exec(url);
23735
+ if (m) {
23736
+ try {
23737
+ bytes = new Uint8Array(Buffer.from(m[1].replace(/\s+/g, ""), "base64"));
23738
+ } catch {
23739
+ }
23740
+ }
23741
+ }
23742
+ if (!bytes || bytes.length === 0) return null;
23743
+ const sniffed = sniffImage(bytes);
23744
+ if (!sniffed) return null;
23745
+ const safe = /^([A-Za-z0-9._-]+)\.([A-Za-z0-9]+)$/.exec(url);
23746
+ const base = safe && !url.includes("..") ? safe[1] : `image${++this.binSeq}`;
23747
+ let itemId = base.replace(/[^A-Za-z0-9_]/g, "_");
23748
+ let n = 1;
23749
+ while (this.ids.has(itemId)) itemId = `${base.replace(/[^A-Za-z0-9_]/g, "_")}_${n++}`;
23750
+ this.ids.add(itemId);
23751
+ const dim = probeImageSize(bytes);
23752
+ let wHU, hHU;
23753
+ if (dim && dim.w > 0 && dim.h > 0) {
23754
+ wHU = dim.w * PX_TO_HU;
23755
+ hHU = dim.h * PX_TO_HU;
23756
+ if (wHU > MAX_IMG_W_HU) {
23757
+ hHU = Math.round(hHU * (MAX_IMG_W_HU / wHU));
23758
+ wHU = MAX_IMG_W_HU;
23759
+ }
23760
+ }
23761
+ const part = { name: `BinData/${itemId}.${sniffed.ext}`, itemId, mime: sniffed.mime, data: bytes, wHU, hHU };
23762
+ this.parts.push(part);
23763
+ return part;
23764
+ }
23526
23765
  /** manifest <opf:item> 조각들 (실측: isEmbeded="1") */
23527
23766
  manifestItems() {
23528
23767
  return this.parts.map((p) => `<opf:item id="${p.itemId}" href="${p.name}" media-type="${p.mime}" isEmbeded="1"/>`);
@@ -23530,8 +23769,9 @@ var ImageRegistry = class {
23530
23769
  /** 인라인 <hp:pic> XML — 실측 저장본 미러, treatAsChar=1 (셀·문단 안 배치) */
23531
23770
  inlinePicXml(part) {
23532
23771
  const id = PIC_ID_BASE + ++this.picSeq;
23533
- const s = 1130;
23534
- return `<hp:pic id="${id}" zOrder="0" numberingType="PICTURE" textWrap="TOP_AND_BOTTOM" textFlow="BOTH_SIDES" lock="0" dropcapstyle="None" href="" groupLevel="0" instid="${id}" reverse="0" xmlns:hc="http://www.hancom.co.kr/hwpml/2011/core"><hp:offset x="0" y="0"/><hp:orgSz width="${s}" height="${s}"/><hp:curSz width="${s}" height="${s}"/><hp:flip horizontal="0" vertical="0"/><hp:rotationInfo angle="0" centerX="${s / 2}" centerY="${s / 2}" rotateimage="1"/><hp:renderingInfo><hc:transMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/><hc:scaMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/><hc:rotMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/></hp:renderingInfo><hp:imgRect><hc:pt0 x="0" y="0"/><hc:pt1 x="${s}" y="0"/><hc:pt2 x="${s}" y="${s}"/><hc:pt3 x="0" y="${s}"/></hp:imgRect><hp:imgClip left="0" right="${s}" top="0" bottom="${s}"/><hp:inMargin left="0" right="0" top="0" bottom="0"/><hp:imgDim dimwidth="${s}" dimheight="${s}"/><hc:img binaryItemIDRef="${part.itemId}" bright="0" contrast="0" effect="REAL_PIC" alpha="0"/><hp:effects/><hp:sz width="${s}" widthRelTo="ABSOLUTE" height="${s}" heightRelTo="ABSOLUTE" protect="0"/><hp:pos treatAsChar="1" affectLSpacing="0" flowWithText="1" allowOverlap="0" holdAnchorAndSO="0" vertRelTo="PARA" horzRelTo="PARA" vertAlign="TOP" horzAlign="LEFT" vertOffset="0" horzOffset="0"/><hp:outMargin left="0" right="0" top="0" bottom="0"/></hp:pic>`;
23772
+ const w = part.wHU ?? 1130;
23773
+ const h = part.hHU ?? 1130;
23774
+ return `<hp:pic id="${id}" zOrder="0" numberingType="PICTURE" textWrap="TOP_AND_BOTTOM" textFlow="BOTH_SIDES" lock="0" dropcapstyle="None" href="" groupLevel="0" instid="${id}" reverse="0" xmlns:hc="http://www.hancom.co.kr/hwpml/2011/core"><hp:offset x="0" y="0"/><hp:orgSz width="${w}" height="${h}"/><hp:curSz width="${w}" height="${h}"/><hp:flip horizontal="0" vertical="0"/><hp:rotationInfo angle="0" centerX="${Math.floor(w / 2)}" centerY="${Math.floor(h / 2)}" rotateimage="1"/><hp:renderingInfo><hc:transMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/><hc:scaMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/><hc:rotMatrix e1="1" e2="0" e3="0" e4="0" e5="1" e6="0"/></hp:renderingInfo><hp:imgRect><hc:pt0 x="0" y="0"/><hc:pt1 x="${w}" y="0"/><hc:pt2 x="${w}" y="${h}"/><hc:pt3 x="0" y="${h}"/></hp:imgRect><hp:imgClip left="0" right="${w}" top="0" bottom="${h}"/><hp:inMargin left="0" right="0" top="0" bottom="0"/><hp:imgDim dimwidth="${w}" dimheight="${h}"/><hc:img binaryItemIDRef="${part.itemId}" bright="0" contrast="0" effect="REAL_PIC" alpha="0"/><hp:effects/><hp:sz width="${w}" widthRelTo="ABSOLUTE" height="${h}" heightRelTo="ABSOLUTE" protect="0"/><hp:pos treatAsChar="1" affectLSpacing="0" flowWithText="1" allowOverlap="0" holdAnchorAndSO="0" vertRelTo="PARA" horzRelTo="PARA" vertAlign="TOP" horzAlign="LEFT" vertOffset="0" horzOffset="0"/><hp:outMargin left="0" right="0" top="0" bottom="0"/></hp:pic>`;
23535
23775
  }
23536
23776
  };
23537
23777
  var MD_IMAGE_RE = /!\[[^\]]*\]\(([^)\s]+)\)/g;
@@ -24418,7 +24658,7 @@ function generateEquationParagraph(input, zOrder = 0) {
24418
24658
  }
24419
24659
 
24420
24660
  // src/hwpx/gen-section.ts
24421
- function generateSecPr(gongmun) {
24661
+ function generateSecPr(gongmun, page = null) {
24422
24662
  const m = gongmun ? {
24423
24663
  top: mmToHwpunit(gongmun.margins.top),
24424
24664
  bottom: mmToHwpunit(gongmun.margins.bottom),
@@ -24431,13 +24671,15 @@ function generateSecPr(gongmun) {
24431
24671
  m.header = gongmun.headerFooter;
24432
24672
  m.footer = gongmun.headerFooter;
24433
24673
  }
24434
- const secPr = `<hp:secPr textDirection="HORIZONTAL" spaceColumns="1134" tabStop="8000" outlineShapeIDRef="1" memoShapeIDRef="0" textVerticalWidthHead="0" masterPageCnt="0"><hp:grid lineGrid="0" charGrid="0" wonggojiFormat="0"/><hp:startNum pageStartsOn="BOTH" page="0" pic="0" tbl="0" equation="0"/><hp:visibility hideFirstHeader="0" hideFirstFooter="0" hideFirstMasterPage="0" border="SHOW_ALL" fill="SHOW_ALL" hideFirstPageNum="0" hideFirstEmptyLine="0" showLineNumber="0"/><hp:pagePr landscape="WIDELY" width="${A4_W_HU}" height="${A4_H_HU}" gutterType="LEFT_ONLY"><hp:margin header="${m.header}" footer="${m.footer}" gutter="0" left="${m.left}" right="${m.right}" top="${m.top}" bottom="${m.bottom}"/></hp:pagePr><hp:footNotePr><hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/><hp:noteLine length="-1" type="SOLID" width="0.12 mm" color="#000000"/><hp:noteSpacing betweenNotes="283" belowLine="567" aboveLine="850"/><hp:numbering type="CONTINUOUS" newNum="1"/><hp:placement place="EACH_COLUMN" beneathText="0"/></hp:footNotePr><hp:endNotePr><hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/><hp:noteLine length="14692344" type="SOLID" width="0.12 mm" color="#000000"/><hp:noteSpacing betweenNotes="0" belowLine="567" aboveLine="850"/><hp:numbering type="CONTINUOUS" newNum="1"/><hp:placement place="END_OF_DOCUMENT" beneathText="0"/></hp:endNotePr></hp:secPr>`;
24435
- const colPr = `<hp:ctrl><hp:colPr id="" type="NEWSPAPER" layout="LEFT" colCount="1" sameSz="1" sameGap="0"/></hp:ctrl>`;
24436
- return secPr + colPr + (gongmun?.pageNumbers ? pageNumCtrl() : "");
24674
+ const secPr = `<hp:secPr textDirection="HORIZONTAL" spaceColumns="1134" tabStop="8000" outlineShapeIDRef="1" memoShapeIDRef="0" textVerticalWidthHead="0" masterPageCnt="0"><hp:grid lineGrid="0" charGrid="0" wonggojiFormat="0"/><hp:startNum pageStartsOn="BOTH" page="0" pic="0" tbl="0" equation="0"/><hp:visibility hideFirstHeader="0" hideFirstFooter="0" hideFirstMasterPage="0" border="SHOW_ALL" fill="SHOW_ALL" hideFirstPageNum="0" hideFirstEmptyLine="0" showLineNumber="0"/><hp:pagePr landscape="${page?.landscape ?? "WIDELY"}" width="${page?.widthHU ?? A4_W_HU}" height="${page?.heightHU ?? A4_H_HU}" gutterType="LEFT_ONLY"><hp:margin header="${m.header}" footer="${m.footer}" gutter="0" left="${m.left}" right="${m.right}" top="${m.top}" bottom="${m.bottom}"/></hp:pagePr><hp:footNotePr><hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/><hp:noteLine length="-1" type="SOLID" width="0.12 mm" color="#000000"/><hp:noteSpacing betweenNotes="283" belowLine="567" aboveLine="850"/><hp:numbering type="CONTINUOUS" newNum="1"/><hp:placement place="EACH_COLUMN" beneathText="0"/></hp:footNotePr><hp:endNotePr><hp:autoNumFormat type="DIGIT" userChar="" prefixChar="" suffixChar=")" supscript="0"/><hp:noteLine length="14692344" type="SOLID" width="0.12 mm" color="#000000"/><hp:noteSpacing betweenNotes="0" belowLine="567" aboveLine="850"/><hp:numbering type="CONTINUOUS" newNum="1"/><hp:placement place="END_OF_DOCUMENT" beneathText="0"/></hp:endNotePr></hp:secPr>`;
24675
+ const colPr = columnColPrXml(page?.columns ?? 1);
24676
+ const hf = (page?.header ? headerFooterCtrl("header", page.header, 1) : "") + (page?.footer ? headerFooterCtrl("footer", page.footer, 2) : "");
24677
+ return secPr + colPr + hf + (gongmun?.pageNumbers ? pageNumCtrl() : "");
24437
24678
  }
24438
24679
  var SectionOpener = class {
24439
- constructor(gongmun) {
24680
+ constructor(gongmun, page = null) {
24440
24681
  this.gongmun = gongmun;
24682
+ this.page = page;
24441
24683
  }
24442
24684
  pending = true;
24443
24685
  /** 아직 secPr를 나를 첫 문단이 안 나왔는가 */
@@ -24449,7 +24691,7 @@ var SectionOpener = class {
24449
24691
  this.pending = false;
24450
24692
  return xml.replace(
24451
24693
  /<hp:run charPrIDRef="(\d+)">/,
24452
- `<hp:run charPrIDRef="$1">${generateSecPr(this.gongmun)}`
24694
+ `<hp:run charPrIDRef="$1">${generateSecPr(this.gongmun, this.page)}`
24453
24695
  );
24454
24696
  }
24455
24697
  /**
@@ -24459,13 +24701,13 @@ var SectionOpener = class {
24459
24701
  emitCarrier(paraXmls) {
24460
24702
  if (!this.pending) return;
24461
24703
  this.pending = false;
24462
- const secRun = `<hp:run charPrIDRef="0">${generateSecPr(this.gongmun)}<hp:t></hp:t></hp:run>`;
24704
+ const secRun = `<hp:run charPrIDRef="0">${generateSecPr(this.gongmun, this.page)}<hp:t></hp:t></hp:run>`;
24463
24705
  paraXmls.push(`<hp:p paraPrIDRef="0" styleIDRef="0">${secRun}</hp:p>`);
24464
24706
  }
24465
24707
  /** 빈 문서 폴백 — secPr를 실은 빈 단락 XML */
24466
24708
  emptyDoc() {
24467
24709
  this.pending = false;
24468
- return `<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="0">${generateSecPr(this.gongmun)}<hp:t></hp:t></hp:run></hp:p>`;
24710
+ return `<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="0">${generateSecPr(this.gongmun, this.page)}<hp:t></hp:t></hp:run></hp:p>`;
24469
24711
  }
24470
24712
  };
24471
24713
  function buildPreamble(blocks, ctx) {
@@ -24706,7 +24948,7 @@ function appendPostamble(blocks, ctx) {
24706
24948
  paraXmls.push(...buildPressContact(gongmun, dfIds, tableStyle.totalWidth, bfReg));
24707
24949
  }
24708
24950
  }
24709
- function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null, fit = null, chartParts = null, bfReg = null, remap = null, dfIds = null, images = null) {
24951
+ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null, fit = null, chartParts = null, bfReg = null, remap = null, dfIds = null, images = null, page = null) {
24710
24952
  resetTableIds();
24711
24953
  resetGjTableIds();
24712
24954
  resetExtraTableIds();
@@ -24745,7 +24987,7 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
24745
24987
  // 개조식 장식표(표지·목차·장헤더·제목박스) 폭 스케일용 본문폭 — margins 오버라이드 대응
24746
24988
  gjBodyW: gongmun ? mmToHwpunit(210 - gongmun.margins.left - gongmun.margins.right) : GAEJOSIK_BASE_WIDTH,
24747
24989
  chamMap: (id) => id === CHAR_BOLD ? GJ_CHAR_CHAM_BOLD : id,
24748
- opener: new SectionOpener(gongmun),
24990
+ opener: new SectionOpener(gongmun, page),
24749
24991
  paraXmls: [],
24750
24992
  // 표 방출 순번 — 생성 성공 여부와 무관하게 '시도' 기준으로 센다. 실패한 표가 이후
24751
24993
  // 표들의 순번을 밀면 앵커 없는 프로필(손편집·구버전)의 table_index 매칭이 어긋난다.
@@ -24830,45 +25072,53 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
24830
25072
  async function markdownToHwpx(markdown, options) {
24831
25073
  const theme = resolveTheme(options?.theme);
24832
25074
  const gongmun = options?.gongmun ? resolveGongmun(options.gongmun) : null;
24833
- const measured = !!gongmun && usesReportFonts(gongmun.preset);
24834
- const richAssets = !!gongmun && needsGaejosikAssets(gongmun);
24835
- const blocks = parseMarkdownToBlocks(markdown);
24836
- const gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null;
24837
- const fit = gongmun && gongmunList ? computeGongmunFitPlan(blocks, gongmun, gongmunList) : null;
24838
- const staticBfEnd = staticBorderFillNext(gongmun);
24839
- const remap = options?.profile ? buildProfileRemap(options.profile, charVariantBase(richAssets, !!gongmun) + (fit?.variants?.length ?? 0) * 4, staticBfEnd, staticFontNext(gongmun)) : null;
24840
- const bfReg = gongmun ? new TableBfRegistry(staticBfEnd + (remap?.borderFillXmls.length ?? 0)) : null;
24841
- const dfActive = !!gongmun && docframeActive(gongmun);
24842
- const dfBase = charVariantBase(richAssets, !!gongmun) + (fit?.variants?.length ?? 0) * 4 + (remap?.charPrXmls.length ?? 0);
24843
- const dfIds = dfActive ? docframeIds(dfBase) : null;
24844
- const chartParts = [];
24845
- const images = new ImageRegistry();
24846
- const sectionXml = blocksToSectionXml(blocks, theme, gongmun, gongmunList, fit, chartParts, bfReg, remap, dfIds, images);
24847
- if (remap && remap.tables.length > 0) {
24848
- const unused = remap.tables.filter((t) => !t.used).length;
24849
- if (unused === remap.tables.length) {
24850
- console.warn(`[kordoc] format profile: \uD504\uB85C\uD544 \uD45C ${unused}\uAC1C\uAC00 \uBB38\uC11C \uD45C\uC640 \uB9E4\uCE6D\uB418\uC9C0 \uC54A\uC544 \uBBF8\uC801\uC6A9 (\uD589\xB7\uC5F4/\uCCAB \uC140 \uD14D\uC2A4\uD2B8 \uBD88\uC77C\uCE58)`);
24851
- }
24852
- }
24853
- const extraBorderFills = [...remap?.borderFillXmls ?? [], ...bfReg?.emit() ?? []];
24854
- const zip = new JSZip8();
24855
- zip.file("mimetype", "application/hwp+zip", { compression: "STORE" });
24856
- zip.file("META-INF/container.xml", generateContainerXml());
24857
- zip.file("Contents/content.hpf", generateManifest(chartParts, images.manifestItems(), gongmun ? "gongmun" : "default"));
24858
- for (const part of images.parts) zip.file(part.name, part.data);
24859
- zip.file("Contents/header.xml", generateHeaderXml(
24860
- theme,
24861
- gongmun,
24862
- fit?.variants ?? [],
24863
- extraBorderFills,
24864
- [...remap?.charPrXmls ?? [], ...dfActive ? docframeCharPrXmls(dfBase, richAssets) : []],
24865
- gongmunList?.indentVariants ?? [],
24866
- remap?.fontFaces ?? []
24867
- ));
24868
- zip.file("Contents/section0.xml", sectionXml);
24869
- for (const part of chartParts) zip.file(part.name, part.xml);
24870
- zip.file("Preview/PrvText.txt", buildPrvText(blocks));
24871
- return await zip.generateAsync({ type: "arraybuffer" });
25075
+ const page = resolvePage(options?.page);
25076
+ const { md: md2, defs } = extractFootnoteDefs(markdown);
25077
+ beginInlineDoc(defs);
25078
+ try {
25079
+ const measured = !!gongmun && usesReportFonts(gongmun.preset);
25080
+ const richAssets = !!gongmun && needsGaejosikAssets(gongmun);
25081
+ const blocks = parseMarkdownToBlocks(md2);
25082
+ const gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null;
25083
+ const fit = gongmun && gongmunList ? computeGongmunFitPlan(blocks, gongmun, gongmunList) : null;
25084
+ const staticBfEnd = staticBorderFillNext(gongmun);
25085
+ const remap = options?.profile ? buildProfileRemap(options.profile, charVariantBase(richAssets, !!gongmun) + (fit?.variants?.length ?? 0) * 4, staticBfEnd, staticFontNext(gongmun)) : null;
25086
+ const bfReg = gongmun ? new TableBfRegistry(staticBfEnd + (remap?.borderFillXmls.length ?? 0)) : null;
25087
+ const dfActive = !!gongmun && docframeActive(gongmun);
25088
+ const dfBase = charVariantBase(richAssets, !!gongmun) + (fit?.variants?.length ?? 0) * 4 + (remap?.charPrXmls.length ?? 0);
25089
+ const dfIds = dfActive ? docframeIds(dfBase) : null;
25090
+ const chartParts = [];
25091
+ const supplied = options?.images ? new Map(Object.entries(options.images).map(([k, v]) => [k, v instanceof Uint8Array ? v : new Uint8Array(v)])) : void 0;
25092
+ const images = new ImageRegistry(supplied);
25093
+ const sectionXml = blocksToSectionXml(blocks, theme, gongmun, gongmunList, fit, chartParts, bfReg, remap, dfIds, images, page);
25094
+ if (remap && remap.tables.length > 0) {
25095
+ const unused = remap.tables.filter((t) => !t.used).length;
25096
+ if (unused === remap.tables.length) {
25097
+ console.warn(`[kordoc] format profile: \uD504\uB85C\uD544 \uD45C ${unused}\uAC1C\uAC00 \uBB38\uC11C \uD45C\uC640 \uB9E4\uCE6D\uB418\uC9C0 \uC54A\uC544 \uBBF8\uC801\uC6A9 (\uD589\xB7\uC5F4/\uCCAB \uC140 \uD14D\uC2A4\uD2B8 \uBD88\uC77C\uCE58)`);
25098
+ }
25099
+ }
25100
+ const extraBorderFills = [...remap?.borderFillXmls ?? [], ...bfReg?.emit() ?? []];
25101
+ const zip = new JSZip8();
25102
+ zip.file("mimetype", "application/hwp+zip", { compression: "STORE" });
25103
+ zip.file("META-INF/container.xml", generateContainerXml());
25104
+ zip.file("Contents/content.hpf", generateManifest(chartParts, images.manifestItems(), gongmun ? "gongmun" : "default"));
25105
+ for (const part of images.parts) zip.file(part.name, part.data);
25106
+ zip.file("Contents/header.xml", generateHeaderXml(
25107
+ theme,
25108
+ gongmun,
25109
+ fit?.variants ?? [],
25110
+ extraBorderFills,
25111
+ [...remap?.charPrXmls ?? [], ...dfActive ? docframeCharPrXmls(dfBase, richAssets) : []],
25112
+ gongmunList?.indentVariants ?? [],
25113
+ remap?.fontFaces ?? []
25114
+ ));
25115
+ zip.file("Contents/section0.xml", sectionXml);
25116
+ for (const part of chartParts) zip.file(part.name, part.xml);
25117
+ zip.file("Preview/PrvText.txt", buildPrvText(blocks));
25118
+ return await zip.generateAsync({ type: "arraybuffer" });
25119
+ } finally {
25120
+ endInlineDoc();
25121
+ }
24872
25122
  }
24873
25123
 
24874
25124
  // src/diff/compare.ts
@@ -28327,7 +28577,7 @@ async function parse(input, options) {
28327
28577
  }
28328
28578
  async function parseImage(buffer, options) {
28329
28579
  try {
28330
- const { parseImageDocument } = await import("./image-ocr-K4XCRBTY.js");
28580
+ const { parseImageDocument } = await import("./image-ocr-YIBJCOUQ.js");
28331
28581
  const { blocks, warnings } = await parseImageDocument(buffer, options);
28332
28582
  return {
28333
28583
  success: true,
@@ -28386,7 +28636,7 @@ async function parseHwp(buffer, options) {
28386
28636
  async function parsePdf(buffer, options) {
28387
28637
  let parsePdfDocument;
28388
28638
  try {
28389
- const mod = await import("./parser-I3ELUUOG.js");
28639
+ const mod = await import("./parser-GFXZV2VJ.js");
28390
28640
  parsePdfDocument = mod.parsePdfDocument;
28391
28641
  } catch {
28392
28642
  return {
@@ -28532,4 +28782,4 @@ export {
28532
28782
  parseHwpml,
28533
28783
  fillForm
28534
28784
  };
28535
- //# sourceMappingURL=chunk-2352RXHG.js.map
28785
+ //# sourceMappingURL=chunk-7BTO44Q7.js.map