kordoc 3.18.0 → 3.18.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 (44) hide show
  1. package/dist/{-OUCPI6B3.js → -V66QW3WA.js} +7 -7
  2. package/dist/{chunk-YWIYGXLI.js → chunk-2IBFK5ZO.js} +2 -2
  3. package/dist/{chunk-4YEZTZAR.js → chunk-4RGDFDQ2.js} +2 -2
  4. package/dist/{chunk-PWHM3KAA.js → chunk-7K5P4RNT.js} +156 -120
  5. package/dist/chunk-7K5P4RNT.js.map +1 -0
  6. package/dist/{chunk-VP34RO24.js → chunk-NZJAXMN7.js} +3 -3
  7. package/dist/{chunk-ZTUQYITH.js → chunk-QMJJI6TD.js} +3 -3
  8. package/dist/{chunk-5HDBLRVP.cjs → chunk-R2H34FY5.cjs} +2 -2
  9. package/dist/{chunk-5HDBLRVP.cjs.map → chunk-R2H34FY5.cjs.map} +1 -1
  10. package/dist/{chunk-GIXXV52X.js → chunk-UHYPUIRH.js} +2 -2
  11. package/dist/{chunk-6Y4KKPC3.js → chunk-UNV7F3FK.js} +2 -2
  12. package/dist/cli.js +14 -14
  13. package/dist/cli.js.map +1 -1
  14. package/dist/index.cjs +377 -340
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +6 -0
  17. package/dist/index.d.ts +6 -0
  18. package/dist/index.js +151 -114
  19. package/dist/index.js.map +1 -1
  20. package/dist/mcp.js +10 -21
  21. package/dist/mcp.js.map +1 -1
  22. package/dist/{parser-NZAE7PBE.js → parser-DOBK652H.js} +3 -3
  23. package/dist/{parser-5D6BQYTX.js → parser-JBBA5A5E.js} +2 -2
  24. package/dist/{parser-S34YR2SH.cjs → parser-XEY5MRGV.cjs} +14 -14
  25. package/dist/{parser-S34YR2SH.cjs.map → parser-XEY5MRGV.cjs.map} +1 -1
  26. package/dist/render-VX4H2S4F.js +10 -0
  27. package/dist/seal-6Z6H4YXN.js +10 -0
  28. package/dist/{watch-2EFXBRYK.js → watch-2MNRQWGV.js} +7 -7
  29. package/package.json +1 -1
  30. package/dist/chunk-PWHM3KAA.js.map +0 -1
  31. package/dist/render-HRAW7ASR.js +0 -10
  32. package/dist/seal-CK64CXWO.js +0 -10
  33. /package/dist/{-OUCPI6B3.js.map → -V66QW3WA.js.map} +0 -0
  34. /package/dist/{chunk-YWIYGXLI.js.map → chunk-2IBFK5ZO.js.map} +0 -0
  35. /package/dist/{chunk-4YEZTZAR.js.map → chunk-4RGDFDQ2.js.map} +0 -0
  36. /package/dist/{chunk-VP34RO24.js.map → chunk-NZJAXMN7.js.map} +0 -0
  37. /package/dist/{chunk-ZTUQYITH.js.map → chunk-QMJJI6TD.js.map} +0 -0
  38. /package/dist/{chunk-GIXXV52X.js.map → chunk-UHYPUIRH.js.map} +0 -0
  39. /package/dist/{chunk-6Y4KKPC3.js.map → chunk-UNV7F3FK.js.map} +0 -0
  40. /package/dist/{parser-NZAE7PBE.js.map → parser-DOBK652H.js.map} +0 -0
  41. /package/dist/{parser-5D6BQYTX.js.map → parser-JBBA5A5E.js.map} +0 -0
  42. /package/dist/{render-HRAW7ASR.js.map → render-VX4H2S4F.js.map} +0 -0
  43. /package/dist/{seal-CK64CXWO.js.map → seal-6Z6H4YXN.js.map} +0 -0
  44. /package/dist/{watch-2EFXBRYK.js.map → watch-2MNRQWGV.js.map} +0 -0
@@ -34,10 +34,10 @@ import {
34
34
  patchHwpxBlocks,
35
35
  renderHtml,
36
36
  validateHwpx
37
- } from "./chunk-PWHM3KAA.js";
37
+ } from "./chunk-7K5P4RNT.js";
38
38
  import {
39
39
  blocksToMarkdown
40
- } from "./chunk-YWIYGXLI.js";
40
+ } from "./chunk-2IBFK5ZO.js";
41
41
  import {
42
42
  detectFormat,
43
43
  detectOle2Format,
@@ -54,7 +54,7 @@ import {
54
54
  buildRangeSplices,
55
55
  placeSealHwpx,
56
56
  scanSectionXml
57
- } from "./chunk-VP34RO24.js";
57
+ } from "./chunk-NZJAXMN7.js";
58
58
  import {
59
59
  SPACE_EM_FIXED,
60
60
  SPACE_EM_FONT,
@@ -64,11 +64,11 @@ import {
64
64
  renderHwpxToSvg,
65
65
  simulateWrap,
66
66
  simulateWrapKeepWord
67
- } from "./chunk-ZTUQYITH.js";
68
- import "./chunk-4YEZTZAR.js";
67
+ } from "./chunk-QMJJI6TD.js";
68
+ import "./chunk-4RGDFDQ2.js";
69
69
  import {
70
70
  VERSION
71
- } from "./chunk-6Y4KKPC3.js";
71
+ } from "./chunk-UNV7F3FK.js";
72
72
  export {
73
73
  HwpxSession,
74
74
  PRESET_ALIAS,
@@ -127,4 +127,4 @@ export {
127
127
  simulateWrapKeepWord,
128
128
  validateHwpx
129
129
  };
130
- //# sourceMappingURL=-OUCPI6B3.js.map
130
+ //# sourceMappingURL=-V66QW3WA.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  sanitizeHref
4
- } from "./chunk-6Y4KKPC3.js";
4
+ } from "./chunk-UNV7F3FK.js";
5
5
 
6
6
  // src/shared/pua.ts
7
7
  var BMP_SYMBOL_MAP = {
@@ -575,4 +575,4 @@ export {
575
575
  HEADING_RATIO_H2,
576
576
  HEADING_RATIO_H3
577
577
  };
578
- //# sourceMappingURL=chunk-YWIYGXLI.js.map
578
+ //# sourceMappingURL=chunk-2IBFK5ZO.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  KordocError
4
- } from "./chunk-6Y4KKPC3.js";
4
+ } from "./chunk-UNV7F3FK.js";
5
5
 
6
6
  // src/hwpx/parser-shared.ts
7
7
  import { DOMParser } from "@xmldom/xmldom";
@@ -258,4 +258,4 @@ export {
258
258
  DEFAULT_CHAR,
259
259
  parseRenderStyles
260
260
  };
261
- //# sourceMappingURL=chunk-4YEZTZAR.js.map
261
+ //# sourceMappingURL=chunk-4RGDFDQ2.js.map
@@ -11,7 +11,7 @@ import {
11
11
  dedupeRunningHeaders,
12
12
  flattenLayoutTables,
13
13
  mapPuaText
14
- } from "./chunk-YWIYGXLI.js";
14
+ } from "./chunk-2IBFK5ZO.js";
15
15
  import {
16
16
  detectFormat,
17
17
  detectOle2Format,
@@ -32,12 +32,12 @@ import {
32
32
  paraTextPureT,
33
33
  patchZipEntries,
34
34
  scanSectionXml
35
- } from "./chunk-VP34RO24.js";
35
+ } from "./chunk-NZJAXMN7.js";
36
36
  import {
37
37
  SPACE_EM_FIXED,
38
38
  charWidthEm1000,
39
39
  fitRatioForFewerLines
40
- } from "./chunk-ZTUQYITH.js";
40
+ } from "./chunk-QMJJI6TD.js";
41
41
  import {
42
42
  MAX_DECOMPRESS_SIZE,
43
43
  MAX_XML_DEPTH,
@@ -48,7 +48,7 @@ import {
48
48
  createXmlParser,
49
49
  extractTextFromNode,
50
50
  findChildByLocalName
51
- } from "./chunk-4YEZTZAR.js";
51
+ } from "./chunk-4RGDFDQ2.js";
52
52
  import {
53
53
  KordocError,
54
54
  classifyError,
@@ -59,7 +59,7 @@ import {
59
59
  sanitizeHref,
60
60
  stripDtd,
61
61
  toArrayBuffer
62
- } from "./chunk-6Y4KKPC3.js";
62
+ } from "./chunk-UNV7F3FK.js";
63
63
 
64
64
  // src/index.ts
65
65
  import { readFile } from "fs/promises";
@@ -2526,7 +2526,7 @@ function crc32(bytes) {
2526
2526
  }
2527
2527
  var BI_RGB = 0;
2528
2528
  var MAX_DIM = 32767;
2529
- var MAX_PIXELS = 64e6;
2529
+ var MAX_PIXELS = 36e6;
2530
2530
  function bmpToPng(bmp) {
2531
2531
  if (bmp.length < 54) return null;
2532
2532
  if (bmp[0] !== 66 || bmp[1] !== 77) return null;
@@ -2614,7 +2614,6 @@ function encodePng(width, height, rgba) {
2614
2614
  out.set(iendChunk, o);
2615
2615
  return out;
2616
2616
  }
2617
- var MAX_INLINE_MD_BYTES = 4 * 1024 * 1024;
2618
2617
  function escapeRegExp(s) {
2619
2618
  return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
2620
2619
  }
@@ -2633,8 +2632,11 @@ function inlineImagesIntoMarkdown(markdown, images, opts) {
2633
2632
  }
2634
2633
  const base64 = Buffer.from(bytes).toString("base64");
2635
2634
  const dataUri = `data:${mime};base64,${base64}`;
2636
- const re = new RegExp(`!\\[image\\]\\((?:images/)?${escapeRegExp(img.filename)}\\)`, "g");
2637
- out = out.replace(re, () => `![image](${dataUri})`);
2635
+ const name = escapeRegExp(img.filename);
2636
+ const mdRe = new RegExp(`!\\[image\\]\\((?:images/)?${name}\\)`, "g");
2637
+ out = out.replace(mdRe, () => `![image](${dataUri})`);
2638
+ const imgTagRe = new RegExp(`(<img\\b[^>]*\\bsrc=")(?:images/)?${name}(")`, "g");
2639
+ out = out.replace(imgTagRe, (_m, pre, post) => `${pre}${dataUri}${post}`);
2638
2640
  }
2639
2641
  return out;
2640
2642
  }
@@ -21082,37 +21084,141 @@ function removeNestedTables(html) {
21082
21084
  return result;
21083
21085
  }
21084
21086
 
21087
+ // src/hwpx/gen-profile.ts
21088
+ function normalizeAnchor(s) {
21089
+ return s.toLowerCase().replace(/[^\p{L}\p{N}]/gu, "").slice(0, 24);
21090
+ }
21091
+ function takeProfile(remap, rows, cols, anchor, seq) {
21092
+ if (!remap) return null;
21093
+ for (const t of remap.tables) {
21094
+ if (t.used) continue;
21095
+ if (t.rows !== rows || t.cols !== cols) continue;
21096
+ if (t.anchor && anchor) {
21097
+ if (t.anchor !== anchor) continue;
21098
+ } else if (t.index !== seq) {
21099
+ continue;
21100
+ }
21101
+ t.used = true;
21102
+ return t;
21103
+ }
21104
+ return null;
21105
+ }
21106
+ function parseHu(s) {
21107
+ if (s == null) return void 0;
21108
+ const n = parseInt(String(s).trim(), 10);
21109
+ return Number.isFinite(n) ? n : void 0;
21110
+ }
21111
+ function edgeXml(tag, d) {
21112
+ return d ? `<hh:${tag} type="${d.type}" width="${d.width}" color="${d.color}"/>` : `<hh:${tag} type="NONE" width="0.1 mm" color="#000000"/>`;
21113
+ }
21114
+ function borderFillDefToXml(id, def) {
21115
+ const fill = def.fill?.faceColor ? `<hh:fillBrush><hh:winBrush faceColor="${def.fill.faceColor}" hatchColor="#000000" alpha="0"/></hh:fillBrush>` : "";
21116
+ return ` <hh:borderFill id="${id}" threeD="0" shadow="0" centerLine="NONE" breakCellSeparateLine="0">
21117
+ <hh:slash type="NONE" Crooked="0" isCounter="0"/>
21118
+ <hh:backSlash type="NONE" Crooked="0" isCounter="0"/>
21119
+ ${edgeXml("leftBorder", def.leftBorder)}
21120
+ ${edgeXml("rightBorder", def.rightBorder)}
21121
+ ${edgeXml("topBorder", def.topBorder)}
21122
+ ${edgeXml("bottomBorder", def.bottomBorder)}${fill ? `
21123
+ ${fill}` : ""}
21124
+ </hh:borderFill>`;
21125
+ }
21126
+ var PROFILE_FONT_MAX = 2;
21127
+ function profileCharPrXml(id, def) {
21128
+ const height = parseHu(def.height_hwpunit) ?? 1e3;
21129
+ const color = def.textColor ?? "#000000";
21130
+ const rawFont = def.fontRef_hangul != null ? parseInt(def.fontRef_hangul, 10) || 0 : 0;
21131
+ const font = rawFont >= 0 && rawFont <= PROFILE_FONT_MAX ? rawFont : 0;
21132
+ const boldAttr = def.bold ? ` bold="1"` : "";
21133
+ const italicAttr = def.italic ? ` italic="1"` : "";
21134
+ const underline = def.underline ? `
21135
+ <hh:underline type="BOTTOM" shape="SOLID" color="${color}"/>` : "";
21136
+ return ` <hh:charPr id="${id}" height="${height}" textColor="${color}" shadeColor="none" useFontSpace="0" useKerning="0" symMark="NONE" borderFillIDRef="1"${boldAttr}${italicAttr}>
21137
+ <hh:fontRef hangul="${font}" latin="${font}" hanja="${font}" japanese="${font}" other="${font}" symbol="${font}" user="${font}"/>
21138
+ <hh:ratio hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
21139
+ <hh:spacing hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>
21140
+ <hh:relSz hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
21141
+ <hh:offset hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>${underline}
21142
+ </hh:charPr>`;
21143
+ }
21144
+ function buildProfileRemap(profile, charPrBase, borderFillBase = 3) {
21145
+ const remap = { borderFillXmls: [], charPrXmls: [], tables: [] };
21146
+ let bfNext = borderFillBase;
21147
+ let charNext = charPrBase;
21148
+ for (const t of profile.tables) {
21149
+ const localBf = {};
21150
+ for (const [key, def] of Object.entries(t.used_border_fills ?? {})) {
21151
+ const gid = bfNext++;
21152
+ remap.borderFillXmls.push(borderFillDefToXml(gid, def));
21153
+ localBf[key] = gid;
21154
+ }
21155
+ const localChar = {};
21156
+ for (const [key, def] of Object.entries(t.used_char_prs ?? {})) {
21157
+ const gid = charNext++;
21158
+ remap.charPrXmls.push(profileCharPrXml(gid, def));
21159
+ localChar[key] = gid;
21160
+ }
21161
+ let colWidths;
21162
+ if (t.col_widths_hwpunit && t.col_widths_hwpunit.length === t.cols) {
21163
+ const parsed = t.col_widths_hwpunit.map(parseHu);
21164
+ if (parsed.every((n) => n != null)) colWidths = parsed;
21165
+ }
21166
+ const tr = {
21167
+ index: t.table_index,
21168
+ rows: t.rows,
21169
+ cols: t.cols,
21170
+ // 재정규화 — 추출기는 정규화해 담지만 손편집된 프로필 JSON도 같은 키 공간으로
21171
+ anchor: t.anchor_text ? normalizeAnchor(t.anchor_text) : void 0,
21172
+ width: parseHu(t.width_hwpunit),
21173
+ colWidths,
21174
+ cellBf: /* @__PURE__ */ new Map(),
21175
+ cellChar: /* @__PURE__ */ new Map(),
21176
+ cellH: /* @__PURE__ */ new Map()
21177
+ };
21178
+ for (const cell of t.cells) {
21179
+ const k = `${cell.row},${cell.col}`;
21180
+ if (cell.borderFillIDRef != null && cell.borderFillIDRef in localBf) {
21181
+ tr.cellBf.set(k, localBf[cell.borderFillIDRef]);
21182
+ }
21183
+ if (cell.charPrIDRef != null && cell.charPrIDRef in localChar) {
21184
+ tr.cellChar.set(k, localChar[cell.charPrIDRef]);
21185
+ }
21186
+ const h = parseHu(cell.height_hwpunit);
21187
+ if (h != null) tr.cellH.set(k, h);
21188
+ }
21189
+ remap.tables.push(tr);
21190
+ }
21191
+ return remap;
21192
+ }
21193
+ function profileCharPrBase(ratioVariantCount) {
21194
+ return CHAR_VARIANT_BASE + ratioVariantCount * 4;
21195
+ }
21196
+
21085
21197
  // src/hwpx/gen-table.ts
21086
21198
  var TABLE_ID_BASE = 1e3;
21087
21199
  var tableIdCounter = TABLE_ID_BASE;
21088
21200
  function nextTableId() {
21089
21201
  return ++tableIdCounter;
21090
21202
  }
21091
- var warnedTables = /* @__PURE__ */ new Set();
21092
- function warnProfileMismatch(tblId, tp, rowCnt, colCnt) {
21093
- if (warnedTables.has(tblId)) return;
21094
- warnedTables.add(tblId);
21095
- console.warn(`[kordoc] format profile: table ${tp.rows}x${tp.cols} vs document ${rowCnt}x${colCnt} \u2014 \uD504\uB85C\uD544 \uBB34\uC2DC`);
21203
+ function anchorOfMarkdownCell(cell) {
21204
+ return normalizeAnchor(cell.replace(/!\[[^\]]*\]\([^)]*\)/g, ""));
21096
21205
  }
21097
- function usableProfile(tp, tblId, rowCnt, colCnt) {
21098
- if (!tp) return null;
21099
- if (tp.rows !== rowCnt || tp.cols !== colCnt) {
21100
- warnProfileMismatch(tblId, tp, rowCnt, colCnt);
21101
- return null;
21102
- }
21103
- return tp;
21206
+ function anchorOfHtmlCell(inner) {
21207
+ const noNested = inner.replace(/<table[\s\S]*?<\/table>/gi, "");
21208
+ const { lines } = htmlCellInnerToLines(noNested);
21209
+ return normalizeAnchor(lines.join(""));
21104
21210
  }
21105
21211
  function resolveColWidths(tp, colCnt, fallbackTotal) {
21106
21212
  if (tp?.colWidths && tp.colWidths.length === colCnt) return tp.colWidths;
21107
21213
  const w = tp?.width ? Math.floor(tp.width / colCnt) : Math.floor(fallbackTotal / colCnt);
21108
21214
  return Array(colCnt).fill(w);
21109
21215
  }
21110
- function generateTable(rows, theme, tp = null) {
21216
+ function generateTable(rows, theme, remap = null, seq = 0) {
21111
21217
  const rowCnt = rows.length;
21112
21218
  const colCnt = Math.max(...rows.map((r) => r.length), 1);
21113
21219
  const cellH = 1500;
21114
21220
  const tblId = nextTableId();
21115
- const prof = usableProfile(tp, tblId, rowCnt, colCnt);
21221
+ const prof = takeProfile(remap, rowCnt, colCnt, anchorOfMarkdownCell(rows[0]?.[0] ?? ""), seq);
21116
21222
  const colW = resolveColWidths(prof, colCnt, 44e3);
21117
21223
  const tblW = colW.reduce((a, b) => a + b, 0);
21118
21224
  const tblH = cellH * rowCnt;
@@ -21159,14 +21265,15 @@ function layoutHtmlRows(rows) {
21159
21265
  function unescapeHtml(s) {
21160
21266
  return s.replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&amp;/g, "&");
21161
21267
  }
21162
- function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, tp = null) {
21268
+ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3, remap = null, seq = 0) {
21163
21269
  const rows = parseHtmlTable(rawHtml);
21164
21270
  if (!rows || rows.length === 0) return null;
21165
21271
  const { placed, rowCnt, colCnt } = layoutHtmlRows(rows);
21166
21272
  if (rowCnt === 0 || colCnt === 0) return null;
21167
21273
  const cellH = 1500;
21168
21274
  const tblId = nextTableId();
21169
- const prof = usableProfile(tp, tblId, rowCnt, colCnt);
21275
+ const first = placed.find((p) => p.r === 0 && p.c === 0) ?? placed[0];
21276
+ const prof = takeProfile(remap, rowCnt, colCnt, first ? anchorOfHtmlCell(first.inner) : "", seq);
21170
21277
  const colW = resolveColWidths(prof, colCnt, totalWidth);
21171
21278
  const tblW = colW.reduce((a, b) => a + b, 0);
21172
21279
  const useHeaderStyle = theme.tableHeader !== theme.body || theme.tableHeaderBold;
@@ -21604,12 +21711,11 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
21604
21711
  paraXmls.push(`<hp:p paraPrIDRef="0" styleIDRef="0">${secRun}</hp:p>`);
21605
21712
  isFirst = false;
21606
21713
  }
21607
- xml = generateTable(block.rows, theme, remap?.tables.get(tableSeq) ?? null);
21608
- tableSeq++;
21714
+ xml = generateTable(block.rows, theme, remap, tableSeq++);
21609
21715
  }
21610
21716
  break;
21611
21717
  case "html_table": {
21612
- const tbl = generateHtmlTableXml(block.text || "", theme, 44e3, remap?.tables.get(tableSeq) ?? null);
21718
+ const tbl = generateHtmlTableXml(block.text || "", theme, 44e3, remap, tableSeq++);
21613
21719
  if (tbl) {
21614
21720
  if (isFirst) {
21615
21721
  const secRun = `<hp:run charPrIDRef="0">${generateSecPr(gongmun)}<hp:t></hp:t></hp:run>`;
@@ -21617,7 +21723,6 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
21617
21723
  isFirst = false;
21618
21724
  }
21619
21725
  xml = `<hp:p paraPrIDRef="0" styleIDRef="0"><hp:run charPrIDRef="0">${tbl}</hp:run></hp:p>`;
21620
- tableSeq++;
21621
21726
  } else {
21622
21727
  const plain = (block.text || "").replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
21623
21728
  xml = plain ? generateParagraph(plain) : "";
@@ -21644,93 +21749,6 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
21644
21749
  </hs:sec>`;
21645
21750
  }
21646
21751
 
21647
- // src/hwpx/gen-profile.ts
21648
- function parseHu(s) {
21649
- if (s == null) return void 0;
21650
- const n = parseInt(String(s).trim(), 10);
21651
- return Number.isFinite(n) ? n : void 0;
21652
- }
21653
- function edgeXml(tag, d) {
21654
- return d ? `<hh:${tag} type="${d.type}" width="${d.width}" color="${d.color}"/>` : `<hh:${tag} type="NONE" width="0.1 mm" color="#000000"/>`;
21655
- }
21656
- function borderFillDefToXml(id, def) {
21657
- const fill = def.fill?.faceColor ? `<hh:fillBrush><hh:winBrush faceColor="${def.fill.faceColor}" hatchColor="#000000" alpha="0"/></hh:fillBrush>` : "";
21658
- return ` <hh:borderFill id="${id}" threeD="0" shadow="0" centerLine="NONE" breakCellSeparateLine="0">
21659
- <hh:slash type="NONE" Crooked="0" isCounter="0"/>
21660
- <hh:backSlash type="NONE" Crooked="0" isCounter="0"/>
21661
- ${edgeXml("leftBorder", def.leftBorder)}
21662
- ${edgeXml("rightBorder", def.rightBorder)}
21663
- ${edgeXml("topBorder", def.topBorder)}
21664
- ${edgeXml("bottomBorder", def.bottomBorder)}${fill ? `
21665
- ${fill}` : ""}
21666
- </hh:borderFill>`;
21667
- }
21668
- function profileCharPrXml(id, def) {
21669
- const height = parseHu(def.height_hwpunit) ?? 1e3;
21670
- const color = def.textColor ?? "#000000";
21671
- const font = def.fontRef_hangul != null ? parseInt(def.fontRef_hangul, 10) || 0 : 0;
21672
- const boldAttr = def.bold ? ` bold="1"` : "";
21673
- const italicAttr = def.italic ? ` italic="1"` : "";
21674
- const underline = def.underline ? `
21675
- <hh:underline type="BOTTOM" shape="SOLID" color="${color}"/>` : "";
21676
- return ` <hh:charPr id="${id}" height="${height}" textColor="${color}" shadeColor="none" useFontSpace="0" useKerning="0" symMark="NONE" borderFillIDRef="1"${boldAttr}${italicAttr}>
21677
- <hh:fontRef hangul="${font}" latin="${font}" hanja="${font}" japanese="${font}" other="${font}" symbol="${font}" user="${font}"/>
21678
- <hh:ratio hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
21679
- <hh:spacing hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>
21680
- <hh:relSz hangul="100" latin="100" hanja="100" japanese="100" other="100" symbol="100" user="100"/>
21681
- <hh:offset hangul="0" latin="0" hanja="0" japanese="0" other="0" symbol="0" user="0"/>${underline}
21682
- </hh:charPr>`;
21683
- }
21684
- function buildProfileRemap(profile, charPrBase, borderFillBase = 3) {
21685
- const remap = { borderFillXmls: [], charPrXmls: [], tables: /* @__PURE__ */ new Map() };
21686
- let bfNext = borderFillBase;
21687
- let charNext = charPrBase;
21688
- for (const t of profile.tables) {
21689
- const localBf = {};
21690
- for (const [key, def] of Object.entries(t.used_border_fills ?? {})) {
21691
- const gid = bfNext++;
21692
- remap.borderFillXmls.push(borderFillDefToXml(gid, def));
21693
- localBf[key] = gid;
21694
- }
21695
- const localChar = {};
21696
- for (const [key, def] of Object.entries(t.used_char_prs ?? {})) {
21697
- const gid = charNext++;
21698
- remap.charPrXmls.push(profileCharPrXml(gid, def));
21699
- localChar[key] = gid;
21700
- }
21701
- let colWidths;
21702
- if (t.col_widths_hwpunit && t.col_widths_hwpunit.length === t.cols) {
21703
- const parsed = t.col_widths_hwpunit.map(parseHu);
21704
- if (parsed.every((n) => n != null)) colWidths = parsed;
21705
- }
21706
- const tr = {
21707
- rows: t.rows,
21708
- cols: t.cols,
21709
- width: parseHu(t.width_hwpunit),
21710
- colWidths,
21711
- cellBf: /* @__PURE__ */ new Map(),
21712
- cellChar: /* @__PURE__ */ new Map(),
21713
- cellH: /* @__PURE__ */ new Map()
21714
- };
21715
- for (const cell of t.cells) {
21716
- const k = `${cell.row},${cell.col}`;
21717
- if (cell.borderFillIDRef != null && cell.borderFillIDRef in localBf) {
21718
- tr.cellBf.set(k, localBf[cell.borderFillIDRef]);
21719
- }
21720
- if (cell.charPrIDRef != null && cell.charPrIDRef in localChar) {
21721
- tr.cellChar.set(k, localChar[cell.charPrIDRef]);
21722
- }
21723
- const h = parseHu(cell.height_hwpunit);
21724
- if (h != null) tr.cellH.set(k, h);
21725
- }
21726
- remap.tables.set(t.table_index, tr);
21727
- }
21728
- return remap;
21729
- }
21730
- function profileCharPrBase(ratioVariantCount) {
21731
- return CHAR_VARIANT_BASE + ratioVariantCount * 4;
21732
- }
21733
-
21734
21752
  // src/hwpx/generator.ts
21735
21753
  async function markdownToHwpx(markdown, options) {
21736
21754
  const theme = resolveTheme(options?.theme);
@@ -21741,6 +21759,12 @@ async function markdownToHwpx(markdown, options) {
21741
21759
  const remap = options?.profile ? buildProfileRemap(options.profile, profileCharPrBase(fit?.variants?.length ?? 0)) : null;
21742
21760
  const chartParts = [];
21743
21761
  const sectionXml = blocksToSectionXml(blocks, theme, gongmun, gongmunList, fit, chartParts, remap);
21762
+ if (remap && remap.tables.length > 0) {
21763
+ const unused = remap.tables.filter((t) => !t.used).length;
21764
+ if (unused === remap.tables.length) {
21765
+ 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)`);
21766
+ }
21767
+ }
21744
21768
  const zip = new JSZip6();
21745
21769
  zip.file("mimetype", "application/hwp+zip", { compression: "STORE" });
21746
21770
  zip.file("META-INF/container.xml", generateContainerXml());
@@ -21967,6 +21991,7 @@ function parseTable3(tbl, tableIndex, borderFills, charPrs) {
21967
21991
  const usedBf = /* @__PURE__ */ new Set();
21968
21992
  const usedCp = /* @__PURE__ */ new Set();
21969
21993
  const colWidths = new Array(cols).fill(void 0);
21994
+ let anchorText = "";
21970
21995
  for (const tc of elemsByLocal(tbl, "tc")) {
21971
21996
  if (nearestTable(tc) !== tbl) continue;
21972
21997
  const addr = findChildByLocalName(tc, "cellAddr");
@@ -21974,6 +21999,7 @@ function parseTable3(tbl, tableIndex, borderFills, charPrs) {
21974
21999
  const csz = findChildByLocalName(tc, "cellSz");
21975
22000
  const row = num(addr?.getAttribute("rowAddr")) ?? 0;
21976
22001
  const col = num(addr?.getAttribute("colAddr")) ?? 0;
22002
+ if (row === 0 && col === 0 && !anchorText) anchorText = directCellText(tc);
21977
22003
  const colSpan = num(span?.getAttribute("colSpan")) ?? 1;
21978
22004
  const rowSpan = num(span?.getAttribute("rowSpan")) ?? 1;
21979
22005
  const bfId = tc.getAttribute("borderFillIDRef") || void 0;
@@ -22001,6 +22027,8 @@ function parseTable3(tbl, tableIndex, borderFills, charPrs) {
22001
22027
  cells,
22002
22028
  used_border_fills: pick(borderFills, usedBf)
22003
22029
  };
22030
+ const anchor = normalizeAnchor(anchorText);
22031
+ if (anchor) table.anchor_text = anchor;
22004
22032
  if (width) table.width_hwpunit = width;
22005
22033
  if (colWidths.every((w) => w != null)) table.col_widths_hwpunit = colWidths;
22006
22034
  const cp = pick(charPrs, usedCp);
@@ -22033,6 +22061,15 @@ function nearestCell(el) {
22033
22061
  }
22034
22062
  return null;
22035
22063
  }
22064
+ function directCellText(tc) {
22065
+ let out = "";
22066
+ for (const t of elemsByLocal(tc, "t")) {
22067
+ if (nearestCell(t) !== tc) continue;
22068
+ out += t.textContent ?? "";
22069
+ if (out.length >= 64) break;
22070
+ }
22071
+ return out;
22072
+ }
22036
22073
  function pick(map, keys) {
22037
22074
  const out = {};
22038
22075
  for (const k of keys) {
@@ -22061,7 +22098,7 @@ async function hwpxToProfile(input) {
22061
22098
  tables.push(parseTable3(tbl, tableIndex++, borderFills, charPrs));
22062
22099
  }
22063
22100
  }
22064
- return { schema_version: "0.1.0", tables };
22101
+ return { schema_version: "0.2.0", tables };
22065
22102
  }
22066
22103
 
22067
22104
  // src/roundtrip/patcher.ts
@@ -24795,7 +24832,7 @@ async function parseHwp(buffer, options) {
24795
24832
  async function parsePdf(buffer, options) {
24796
24833
  let parsePdfDocument;
24797
24834
  try {
24798
- const mod = await import("./parser-NZAE7PBE.js");
24835
+ const mod = await import("./parser-DOBK652H.js");
24799
24836
  parsePdfDocument = mod.parsePdfDocument;
24800
24837
  } catch {
24801
24838
  return {
@@ -24887,7 +24924,6 @@ async function fillForm(input, values, outputFormat = "markdown") {
24887
24924
 
24888
24925
  export {
24889
24926
  extractHwpxMetadataOnly,
24890
- MAX_INLINE_MD_BYTES,
24891
24927
  extractHwp5MetadataOnly,
24892
24928
  formatFillValue,
24893
24929
  ValueCursor,
@@ -24924,4 +24960,4 @@ export {
24924
24960
  parseHwpml,
24925
24961
  fillForm
24926
24962
  };
24927
- //# sourceMappingURL=chunk-PWHM3KAA.js.map
24963
+ //# sourceMappingURL=chunk-7K5P4RNT.js.map