kordoc 3.8.4 → 3.9.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.
package/dist/index.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  sanitizeHref,
20
20
  stripDtd,
21
21
  toArrayBuffer
22
- } from "./chunk-T4SGNVVS.js";
22
+ } from "./chunk-EZ5GBTBE.js";
23
23
  import {
24
24
  parsePageRange
25
25
  } from "./chunk-GE43BE46.js";
@@ -664,8 +664,10 @@ var CONVERT_MAP = {
664
664
  SUCC: "\\succ",
665
665
  UPLUS: "\\uplus",
666
666
  "\xB1": "\\pm",
667
+ "+-": "\\pm",
667
668
  "-+": "\\mp",
668
669
  "\xF7": "\\div",
670
+ cdot: "\\cdot",
669
671
  CIRC: "\\circ",
670
672
  BULLET: "\\bullet",
671
673
  DEG: " ^\\circ",
@@ -1054,6 +1056,10 @@ function hmlToLatex(hmlEqStr) {
1054
1056
  const t = tokens[i];
1055
1057
  if (t in CONVERT_MAP) tokens[i] = CONVERT_MAP[t];
1056
1058
  else if (t in MIDDLE_CONVERT_MAP) tokens[i] = MIDDLE_CONVERT_MAP[t];
1059
+ else {
1060
+ const quoted = /^"(.+)"$/.exec(t);
1061
+ if (quoted) tokens[i] = `\\text{${quoted[1]}}`;
1062
+ }
1057
1063
  }
1058
1064
  tokens = tokens.filter((tok) => tok.length !== 0);
1059
1065
  tokens = replaceBracket(tokens);
@@ -20770,6 +20776,16 @@ function buildPrvText(blocks) {
20770
20776
  }
20771
20777
  return lines.join("\n").slice(0, 1024);
20772
20778
  }
20779
+ function findMathDelim(s, from) {
20780
+ let i = s.indexOf("$$", from);
20781
+ while (i > 0) {
20782
+ let backslashes = 0;
20783
+ for (let j = i - 1; j >= 0 && s[j] === "\\"; j--) backslashes++;
20784
+ if (backslashes % 2 === 0) break;
20785
+ i = s.indexOf("$$", i + 1);
20786
+ }
20787
+ return i;
20788
+ }
20773
20789
  function parseMarkdownToBlocks(md2) {
20774
20790
  const lines = md2.split("\n");
20775
20791
  const blocks = [];
@@ -20780,6 +20796,45 @@ function parseMarkdownToBlocks(md2) {
20780
20796
  i++;
20781
20797
  continue;
20782
20798
  }
20799
+ const mathOpen = /^\s*\$\$/.exec(line);
20800
+ if (mathOpen) {
20801
+ const afterOpen = line.slice(mathOpen[0].length);
20802
+ const closeSame = findMathDelim(afterOpen, 0);
20803
+ if (closeSame >= 0) {
20804
+ const inner = afterOpen.slice(0, closeSame).trim();
20805
+ const trailing2 = afterOpen.slice(closeSame + 2).trim();
20806
+ if (inner) blocks.push({ type: "equation", text: inner });
20807
+ if (trailing2) blocks.push({ type: "paragraph", text: trailing2 });
20808
+ i++;
20809
+ continue;
20810
+ }
20811
+ const mathLines = [];
20812
+ if (afterOpen.trim()) mathLines.push(afterOpen);
20813
+ let closed = false;
20814
+ let trailing = "";
20815
+ let j = i + 1;
20816
+ for (; j < lines.length; j++) {
20817
+ const l = lines[j];
20818
+ if (!l.trim() || /^\s*(`{3,}|~{3,})/.test(l)) break;
20819
+ const end = findMathDelim(l, 0);
20820
+ if (end >= 0) {
20821
+ const before = l.slice(0, end);
20822
+ if (before.trim()) mathLines.push(before);
20823
+ trailing = l.slice(end + 2).trim();
20824
+ closed = true;
20825
+ j++;
20826
+ break;
20827
+ }
20828
+ mathLines.push(l);
20829
+ }
20830
+ if (closed) {
20831
+ const text = mathLines.join("\n").trim();
20832
+ if (text) blocks.push({ type: "equation", text });
20833
+ if (trailing) blocks.push({ type: "paragraph", text: trailing });
20834
+ i = j;
20835
+ continue;
20836
+ }
20837
+ }
20783
20838
  const fenceMatch = line.match(/^(`{3,}|~{3,})(.*)$/);
20784
20839
  if (fenceMatch) {
20785
20840
  const fence = fenceMatch[1];
@@ -21172,6 +21227,7 @@ function precomputeGongmunList(blocks, gongmun) {
21172
21227
  i++;
21173
21228
  continue;
21174
21229
  }
21230
+ const passThrough = (t) => t === "table" || t === "html_table" || t === "equation";
21175
21231
  const run = [];
21176
21232
  while (i < blocks.length) {
21177
21233
  const t = blocks[i].type;
@@ -21180,9 +21236,9 @@ function precomputeGongmunList(blocks, gongmun) {
21180
21236
  i++;
21181
21237
  continue;
21182
21238
  }
21183
- if (t === "table" || t === "html_table") {
21239
+ if (passThrough(t)) {
21184
21240
  let j = i + 1;
21185
- while (j < blocks.length && (blocks[j].type === "table" || blocks[j].type === "html_table")) j++;
21241
+ while (j < blocks.length && passThrough(blocks[j].type)) j++;
21186
21242
  if (j < blocks.length && blocks[j].type === "list_item") {
21187
21243
  i = j;
21188
21244
  continue;
@@ -21708,6 +21764,280 @@ function generateHtmlTableXml(rawHtml, theme, totalWidth = 44e3) {
21708
21764
  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>`;
21709
21765
  }
21710
21766
 
21767
+ // src/hwpx/equation-generate.ts
21768
+ var MAX_EQUATION_SOURCE = 1e4;
21769
+ var MAX_GROUP_DEPTH = 64;
21770
+ var COMMAND_MAP = {
21771
+ alpha: "alpha",
21772
+ beta: "beta",
21773
+ gamma: "gamma",
21774
+ delta: "delta",
21775
+ epsilon: "epsilon",
21776
+ zeta: "zeta",
21777
+ eta: "eta",
21778
+ theta: "theta",
21779
+ iota: "iota",
21780
+ kappa: "kappa",
21781
+ lambda: "lambda",
21782
+ mu: "mu",
21783
+ nu: "nu",
21784
+ xi: "xi",
21785
+ pi: "pi",
21786
+ rho: "rho",
21787
+ sigma: "sigma",
21788
+ tau: "tau",
21789
+ upsilon: "upsilon",
21790
+ phi: "phi",
21791
+ chi: "chi",
21792
+ psi: "psi",
21793
+ omega: "omega",
21794
+ Gamma: "GAMMA",
21795
+ Delta: "DELTA",
21796
+ Theta: "THETA",
21797
+ Lambda: "LAMBDA",
21798
+ Xi: "XI",
21799
+ Pi: "PI",
21800
+ Sigma: "SIGMA",
21801
+ Upsilon: "UPSILON",
21802
+ Phi: "PHI",
21803
+ Psi: "PSI",
21804
+ Omega: "OMEGA",
21805
+ le: "LEQ",
21806
+ leq: "LEQ",
21807
+ ge: "GEQ",
21808
+ geq: "GEQ",
21809
+ ne: "!=",
21810
+ neq: "!=",
21811
+ pm: "+-",
21812
+ mp: "-+",
21813
+ times: "TIMES",
21814
+ cdot: "cdot",
21815
+ ast: "AST",
21816
+ circ: "CIRC",
21817
+ bullet: "BULLET",
21818
+ in: "IN",
21819
+ notin: "NOTIN",
21820
+ subset: "SUBSET",
21821
+ subseteq: "SUBSETEQ",
21822
+ supset: "SUPERSET",
21823
+ supseteq: "SUPSETEQ",
21824
+ cup: "CUP",
21825
+ cap: "SMALLINTER",
21826
+ emptyset: "EMPTYSET",
21827
+ forall: "FORALL",
21828
+ exists: "EXIST",
21829
+ infinity: "INF",
21830
+ infty: "INF",
21831
+ partial: "Partial",
21832
+ nabla: "NABLA",
21833
+ int: "int",
21834
+ iint: "dint",
21835
+ iiint: "tint",
21836
+ oint: "oint",
21837
+ sum: "sum",
21838
+ prod: "prod",
21839
+ lim: "lim",
21840
+ to: "->",
21841
+ rightarrow: "->",
21842
+ leftarrow: "larrow",
21843
+ leftrightarrow: "<->",
21844
+ Rightarrow: "RARROW",
21845
+ Leftarrow: "LARROW",
21846
+ Leftrightarrow: "LRARROW",
21847
+ cdots: "CDOTS",
21848
+ ldots: "LDOTS",
21849
+ vdots: "VDOTS",
21850
+ ddots: "DDOTS"
21851
+ };
21852
+ var ACCENT_COMMANDS = {
21853
+ bar: "bar",
21854
+ overline: "bar",
21855
+ vec: "vec",
21856
+ overrightarrow: "vec",
21857
+ hat: "hat",
21858
+ widehat: "hat",
21859
+ tilde: "tilde",
21860
+ widetilde: "tilde",
21861
+ dot: "dot",
21862
+ ddot: "ddot",
21863
+ underline: "under"
21864
+ };
21865
+ var RESERVED_WORDS = new Set(
21866
+ [...Object.keys(CONVERT_MAP), ...Object.keys(MIDDLE_CONVERT_MAP), "over", "root", "of"].filter((w) => /^[A-Za-z]+$/.test(w))
21867
+ );
21868
+ function skipSpaces(input, idx) {
21869
+ while (idx < input.length && /\s/.test(input[idx])) idx++;
21870
+ return idx;
21871
+ }
21872
+ function normalizeEqEdit(input) {
21873
+ return input.replace(/\s+/g, " ").trim();
21874
+ }
21875
+ function stripMathDelimiters(input) {
21876
+ let s = input.trim();
21877
+ if (s.startsWith("$$") && s.endsWith("$$")) s = s.slice(2, -2).trim();
21878
+ if (s.startsWith("\\[") && s.endsWith("\\]")) s = s.slice(2, -2).trim();
21879
+ return s;
21880
+ }
21881
+ function readBalanced(input, idx, open, close) {
21882
+ let depth = 1;
21883
+ let cursor = idx + 1;
21884
+ while (cursor < input.length) {
21885
+ const ch = input[cursor];
21886
+ if (ch === "\\") {
21887
+ cursor += 2;
21888
+ continue;
21889
+ }
21890
+ if (ch === open) depth++;
21891
+ else if (ch === close) depth--;
21892
+ if (depth === 0) {
21893
+ return { value: input.slice(idx + 1, cursor), next: cursor + 1 };
21894
+ }
21895
+ cursor++;
21896
+ }
21897
+ return { value: input.slice(idx + 1), next: input.length };
21898
+ }
21899
+ function readGroupOrToken(input, idx, depth) {
21900
+ const start = skipSpaces(input, idx);
21901
+ if (depth > MAX_GROUP_DEPTH) return { value: input.slice(start), next: input.length };
21902
+ if (input[start] === "{") {
21903
+ const group = readBalanced(input, start, "{", "}");
21904
+ return { value: convertLatexFragment(group.value, depth + 1), next: group.next };
21905
+ }
21906
+ if (input[start] === "\\") {
21907
+ const cmd = readCommand(input, start, depth + 1);
21908
+ return { value: cmd.value, next: cmd.next };
21909
+ }
21910
+ return { value: input[start] ?? "", next: Math.min(start + 1, input.length) };
21911
+ }
21912
+ function readCommandName(input, idx) {
21913
+ if (input[idx + 1] === "\\") return { value: "\\", next: idx + 2 };
21914
+ const match = /^[A-Za-z]+/.exec(input.slice(idx + 1));
21915
+ if (match) return { value: match[0], next: idx + 1 + match[0].length };
21916
+ return { value: input[idx + 1] ?? "", next: Math.min(idx + 2, input.length) };
21917
+ }
21918
+ function readCommand(input, idx, depth) {
21919
+ const name = readCommandName(input, idx);
21920
+ const command = name.value;
21921
+ if (command === "\\") return { value: "#", next: name.next };
21922
+ if (command === "frac") {
21923
+ const num = readGroupOrToken(input, name.next, depth);
21924
+ const den = readGroupOrToken(input, num.next, depth);
21925
+ return { value: `{${num.value}} over {${den.value}}`, next: den.next };
21926
+ }
21927
+ if (command === "sqrt") {
21928
+ let cursor = skipSpaces(input, name.next);
21929
+ let root = null;
21930
+ if (input[cursor] === "[") {
21931
+ const opt = readBalanced(input, cursor, "[", "]");
21932
+ root = { value: convertLatexFragment(opt.value, depth + 1), next: opt.next };
21933
+ cursor = opt.next;
21934
+ }
21935
+ const body = readGroupOrToken(input, cursor, depth);
21936
+ if (root) return { value: `root {${root.value}} of {${body.value}}`, next: body.next };
21937
+ return { value: `sqrt{${body.value}}`, next: body.next };
21938
+ }
21939
+ if (command === "begin") {
21940
+ const env = readGroupOrToken(input, name.next, depth);
21941
+ const endTag = `\\end{${env.value}}`;
21942
+ const endIdx = input.indexOf(endTag, env.next);
21943
+ if (endIdx === -1) return { value: env.value, next: env.next };
21944
+ const body = convertLatexFragment(input.slice(env.next, endIdx), depth + 1);
21945
+ if (env.value === "matrix" || env.value === "pmatrix" || env.value === "bmatrix") {
21946
+ return { value: `{${env.value}{${body}}}`, next: endIdx + endTag.length };
21947
+ }
21948
+ return { value: body, next: endIdx + endTag.length };
21949
+ }
21950
+ if (command === "left" || command === "right") {
21951
+ const kw = command === "left" ? "LEFT" : "RIGHT";
21952
+ const cursor = skipSpaces(input, name.next);
21953
+ let delimiter = input[cursor] ?? "";
21954
+ let next = delimiter ? cursor + 1 : cursor;
21955
+ if (delimiter === "\\") {
21956
+ const escaped = readCommandName(input, cursor);
21957
+ delimiter = escaped.value === "\\" ? "\\" : COMMAND_MAP[escaped.value] ?? escaped.value;
21958
+ next = escaped.next;
21959
+ }
21960
+ return { value: delimiter ? `${kw} ${delimiter}` : kw, next };
21961
+ }
21962
+ if (command in ACCENT_COMMANDS) {
21963
+ const body = readGroupOrToken(input, name.next, depth);
21964
+ return { value: `${ACCENT_COMMANDS[command]}{${body.value}}`, next: body.next };
21965
+ }
21966
+ if (command === "mathrm" || command === "text") {
21967
+ const start = skipSpaces(input, name.next);
21968
+ if (input[start] === "{") {
21969
+ const group = readBalanced(input, start, "{", "}");
21970
+ return { value: `"${group.value}"`, next: group.next };
21971
+ }
21972
+ const tok = readGroupOrToken(input, start, depth);
21973
+ return { value: `"${tok.value}"`, next: tok.next };
21974
+ }
21975
+ return { value: COMMAND_MAP[command] ?? command, next: name.next };
21976
+ }
21977
+ function convertLatexFragment(input, depth) {
21978
+ if (depth > MAX_GROUP_DEPTH) return normalizeEqEdit(input);
21979
+ let out = "";
21980
+ let idx = 0;
21981
+ while (idx < input.length) {
21982
+ const ch = input[idx];
21983
+ if (ch === "\\") {
21984
+ const cmd = readCommand(input, idx, depth + 1);
21985
+ out += ` ${cmd.value} `;
21986
+ idx = cmd.next;
21987
+ continue;
21988
+ }
21989
+ if (ch === "{") {
21990
+ const group = readBalanced(input, idx, "{", "}");
21991
+ out += `{${convertLatexFragment(group.value, depth + 1)}}`;
21992
+ idx = group.next;
21993
+ continue;
21994
+ }
21995
+ if (ch === "_" || ch === "^") {
21996
+ const script = readGroupOrToken(input, idx + 1, depth);
21997
+ out += ` ${ch}{${script.value}}`;
21998
+ idx = script.next;
21999
+ continue;
22000
+ }
22001
+ if (ch === "&") {
22002
+ out += " & ";
22003
+ idx++;
22004
+ continue;
22005
+ }
22006
+ out += ch;
22007
+ idx++;
22008
+ }
22009
+ return normalizeEqEdit(out);
22010
+ }
22011
+ function quoteReservedKeywords(latex) {
22012
+ return latex.replace(/([_^])\s*\{\s*([A-Za-z]+)\s*\}/g, (match, op, word) => RESERVED_WORDS.has(word) ? `${op}{"${word}"}` : match);
22013
+ }
22014
+ function latexLikeToEqEdit(input) {
22015
+ const src = stripMathDelimiters(input);
22016
+ if (src.length > MAX_EQUATION_SOURCE) return normalizeEqEdit(src);
22017
+ return convertLatexFragment(quoteReservedKeywords(src), 0);
22018
+ }
22019
+ function estimateEquationMetrics(script) {
22020
+ const cleaned = script.replace(/[{}\\^_]/g, "").replace(/\s+/g, " ").trim();
22021
+ const width = Math.min(Math.max(cleaned.length, 5) * 700 + 2e3, 4e4);
22022
+ const rowCount = Math.max(1, (script.match(/#/g) ?? []).length + 1);
22023
+ if (/\bmatrix\b|#/.test(script)) {
22024
+ if (rowCount >= 4) return { width, height: 5500, baseline: 55 };
22025
+ if (rowCount === 3) return { width, height: 4500, baseline: 60 };
22026
+ return { width, height: 3260, baseline: 63 };
22027
+ }
22028
+ if (/\bover\b|\broot\b|\bsqrt\b/.test(script)) return { width, height: 3010, baseline: 69 };
22029
+ return { width, height: 1450, baseline: 71 };
22030
+ }
22031
+ function generateEquationXml(script, zOrder = 0) {
22032
+ const { width, height, baseline } = estimateEquationMetrics(script);
22033
+ const eqId = 2000000001 + zOrder;
22034
+ 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>`;
22035
+ }
22036
+ function generateEquationParagraph(input, zOrder = 0) {
22037
+ const script = latexLikeToEqEdit(input);
22038
+ return `<hp:p paraPrIDRef="${PARA_NORMAL}" styleIDRef="0"><hp:run charPrIDRef="${CHAR_NORMAL}">${generateEquationXml(script, zOrder)}</hp:run></hp:p>`;
22039
+ }
22040
+
21711
22041
  // src/hwpx/gen-section.ts
21712
22042
  function generateSecPr(gongmun) {
21713
22043
  const m = gongmun ? {
@@ -21755,6 +22085,15 @@ function blocksToSectionXml(blocks, theme, gongmun, gongmunList = gongmun ? prec
21755
22085
  xml = codeLines.map((line) => generateParagraph(line || " ", PARA_CODE)).join("\n ");
21756
22086
  break;
21757
22087
  }
22088
+ case "equation": {
22089
+ if (isFirst) {
22090
+ const secRun = `<hp:run charPrIDRef="0">${generateSecPr(gongmun)}<hp:t></hp:t></hp:run>`;
22091
+ paraXmls.push(`<hp:p paraPrIDRef="0" styleIDRef="0">${secRun}</hp:p>`);
22092
+ isFirst = false;
22093
+ }
22094
+ xml = generateEquationParagraph(block.text || "", blockIdx);
22095
+ break;
22096
+ }
21758
22097
  case "blockquote":
21759
22098
  xml = generateParagraph(
21760
22099
  block.text || "",
@@ -24586,7 +24925,7 @@ async function parseHwp(buffer, options) {
24586
24925
  async function parsePdf(buffer, options) {
24587
24926
  let parsePdfDocument;
24588
24927
  try {
24589
- const mod = await import("./parser-2THIF623.js");
24928
+ const mod = await import("./parser-NCNME2Z6.js");
24590
24929
  parsePdfDocument = mod.parsePdfDocument;
24591
24930
  } catch {
24592
24931
  return {