kordoc 4.4.0 → 4.5.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 (104) hide show
  1. package/README.md +18 -3
  2. package/dist/{-R6NUMPRV.js → -CWYIC4ES.js} +9 -9
  3. package/dist/{chunk-W6CUD7V3.js → chunk-2CF2WXBG.js} +3 -3
  4. package/dist/{chunk-YOZ7ZRCD.js → chunk-45EUJ2P6.js} +310 -76
  5. package/dist/chunk-45EUJ2P6.js.map +1 -0
  6. package/dist/{chunk-HNRULYUH.js → chunk-7ZQKECQT.js} +2 -2
  7. package/dist/{chunk-RZURSA4N.js → chunk-CBUC73JM.js} +3 -3
  8. package/dist/chunk-DCZVOIEO.cjs.map +1 -1
  9. package/dist/{chunk-ONS7JKVA.js → chunk-EYLOFSA5.js} +2 -2
  10. package/dist/{chunk-ONS7JKVA.js.map → chunk-EYLOFSA5.js.map} +1 -1
  11. package/dist/{chunk-YVYU267E.js → chunk-FT2EXMMP.js} +16 -5
  12. package/dist/chunk-FT2EXMMP.js.map +1 -0
  13. package/dist/{chunk-V35DRUJC.js → chunk-GCHH4WHT.js} +2 -2
  14. package/dist/{chunk-UDGPM5R5.cjs → chunk-GLPLLT4Q.cjs} +4 -4
  15. package/dist/chunk-GLPLLT4Q.cjs.map +1 -0
  16. package/dist/chunk-GS7T56RP.cjs.map +1 -1
  17. package/dist/{chunk-HFJF477F.js → chunk-M4I5F6GK.js} +16 -5
  18. package/dist/chunk-M4I5F6GK.js.map +1 -0
  19. package/dist/{chunk-GHGZU2LQ.js → chunk-NBOVSNSR.js} +2 -2
  20. package/dist/{chunk-AB322K3O.cjs → chunk-TCPO6XAY.cjs} +17 -6
  21. package/dist/chunk-TCPO6XAY.cjs.map +1 -0
  22. package/dist/{chunk-5KLE3U23.js → chunk-TP4P7M4I.js} +2 -2
  23. package/dist/{chunk-P7YPCK7C.js → chunk-TTEHX4FN.js} +2 -2
  24. package/dist/{chunk-SKM6KZUH.cjs → chunk-U3ZNF4SO.cjs} +9 -9
  25. package/dist/chunk-U3ZNF4SO.cjs.map +1 -0
  26. package/dist/{chunk-A73RMJ6B.js → chunk-UEWW3DH2.js} +1 -1
  27. package/dist/{chunk-A73RMJ6B.js.map → chunk-UEWW3DH2.js.map} +1 -1
  28. package/dist/{chunk-H2KMJOB6.cjs → chunk-UQ6KDJWE.cjs} +2 -2
  29. package/dist/chunk-UQ6KDJWE.cjs.map +1 -0
  30. package/dist/{chunk-65DYCXGC.js → chunk-WDIPTY3Q.js} +3 -3
  31. package/dist/{chunk-XCIC7U6Y.js → chunk-XYSTZIIL.js} +2 -2
  32. package/dist/{chunk-QXYB74QF.js → chunk-ZHNUH2IW.js} +2 -2
  33. package/dist/chunk-ZV5OKQ3Z.cjs.map +1 -1
  34. package/dist/chunks-EYDY4Y6O.js +10 -0
  35. package/dist/cli.js +54 -19
  36. package/dist/cli.js.map +1 -1
  37. package/dist/formula-CG4S7TWO.cjs.map +1 -1
  38. package/dist/{image-ocr-U2DRRFL3.js → image-ocr-BWQIUUVC.js} +13 -5
  39. package/dist/image-ocr-BWQIUUVC.js.map +1 -0
  40. package/dist/{image-ocr-XC52AQDV.js → image-ocr-EDZOUU6Q.js} +14 -6
  41. package/dist/image-ocr-EDZOUU6Q.js.map +1 -0
  42. package/dist/{image-ocr-F2BQA26V.cjs → image-ocr-KZ4MGVJ3.cjs} +19 -11
  43. package/dist/image-ocr-KZ4MGVJ3.cjs.map +1 -0
  44. package/dist/index.cjs +647 -413
  45. package/dist/index.cjs.map +1 -1
  46. package/dist/index.d.cts +42 -2
  47. package/dist/index.d.ts +42 -2
  48. package/dist/index.js +305 -71
  49. package/dist/index.js.map +1 -1
  50. package/dist/mcp.js +63 -30
  51. package/dist/mcp.js.map +1 -1
  52. package/dist/page-range-P7SDW6LR.cjs.map +1 -1
  53. package/dist/{parser-TFPGQWCC.js → parser-6OJOFJ64.js} +5 -5
  54. package/dist/{parser-FFQN67O6.cjs → parser-7G2QFIYZ.cjs} +24 -24
  55. package/dist/parser-7G2QFIYZ.cjs.map +1 -0
  56. package/dist/{parser-ESGFWWCT.js → parser-JLEKXA2Z.js} +6 -6
  57. package/dist/pdf-ocr-364VNE6N.cjs +13 -0
  58. package/dist/pdf-ocr-364VNE6N.cjs.map +1 -0
  59. package/dist/{pdf-ocr-WE5TMRFU.js → pdf-ocr-OWUZLWQ3.js} +5 -5
  60. package/dist/pdf-ocr-YQGMCT53.js +12 -0
  61. package/dist/{profile-io-O6BDCUJN.js → profile-io-FMPT6VEZ.js} +3 -3
  62. package/dist/{rasterize-V22VCCE7.js → rasterize-LARCX6CS.js} +2 -2
  63. package/dist/render-4WHQ7JCX.js +10 -0
  64. package/dist/seal-BX6YA6PI.js +10 -0
  65. package/dist/{watch-HGKBICED.js → watch-Y2VKD2MN.js} +9 -9
  66. package/package.json +1 -1
  67. package/dist/chunk-AB322K3O.cjs.map +0 -1
  68. package/dist/chunk-H2KMJOB6.cjs.map +0 -1
  69. package/dist/chunk-HFJF477F.js.map +0 -1
  70. package/dist/chunk-SKM6KZUH.cjs.map +0 -1
  71. package/dist/chunk-UDGPM5R5.cjs.map +0 -1
  72. package/dist/chunk-YOZ7ZRCD.js.map +0 -1
  73. package/dist/chunk-YVYU267E.js.map +0 -1
  74. package/dist/chunks-QMGCI5DG.js +0 -10
  75. package/dist/image-ocr-F2BQA26V.cjs.map +0 -1
  76. package/dist/image-ocr-U2DRRFL3.js.map +0 -1
  77. package/dist/image-ocr-XC52AQDV.js.map +0 -1
  78. package/dist/parser-FFQN67O6.cjs.map +0 -1
  79. package/dist/pdf-ocr-4R646OO6.js +0 -12
  80. package/dist/pdf-ocr-UQBZH3HE.cjs +0 -13
  81. package/dist/pdf-ocr-UQBZH3HE.cjs.map +0 -1
  82. package/dist/render-3BSVTTZE.js +0 -10
  83. package/dist/seal-6ZSEJVOD.js +0 -10
  84. /package/dist/{-R6NUMPRV.js.map → -CWYIC4ES.js.map} +0 -0
  85. /package/dist/{chunk-W6CUD7V3.js.map → chunk-2CF2WXBG.js.map} +0 -0
  86. /package/dist/{chunk-HNRULYUH.js.map → chunk-7ZQKECQT.js.map} +0 -0
  87. /package/dist/{chunk-RZURSA4N.js.map → chunk-CBUC73JM.js.map} +0 -0
  88. /package/dist/{chunk-V35DRUJC.js.map → chunk-GCHH4WHT.js.map} +0 -0
  89. /package/dist/{chunk-GHGZU2LQ.js.map → chunk-NBOVSNSR.js.map} +0 -0
  90. /package/dist/{chunk-5KLE3U23.js.map → chunk-TP4P7M4I.js.map} +0 -0
  91. /package/dist/{chunk-P7YPCK7C.js.map → chunk-TTEHX4FN.js.map} +0 -0
  92. /package/dist/{chunk-65DYCXGC.js.map → chunk-WDIPTY3Q.js.map} +0 -0
  93. /package/dist/{chunk-XCIC7U6Y.js.map → chunk-XYSTZIIL.js.map} +0 -0
  94. /package/dist/{chunk-QXYB74QF.js.map → chunk-ZHNUH2IW.js.map} +0 -0
  95. /package/dist/{chunks-QMGCI5DG.js.map → chunks-EYDY4Y6O.js.map} +0 -0
  96. /package/dist/{parser-TFPGQWCC.js.map → parser-6OJOFJ64.js.map} +0 -0
  97. /package/dist/{parser-ESGFWWCT.js.map → parser-JLEKXA2Z.js.map} +0 -0
  98. /package/dist/{pdf-ocr-4R646OO6.js.map → pdf-ocr-OWUZLWQ3.js.map} +0 -0
  99. /package/dist/{pdf-ocr-WE5TMRFU.js.map → pdf-ocr-YQGMCT53.js.map} +0 -0
  100. /package/dist/{profile-io-O6BDCUJN.js.map → profile-io-FMPT6VEZ.js.map} +0 -0
  101. /package/dist/{rasterize-V22VCCE7.js.map → rasterize-LARCX6CS.js.map} +0 -0
  102. /package/dist/{render-3BSVTTZE.js.map → render-4WHQ7JCX.js.map} +0 -0
  103. /package/dist/{seal-6ZSEJVOD.js.map → seal-BX6YA6PI.js.map} +0 -0
  104. /package/dist/{watch-HGKBICED.js.map → watch-Y2VKD2MN.js.map} +0 -0
@@ -6,7 +6,7 @@ import {
6
6
  HEADING_RATIO_H1,
7
7
  HEADING_RATIO_H2,
8
8
  HEADING_RATIO_H3
9
- } from "./chunk-A73RMJ6B.js";
9
+ } from "./chunk-UEWW3DH2.js";
10
10
  import {
11
11
  parsePageRange
12
12
  } from "./chunk-MOL7MDBG.js";
@@ -22,7 +22,7 @@ import {
22
22
  paraTextPureT,
23
23
  patchZipEntries,
24
24
  scanSectionXml
25
- } from "./chunk-RZURSA4N.js";
25
+ } from "./chunk-CBUC73JM.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-QXYB74QF.js";
35
+ } from "./chunk-ZHNUH2IW.js";
36
36
  import {
37
37
  SPACE_EM_FIXED,
38
38
  charWidthEm1000,
39
39
  fitRatioForFewerLines,
40
40
  measureTextWidth,
41
41
  simulateWrap
42
- } from "./chunk-65DYCXGC.js";
42
+ } from "./chunk-WDIPTY3Q.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-5KLE3U23.js";
58
+ } from "./chunk-TP4P7M4I.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-P7YPCK7C.js";
70
+ } from "./chunk-TTEHX4FN.js";
71
71
 
72
72
  // src/index.ts
73
73
  import { readFile } from "fs/promises";
@@ -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,8 +21865,45 @@ 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
+ function emphasisSpans(text) {
21850
21907
  const spans = [];
21851
21908
  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;
@@ -21870,16 +21927,6 @@ function parseInlineMarkdown(text) {
21870
21927
  if (lastIdx < text.length) {
21871
21928
  spans.push({ text: text.slice(lastIdx), bold: false, italic: false, code: false });
21872
21929
  }
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
21930
  return spans;
21884
21931
  }
21885
21932
  function spanToCharPrId(span) {
@@ -21889,13 +21936,54 @@ function spanToCharPrId(span) {
21889
21936
  if (span.italic) return CHAR_ITALIC;
21890
21937
  return CHAR_NORMAL;
21891
21938
  }
21939
+ function hyperlinkBeginXml(fid, href) {
21940
+ const cmd = escapeXml(href.replace(/:/g, "\\:"));
21941
+ const path = escapeXml(href);
21942
+ 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>`;
21943
+ }
21944
+ function footnoteXml(note, mapCharId) {
21945
+ const d = inlineDoc;
21946
+ const n = ++d.noteSeq;
21947
+ d.inNote = true;
21948
+ let body;
21949
+ try {
21950
+ body = generateRuns(note, CHAR_NORMAL, mapCharId);
21951
+ } finally {
21952
+ d.inNote = false;
21953
+ }
21954
+ 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>`;
21955
+ }
21892
21956
  function generateRuns(text, defaultCharPr = CHAR_NORMAL, mapCharId) {
21893
21957
  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("");
21958
+ const mapped = (id) => mapCharId ? mapCharId(id) : id;
21959
+ const out = [];
21960
+ let openHref = null;
21961
+ let openFid = 0;
21962
+ const closeField = () => {
21963
+ if (openHref === null) return;
21964
+ out.push(`<hp:run charPrIDRef="${mapped(defaultCharPr)}"><hp:ctrl><hp:fieldEnd beginIDRef="${openFid}" fieldid="${HYPERLINK_FIELDID}"/></hp:ctrl></hp:run>`);
21965
+ openHref = null;
21966
+ };
21967
+ for (const span of spans) {
21968
+ if (span.note !== void 0 && inlineDoc) {
21969
+ closeField();
21970
+ out.push(`<hp:run charPrIDRef="${mapped(defaultCharPr)}">${footnoteXml(span.note, mapCharId)}</hp:run>`);
21971
+ continue;
21972
+ }
21973
+ const href = inlineDoc ? span.href ?? null : null;
21974
+ if (href !== openHref) {
21975
+ closeField();
21976
+ if (href !== null) {
21977
+ openFid = FIELD_ID_BASE + ++inlineDoc.fieldSeq;
21978
+ openHref = href;
21979
+ out.push(`<hp:run charPrIDRef="${mapped(defaultCharPr)}">${hyperlinkBeginXml(openFid, href)}</hp:run>`);
21980
+ }
21981
+ }
21982
+ const charId = span.code || span.bold || span.italic ? spanToCharPrId(span) : defaultCharPr;
21983
+ out.push(`<hp:run charPrIDRef="${mapped(charId)}"><hp:t>${escapeXml(span.text)}</hp:t></hp:run>`);
21984
+ }
21985
+ closeField();
21986
+ return out.join("");
21899
21987
  }
21900
21988
  function generateParagraph(text, paraPrId = PARA_NORMAL, charPrId = CHAR_NORMAL, mapCharId, styleId = 0) {
21901
21989
  if (paraPrId === PARA_CODE) {
@@ -21905,6 +21993,56 @@ function generateParagraph(text, paraPrId = PARA_NORMAL, charPrId = CHAR_NORMAL,
21905
21993
  return `<hp:p paraPrIDRef="${paraPrId}" styleIDRef="${styleId}">${runs}</hp:p>`;
21906
21994
  }
21907
21995
 
21996
+ // src/hwpx/gen-page.ts
21997
+ var PAPER_MM = {
21998
+ A4: [210, 297],
21999
+ A3: [297, 420],
22000
+ B4: [257, 364],
22001
+ B5: [182, 257],
22002
+ Letter: [215.9, 279.4]
22003
+ };
22004
+ function resolvePage(opts) {
22005
+ if (!opts) return null;
22006
+ const { size, orientation, columns, header, footer } = opts;
22007
+ if (size === void 0 && orientation === void 0 && columns === void 0 && header === void 0 && footer === void 0) return null;
22008
+ let wMm = 210, hMm = 297;
22009
+ if (size !== void 0) {
22010
+ if (typeof size === "string") {
22011
+ const preset = PAPER_MM[size];
22012
+ if (!preset) throw new Error(`\uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC6A9\uC9C0 \uD504\uB9AC\uC14B: ${size} (A4\xB7A3\xB7B4\xB7B5\xB7Letter)`);
22013
+ [wMm, hMm] = preset;
22014
+ } else {
22015
+ if (!(size.widthMm > 0) || !(size.heightMm > 0) || size.widthMm > 1e3 || size.heightMm > 1e3) {
22016
+ throw new Error(`\uC6A9\uC9C0 \uCE58\uC218\uB294 0~1000mm \uBC94\uC704\uC5EC\uC57C \uD569\uB2C8\uB2E4: ${size.widthMm}\xD7${size.heightMm}`);
22017
+ }
22018
+ wMm = size.widthMm;
22019
+ hMm = size.heightMm;
22020
+ }
22021
+ }
22022
+ const cols = columns ?? 1;
22023
+ if (!Number.isInteger(cols) || cols < 1 || cols > 8) {
22024
+ throw new Error(`\uB2E4\uB2E8 \uAC1C\uC218\uB294 1~8 \uC815\uC218\uC5EC\uC57C \uD569\uB2C8\uB2E4: ${columns}`);
22025
+ }
22026
+ const paperHU = (mm) => Math.floor(mm * 7200 / 25.4);
22027
+ return {
22028
+ widthHU: size === void 0 ? A4_W_HU : paperHU(wMm),
22029
+ heightHU: size === void 0 ? A4_H_HU : paperHU(hMm),
22030
+ // 실측: 용지 치수는 방향과 무관하게 유지, 방향은 landscape 속성만 바뀐다
22031
+ landscape: orientation === "landscape" ? "NARROWLY" : "WIDELY",
22032
+ columns: cols,
22033
+ header: header?.trim() ? header.trim() : null,
22034
+ footer: footer?.trim() ? footer.trim() : null
22035
+ };
22036
+ }
22037
+ function columnColPrXml(columns) {
22038
+ const gap = columns > 1 ? 2268 : 0;
22039
+ return `<hp:ctrl><hp:colPr id="" type="NEWSPAPER" layout="LEFT" colCount="${columns}" sameSz="1" sameGap="${gap}"/></hp:ctrl>`;
22040
+ }
22041
+ function headerFooterCtrl(tag, text, id, mapCharId) {
22042
+ const runs = generateRuns(text, void 0, mapCharId);
22043
+ 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>`;
22044
+ }
22045
+
21908
22046
  // src/hwpx/gen-header.ts
21909
22047
  function generateContainerXml() {
21910
22048
  return `<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
@@ -23495,15 +23633,65 @@ var IMAGE_EXT_MIME = {
23495
23633
  tif: "image/tiff",
23496
23634
  tiff: "image/tiff"
23497
23635
  };
23636
+ function sniffImage(b) {
23637
+ if (b.length >= 8 && b[0] === 137 && b[1] === 80 && b[2] === 78 && b[3] === 71) return { mime: "image/png", ext: "png" };
23638
+ if (b.length >= 3 && b[0] === 255 && b[1] === 216 && b[2] === 255) return { mime: "image/jpeg", ext: "jpg" };
23639
+ if (b.length >= 6 && b[0] === 71 && b[1] === 73 && b[2] === 70) return { mime: "image/gif", ext: "gif" };
23640
+ if (b.length >= 2 && b[0] === 66 && b[1] === 77) return { mime: "image/bmp", ext: "bmp" };
23641
+ return null;
23642
+ }
23643
+ function probeImageSize(b) {
23644
+ const dv = new DataView(b.buffer, b.byteOffset, b.byteLength);
23645
+ try {
23646
+ if (b[0] === 137 && b[1] === 80) {
23647
+ return { w: dv.getUint32(16), h: dv.getUint32(20) };
23648
+ }
23649
+ if (b[0] === 255 && b[1] === 216) {
23650
+ let i = 2;
23651
+ while (i + 9 < b.length) {
23652
+ if (b[i] !== 255) {
23653
+ i++;
23654
+ continue;
23655
+ }
23656
+ const marker = b[i + 1];
23657
+ if (marker >= 192 && marker <= 207 && marker !== 196 && marker !== 200 && marker !== 204) {
23658
+ return { w: dv.getUint16(i + 7), h: dv.getUint16(i + 5) };
23659
+ }
23660
+ i += 2 + dv.getUint16(i + 2);
23661
+ }
23662
+ return null;
23663
+ }
23664
+ if (b[0] === 71 && b[1] === 73) {
23665
+ return { w: dv.getUint16(6, true), h: dv.getUint16(8, true) };
23666
+ }
23667
+ if (b[0] === 66 && b[1] === 77) {
23668
+ return { w: dv.getUint32(18, true), h: Math.abs(dv.getInt32(22, true)) };
23669
+ }
23670
+ } catch {
23671
+ }
23672
+ return null;
23673
+ }
23674
+ var PX_TO_HU = 75;
23675
+ var MAX_IMG_W_HU = 48189;
23498
23676
  var ImageRegistry = class {
23677
+ /** @param supplied url → 실데이터 바이트 (markdownToHwpx images 옵션) */
23678
+ constructor(supplied) {
23679
+ this.supplied = supplied;
23680
+ }
23499
23681
  byUrl = /* @__PURE__ */ new Map();
23500
23682
  ids = /* @__PURE__ */ new Set();
23501
23683
  parts = [];
23502
23684
  picSeq = 0;
23685
+ binSeq = 0;
23503
23686
  /** url 등록(중복 시 기존 파트) — 수용 불가면 null */
23504
23687
  take(url) {
23505
23688
  const cached = this.byUrl.get(url);
23506
23689
  if (cached !== void 0) return cached;
23690
+ const real = this.takeReal(url);
23691
+ if (real) {
23692
+ this.byUrl.set(url, real);
23693
+ return real;
23694
+ }
23507
23695
  let part = null;
23508
23696
  const m = /^([A-Za-z0-9._-]+)\.([A-Za-z0-9]+)$/.exec(url);
23509
23697
  const mime = m ? IMAGE_EXT_MIME[m[2].toLowerCase()] : void 0;
@@ -23523,6 +23711,41 @@ var ImageRegistry = class {
23523
23711
  this.byUrl.set(url, part);
23524
23712
  return part;
23525
23713
  }
23714
+ /** 실데이터 등록 — images 맵 바이트·data: URI. 포맷 미상(webp 등)은 null → placeholder 폴백 */
23715
+ takeReal(url) {
23716
+ let bytes = this.supplied?.get(url);
23717
+ if (!bytes && url.startsWith("data:")) {
23718
+ const m = /^data:image\/[a-z+]+;base64,([A-Za-z0-9+/=\s]+)$/i.exec(url);
23719
+ if (m) {
23720
+ try {
23721
+ bytes = new Uint8Array(Buffer.from(m[1].replace(/\s+/g, ""), "base64"));
23722
+ } catch {
23723
+ }
23724
+ }
23725
+ }
23726
+ if (!bytes || bytes.length === 0) return null;
23727
+ const sniffed = sniffImage(bytes);
23728
+ if (!sniffed) return null;
23729
+ const safe = /^([A-Za-z0-9._-]+)\.([A-Za-z0-9]+)$/.exec(url);
23730
+ const base = safe && !url.includes("..") ? safe[1] : `image${++this.binSeq}`;
23731
+ let itemId = base.replace(/[^A-Za-z0-9_]/g, "_");
23732
+ let n = 1;
23733
+ while (this.ids.has(itemId)) itemId = `${base.replace(/[^A-Za-z0-9_]/g, "_")}_${n++}`;
23734
+ this.ids.add(itemId);
23735
+ const dim = probeImageSize(bytes);
23736
+ let wHU, hHU;
23737
+ if (dim && dim.w > 0 && dim.h > 0) {
23738
+ wHU = dim.w * PX_TO_HU;
23739
+ hHU = dim.h * PX_TO_HU;
23740
+ if (wHU > MAX_IMG_W_HU) {
23741
+ hHU = Math.round(hHU * (MAX_IMG_W_HU / wHU));
23742
+ wHU = MAX_IMG_W_HU;
23743
+ }
23744
+ }
23745
+ const part = { name: `BinData/${itemId}.${sniffed.ext}`, itemId, mime: sniffed.mime, data: bytes, wHU, hHU };
23746
+ this.parts.push(part);
23747
+ return part;
23748
+ }
23526
23749
  /** manifest <opf:item> 조각들 (실측: isEmbeded="1") */
23527
23750
  manifestItems() {
23528
23751
  return this.parts.map((p) => `<opf:item id="${p.itemId}" href="${p.name}" media-type="${p.mime}" isEmbeded="1"/>`);
@@ -23530,8 +23753,9 @@ var ImageRegistry = class {
23530
23753
  /** 인라인 <hp:pic> XML — 실측 저장본 미러, treatAsChar=1 (셀·문단 안 배치) */
23531
23754
  inlinePicXml(part) {
23532
23755
  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>`;
23756
+ const w = part.wHU ?? 1130;
23757
+ const h = part.hHU ?? 1130;
23758
+ 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
23759
  }
23536
23760
  };
23537
23761
  var MD_IMAGE_RE = /!\[[^\]]*\]\(([^)\s]+)\)/g;
@@ -24418,7 +24642,7 @@ function generateEquationParagraph(input, zOrder = 0) {
24418
24642
  }
24419
24643
 
24420
24644
  // src/hwpx/gen-section.ts
24421
- function generateSecPr(gongmun) {
24645
+ function generateSecPr(gongmun, page = null) {
24422
24646
  const m = gongmun ? {
24423
24647
  top: mmToHwpunit(gongmun.margins.top),
24424
24648
  bottom: mmToHwpunit(gongmun.margins.bottom),
@@ -24431,13 +24655,15 @@ function generateSecPr(gongmun) {
24431
24655
  m.header = gongmun.headerFooter;
24432
24656
  m.footer = gongmun.headerFooter;
24433
24657
  }
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() : "");
24658
+ 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>`;
24659
+ const colPr = columnColPrXml(page?.columns ?? 1);
24660
+ const hf = (page?.header ? headerFooterCtrl("header", page.header, 1) : "") + (page?.footer ? headerFooterCtrl("footer", page.footer, 2) : "");
24661
+ return secPr + colPr + hf + (gongmun?.pageNumbers ? pageNumCtrl() : "");
24437
24662
  }
24438
24663
  var SectionOpener = class {
24439
- constructor(gongmun) {
24664
+ constructor(gongmun, page = null) {
24440
24665
  this.gongmun = gongmun;
24666
+ this.page = page;
24441
24667
  }
24442
24668
  pending = true;
24443
24669
  /** 아직 secPr를 나를 첫 문단이 안 나왔는가 */
@@ -24449,7 +24675,7 @@ var SectionOpener = class {
24449
24675
  this.pending = false;
24450
24676
  return xml.replace(
24451
24677
  /<hp:run charPrIDRef="(\d+)">/,
24452
- `<hp:run charPrIDRef="$1">${generateSecPr(this.gongmun)}`
24678
+ `<hp:run charPrIDRef="$1">${generateSecPr(this.gongmun, this.page)}`
24453
24679
  );
24454
24680
  }
24455
24681
  /**
@@ -24459,13 +24685,13 @@ var SectionOpener = class {
24459
24685
  emitCarrier(paraXmls) {
24460
24686
  if (!this.pending) return;
24461
24687
  this.pending = false;
24462
- const secRun = `<hp:run charPrIDRef="0">${generateSecPr(this.gongmun)}<hp:t></hp:t></hp:run>`;
24688
+ const secRun = `<hp:run charPrIDRef="0">${generateSecPr(this.gongmun, this.page)}<hp:t></hp:t></hp:run>`;
24463
24689
  paraXmls.push(`<hp:p paraPrIDRef="0" styleIDRef="0">${secRun}</hp:p>`);
24464
24690
  }
24465
24691
  /** 빈 문서 폴백 — secPr를 실은 빈 단락 XML */
24466
24692
  emptyDoc() {
24467
24693
  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>`;
24694
+ 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
24695
  }
24470
24696
  };
24471
24697
  function buildPreamble(blocks, ctx) {
@@ -24706,7 +24932,7 @@ function appendPostamble(blocks, ctx) {
24706
24932
  paraXmls.push(...buildPressContact(gongmun, dfIds, tableStyle.totalWidth, bfReg));
24707
24933
  }
24708
24934
  }
24709
- function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null, fit = null, chartParts = null, bfReg = null, remap = null, dfIds = null, images = null) {
24935
+ 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
24936
  resetTableIds();
24711
24937
  resetGjTableIds();
24712
24938
  resetExtraTableIds();
@@ -24745,7 +24971,7 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
24745
24971
  // 개조식 장식표(표지·목차·장헤더·제목박스) 폭 스케일용 본문폭 — margins 오버라이드 대응
24746
24972
  gjBodyW: gongmun ? mmToHwpunit(210 - gongmun.margins.left - gongmun.margins.right) : GAEJOSIK_BASE_WIDTH,
24747
24973
  chamMap: (id) => id === CHAR_BOLD ? GJ_CHAR_CHAM_BOLD : id,
24748
- opener: new SectionOpener(gongmun),
24974
+ opener: new SectionOpener(gongmun, page),
24749
24975
  paraXmls: [],
24750
24976
  // 표 방출 순번 — 생성 성공 여부와 무관하게 '시도' 기준으로 센다. 실패한 표가 이후
24751
24977
  // 표들의 순번을 밀면 앵커 없는 프로필(손편집·구버전)의 table_index 매칭이 어긋난다.
@@ -24830,45 +25056,53 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
24830
25056
  async function markdownToHwpx(markdown, options) {
24831
25057
  const theme = resolveTheme(options?.theme);
24832
25058
  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" });
25059
+ const page = resolvePage(options?.page);
25060
+ const { md: md2, defs } = extractFootnoteDefs(markdown);
25061
+ beginInlineDoc(defs);
25062
+ try {
25063
+ const measured = !!gongmun && usesReportFonts(gongmun.preset);
25064
+ const richAssets = !!gongmun && needsGaejosikAssets(gongmun);
25065
+ const blocks = parseMarkdownToBlocks(md2);
25066
+ const gongmunList = gongmun ? precomputeGongmunList(blocks, gongmun) : null;
25067
+ const fit = gongmun && gongmunList ? computeGongmunFitPlan(blocks, gongmun, gongmunList) : null;
25068
+ const staticBfEnd = staticBorderFillNext(gongmun);
25069
+ const remap = options?.profile ? buildProfileRemap(options.profile, charVariantBase(richAssets, !!gongmun) + (fit?.variants?.length ?? 0) * 4, staticBfEnd, staticFontNext(gongmun)) : null;
25070
+ const bfReg = gongmun ? new TableBfRegistry(staticBfEnd + (remap?.borderFillXmls.length ?? 0)) : null;
25071
+ const dfActive = !!gongmun && docframeActive(gongmun);
25072
+ const dfBase = charVariantBase(richAssets, !!gongmun) + (fit?.variants?.length ?? 0) * 4 + (remap?.charPrXmls.length ?? 0);
25073
+ const dfIds = dfActive ? docframeIds(dfBase) : null;
25074
+ const chartParts = [];
25075
+ const supplied = options?.images ? new Map(Object.entries(options.images).map(([k, v]) => [k, v instanceof Uint8Array ? v : new Uint8Array(v)])) : void 0;
25076
+ const images = new ImageRegistry(supplied);
25077
+ const sectionXml = blocksToSectionXml(blocks, theme, gongmun, gongmunList, fit, chartParts, bfReg, remap, dfIds, images, page);
25078
+ if (remap && remap.tables.length > 0) {
25079
+ const unused = remap.tables.filter((t) => !t.used).length;
25080
+ if (unused === remap.tables.length) {
25081
+ 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)`);
25082
+ }
25083
+ }
25084
+ const extraBorderFills = [...remap?.borderFillXmls ?? [], ...bfReg?.emit() ?? []];
25085
+ const zip = new JSZip8();
25086
+ zip.file("mimetype", "application/hwp+zip", { compression: "STORE" });
25087
+ zip.file("META-INF/container.xml", generateContainerXml());
25088
+ zip.file("Contents/content.hpf", generateManifest(chartParts, images.manifestItems(), gongmun ? "gongmun" : "default"));
25089
+ for (const part of images.parts) zip.file(part.name, part.data);
25090
+ zip.file("Contents/header.xml", generateHeaderXml(
25091
+ theme,
25092
+ gongmun,
25093
+ fit?.variants ?? [],
25094
+ extraBorderFills,
25095
+ [...remap?.charPrXmls ?? [], ...dfActive ? docframeCharPrXmls(dfBase, richAssets) : []],
25096
+ gongmunList?.indentVariants ?? [],
25097
+ remap?.fontFaces ?? []
25098
+ ));
25099
+ zip.file("Contents/section0.xml", sectionXml);
25100
+ for (const part of chartParts) zip.file(part.name, part.xml);
25101
+ zip.file("Preview/PrvText.txt", buildPrvText(blocks));
25102
+ return await zip.generateAsync({ type: "arraybuffer" });
25103
+ } finally {
25104
+ endInlineDoc();
25105
+ }
24872
25106
  }
24873
25107
 
24874
25108
  // src/diff/compare.ts
@@ -28327,7 +28561,7 @@ async function parse(input, options) {
28327
28561
  }
28328
28562
  async function parseImage(buffer, options) {
28329
28563
  try {
28330
- const { parseImageDocument } = await import("./image-ocr-XC52AQDV.js");
28564
+ const { parseImageDocument } = await import("./image-ocr-EDZOUU6Q.js");
28331
28565
  const { blocks, warnings } = await parseImageDocument(buffer, options);
28332
28566
  return {
28333
28567
  success: true,
@@ -28386,7 +28620,7 @@ async function parseHwp(buffer, options) {
28386
28620
  async function parsePdf(buffer, options) {
28387
28621
  let parsePdfDocument;
28388
28622
  try {
28389
- const mod = await import("./parser-ESGFWWCT.js");
28623
+ const mod = await import("./parser-JLEKXA2Z.js");
28390
28624
  parsePdfDocument = mod.parsePdfDocument;
28391
28625
  } catch {
28392
28626
  return {
@@ -28532,4 +28766,4 @@ export {
28532
28766
  parseHwpml,
28533
28767
  fillForm
28534
28768
  };
28535
- //# sourceMappingURL=chunk-YOZ7ZRCD.js.map
28769
+ //# sourceMappingURL=chunk-45EUJ2P6.js.map