kordoc 3.8.4 → 3.10.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 (38) hide show
  1. package/README.md +39 -0
  2. package/dist/{-ZAIG6FWT.js → -3B5FDXW2.js} +18 -12
  3. package/dist/{chunk-2UDAEQPW.js → chunk-5DL6VCIJ.js} +4 -120
  4. package/dist/chunk-5DL6VCIJ.js.map +1 -0
  5. package/dist/{chunk-6EDNKPXQ.js → chunk-5TK4X4JQ.js} +373 -315
  6. package/dist/chunk-5TK4X4JQ.js.map +1 -0
  7. package/dist/chunk-FU25KFFZ.js +938 -0
  8. package/dist/chunk-FU25KFFZ.js.map +1 -0
  9. package/dist/chunk-MZA7AXHN.js +124 -0
  10. package/dist/chunk-MZA7AXHN.js.map +1 -0
  11. package/dist/{chunk-T4SGNVVS.js → chunk-PNXOUDS7.js} +2 -2
  12. package/dist/{chunk-T4SGNVVS.js.map → chunk-PNXOUDS7.js.map} +1 -1
  13. package/dist/{chunk-Z3O36LBJ.cjs → chunk-ZQOGTAT5.cjs} +2 -2
  14. package/dist/{chunk-Z3O36LBJ.cjs.map → chunk-ZQOGTAT5.cjs.map} +1 -1
  15. package/dist/cli.js +33 -6
  16. package/dist/cli.js.map +1 -1
  17. package/dist/index.cjs +1136 -173
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +40 -1
  20. package/dist/index.d.ts +40 -1
  21. package/dist/index.js +1018 -55
  22. package/dist/index.js.map +1 -1
  23. package/dist/mcp.js +8 -5
  24. package/dist/mcp.js.map +1 -1
  25. package/dist/{parser-ZVKCFXR3.cjs → parser-6B7BUSX3.cjs} +14 -14
  26. package/dist/{parser-ZVKCFXR3.cjs.map → parser-6B7BUSX3.cjs.map} +1 -1
  27. package/dist/{parser-2THIF623.js → parser-DKIA66MN.js} +2 -2
  28. package/dist/{parser-PR7CPMM4.js → parser-VCJTQVAH.js} +8 -6
  29. package/dist/{parser-PR7CPMM4.js.map → parser-VCJTQVAH.js.map} +1 -1
  30. package/dist/render-4I72JOAR.js +9 -0
  31. package/dist/render-4I72JOAR.js.map +1 -0
  32. package/dist/{watch-2HYPNMOB.js → watch-MQTMNUSB.js} +6 -4
  33. package/dist/{watch-2HYPNMOB.js.map → watch-MQTMNUSB.js.map} +1 -1
  34. package/package.json +2 -2
  35. package/dist/chunk-2UDAEQPW.js.map +0 -1
  36. package/dist/chunk-6EDNKPXQ.js.map +0 -1
  37. /package/dist/{-ZAIG6FWT.js.map → -3B5FDXW2.js.map} +0 -0
  38. /package/dist/{parser-2THIF623.js.map → parser-DKIA66MN.js.map} +0 -0
@@ -5,30 +5,46 @@ import {
5
5
  detectZipFormat,
6
6
  parseLenientCfb
7
7
  } from "./chunk-MEPHGCPQ.js";
8
+ import {
9
+ MAX_DECOMPRESS_SIZE,
10
+ MAX_XML_DEPTH,
11
+ MAX_ZIP_ENTRIES,
12
+ SPACE_EM_FIXED,
13
+ applyPageText,
14
+ charWidthEm1000,
15
+ clampSpan,
16
+ createSectionShared,
17
+ createXmlParser,
18
+ extractTextFromNode,
19
+ findChildByLocalName,
20
+ fitRatioForFewerLines
21
+ } from "./chunk-FU25KFFZ.js";
8
22
  import {
9
23
  HEADING_RATIO_H1,
10
24
  HEADING_RATIO_H2,
11
25
  HEADING_RATIO_H3,
12
- KordocError,
13
26
  MAX_COLS,
14
27
  MAX_ROWS,
15
28
  blocksToMarkdown,
16
29
  buildTable,
17
- classifyError,
18
- compareSectionPaths,
19
30
  convertTableToText,
20
31
  flattenLayoutTables,
32
+ mapPuaText
33
+ } from "./chunk-5DL6VCIJ.js";
34
+ import {
35
+ parsePageRange
36
+ } from "./chunk-MOL7MDBG.js";
37
+ import {
38
+ KordocError,
39
+ classifyError,
40
+ compareSectionPaths,
21
41
  isPathTraversal,
22
- mapPuaText,
23
42
  normalizeSectionHref,
24
43
  precheckZipSize,
25
44
  sanitizeHref,
26
45
  stripDtd,
27
46
  toArrayBuffer
28
- } from "./chunk-2UDAEQPW.js";
29
- import {
30
- parsePageRange
31
- } from "./chunk-MOL7MDBG.js";
47
+ } from "./chunk-MZA7AXHN.js";
32
48
 
33
49
  // src/index.ts
34
50
  import { readFile } from "fs/promises";
@@ -143,57 +159,6 @@ function comResultToParseResult(pages, pageCount, warnings) {
143
159
  };
144
160
  }
145
161
 
146
- // src/hwpx/parser-shared.ts
147
- import { DOMParser } from "@xmldom/xmldom";
148
- var MAX_DECOMPRESS_SIZE = 100 * 1024 * 1024;
149
- var MAX_ZIP_ENTRIES = 500;
150
- function clampSpan(val, max) {
151
- return Math.max(1, Math.min(val, max));
152
- }
153
- var MAX_XML_DEPTH = 200;
154
- function createSectionShared() {
155
- return { numState: /* @__PURE__ */ new Map(), pageText: { headers: [], footers: [] }, track: { deleteDepth: 0, warned: false } };
156
- }
157
- function createXmlParser(warnings) {
158
- return new DOMParser({
159
- onError(level, msg2) {
160
- if (level === "fatalError") throw new KordocError(`XML \uD30C\uC2F1 \uC2E4\uD328: ${msg2}`);
161
- warnings?.push({ code: "MALFORMED_XML", message: `XML ${level === "warn" ? "\uACBD\uACE0" : "\uC624\uB958"}: ${msg2}` });
162
- }
163
- });
164
- }
165
- function applyPageText(blocks, shared) {
166
- const { headers, footers } = shared.pageText;
167
- if (headers.length > 0) {
168
- blocks.unshift(...headers.map((t) => ({ type: "paragraph", text: t, pageNumber: 1 })));
169
- }
170
- if (footers.length > 0) {
171
- blocks.push(...footers.map((t) => ({ type: "paragraph", text: t })));
172
- }
173
- }
174
- function findChildByLocalName(parent, name) {
175
- const children = parent.childNodes;
176
- if (!children) return null;
177
- for (let i = 0; i < children.length; i++) {
178
- const ch = children[i];
179
- if (ch.nodeType !== 1) continue;
180
- const tag = (ch.tagName || ch.localName || "").replace(/^[^:]+:/, "");
181
- if (tag === name) return ch;
182
- }
183
- return null;
184
- }
185
- function extractTextFromNode(node) {
186
- let result = "";
187
- const children = node.childNodes;
188
- if (!children) return result;
189
- for (let i = 0; i < children.length; i++) {
190
- const child = children[i];
191
- if (child.nodeType === 3) result += child.textContent || "";
192
- else if (child.nodeType === 1) result += extractTextFromNode(child);
193
- }
194
- return result.trim();
195
- }
196
-
197
162
  // src/hwpx/styles.ts
198
163
  async function extractHwpxStyles(zip, decompressed) {
199
164
  const result = {
@@ -419,8 +384,10 @@ var CONVERT_MAP = {
419
384
  SUCC: "\\succ",
420
385
  UPLUS: "\\uplus",
421
386
  "\xB1": "\\pm",
387
+ "+-": "\\pm",
422
388
  "-+": "\\mp",
423
389
  "\xF7": "\\div",
390
+ cdot: "\\cdot",
424
391
  CIRC: "\\circ",
425
392
  BULLET: "\\bullet",
426
393
  DEG: " ^\\circ",
@@ -809,6 +776,10 @@ function hmlToLatex(hmlEqStr) {
809
776
  const t = tokens[i];
810
777
  if (t in CONVERT_MAP) tokens[i] = CONVERT_MAP[t];
811
778
  else if (t in MIDDLE_CONVERT_MAP) tokens[i] = MIDDLE_CONVERT_MAP[t];
779
+ else {
780
+ const quoted = /^"(.+)"$/.exec(t);
781
+ if (quoted) tokens[i] = `\\text{${quoted[1]}}`;
782
+ }
812
783
  }
813
784
  tokens = tokens.filter((tok) => tok.length !== 0);
814
785
  tokens = replaceBracket(tokens);
@@ -16550,7 +16521,7 @@ function isDistributionSentinel(markdown) {
16550
16521
 
16551
16522
  // src/xlsx/parser.ts
16552
16523
  import JSZip3 from "jszip";
16553
- import { DOMParser as DOMParser2 } from "@xmldom/xmldom";
16524
+ import { DOMParser } from "@xmldom/xmldom";
16554
16525
  var MAX_SHEETS = 100;
16555
16526
  var MAX_DECOMPRESS_SIZE3 = 100 * 1024 * 1024;
16556
16527
  var MAX_ROWS2 = 1e4;
@@ -16590,7 +16561,7 @@ function getTextContent(el) {
16590
16561
  return el.textContent?.trim() ?? "";
16591
16562
  }
16592
16563
  function parseXml(text) {
16593
- return new DOMParser2().parseFromString(stripDtd(text), "text/xml");
16564
+ return new DOMParser().parseFromString(stripDtd(text), "text/xml");
16594
16565
  }
16595
16566
  function parseSharedStrings(xml) {
16596
16567
  const doc = parseXml(xml);
@@ -17450,7 +17421,7 @@ async function parseXlsDocument(buffer, options) {
17450
17421
 
17451
17422
  // src/docx/parser.ts
17452
17423
  import JSZip4 from "jszip";
17453
- import { DOMParser as DOMParser3 } from "@xmldom/xmldom";
17424
+ import { DOMParser as DOMParser2 } from "@xmldom/xmldom";
17454
17425
 
17455
17426
  // src/docx/equation.ts
17456
17427
  function lname(el) {
@@ -17879,7 +17850,7 @@ function getAttr(el, localName2) {
17879
17850
  return null;
17880
17851
  }
17881
17852
  function parseXml2(text) {
17882
- return new DOMParser3().parseFromString(stripDtd(text), "text/xml");
17853
+ return new DOMParser2().parseFromString(stripDtd(text), "text/xml");
17883
17854
  }
17884
17855
  function parseStyles(xml) {
17885
17856
  const doc = parseXml2(xml);
@@ -18316,7 +18287,7 @@ async function parseDocxDocument(buffer, options) {
18316
18287
  }
18317
18288
 
18318
18289
  // src/hwpml/parser.ts
18319
- import { DOMParser as DOMParser4 } from "@xmldom/xmldom";
18290
+ import { DOMParser as DOMParser3 } from "@xmldom/xmldom";
18320
18291
  var MAX_XML_DEPTH2 = 200;
18321
18292
  var MAX_TABLE_ROWS = 5e3;
18322
18293
  var MAX_TABLE_COLS = 500;
@@ -18329,7 +18300,7 @@ function parseHwpmlDocument(buffer, options) {
18329
18300
  const normalized = text.replace(/&nbsp;/g, "&#160;");
18330
18301
  const xml = stripDtd(normalized);
18331
18302
  const warnings = [];
18332
- const parser = new DOMParser4({
18303
+ const parser = new DOMParser3({
18333
18304
  onError: (_level, msg2) => {
18334
18305
  warnings.push({ message: `HWPML XML \uD30C\uC2F1 \uACBD\uACE0: ${msg2}`, code: "MALFORMED_XML" });
18335
18306
  }
@@ -20079,245 +20050,6 @@ async function fillHwpx(hwpxBuffer, values) {
20079
20050
  // src/hwpx/generator.ts
20080
20051
  import JSZip6 from "jszip";
20081
20052
 
20082
- // src/hwpx/text-metrics.ts
20083
- var ASCII_W = [
20084
- 300,
20085
- 320,
20086
- 320,
20087
- 610,
20088
- 610,
20089
- 830,
20090
- 724,
20091
- 320,
20092
- 320,
20093
- 320,
20094
- 550,
20095
- 550,
20096
- 320,
20097
- 550,
20098
- 320,
20099
- 550,
20100
- // 0x20-0x2F
20101
- 550,
20102
- 550,
20103
- 550,
20104
- 550,
20105
- 550,
20106
- 550,
20107
- 550,
20108
- 550,
20109
- 550,
20110
- 550,
20111
- 320,
20112
- 320,
20113
- 550,
20114
- 550,
20115
- 550,
20116
- 550,
20117
- // 0x30-0x3F
20118
- 830,
20119
- 706,
20120
- 605,
20121
- 685,
20122
- 719,
20123
- 627,
20124
- 617,
20125
- 683,
20126
- 734,
20127
- 305,
20128
- 315,
20129
- 660,
20130
- 605,
20131
- 839,
20132
- 734,
20133
- 732,
20134
- // 0x40-0x4F
20135
- 603,
20136
- 705,
20137
- 660,
20138
- 627,
20139
- 664,
20140
- 731,
20141
- 706,
20142
- 910,
20143
- 705,
20144
- 705,
20145
- 626,
20146
- 320,
20147
- 550,
20148
- 320,
20149
- 550,
20150
- 550,
20151
- // 0x50-0x5F
20152
- 320,
20153
- 569,
20154
- 597,
20155
- 552,
20156
- 597,
20157
- 536,
20158
- 356,
20159
- 562,
20160
- 635,
20161
- 287,
20162
- 288,
20163
- 582,
20164
- 287,
20165
- 907,
20166
- 635,
20167
- 588,
20168
- // 0x60-0x6F
20169
- 597,
20170
- 579,
20171
- 478,
20172
- 496,
20173
- 356,
20174
- 635,
20175
- 563,
20176
- 720,
20177
- 542,
20178
- 543,
20179
- 486,
20180
- 320,
20181
- 320,
20182
- 320,
20183
- 550,
20184
- 0
20185
- // 0x70-0x7E(+DEL)
20186
- ];
20187
- var SYM_W = {
20188
- 160: 300,
20189
- 163: 568,
20190
- 165: 707,
20191
- 167: 498,
20192
- 171: 440,
20193
- 172: 564,
20194
- 176: 291,
20195
- 177: 798,
20196
- 182: 606,
20197
- 183: 320,
20198
- 187: 440,
20199
- 215: 617,
20200
- 247: 678,
20201
- 8211: 625,
20202
- 8212: 875,
20203
- 8213: 875,
20204
- 8216: 320,
20205
- 8217: 320,
20206
- 8220: 480,
20207
- 8221: 480,
20208
- 8224: 558,
20209
- 8225: 438,
20210
- 8229: 640,
20211
- 8230: 960,
20212
- 8240: 988,
20213
- 8242: 335,
20214
- 8243: 474,
20215
- 8251: 770,
20216
- 8364: 656,
20217
- 9756: 1012,
20218
- 9758: 1012
20219
- };
20220
- function charWidthEm1000(cp) {
20221
- if (cp >= 32 && cp <= 126) return ASCII_W[cp - 32];
20222
- const sym = SYM_W[cp];
20223
- if (sym !== void 0) return sym;
20224
- if (cp >= 44032 && cp <= 55203) return 970;
20225
- if (cp >= 4352 && cp <= 4607) return 970;
20226
- if (cp >= 12593 && cp <= 12686) return 970;
20227
- if (cp >= 19968 && cp <= 40959 || cp >= 63744 && cp <= 64255) return 1e3;
20228
- if (cp >= 12296 && cp <= 12305 || cp >= 12308 && cp <= 12315) return 500;
20229
- if (cp === 12288) return 970;
20230
- if (cp >= 8592 && cp <= 8959) return 970;
20231
- if (cp >= 9312 && cp <= 9471) return 970;
20232
- if (cp >= 9632 && cp <= 9983) return 970;
20233
- if (cp >= 12800 && cp <= 13311) return 970;
20234
- if (cp >= 65281 && cp <= 65376) return 970;
20235
- return cp >= 11904 ? 970 : 550;
20236
- }
20237
- var SPACE_EM_FIXED = 500;
20238
- var SPACE_EM_FONT = 300;
20239
- function measureTextWidth(text, height, ratioPct, opts) {
20240
- const spaceEm = opts?.spaceEm ?? SPACE_EM_FIXED;
20241
- const spacing = opts?.spacingPct ?? 0;
20242
- let em = 0;
20243
- for (const ch of text) {
20244
- const cp = ch.codePointAt(0);
20245
- const w = cp === 32 ? spaceEm : charWidthEm1000(cp);
20246
- em += w * (1 + spacing / 100);
20247
- }
20248
- return em / 1e3 * height * (ratioPct / 100);
20249
- }
20250
- var FORBID_START = /* @__PURE__ */ new Set([..."!%),.:;?]}\xA2\xB0\u2032\u2033\u2103\u3009\u300B\u300D\u300F\u3011\u3015!%),.:;?]}\u20A9~\u2026\xB7\u3001\u3002\u3003"]);
20251
- var FORBID_END = /* @__PURE__ */ new Set([..."$([{\xA3\xA5\u3008\u300A\u300C\u300E\u3010\u3014$([{\u20A9"]);
20252
- function simulateWrap(text, firstWidth, contWidth, height, ratioPct, mode = "keep", opts) {
20253
- const EPS = 0.5;
20254
- const spaceEm = opts?.spaceEm ?? SPACE_EM_FIXED;
20255
- const spacing = opts?.spacingPct ?? 0;
20256
- const k = height * ratioPct / 100 / 1e3;
20257
- const cwCp = (cp) => (cp === 32 ? spaceEm : charWidthEm1000(cp)) * (1 + spacing / 100) * k;
20258
- const charW = (ch) => cwCp(ch.codePointAt(0));
20259
- const rangeW = (from, to) => {
20260
- let w = 0;
20261
- for (const ch of text.slice(from, to)) w += charW(ch);
20262
- return w;
20263
- };
20264
- const units = text.match(mode === "keep" ? / +|[^ ]+/g : / +|[^ ]/g) ?? [];
20265
- const starts = [0];
20266
- let lineW = 0;
20267
- let avail = firstWidth;
20268
- let pos = 0;
20269
- const lineStart = () => starts[starts.length - 1];
20270
- const breakBefore = (unitPos, w) => {
20271
- let bp = unitPos;
20272
- const u = text[unitPos];
20273
- if (u !== void 0 && FORBID_START.has(u) && bp - 1 > lineStart() && text[bp - 1] !== " ") bp--;
20274
- while (bp - 1 > lineStart() && FORBID_END.has(text[bp - 1])) bp--;
20275
- if (bp <= lineStart()) bp = unitPos;
20276
- starts.push(bp);
20277
- avail = contWidth;
20278
- lineW = rangeW(bp, unitPos) + w;
20279
- };
20280
- for (const u of units) {
20281
- if (u[0] === " ") {
20282
- lineW += charW(" ") * u.length;
20283
- pos += u.length;
20284
- continue;
20285
- }
20286
- const w = rangeW(pos, pos + u.length);
20287
- if (lineW + w <= avail + EPS) {
20288
- lineW += w;
20289
- pos += u.length;
20290
- continue;
20291
- }
20292
- if (lineW === 0 || w > contWidth + EPS) {
20293
- let sub = 0;
20294
- for (const ch of u) {
20295
- const c = charW(ch);
20296
- if (lineW + c > avail + EPS && lineW > 0) breakBefore(pos + sub, 0);
20297
- lineW += c;
20298
- sub += ch.length;
20299
- }
20300
- pos += u.length;
20301
- continue;
20302
- }
20303
- breakBefore(pos, w);
20304
- pos += u.length;
20305
- }
20306
- return { lines: starts.length, starts, lastLineWidth: lineW };
20307
- }
20308
- function simulateWrapKeepWord(text, firstWidth, contWidth, height, ratioPct, opts) {
20309
- return simulateWrap(text, firstWidth, contWidth, height, ratioPct, "keep", opts);
20310
- }
20311
- function fitRatioForFewerLines(text, firstWidth, contWidth, height, baseRatio, minRatio, opts) {
20312
- const base = simulateWrap(text, firstWidth, contWidth, height, baseRatio, "keep", opts);
20313
- if (base.lines < 2) return null;
20314
- for (let r = baseRatio - 1; r >= minRatio; r--) {
20315
- const sim = simulateWrap(text, firstWidth, contWidth, height, r, "keep", opts);
20316
- if (sim.lines < base.lines) return r;
20317
- }
20318
- return null;
20319
- }
20320
-
20321
20053
  // src/hwpx/gongmun.ts
20322
20054
  var OFFICIAL_MARGINS = { top: 20, bottom: 10, left: 20, right: 20 };
20323
20055
  var PRESET_DEFAULTS = {
@@ -20552,6 +20284,16 @@ function buildPrvText(blocks) {
20552
20284
  }
20553
20285
  return lines.join("\n").slice(0, 1024);
20554
20286
  }
20287
+ function findMathDelim(s, from) {
20288
+ let i = s.indexOf("$$", from);
20289
+ while (i > 0) {
20290
+ let backslashes = 0;
20291
+ for (let j = i - 1; j >= 0 && s[j] === "\\"; j--) backslashes++;
20292
+ if (backslashes % 2 === 0) break;
20293
+ i = s.indexOf("$$", i + 1);
20294
+ }
20295
+ return i;
20296
+ }
20555
20297
  function parseMarkdownToBlocks(md2) {
20556
20298
  const lines = md2.split("\n");
20557
20299
  const blocks = [];
@@ -20562,6 +20304,45 @@ function parseMarkdownToBlocks(md2) {
20562
20304
  i++;
20563
20305
  continue;
20564
20306
  }
20307
+ const mathOpen = /^\s*\$\$/.exec(line);
20308
+ if (mathOpen) {
20309
+ const afterOpen = line.slice(mathOpen[0].length);
20310
+ const closeSame = findMathDelim(afterOpen, 0);
20311
+ if (closeSame >= 0) {
20312
+ const inner = afterOpen.slice(0, closeSame).trim();
20313
+ const trailing2 = afterOpen.slice(closeSame + 2).trim();
20314
+ if (inner) blocks.push({ type: "equation", text: inner });
20315
+ if (trailing2) blocks.push({ type: "paragraph", text: trailing2 });
20316
+ i++;
20317
+ continue;
20318
+ }
20319
+ const mathLines = [];
20320
+ if (afterOpen.trim()) mathLines.push(afterOpen);
20321
+ let closed = false;
20322
+ let trailing = "";
20323
+ let j = i + 1;
20324
+ for (; j < lines.length; j++) {
20325
+ const l = lines[j];
20326
+ if (!l.trim() || /^\s*(`{3,}|~{3,})/.test(l)) break;
20327
+ const end = findMathDelim(l, 0);
20328
+ if (end >= 0) {
20329
+ const before = l.slice(0, end);
20330
+ if (before.trim()) mathLines.push(before);
20331
+ trailing = l.slice(end + 2).trim();
20332
+ closed = true;
20333
+ j++;
20334
+ break;
20335
+ }
20336
+ mathLines.push(l);
20337
+ }
20338
+ if (closed) {
20339
+ const text = mathLines.join("\n").trim();
20340
+ if (text) blocks.push({ type: "equation", text });
20341
+ if (trailing) blocks.push({ type: "paragraph", text: trailing });
20342
+ i = j;
20343
+ continue;
20344
+ }
20345
+ }
20565
20346
  const fenceMatch = line.match(/^(`{3,}|~{3,})(.*)$/);
20566
20347
  if (fenceMatch) {
20567
20348
  const fence = fenceMatch[1];
@@ -20954,6 +20735,7 @@ function precomputeGongmunList(blocks, gongmun) {
20954
20735
  i++;
20955
20736
  continue;
20956
20737
  }
20738
+ const passThrough = (t) => t === "table" || t === "html_table" || t === "equation";
20957
20739
  const run = [];
20958
20740
  while (i < blocks.length) {
20959
20741
  const t = blocks[i].type;
@@ -20962,9 +20744,9 @@ function precomputeGongmunList(blocks, gongmun) {
20962
20744
  i++;
20963
20745
  continue;
20964
20746
  }
20965
- if (t === "table" || t === "html_table") {
20747
+ if (passThrough(t)) {
20966
20748
  let j = i + 1;
20967
- while (j < blocks.length && (blocks[j].type === "table" || blocks[j].type === "html_table")) j++;
20749
+ while (j < blocks.length && passThrough(blocks[j].type)) j++;
20968
20750
  if (j < blocks.length && blocks[j].type === "list_item") {
20969
20751
  i = j;
20970
20752
  continue;
@@ -21490,6 +21272,280 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3) {
21490
21272
  return `<hp:tbl id="${tblId}" zOrder="0" numberingType="TABLE" pageBreak="CELL" repeatHeader="0" rowCnt="${rowCnt}" colCnt="${colCnt}" cellSpacing="0" borderFillIDRef="2" noShading="0"><hp:sz width="${tblW}" widthRelTo="ABSOLUTE" height="${cellH * rowCnt}" heightRelTo="ABSOLUTE" protect="0"/><hp:pos treatAsChar="1" affectLSpacing="0" flowWithText="0" 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:inMargin left="510" right="510" top="141" bottom="141"/>` + trXmls.join("") + `</hp:tbl>`;
21491
21273
  }
21492
21274
 
21275
+ // src/hwpx/equation-generate.ts
21276
+ var MAX_EQUATION_SOURCE = 1e4;
21277
+ var MAX_GROUP_DEPTH = 64;
21278
+ var COMMAND_MAP = {
21279
+ alpha: "alpha",
21280
+ beta: "beta",
21281
+ gamma: "gamma",
21282
+ delta: "delta",
21283
+ epsilon: "epsilon",
21284
+ zeta: "zeta",
21285
+ eta: "eta",
21286
+ theta: "theta",
21287
+ iota: "iota",
21288
+ kappa: "kappa",
21289
+ lambda: "lambda",
21290
+ mu: "mu",
21291
+ nu: "nu",
21292
+ xi: "xi",
21293
+ pi: "pi",
21294
+ rho: "rho",
21295
+ sigma: "sigma",
21296
+ tau: "tau",
21297
+ upsilon: "upsilon",
21298
+ phi: "phi",
21299
+ chi: "chi",
21300
+ psi: "psi",
21301
+ omega: "omega",
21302
+ Gamma: "GAMMA",
21303
+ Delta: "DELTA",
21304
+ Theta: "THETA",
21305
+ Lambda: "LAMBDA",
21306
+ Xi: "XI",
21307
+ Pi: "PI",
21308
+ Sigma: "SIGMA",
21309
+ Upsilon: "UPSILON",
21310
+ Phi: "PHI",
21311
+ Psi: "PSI",
21312
+ Omega: "OMEGA",
21313
+ le: "LEQ",
21314
+ leq: "LEQ",
21315
+ ge: "GEQ",
21316
+ geq: "GEQ",
21317
+ ne: "!=",
21318
+ neq: "!=",
21319
+ pm: "+-",
21320
+ mp: "-+",
21321
+ times: "TIMES",
21322
+ cdot: "cdot",
21323
+ ast: "AST",
21324
+ circ: "CIRC",
21325
+ bullet: "BULLET",
21326
+ in: "IN",
21327
+ notin: "NOTIN",
21328
+ subset: "SUBSET",
21329
+ subseteq: "SUBSETEQ",
21330
+ supset: "SUPERSET",
21331
+ supseteq: "SUPSETEQ",
21332
+ cup: "CUP",
21333
+ cap: "SMALLINTER",
21334
+ emptyset: "EMPTYSET",
21335
+ forall: "FORALL",
21336
+ exists: "EXIST",
21337
+ infinity: "INF",
21338
+ infty: "INF",
21339
+ partial: "Partial",
21340
+ nabla: "NABLA",
21341
+ int: "int",
21342
+ iint: "dint",
21343
+ iiint: "tint",
21344
+ oint: "oint",
21345
+ sum: "sum",
21346
+ prod: "prod",
21347
+ lim: "lim",
21348
+ to: "->",
21349
+ rightarrow: "->",
21350
+ leftarrow: "larrow",
21351
+ leftrightarrow: "<->",
21352
+ Rightarrow: "RARROW",
21353
+ Leftarrow: "LARROW",
21354
+ Leftrightarrow: "LRARROW",
21355
+ cdots: "CDOTS",
21356
+ ldots: "LDOTS",
21357
+ vdots: "VDOTS",
21358
+ ddots: "DDOTS"
21359
+ };
21360
+ var ACCENT_COMMANDS = {
21361
+ bar: "bar",
21362
+ overline: "bar",
21363
+ vec: "vec",
21364
+ overrightarrow: "vec",
21365
+ hat: "hat",
21366
+ widehat: "hat",
21367
+ tilde: "tilde",
21368
+ widetilde: "tilde",
21369
+ dot: "dot",
21370
+ ddot: "ddot",
21371
+ underline: "under"
21372
+ };
21373
+ var RESERVED_WORDS = new Set(
21374
+ [...Object.keys(CONVERT_MAP), ...Object.keys(MIDDLE_CONVERT_MAP), "over", "root", "of"].filter((w) => /^[A-Za-z]+$/.test(w))
21375
+ );
21376
+ function skipSpaces(input, idx) {
21377
+ while (idx < input.length && /\s/.test(input[idx])) idx++;
21378
+ return idx;
21379
+ }
21380
+ function normalizeEqEdit(input) {
21381
+ return input.replace(/\s+/g, " ").trim();
21382
+ }
21383
+ function stripMathDelimiters(input) {
21384
+ let s = input.trim();
21385
+ if (s.startsWith("$$") && s.endsWith("$$")) s = s.slice(2, -2).trim();
21386
+ if (s.startsWith("\\[") && s.endsWith("\\]")) s = s.slice(2, -2).trim();
21387
+ return s;
21388
+ }
21389
+ function readBalanced(input, idx, open, close) {
21390
+ let depth = 1;
21391
+ let cursor = idx + 1;
21392
+ while (cursor < input.length) {
21393
+ const ch = input[cursor];
21394
+ if (ch === "\\") {
21395
+ cursor += 2;
21396
+ continue;
21397
+ }
21398
+ if (ch === open) depth++;
21399
+ else if (ch === close) depth--;
21400
+ if (depth === 0) {
21401
+ return { value: input.slice(idx + 1, cursor), next: cursor + 1 };
21402
+ }
21403
+ cursor++;
21404
+ }
21405
+ return { value: input.slice(idx + 1), next: input.length };
21406
+ }
21407
+ function readGroupOrToken(input, idx, depth) {
21408
+ const start = skipSpaces(input, idx);
21409
+ if (depth > MAX_GROUP_DEPTH) return { value: input.slice(start), next: input.length };
21410
+ if (input[start] === "{") {
21411
+ const group = readBalanced(input, start, "{", "}");
21412
+ return { value: convertLatexFragment(group.value, depth + 1), next: group.next };
21413
+ }
21414
+ if (input[start] === "\\") {
21415
+ const cmd = readCommand(input, start, depth + 1);
21416
+ return { value: cmd.value, next: cmd.next };
21417
+ }
21418
+ return { value: input[start] ?? "", next: Math.min(start + 1, input.length) };
21419
+ }
21420
+ function readCommandName(input, idx) {
21421
+ if (input[idx + 1] === "\\") return { value: "\\", next: idx + 2 };
21422
+ const match = /^[A-Za-z]+/.exec(input.slice(idx + 1));
21423
+ if (match) return { value: match[0], next: idx + 1 + match[0].length };
21424
+ return { value: input[idx + 1] ?? "", next: Math.min(idx + 2, input.length) };
21425
+ }
21426
+ function readCommand(input, idx, depth) {
21427
+ const name = readCommandName(input, idx);
21428
+ const command = name.value;
21429
+ if (command === "\\") return { value: "#", next: name.next };
21430
+ if (command === "frac") {
21431
+ const num = readGroupOrToken(input, name.next, depth);
21432
+ const den = readGroupOrToken(input, num.next, depth);
21433
+ return { value: `{${num.value}} over {${den.value}}`, next: den.next };
21434
+ }
21435
+ if (command === "sqrt") {
21436
+ let cursor = skipSpaces(input, name.next);
21437
+ let root = null;
21438
+ if (input[cursor] === "[") {
21439
+ const opt = readBalanced(input, cursor, "[", "]");
21440
+ root = { value: convertLatexFragment(opt.value, depth + 1), next: opt.next };
21441
+ cursor = opt.next;
21442
+ }
21443
+ const body = readGroupOrToken(input, cursor, depth);
21444
+ if (root) return { value: `root {${root.value}} of {${body.value}}`, next: body.next };
21445
+ return { value: `sqrt{${body.value}}`, next: body.next };
21446
+ }
21447
+ if (command === "begin") {
21448
+ const env = readGroupOrToken(input, name.next, depth);
21449
+ const endTag = `\\end{${env.value}}`;
21450
+ const endIdx = input.indexOf(endTag, env.next);
21451
+ if (endIdx === -1) return { value: env.value, next: env.next };
21452
+ const body = convertLatexFragment(input.slice(env.next, endIdx), depth + 1);
21453
+ if (env.value === "matrix" || env.value === "pmatrix" || env.value === "bmatrix") {
21454
+ return { value: `{${env.value}{${body}}}`, next: endIdx + endTag.length };
21455
+ }
21456
+ return { value: body, next: endIdx + endTag.length };
21457
+ }
21458
+ if (command === "left" || command === "right") {
21459
+ const kw = command === "left" ? "LEFT" : "RIGHT";
21460
+ const cursor = skipSpaces(input, name.next);
21461
+ let delimiter = input[cursor] ?? "";
21462
+ let next = delimiter ? cursor + 1 : cursor;
21463
+ if (delimiter === "\\") {
21464
+ const escaped = readCommandName(input, cursor);
21465
+ delimiter = escaped.value === "\\" ? "\\" : COMMAND_MAP[escaped.value] ?? escaped.value;
21466
+ next = escaped.next;
21467
+ }
21468
+ return { value: delimiter ? `${kw} ${delimiter}` : kw, next };
21469
+ }
21470
+ if (command in ACCENT_COMMANDS) {
21471
+ const body = readGroupOrToken(input, name.next, depth);
21472
+ return { value: `${ACCENT_COMMANDS[command]}{${body.value}}`, next: body.next };
21473
+ }
21474
+ if (command === "mathrm" || command === "text") {
21475
+ const start = skipSpaces(input, name.next);
21476
+ if (input[start] === "{") {
21477
+ const group = readBalanced(input, start, "{", "}");
21478
+ return { value: `"${group.value}"`, next: group.next };
21479
+ }
21480
+ const tok = readGroupOrToken(input, start, depth);
21481
+ return { value: `"${tok.value}"`, next: tok.next };
21482
+ }
21483
+ return { value: COMMAND_MAP[command] ?? command, next: name.next };
21484
+ }
21485
+ function convertLatexFragment(input, depth) {
21486
+ if (depth > MAX_GROUP_DEPTH) return normalizeEqEdit(input);
21487
+ let out = "";
21488
+ let idx = 0;
21489
+ while (idx < input.length) {
21490
+ const ch = input[idx];
21491
+ if (ch === "\\") {
21492
+ const cmd = readCommand(input, idx, depth + 1);
21493
+ out += ` ${cmd.value} `;
21494
+ idx = cmd.next;
21495
+ continue;
21496
+ }
21497
+ if (ch === "{") {
21498
+ const group = readBalanced(input, idx, "{", "}");
21499
+ out += `{${convertLatexFragment(group.value, depth + 1)}}`;
21500
+ idx = group.next;
21501
+ continue;
21502
+ }
21503
+ if (ch === "_" || ch === "^") {
21504
+ const script = readGroupOrToken(input, idx + 1, depth);
21505
+ out += ` ${ch}{${script.value}}`;
21506
+ idx = script.next;
21507
+ continue;
21508
+ }
21509
+ if (ch === "&") {
21510
+ out += " & ";
21511
+ idx++;
21512
+ continue;
21513
+ }
21514
+ out += ch;
21515
+ idx++;
21516
+ }
21517
+ return normalizeEqEdit(out);
21518
+ }
21519
+ function quoteReservedKeywords(latex) {
21520
+ return latex.replace(/([_^])\s*\{\s*([A-Za-z]+)\s*\}/g, (match, op, word) => RESERVED_WORDS.has(word) ? `${op}{"${word}"}` : match);
21521
+ }
21522
+ function latexLikeToEqEdit(input) {
21523
+ const src = stripMathDelimiters(input);
21524
+ if (src.length > MAX_EQUATION_SOURCE) return normalizeEqEdit(src);
21525
+ return convertLatexFragment(quoteReservedKeywords(src), 0);
21526
+ }
21527
+ function estimateEquationMetrics(script) {
21528
+ const cleaned = script.replace(/[{}\\^_]/g, "").replace(/\s+/g, " ").trim();
21529
+ const width = Math.min(Math.max(cleaned.length, 5) * 700 + 2e3, 4e4);
21530
+ const rowCount = Math.max(1, (script.match(/#/g) ?? []).length + 1);
21531
+ if (/\bmatrix\b|#/.test(script)) {
21532
+ if (rowCount >= 4) return { width, height: 5500, baseline: 55 };
21533
+ if (rowCount === 3) return { width, height: 4500, baseline: 60 };
21534
+ return { width, height: 3260, baseline: 63 };
21535
+ }
21536
+ if (/\bover\b|\broot\b|\bsqrt\b/.test(script)) return { width, height: 3010, baseline: 69 };
21537
+ return { width, height: 1450, baseline: 71 };
21538
+ }
21539
+ function generateEquationXml(script, zOrder = 0) {
21540
+ const { width, height, baseline } = estimateEquationMetrics(script);
21541
+ const eqId = 2000000001 + zOrder;
21542
+ return `<hp:equation id="${eqId}" zOrder="${zOrder}" numberingType="EQUATION" textWrap="TOP_AND_BOTTOM" textFlow="BOTH_SIDES" lock="0" dropcapstyle="None" version="Equation Version 60" baseLine="${baseline}" textColor="#000000" baseUnit="1200" lineMode="CHAR" font="HYhwpEQ"><hp:sz width="${width}" widthRelTo="ABSOLUTE" height="${height}" 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="56" right="56" top="0" bottom="0"/><hp:shapeComment>\uC218\uC2DD\uC785\uB2C8\uB2E4.</hp:shapeComment><hp:script>${escapeXml(script)}</hp:script></hp:equation>`;
21543
+ }
21544
+ function generateEquationParagraph(input, zOrder = 0) {
21545
+ const script = latexLikeToEqEdit(input);
21546
+ return `<hp:p paraPrIDRef="${PARA_NORMAL}" styleIDRef="0"><hp:run charPrIDRef="${CHAR_NORMAL}">${generateEquationXml(script, zOrder)}</hp:run></hp:p>`;
21547
+ }
21548
+
21493
21549
  // src/hwpx/gen-section.ts
21494
21550
  function generateSecPr(gongmun) {
21495
21551
  const m = gongmun ? {
@@ -21537,6 +21593,15 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
21537
21593
  xml = codeLines.map((line) => generateParagraph(line || " ", PARA_CODE)).join("\n ");
21538
21594
  break;
21539
21595
  }
21596
+ case "equation": {
21597
+ if (isFirst) {
21598
+ const secRun = `<hp:run charPrIDRef="0">${generateSecPr(gongmun)}<hp:t></hp:t></hp:run>`;
21599
+ paraXmls.push(`<hp:p paraPrIDRef="0" styleIDRef="0">${secRun}</hp:p>`);
21600
+ isFirst = false;
21601
+ }
21602
+ xml = generateEquationParagraph(block.text || "", blockIdx);
21603
+ break;
21604
+ }
21540
21605
  case "blockquote":
21541
21606
  xml = generateParagraph(
21542
21607
  block.text || "",
@@ -24368,7 +24433,7 @@ async function parseHwp(buffer, options) {
24368
24433
  async function parsePdf(buffer, options) {
24369
24434
  let parsePdfDocument;
24370
24435
  try {
24371
- const mod = await import("./parser-PR7CPMM4.js");
24436
+ const mod = await import("./parser-VCJTQVAH.js");
24372
24437
  parsePdfDocument = mod.parsePdfDocument;
24373
24438
  } catch {
24374
24439
  return {
@@ -24472,13 +24537,6 @@ export {
24472
24537
  buildRangeSplices,
24473
24538
  applySplices,
24474
24539
  fillHwpx,
24475
- charWidthEm1000,
24476
- SPACE_EM_FIXED,
24477
- SPACE_EM_FONT,
24478
- measureTextWidth,
24479
- simulateWrap,
24480
- simulateWrapKeepWord,
24481
- fitRatioForFewerLines,
24482
24540
  PRESET_ALIAS,
24483
24541
  normalizeGongmunPreset,
24484
24542
  markdownToHwpx,
@@ -24503,4 +24561,4 @@ export {
24503
24561
  parseHwpml,
24504
24562
  fillForm
24505
24563
  };
24506
- //# sourceMappingURL=chunk-6EDNKPXQ.js.map
24564
+ //# sourceMappingURL=chunk-5TK4X4JQ.js.map