ooxml-core 0.4.0 → 0.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 (50) hide show
  1. package/NOTICE +2 -0
  2. package/dist/docx/embedded.cjs +23 -6
  3. package/dist/docx/embedded.mjs +23 -6
  4. package/dist/docx/index.cjs +23 -6
  5. package/dist/docx/index.mjs +23 -6
  6. package/dist/docx/load/index.cjs +23 -6
  7. package/dist/docx/load/index.mjs +23 -6
  8. package/dist/docx/parse-table.d.ts.map +1 -1
  9. package/dist/docx/write-table-properties.d.ts +3 -1
  10. package/dist/docx/write-table-properties.d.ts.map +1 -1
  11. package/dist/docx/write-table.d.ts.map +1 -1
  12. package/dist/index.cjs +2042 -13
  13. package/dist/index.d.ts +1 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.mjs +2042 -14
  16. package/dist/math/index.cjs +2050 -0
  17. package/dist/math/index.d.ts +15 -0
  18. package/dist/math/index.d.ts.map +1 -0
  19. package/dist/math/index.mjs +1985 -0
  20. package/dist/math/latex-omml-siblings.d.ts +21 -0
  21. package/dist/math/latex-omml-siblings.d.ts.map +1 -0
  22. package/dist/math/latex-omml-symbols.d.ts +42 -0
  23. package/dist/math/latex-omml-symbols.d.ts.map +1 -0
  24. package/dist/math/latex-to-omml-commands.d.ts +9 -0
  25. package/dist/math/latex-to-omml-commands.d.ts.map +1 -0
  26. package/dist/math/latex-to-omml-constructs.d.ts +39 -0
  27. package/dist/math/latex-to-omml-constructs.d.ts.map +1 -0
  28. package/dist/math/latex-to-omml-environments.d.ts +28 -0
  29. package/dist/math/latex-to-omml-environments.d.ts.map +1 -0
  30. package/dist/math/latex-to-omml.d.ts +9 -0
  31. package/dist/math/latex-to-omml.d.ts.map +1 -0
  32. package/dist/math/omml-color.d.ts +11 -0
  33. package/dist/math/omml-color.d.ts.map +1 -0
  34. package/dist/math/omml-dom.d.ts +7 -0
  35. package/dist/math/omml-dom.d.ts.map +1 -0
  36. package/dist/math/omml-mathml-converters.d.ts +39 -0
  37. package/dist/math/omml-mathml-converters.d.ts.map +1 -0
  38. package/dist/math/omml-mathml-helpers.d.ts +23 -0
  39. package/dist/math/omml-mathml-helpers.d.ts.map +1 -0
  40. package/dist/math/omml-node.d.ts +7 -0
  41. package/dist/math/omml-node.d.ts.map +1 -0
  42. package/dist/math/omml-to-latex-helpers.d.ts +41 -0
  43. package/dist/math/omml-to-latex-helpers.d.ts.map +1 -0
  44. package/dist/math/omml-to-latex-layout.d.ts +18 -0
  45. package/dist/math/omml-to-latex-layout.d.ts.map +1 -0
  46. package/dist/math/omml-to-latex.d.ts +6 -0
  47. package/dist/math/omml-to-latex.d.ts.map +1 -0
  48. package/dist/math/omml-to-mathml.d.ts +21 -0
  49. package/dist/math/omml-to-mathml.d.ts.map +1 -0
  50. package/package.json +6 -1
package/dist/index.cjs CHANGED
@@ -732,10 +732,10 @@ function booleanAttribute(element, name) {
732
732
  function descendants(root, local) {
733
733
  const result = [];
734
734
  const visit = (node) => {
735
- for (const child of Array.from(node.childNodes)) {
736
- if (!isElement(child)) continue;
737
- if (child.localName === local) result.push(child);
738
- visit(child);
735
+ for (const child2 of Array.from(node.childNodes)) {
736
+ if (!isElement(child2)) continue;
737
+ if (child2.localName === local) result.push(child2);
738
+ visit(child2);
739
739
  }
740
740
  };
741
741
  visit(root);
@@ -887,9 +887,9 @@ function parseDrawingColor(element) {
887
887
  const color = {
888
888
  kind,
889
889
  value: colorValue(kind, element),
890
- transforms: elements(element).map((child) => ({
891
- name: child.localName,
892
- value: child.getAttribute("val") ?? ""
890
+ transforms: elements(element).map((child2) => ({
891
+ name: child2.localName,
892
+ value: child2.getAttribute("val") ?? ""
893
893
  }))
894
894
  };
895
895
  const fallback = kind === "system" ? element.getAttribute("lastClr") : null;
@@ -1204,7 +1204,7 @@ function parseRun(run) {
1204
1204
  }
1205
1205
  function parseParagraph(paragraph) {
1206
1206
  const runs = [];
1207
- for (const child of children(paragraph, "r", NS.a)) runs.push(parseRun(child));
1207
+ for (const child2 of children(paragraph, "r", NS.a)) runs.push(parseRun(child2));
1208
1208
  for (const field of children(paragraph, "fld", NS.a)) runs.push(parseRun(field));
1209
1209
  const align = first(paragraph, "pPr", NS.a)?.getAttribute("algn");
1210
1210
  return { ...align ? { align } : {}, runs };
@@ -1415,9 +1415,9 @@ function parseDiagramDrawing(source, part) {
1415
1415
  const tree = root.localName === "spTree" ? root : first(root, "spTree", NS.dsp);
1416
1416
  let counter = 0;
1417
1417
  const visit = (container, group) => {
1418
- for (const child of Array.from(container.childNodes)) {
1419
- if (child.nodeType !== 1) continue;
1420
- const element = child;
1418
+ for (const child2 of Array.from(container.childNodes)) {
1419
+ if (child2.nodeType !== 1) continue;
1420
+ const element = child2;
1421
1421
  if (element.localName === "sp") {
1422
1422
  const shape = parseShape(element, counter++, group, issues);
1423
1423
  if (shape) shapes.push(shape);
@@ -2634,9 +2634,9 @@ function evaluateFormula(parsed, vars) {
2634
2634
  // pin x y z — clamp y between x and z
2635
2635
  case "pin": {
2636
2636
  const lo = r(0);
2637
- const val = r(1);
2637
+ const val2 = r(1);
2638
2638
  const hi = r(2);
2639
- return Math.max(lo, Math.min(val, hi));
2639
+ return Math.max(lo, Math.min(val2, hi));
2640
2640
  }
2641
2641
  // sin x y — x * sin(y) where y is in OOXML angle units
2642
2642
  case "sin": {
@@ -16643,9 +16643,2038 @@ var TWIPS_PER_POINT = 20;
16643
16643
  var TWIPS_PER_INCH = 1440;
16644
16644
  var PIXELS_PER_INCH = 96;
16645
16645
 
16646
+ // src/math/index.ts
16647
+ var math_exports = {};
16648
+ __export(math_exports, {
16649
+ ACCENT_ALIASES: () => ACCENT_ALIASES,
16650
+ ACCENT_MAP: () => ACCENT_MAP,
16651
+ DELIM_MAP: () => DELIM_MAP,
16652
+ EQARR_ENVS: () => EQARR_ENVS,
16653
+ ESCAPE_MAP: () => ESCAPE_MAP,
16654
+ FUNC_NAMES: () => FUNC_NAMES,
16655
+ GREEK_MAP: () => GREEK_MAP,
16656
+ LIMIT_FUNC_NAMES: () => LIMIT_FUNC_NAMES,
16657
+ MATRIX_ENVS: () => MATRIX_ENVS,
16658
+ NARY_MAP: () => NARY_MAP,
16659
+ OPERATOR_MAP: () => OPERATOR_MAP,
16660
+ REVERSE_ACCENT: () => REVERSE_ACCENT,
16661
+ REVERSE_DELIM: () => REVERSE_DELIM,
16662
+ REVERSE_ESCAPE: () => REVERSE_ESCAPE,
16663
+ REVERSE_GREEK: () => REVERSE_GREEK,
16664
+ REVERSE_NARY: () => REVERSE_NARY,
16665
+ REVERSE_OPERATOR: () => REVERSE_OPERATOR,
16666
+ applyScripts: () => applyScripts,
16667
+ attrVal: () => attrVal,
16668
+ buildPrescript: () => buildPrescript,
16669
+ childNode: () => childNode,
16670
+ collectText: () => collectText,
16671
+ contentKeys: () => contentKeys,
16672
+ convertLatexToOmml: () => convertLatexToOmml,
16673
+ convertOmmlToLatex: () => convertOmmlToLatex,
16674
+ convertOmmlToMathMl: () => convertOmmlToMathMl,
16675
+ delimiterToLatex: () => delimiterToLatex,
16676
+ ensureArr: () => ensureArr,
16677
+ eqArrToLatex: () => eqArrToLatex,
16678
+ escapeChar: () => escapeChar,
16679
+ escapeMathText: () => escapeMathText,
16680
+ escapeTextArgument: () => escapeTextArgument,
16681
+ getOmmlMathColor: () => getOmmlMathColor,
16682
+ getOmmlMathFontSize: () => getOmmlMathFontSize,
16683
+ hasAttr: () => hasAttr,
16684
+ isOn: () => isOn,
16685
+ isSingleAtom: () => isSingleAtom,
16686
+ matrixToLatex: () => matrixToLatex,
16687
+ mergeSiblings: () => mergeSiblings,
16688
+ naryToLatex: () => naryToLatex,
16689
+ ommlFromElement: () => ommlFromElement,
16690
+ ommlToMathml: () => ommlToMathml,
16691
+ parseAccent: () => parseAccent,
16692
+ parseBar: () => parseBar,
16693
+ parseBoxed: () => parseBoxed,
16694
+ parseCommand: () => parseCommand,
16695
+ parseDelimiter: () => parseDelimiter,
16696
+ parseEnvironment: () => parseEnvironment,
16697
+ parseFuncApplication: () => parseFuncApplication,
16698
+ parseGroupChr: () => parseGroupChr,
16699
+ parseNary: () => parseNary,
16700
+ parseOmml: () => parseOmml,
16701
+ parseOperatorName: () => parseOperatorName,
16702
+ parsePhantom: () => parsePhantom,
16703
+ parsePrescript: () => parsePrescript,
16704
+ parseScriptArgs: () => parseScriptArgs,
16705
+ parseTextArgument: () => parseTextArgument,
16706
+ parseUnderOverset: () => parseUnderOverset,
16707
+ readRunText: () => readRunText,
16708
+ rowsToLatex: () => rowsToLatex,
16709
+ soleChild: () => soleChild,
16710
+ tokenize: () => tokenize,
16711
+ tryParseScripts: () => tryParseScripts,
16712
+ wrapDelimited: () => wrapDelimited
16713
+ });
16714
+
16715
+ // src/math/omml-node.ts
16716
+ function orderedXmlKey(baseName, order) {
16717
+ return `${baseName}#pptx-order-${order}`;
16718
+ }
16719
+ function stripXmlOrderSuffix(tagName) {
16720
+ return tagName.split(/#(?:pptx|math)-order-/u, 1)[0] ?? tagName;
16721
+ }
16722
+
16723
+ // src/math/latex-omml-siblings.ts
16724
+ var LETTER_RE = /[a-zA-Z]/u;
16725
+ var WHITESPACE_RE = /\s/u;
16726
+ function tokenize(latex) {
16727
+ const tokens = [];
16728
+ let i = 0;
16729
+ while (i < latex.length) {
16730
+ const ch = latex[i];
16731
+ if (ch === "{") {
16732
+ tokens.push({ type: "group_start", value: "{" });
16733
+ i++;
16734
+ } else if (ch === "}") {
16735
+ tokens.push({ type: "group_end", value: "}" });
16736
+ i++;
16737
+ } else if (ch === "^") {
16738
+ tokens.push({ type: "superscript", value: "^" });
16739
+ i++;
16740
+ } else if (ch === "_") {
16741
+ tokens.push({ type: "subscript", value: "_" });
16742
+ i++;
16743
+ } else if (ch === "\\") {
16744
+ let cmd = "\\";
16745
+ i++;
16746
+ if (i < latex.length && LETTER_RE.test(latex[i])) {
16747
+ while (i < latex.length && LETTER_RE.test(latex[i])) {
16748
+ cmd += latex[i];
16749
+ i++;
16750
+ }
16751
+ } else if (i < latex.length) {
16752
+ cmd += latex[i];
16753
+ i++;
16754
+ }
16755
+ tokens.push({ type: "command", value: cmd });
16756
+ } else if (WHITESPACE_RE.test(ch)) {
16757
+ i++;
16758
+ tokens.push({ type: "whitespace", value: " " });
16759
+ } else {
16760
+ tokens.push({ type: "text", value: ch });
16761
+ i++;
16762
+ }
16763
+ }
16764
+ return tokens;
16765
+ }
16766
+ function isGroupedByTag(tags) {
16767
+ const seen = /* @__PURE__ */ new Set();
16768
+ let previous = "";
16769
+ for (const tag of tags) {
16770
+ if (tag !== previous && seen.has(tag)) {
16771
+ return false;
16772
+ }
16773
+ seen.add(tag);
16774
+ previous = tag;
16775
+ }
16776
+ return true;
16777
+ }
16778
+ function mergeSiblings(nodes) {
16779
+ const entries = [];
16780
+ for (const node of nodes) {
16781
+ for (const key of Object.keys(node)) {
16782
+ if (node[key] !== void 0) {
16783
+ entries.push([key, node[key]]);
16784
+ }
16785
+ }
16786
+ }
16787
+ if (!isGroupedByTag(entries.map(([key]) => key))) {
16788
+ const counts = /* @__PURE__ */ new Map();
16789
+ for (const [key] of entries) {
16790
+ counts.set(key, (counts.get(key) ?? 0) + 1);
16791
+ }
16792
+ const ordered = {};
16793
+ for (const [position, [key, value]] of entries.entries()) {
16794
+ ordered[(counts.get(key) ?? 0) > 1 ? orderedXmlKey(key, position) : key] = value;
16795
+ }
16796
+ return ordered;
16797
+ }
16798
+ const result = {};
16799
+ for (const [key, value] of entries) {
16800
+ if (result[key]) {
16801
+ const existing = result[key];
16802
+ if (Array.isArray(existing)) {
16803
+ existing.push(value);
16804
+ } else {
16805
+ result[key] = [existing, value];
16806
+ }
16807
+ } else {
16808
+ result[key] = value;
16809
+ }
16810
+ }
16811
+ return result;
16812
+ }
16813
+
16814
+ // src/math/latex-omml-symbols.ts
16815
+ var GREEK_MAP = {
16816
+ "\\alpha": "\u03B1",
16817
+ "\\beta": "\u03B2",
16818
+ "\\gamma": "\u03B3",
16819
+ "\\delta": "\u03B4",
16820
+ "\\epsilon": "\u03B5",
16821
+ "\\varepsilon": "\u03B5",
16822
+ "\\zeta": "\u03B6",
16823
+ "\\eta": "\u03B7",
16824
+ "\\theta": "\u03B8",
16825
+ "\\vartheta": "\u03D1",
16826
+ "\\iota": "\u03B9",
16827
+ "\\kappa": "\u03BA",
16828
+ "\\lambda": "\u03BB",
16829
+ "\\mu": "\u03BC",
16830
+ "\\nu": "\u03BD",
16831
+ "\\xi": "\u03BE",
16832
+ "\\pi": "\u03C0",
16833
+ "\\rho": "\u03C1",
16834
+ "\\sigma": "\u03C3",
16835
+ "\\tau": "\u03C4",
16836
+ "\\upsilon": "\u03C5",
16837
+ "\\phi": "\u03C6",
16838
+ "\\varphi": "\u03D5",
16839
+ "\\chi": "\u03C7",
16840
+ "\\psi": "\u03C8",
16841
+ "\\omega": "\u03C9",
16842
+ "\\Gamma": "\u0393",
16843
+ "\\Delta": "\u0394",
16844
+ "\\Theta": "\u0398",
16845
+ "\\Lambda": "\u039B",
16846
+ "\\Xi": "\u039E",
16847
+ "\\Pi": "\u03A0",
16848
+ "\\Sigma": "\u03A3",
16849
+ "\\Phi": "\u03A6",
16850
+ "\\Psi": "\u03A8",
16851
+ "\\Omega": "\u03A9"
16852
+ };
16853
+ var OPERATOR_MAP = {
16854
+ "\\times": "\xD7",
16855
+ "\\div": "\xF7",
16856
+ "\\pm": "\xB1",
16857
+ "\\mp": "\u2213",
16858
+ "\\cdot": "\xB7",
16859
+ "\\leq": "\u2264",
16860
+ "\\geq": "\u2265",
16861
+ "\\neq": "\u2260",
16862
+ "\\approx": "\u2248",
16863
+ "\\equiv": "\u2261",
16864
+ "\\ll": "\u226A",
16865
+ "\\gg": "\u226B",
16866
+ "\\subset": "\u2282",
16867
+ "\\supset": "\u2283",
16868
+ "\\subseteq": "\u2286",
16869
+ "\\supseteq": "\u2287",
16870
+ "\\in": "\u2208",
16871
+ "\\notin": "\u2209",
16872
+ "\\cup": "\u222A",
16873
+ "\\cap": "\u2229",
16874
+ "\\to": "\u2192",
16875
+ "\\rightarrow": "\u2192",
16876
+ "\\leftarrow": "\u2190",
16877
+ "\\leftrightarrow": "\u2194",
16878
+ "\\Rightarrow": "\u21D2",
16879
+ "\\Leftarrow": "\u21D0",
16880
+ "\\Leftrightarrow": "\u21D4",
16881
+ "\\infty": "\u221E",
16882
+ "\\partial": "\u2202",
16883
+ "\\nabla": "\u2207",
16884
+ "\\forall": "\u2200",
16885
+ "\\exists": "\u2203",
16886
+ "\\therefore": "\u2234",
16887
+ "\\because": "\u2235",
16888
+ "\\propto": "\u221D",
16889
+ "\\ldots": "\u2026",
16890
+ "\\cdots": "\u22EF",
16891
+ "\\vdots": "\u22EE",
16892
+ "\\ddots": "\u22F1",
16893
+ "\\le": "\u2264",
16894
+ "\\ge": "\u2265",
16895
+ "\\ne": "\u2260"
16896
+ };
16897
+ var ESCAPE_MAP = {
16898
+ "\\{": "{",
16899
+ "\\}": "}",
16900
+ "\\lbrace": "{",
16901
+ "\\rbrace": "}",
16902
+ "\\_": "_",
16903
+ "\\^": "^",
16904
+ "\\&": "&",
16905
+ "\\%": "%",
16906
+ "\\#": "#",
16907
+ "\\$": "$",
16908
+ "\\ ": " ",
16909
+ "\\backslash": "\\",
16910
+ // Spacing commands render as an ordinary space run (`\ ` wins on reversal).
16911
+ "\\quad": " ",
16912
+ "\\qquad": " ",
16913
+ "\\,": " ",
16914
+ "\\:": " ",
16915
+ "\\;": " ",
16916
+ "\\!": ""
16917
+ };
16918
+ var NARY_MAP = {
16919
+ "\\sum": "\u2211",
16920
+ "\\prod": "\u220F",
16921
+ "\\int": "\u222B",
16922
+ "\\iint": "\u222C",
16923
+ "\\iiint": "\u222D",
16924
+ "\\oint": "\u222E",
16925
+ "\\coprod": "\u2210",
16926
+ "\\bigcup": "\u22C3",
16927
+ "\\bigcap": "\u22C2",
16928
+ "\\bigwedge": "\u22C0",
16929
+ "\\bigvee": "\u22C1"
16930
+ };
16931
+ var FUNC_NAMES = /* @__PURE__ */ new Set([
16932
+ "sin",
16933
+ "cos",
16934
+ "tan",
16935
+ "cot",
16936
+ "sec",
16937
+ "csc",
16938
+ "arcsin",
16939
+ "arccos",
16940
+ "arctan",
16941
+ "sinh",
16942
+ "cosh",
16943
+ "tanh",
16944
+ "coth",
16945
+ "log",
16946
+ "ln",
16947
+ "exp",
16948
+ "lim",
16949
+ "min",
16950
+ "max",
16951
+ "sup",
16952
+ "inf",
16953
+ "det",
16954
+ "dim",
16955
+ "mod",
16956
+ "gcd",
16957
+ "deg",
16958
+ "hom",
16959
+ "ker"
16960
+ ]);
16961
+ var LIMIT_FUNC_NAMES = /* @__PURE__ */ new Set(["lim", "min", "max", "sup", "inf", "det", "gcd"]);
16962
+ var ACCENT_MAP = {
16963
+ "\\hat": "\u0302",
16964
+ "\\check": "\u030C",
16965
+ "\\tilde": "\u0303",
16966
+ "\\acute": "\u0301",
16967
+ "\\grave": "\u0300",
16968
+ "\\dot": "\u0307",
16969
+ "\\ddot": "\u0308",
16970
+ "\\dddot": "\u20DB",
16971
+ "\\breve": "\u0306",
16972
+ "\\bar": "\u0305",
16973
+ "\\vec": "\u20D7",
16974
+ "\\overleftarrow": "\u20D6",
16975
+ "\\overrightarrow": "\u20D7"
16976
+ };
16977
+ var ACCENT_ALIASES = {
16978
+ "\u0304": "\u0305",
16979
+ "^": "\u0302",
16980
+ "~": "\u0303",
16981
+ "\xAF": "\u0305"
16982
+ };
16983
+ var DELIM_MAP = {
16984
+ "\\{": "{",
16985
+ "\\}": "}",
16986
+ "\\lbrace": "{",
16987
+ "\\rbrace": "}",
16988
+ "\\langle": "\u27E8",
16989
+ "\\rangle": "\u27E9",
16990
+ "\\lfloor": "\u230A",
16991
+ "\\rfloor": "\u230B",
16992
+ "\\lceil": "\u2308",
16993
+ "\\rceil": "\u2309",
16994
+ "\\vert": "|",
16995
+ "\\lvert": "|",
16996
+ "\\rvert": "|",
16997
+ "\\|": "\u2016",
16998
+ "\\Vert": "\u2016",
16999
+ "\\lVert": "\u2016",
17000
+ "\\rVert": "\u2016"
17001
+ };
17002
+ var MATRIX_ENVS = {
17003
+ matrix: ["", ""],
17004
+ pmatrix: ["(", ")"],
17005
+ bmatrix: ["[", "]"],
17006
+ Bmatrix: ["{", "}"],
17007
+ vmatrix: ["|", "|"],
17008
+ Vmatrix: ["\u2016", "\u2016"],
17009
+ array: ["", ""]
17010
+ };
17011
+ var EQARR_ENVS = /* @__PURE__ */ new Set([
17012
+ "aligned",
17013
+ "align",
17014
+ "align*",
17015
+ "gather",
17016
+ "gather*",
17017
+ "gathered",
17018
+ "eqnarray",
17019
+ "eqnarray*",
17020
+ "split"
17021
+ ]);
17022
+ function invert(map) {
17023
+ const reversed = {};
17024
+ for (const [cmd, ch] of Object.entries(map)) {
17025
+ if (!reversed[ch]) {
17026
+ reversed[ch] = cmd;
17027
+ }
17028
+ }
17029
+ return reversed;
17030
+ }
17031
+ var REVERSE_GREEK = invert(GREEK_MAP);
17032
+ var REVERSE_OPERATOR = invert(OPERATOR_MAP);
17033
+ var REVERSE_NARY = invert(NARY_MAP);
17034
+ var REVERSE_ACCENT = invert(ACCENT_MAP);
17035
+ var REVERSE_DELIM = invert(DELIM_MAP);
17036
+ var REVERSE_ESCAPE = {
17037
+ "{": "\\{",
17038
+ "}": "\\}",
17039
+ _: "\\_",
17040
+ "^": "\\^",
17041
+ "%": "\\%",
17042
+ "#": "\\#",
17043
+ $: "\\$",
17044
+ " ": "\\ ",
17045
+ "\\": "\\backslash "
17046
+ };
17047
+
17048
+ // src/math/latex-to-omml-constructs.ts
17049
+ function parseScriptArgs(ctx) {
17050
+ const args = { sub: [], sup: [], hasSub: false, hasSup: false };
17051
+ for (let round = 0; round < 2; round++) {
17052
+ while (ctx.peek()?.type === "whitespace") {
17053
+ ctx.next();
17054
+ }
17055
+ const tok = ctx.peek();
17056
+ if (tok?.type === "superscript" && !args.hasSup) {
17057
+ ctx.next();
17058
+ args.sup = ctx.parseSingleOrGroup();
17059
+ args.hasSup = true;
17060
+ } else if (tok?.type === "subscript" && !args.hasSub) {
17061
+ ctx.next();
17062
+ args.sub = ctx.parseSingleOrGroup();
17063
+ args.hasSub = true;
17064
+ }
17065
+ }
17066
+ return args;
17067
+ }
17068
+ function applyScripts(ctx, base, args) {
17069
+ if (args.hasSup && args.hasSub) {
17070
+ return {
17071
+ "m:sSubSup": {
17072
+ "m:e": ctx.wrapE([base]),
17073
+ "m:sub": ctx.wrapE(args.sub),
17074
+ "m:sup": ctx.wrapE(args.sup)
17075
+ }
17076
+ };
17077
+ }
17078
+ if (args.hasSup) {
17079
+ return {
17080
+ "m:sSup": {
17081
+ "m:e": ctx.wrapE([base]),
17082
+ "m:sup": ctx.wrapE(args.sup)
17083
+ }
17084
+ };
17085
+ }
17086
+ if (args.hasSub) {
17087
+ return {
17088
+ "m:sSub": {
17089
+ "m:e": ctx.wrapE([base]),
17090
+ "m:sub": ctx.wrapE(args.sub)
17091
+ }
17092
+ };
17093
+ }
17094
+ return base;
17095
+ }
17096
+ function tryParseScripts(ctx, base) {
17097
+ return applyScripts(ctx, base, parseScriptArgs(ctx));
17098
+ }
17099
+ function parseNary(ctx, operatorChar) {
17100
+ let limLoc = "";
17101
+ const limTok = ctx.peek();
17102
+ if (limTok?.type === "command" && (limTok.value === "\\limits" || limTok.value === "\\nolimits")) {
17103
+ ctx.next();
17104
+ limLoc = limTok.value === "\\limits" ? "undOvr" : "subSup";
17105
+ }
17106
+ const { sub, sup, hasSub, hasSup } = parseScriptArgs(ctx);
17107
+ const body = ctx.parseSingleOrGroup();
17108
+ const naryPr = {
17109
+ "m:chr": { "@_val": operatorChar }
17110
+ };
17111
+ if (limLoc) {
17112
+ naryPr["m:limLoc"] = { "@_val": limLoc };
17113
+ }
17114
+ if (!hasSub) {
17115
+ naryPr["m:subHide"] = { "@_val": "1" };
17116
+ }
17117
+ if (!hasSup) {
17118
+ naryPr["m:supHide"] = { "@_val": "1" };
17119
+ }
17120
+ return {
17121
+ "m:nary": {
17122
+ "m:naryPr": naryPr,
17123
+ "m:sub": hasSub ? ctx.wrapE(sub) : {},
17124
+ "m:sup": hasSup ? ctx.wrapE(sup) : {},
17125
+ "m:e": ctx.wrapE(body)
17126
+ }
17127
+ };
17128
+ }
17129
+ function readDelimiterChar(tok, fallback) {
17130
+ if (!tok) {
17131
+ return fallback;
17132
+ }
17133
+ if (tok.type === "command") {
17134
+ return DELIM_MAP[tok.value] ?? tok.value.slice(1);
17135
+ }
17136
+ if (tok.value === ".") {
17137
+ return "";
17138
+ }
17139
+ return tok.value;
17140
+ }
17141
+ function parseDelimiter(ctx) {
17142
+ const openChar = readDelimiterChar(ctx.next(), "(");
17143
+ const inner = [];
17144
+ while (ctx.peek()) {
17145
+ if (ctx.peek().type === "command" && ctx.peek().value === "\\right") {
17146
+ ctx.next();
17147
+ break;
17148
+ }
17149
+ const node = ctx.parseAtom();
17150
+ if (node) {
17151
+ inner.push(node);
17152
+ }
17153
+ }
17154
+ const closeChar = readDelimiterChar(ctx.next(), ")");
17155
+ const dPr = {};
17156
+ if (openChar !== "(") {
17157
+ dPr["m:begChr"] = { "@_val": openChar };
17158
+ }
17159
+ if (closeChar !== ")") {
17160
+ dPr["m:endChr"] = { "@_val": closeChar };
17161
+ }
17162
+ return {
17163
+ "m:d": {
17164
+ "m:dPr": Object.keys(dPr).length > 0 ? dPr : void 0,
17165
+ "m:e": ctx.wrapE(inner)
17166
+ }
17167
+ };
17168
+ }
17169
+ function parseFuncApplication(ctx, name) {
17170
+ const fNameNode = ctx.makeRun(name, true);
17171
+ const args = parseScriptArgs(ctx);
17172
+ let withScripts;
17173
+ if (LIMIT_FUNC_NAMES.has(name) && args.hasSub !== args.hasSup) {
17174
+ const limit = {
17175
+ "m:e": ctx.wrapE([fNameNode]),
17176
+ "m:lim": ctx.wrapE(args.hasSub ? args.sub : args.sup)
17177
+ };
17178
+ withScripts = args.hasSub ? { "m:limLow": limit } : { "m:limUpp": limit };
17179
+ } else {
17180
+ withScripts = applyScripts(ctx, fNameNode, args);
17181
+ }
17182
+ let body = [];
17183
+ if (ctx.peek()?.type === "group_start") {
17184
+ body = ctx.parseGroup();
17185
+ } else if (ctx.peek() && ctx.peek().type !== "group_end") {
17186
+ const atom = ctx.parseAtom();
17187
+ if (atom) {
17188
+ body = [atom];
17189
+ }
17190
+ }
17191
+ if (body.length === 0) {
17192
+ return withScripts;
17193
+ }
17194
+ return {
17195
+ "m:func": {
17196
+ "m:fName": ctx.wrapE([withScripts]),
17197
+ "m:e": ctx.wrapE(body)
17198
+ }
17199
+ };
17200
+ }
17201
+ function parseTextArgument(ctx) {
17202
+ if (ctx.peek()?.type !== "group_start") {
17203
+ const tok = ctx.next();
17204
+ return tok ? tok.value : "";
17205
+ }
17206
+ ctx.next();
17207
+ let depth = 1;
17208
+ let text = "";
17209
+ while (ctx.peek()) {
17210
+ const tok = ctx.next();
17211
+ if (tok.type === "group_start") {
17212
+ depth++;
17213
+ } else if (tok.type === "group_end") {
17214
+ depth--;
17215
+ if (depth === 0) {
17216
+ break;
17217
+ }
17218
+ } else if (tok.type === "command") {
17219
+ text += ESCAPE_MAP[tok.value] ?? OPERATOR_MAP[tok.value] ?? tok.value.slice(1);
17220
+ continue;
17221
+ }
17222
+ if (depth > 0 && tok.type !== "group_start" && tok.type !== "group_end") {
17223
+ text += tok.value;
17224
+ }
17225
+ }
17226
+ return text;
17227
+ }
17228
+
17229
+ // src/math/latex-to-omml-environments.ts
17230
+ function valNode(value) {
17231
+ return { "@_val": value };
17232
+ }
17233
+ function wrapDelimited(ctx, inner, open, close) {
17234
+ const dPr = {};
17235
+ if (open !== "(") {
17236
+ dPr["m:begChr"] = valNode(open);
17237
+ }
17238
+ if (close !== ")") {
17239
+ dPr["m:endChr"] = valNode(close);
17240
+ }
17241
+ return {
17242
+ "m:d": {
17243
+ "m:dPr": Object.keys(dPr).length > 0 ? dPr : void 0,
17244
+ "m:e": ctx.wrapE([inner])
17245
+ }
17246
+ };
17247
+ }
17248
+ function readEnvName(ctx) {
17249
+ return parseTextArgument(ctx).trim();
17250
+ }
17251
+ function parseEnvBody(ctx) {
17252
+ const rows = [];
17253
+ let row = [];
17254
+ let cell = [];
17255
+ while (ctx.peek()) {
17256
+ const tok = ctx.peek();
17257
+ if (tok.type === "command" && tok.value === "\\end") {
17258
+ ctx.next();
17259
+ readEnvName(ctx);
17260
+ break;
17261
+ }
17262
+ if (tok.type === "command" && tok.value === "\\\\") {
17263
+ ctx.next();
17264
+ row.push(cell);
17265
+ rows.push(row);
17266
+ row = [];
17267
+ cell = [];
17268
+ continue;
17269
+ }
17270
+ if (tok.type === "text" && tok.value === "&") {
17271
+ ctx.next();
17272
+ row.push(cell);
17273
+ cell = [];
17274
+ continue;
17275
+ }
17276
+ const atom = ctx.parseAtom();
17277
+ if (atom) {
17278
+ cell.push(atom);
17279
+ }
17280
+ }
17281
+ if (cell.length > 0 || row.length > 0) {
17282
+ row.push(cell);
17283
+ rows.push(row);
17284
+ }
17285
+ return rows;
17286
+ }
17287
+ function buildMatrix(ctx, rows) {
17288
+ return {
17289
+ "m:m": {
17290
+ "m:mr": rows.map((cells) => ({
17291
+ "m:e": cells.map((cell) => ctx.wrapE(cell))
17292
+ }))
17293
+ }
17294
+ };
17295
+ }
17296
+ function buildEqArr(ctx, rows) {
17297
+ const lines = rows.map((cells) => {
17298
+ const nodes = [];
17299
+ cells.forEach((cell, index) => {
17300
+ if (index > 0) {
17301
+ nodes.push(ctx.makeRun("&"));
17302
+ }
17303
+ nodes.push(...cell);
17304
+ });
17305
+ return ctx.wrapE(nodes);
17306
+ });
17307
+ return { "m:eqArr": { "m:e": lines } };
17308
+ }
17309
+ function parseEnvironment(ctx) {
17310
+ const name = readEnvName(ctx);
17311
+ if (name === "array" && ctx.peek()?.type === "group_start") {
17312
+ parseTextArgument(ctx);
17313
+ }
17314
+ const rows = parseEnvBody(ctx);
17315
+ const matrixDelims = MATRIX_ENVS[name];
17316
+ if (matrixDelims) {
17317
+ const matrix = buildMatrix(ctx, rows);
17318
+ const [open, close] = matrixDelims;
17319
+ return open || close ? wrapDelimited(ctx, matrix, open, close) : matrix;
17320
+ }
17321
+ if (name === "cases") {
17322
+ return wrapDelimited(ctx, buildEqArr(ctx, rows), "{", "");
17323
+ }
17324
+ if (EQARR_ENVS.has(name) || rows.length > 1) {
17325
+ return buildEqArr(ctx, rows);
17326
+ }
17327
+ const inline = rows.flat(2);
17328
+ return inline.length > 0 ? ctx.wrapE(inline) : null;
17329
+ }
17330
+ function parseAccent(ctx, chr) {
17331
+ return {
17332
+ "m:acc": {
17333
+ "m:accPr": { "m:chr": valNode(chr) },
17334
+ "m:e": ctx.wrapE(ctx.parseSingleOrGroup())
17335
+ }
17336
+ };
17337
+ }
17338
+ function parseBar(ctx, pos) {
17339
+ return {
17340
+ "m:bar": {
17341
+ "m:barPr": { "m:pos": valNode(pos) },
17342
+ "m:e": ctx.wrapE(ctx.parseSingleOrGroup())
17343
+ }
17344
+ };
17345
+ }
17346
+ function parseGroupChr(ctx, chr, pos) {
17347
+ const groupChrPr = { "m:chr": valNode(chr) };
17348
+ if (pos === "top") {
17349
+ groupChrPr["m:pos"] = valNode("top");
17350
+ }
17351
+ const group = {
17352
+ "m:groupChr": {
17353
+ "m:groupChrPr": groupChrPr,
17354
+ "m:e": ctx.wrapE(ctx.parseSingleOrGroup())
17355
+ }
17356
+ };
17357
+ const args = parseScriptArgs(ctx);
17358
+ if (pos === "bot" && args.hasSub && !args.hasSup) {
17359
+ return { "m:limLow": { "m:e": group, "m:lim": ctx.wrapE(args.sub) } };
17360
+ }
17361
+ if (pos === "top" && args.hasSup && !args.hasSub) {
17362
+ return { "m:limUpp": { "m:e": group, "m:lim": ctx.wrapE(args.sup) } };
17363
+ }
17364
+ return applyScripts(ctx, group, args);
17365
+ }
17366
+ function parseUnderOverset(ctx, tag) {
17367
+ const lim = ctx.parseSingleOrGroup();
17368
+ const base = ctx.parseSingleOrGroup();
17369
+ const limit = { "m:e": ctx.wrapE(base), "m:lim": ctx.wrapE(lim) };
17370
+ return tag === "m:limLow" ? { "m:limLow": limit } : { "m:limUpp": limit };
17371
+ }
17372
+ function parseBoxed(ctx) {
17373
+ return { "m:borderBox": { "m:e": ctx.wrapE(ctx.parseSingleOrGroup()) } };
17374
+ }
17375
+ function parsePhantom(ctx, kind) {
17376
+ const phantPr = {};
17377
+ if (kind === "h") {
17378
+ phantPr["m:zeroAsc"] = valNode("1");
17379
+ phantPr["m:zeroDesc"] = valNode("1");
17380
+ } else if (kind === "v") {
17381
+ phantPr["m:zeroWid"] = valNode("1");
17382
+ }
17383
+ return {
17384
+ "m:phant": {
17385
+ "m:phantPr": Object.keys(phantPr).length > 0 ? phantPr : void 0,
17386
+ "m:e": ctx.wrapE(ctx.parseSingleOrGroup())
17387
+ }
17388
+ };
17389
+ }
17390
+ function buildPrescript(ctx, sub, sup) {
17391
+ const base = ctx.parseAtom();
17392
+ return {
17393
+ "m:sPre": {
17394
+ "m:sub": ctx.wrapE(sub),
17395
+ "m:sup": ctx.wrapE(sup),
17396
+ "m:e": base ?? {}
17397
+ }
17398
+ };
17399
+ }
17400
+ function parsePrescript(ctx) {
17401
+ const sup = ctx.parseSingleOrGroup();
17402
+ const sub = ctx.parseSingleOrGroup();
17403
+ return buildPrescript(ctx, sub, sup);
17404
+ }
17405
+ function parseOperatorName(ctx) {
17406
+ return parseFuncApplication(ctx, parseTextArgument(ctx));
17407
+ }
17408
+
17409
+ // src/math/latex-to-omml-commands.ts
17410
+ function parseFraction(ctx, cmd) {
17411
+ const num = ctx.parseGroup();
17412
+ const den = ctx.parseGroup();
17413
+ const frac = { "m:num": ctx.wrapE(num), "m:den": ctx.wrapE(den) };
17414
+ if (cmd === "\\sfrac" || cmd === "\\binom") {
17415
+ frac["m:fPr"] = {
17416
+ "m:type": { "@_val": cmd === "\\sfrac" ? "lin" : "noBar" }
17417
+ };
17418
+ }
17419
+ const node = { "m:f": frac };
17420
+ if (cmd === "\\binom") {
17421
+ return { "m:d": { "m:e": node } };
17422
+ }
17423
+ return node;
17424
+ }
17425
+ function parseRadical(ctx) {
17426
+ if (ctx.peek()?.type === "text" && ctx.peek()?.value === "[") {
17427
+ ctx.next();
17428
+ const degree = [];
17429
+ while (ctx.peek() && !(ctx.peek().type === "text" && ctx.peek().value === "]")) {
17430
+ const atom = ctx.parseAtom();
17431
+ if (atom) {
17432
+ degree.push(atom);
17433
+ }
17434
+ }
17435
+ if (ctx.peek()?.value === "]") {
17436
+ ctx.next();
17437
+ }
17438
+ return {
17439
+ "m:rad": {
17440
+ "m:deg": ctx.wrapE(degree),
17441
+ "m:e": ctx.wrapE(ctx.parseGroup())
17442
+ }
17443
+ };
17444
+ }
17445
+ return {
17446
+ "m:rad": {
17447
+ "m:radPr": { "m:degHide": { "@_val": "1" } },
17448
+ "m:e": ctx.wrapE(ctx.parseGroup())
17449
+ }
17450
+ };
17451
+ }
17452
+ function parseCommand(ctx, cmd) {
17453
+ const symbol = GREEK_MAP[cmd] ?? OPERATOR_MAP[cmd] ?? ESCAPE_MAP[cmd];
17454
+ if (symbol !== void 0) {
17455
+ return symbol === "" ? null : ctx.makeRun(symbol);
17456
+ }
17457
+ if (NARY_MAP[cmd]) {
17458
+ return parseNary(ctx, NARY_MAP[cmd]);
17459
+ }
17460
+ if (ACCENT_MAP[cmd]) {
17461
+ return parseAccent(ctx, ACCENT_MAP[cmd]);
17462
+ }
17463
+ switch (cmd) {
17464
+ case "\\frac":
17465
+ case "\\dfrac":
17466
+ case "\\tfrac":
17467
+ case "\\sfrac":
17468
+ case "\\binom":
17469
+ return parseFraction(ctx, cmd);
17470
+ case "\\sqrt":
17471
+ return parseRadical(ctx);
17472
+ case "\\text":
17473
+ case "\\mathrm":
17474
+ case "\\textrm":
17475
+ case "\\mbox":
17476
+ return ctx.makeRun(parseTextArgument(ctx), true);
17477
+ case "\\operatorname":
17478
+ return parseOperatorName(ctx);
17479
+ case "\\left":
17480
+ return parseDelimiter(ctx);
17481
+ case "\\right":
17482
+ case "\\\\":
17483
+ case "\\limits":
17484
+ case "\\nolimits":
17485
+ case "\\displaystyle":
17486
+ case "\\textstyle":
17487
+ return null;
17488
+ case "\\begin":
17489
+ return parseEnvironment(ctx);
17490
+ case "\\end":
17491
+ parseTextArgument(ctx);
17492
+ return null;
17493
+ case "\\overline":
17494
+ return parseBar(ctx, "top");
17495
+ case "\\underline":
17496
+ return parseBar(ctx, "bot");
17497
+ case "\\overbrace":
17498
+ return parseGroupChr(ctx, "\u23DE", "top");
17499
+ case "\\underbrace":
17500
+ return parseGroupChr(ctx, "\u23DF", "bot");
17501
+ case "\\overset":
17502
+ return parseUnderOverset(ctx, "m:limUpp");
17503
+ case "\\underset":
17504
+ return parseUnderOverset(ctx, "m:limLow");
17505
+ case "\\boxed":
17506
+ return parseBoxed(ctx);
17507
+ case "\\phantom":
17508
+ return parsePhantom(ctx, "full");
17509
+ case "\\hphantom":
17510
+ return parsePhantom(ctx, "h");
17511
+ case "\\vphantom":
17512
+ return parsePhantom(ctx, "v");
17513
+ case "\\prescript":
17514
+ return parsePrescript(ctx);
17515
+ }
17516
+ const funcName = cmd.slice(1);
17517
+ if (FUNC_NAMES.has(funcName)) {
17518
+ return parseFuncApplication(ctx, funcName);
17519
+ }
17520
+ return ctx.makeRun(funcName, true);
17521
+ }
17522
+
17523
+ // src/math/omml-to-latex-helpers.ts
17524
+ function ensureArr(val2) {
17525
+ if (val2 === void 0 || val2 === null) {
17526
+ return [];
17527
+ }
17528
+ if (Array.isArray(val2)) {
17529
+ return val2.filter((entry) => Boolean(entry) && typeof entry === "object");
17530
+ }
17531
+ if (typeof val2 === "object") {
17532
+ return [val2];
17533
+ }
17534
+ return [];
17535
+ }
17536
+ function childNode(node, key) {
17537
+ if (!node) {
17538
+ return {};
17539
+ }
17540
+ const v = node[key];
17541
+ if (Array.isArray(v)) {
17542
+ return ensureArr(v)[0] ?? {};
17543
+ }
17544
+ if (v && typeof v === "object") {
17545
+ return v;
17546
+ }
17547
+ return {};
17548
+ }
17549
+ function attrVal(node) {
17550
+ if (!node) {
17551
+ return "";
17552
+ }
17553
+ const v = node["@_val"];
17554
+ if (typeof v === "string") {
17555
+ return v;
17556
+ }
17557
+ return v !== void 0 && v !== null ? String(v) : "";
17558
+ }
17559
+ function hasAttr(node) {
17560
+ return Boolean(node) && node["@_val"] !== void 0;
17561
+ }
17562
+ function isOn(node) {
17563
+ const v = attrVal(node);
17564
+ return v === "1" || v === "on" || v === "true";
17565
+ }
17566
+ function readRunText(run) {
17567
+ const t = run["m:t"];
17568
+ if (typeof t === "string") {
17569
+ return t;
17570
+ }
17571
+ if (typeof t === "number" || typeof t === "boolean") {
17572
+ return String(t);
17573
+ }
17574
+ if (Array.isArray(t)) {
17575
+ return t.map((entry) => readRunText({ "m:t": entry })).join("");
17576
+ }
17577
+ if (t && typeof t === "object") {
17578
+ const inner = t["#text"];
17579
+ return typeof inner === "string" || typeof inner === "number" ? String(inner) : "";
17580
+ }
17581
+ return "";
17582
+ }
17583
+ function contentKeys(node) {
17584
+ return Object.keys(node).filter((key) => {
17585
+ if (key.startsWith("@_") || key === "#text") {
17586
+ return false;
17587
+ }
17588
+ const tag = stripXmlOrderSuffix(key);
17589
+ return !tag.endsWith("Pr") && tag !== "m:t";
17590
+ });
17591
+ }
17592
+ function soleChild(container) {
17593
+ if (!container) {
17594
+ return null;
17595
+ }
17596
+ const keys = contentKeys(container);
17597
+ if (keys.length !== 1) {
17598
+ return null;
17599
+ }
17600
+ const items = ensureArr(container[keys[0]]);
17601
+ if (items.length !== 1) {
17602
+ return null;
17603
+ }
17604
+ return { tag: stripXmlOrderSuffix(keys[0]), node: items[0] };
17605
+ }
17606
+ function escapeChar(ch) {
17607
+ if (REVERSE_GREEK[ch]) {
17608
+ return `${REVERSE_GREEK[ch]} `;
17609
+ }
17610
+ if (REVERSE_OPERATOR[ch]) {
17611
+ return `${REVERSE_OPERATOR[ch]} `;
17612
+ }
17613
+ return REVERSE_ESCAPE[ch] ?? ch;
17614
+ }
17615
+ function escapeMathText(text) {
17616
+ return Array.from(text).map(escapeChar).join("");
17617
+ }
17618
+ var TEXT_ARGUMENT_ESCAPES = {
17619
+ "\\": "\\backslash ",
17620
+ "{": "\\{",
17621
+ "}": "\\}"
17622
+ };
17623
+ function escapeTextArgument(text) {
17624
+ return text.replace(/[\\{}]/gu, (ch) => TEXT_ARGUMENT_ESCAPES[ch] ?? ch);
17625
+ }
17626
+ function isSingleAtom(container) {
17627
+ const sole = soleChild(container);
17628
+ if (!sole) {
17629
+ return false;
17630
+ }
17631
+ if (sole.tag !== "m:r") {
17632
+ return true;
17633
+ }
17634
+ const text = readRunText(sole.node);
17635
+ if (isOn(childNode(childNode(sole.node, "m:rPr"), "m:nor"))) {
17636
+ return true;
17637
+ }
17638
+ return Array.from(text).length === 1;
17639
+ }
17640
+ function collectText(node) {
17641
+ if (node === null || node === void 0) {
17642
+ return "";
17643
+ }
17644
+ if (typeof node === "string" || typeof node === "number") {
17645
+ return String(node);
17646
+ }
17647
+ if (Array.isArray(node)) {
17648
+ return node.map((entry) => collectText(entry)).join("");
17649
+ }
17650
+ if (typeof node !== "object") {
17651
+ return "";
17652
+ }
17653
+ const record = node;
17654
+ let out = "";
17655
+ for (const [key, value] of Object.entries(record)) {
17656
+ if (key.startsWith("@_")) {
17657
+ continue;
17658
+ }
17659
+ const tag = stripXmlOrderSuffix(key);
17660
+ if (tag === "m:t") {
17661
+ out += escapeMathText(readRunText(record));
17662
+ } else if (tag === "#text") {
17663
+ out += escapeMathText(String(value));
17664
+ } else if (!tag.endsWith("Pr")) {
17665
+ out += collectText(value);
17666
+ }
17667
+ }
17668
+ return out;
17669
+ }
17670
+
17671
+ // src/math/omml-to-latex-layout.ts
17672
+ var CMD_ENDS_WITH_LETTER = /[a-zA-Z]$/u;
17673
+ var PLAIN_DELIM = /^[()[\]|]$/u;
17674
+ function naryToLatex(emit, node) {
17675
+ const naryPr = childNode(node, "m:naryPr");
17676
+ const chr = attrVal(childNode(naryPr, "m:chr"));
17677
+ let result = chr ? REVERSE_NARY[chr] ?? escapeMathText(chr) : "\\int";
17678
+ if (attrVal(childNode(naryPr, "m:limLoc")) === "undOvr") {
17679
+ result += "\\limits";
17680
+ }
17681
+ const sub = emit.arg(node, "m:sub");
17682
+ const sup = emit.arg(node, "m:sup");
17683
+ if (sub && !isOn(childNode(naryPr, "m:subHide"))) {
17684
+ result += `_{${sub}}`;
17685
+ }
17686
+ if (sup && !isOn(childNode(naryPr, "m:supHide"))) {
17687
+ result += `^{${sup}}`;
17688
+ }
17689
+ return `${result}{${emit.arg(node, "m:e")}}`;
17690
+ }
17691
+ function delimToLatex(chr) {
17692
+ if (chr.length === 0) {
17693
+ return ".";
17694
+ }
17695
+ if (PLAIN_DELIM.test(chr)) {
17696
+ return chr;
17697
+ }
17698
+ const cmd = REVERSE_DELIM[chr];
17699
+ if (cmd) {
17700
+ return CMD_ENDS_WITH_LETTER.test(cmd) ? `${cmd} ` : cmd;
17701
+ }
17702
+ return chr;
17703
+ }
17704
+ function matrixEnvFor(open, close) {
17705
+ return Object.keys(MATRIX_ENVS).find((env) => {
17706
+ const [envOpen, envClose] = MATRIX_ENVS[env];
17707
+ return env !== "array" && env !== "matrix" && envOpen === open && envClose === close;
17708
+ });
17709
+ }
17710
+ function rowsToLatex(emit, rows) {
17711
+ return rows.map((row) => emit.children(row)).join(" \\\\ ");
17712
+ }
17713
+ function matrixToLatex(emit, node, env) {
17714
+ const rows = ensureArr(node["m:mr"]).map(
17715
+ (row) => ensureArr(row["m:e"]).map((cell) => emit.children(cell)).join(" & ")
17716
+ );
17717
+ return `\\begin{${env}}${rows.join(" \\\\ ")}\\end{${env}}`;
17718
+ }
17719
+ function eqArrToLatex(emit, node) {
17720
+ return `\\begin{aligned}${rowsToLatex(emit, ensureArr(node["m:e"]))}\\end{aligned}`;
17721
+ }
17722
+ function delimiterToLatex(emit, node) {
17723
+ const dPr = childNode(node, "m:dPr");
17724
+ const begNode = childNode(dPr, "m:begChr");
17725
+ const endNode = childNode(dPr, "m:endChr");
17726
+ const open = hasAttr(begNode) ? attrVal(begNode) : "(";
17727
+ const close = hasAttr(endNode) ? attrVal(endNode) : ")";
17728
+ const elements2 = ensureArr(node["m:e"]);
17729
+ const sole = elements2.length === 1 ? soleChild(elements2[0]) : null;
17730
+ if (sole?.tag === "m:m") {
17731
+ const env = matrixEnvFor(open, close);
17732
+ if (env) {
17733
+ return matrixToLatex(emit, sole.node, env);
17734
+ }
17735
+ }
17736
+ if (sole?.tag === "m:eqArr" && open === "{" && close === "") {
17737
+ return `\\begin{cases}${rowsToLatex(emit, ensureArr(sole.node["m:e"]))}\\end{cases}`;
17738
+ }
17739
+ if (sole?.tag === "m:f" && open === "(" && close === ")") {
17740
+ if (attrVal(childNode(childNode(sole.node, "m:fPr"), "m:type")) === "noBar") {
17741
+ return `\\binom{${emit.arg(sole.node, "m:num")}}{${emit.arg(sole.node, "m:den")}}`;
17742
+ }
17743
+ }
17744
+ const sepNode = childNode(dPr, "m:sepChr");
17745
+ const separator = hasAttr(sepNode) ? attrVal(sepNode) : "|";
17746
+ const inner = elements2.map((e) => emit.children(e)).join(escapeMathText(separator));
17747
+ return `\\left${delimToLatex(open)}${inner}\\right${delimToLatex(close)}`;
17748
+ }
17749
+
17750
+ // src/math/omml-to-latex.ts
17751
+ function childrenToLatex(node) {
17752
+ if (!node || typeof node !== "object") {
17753
+ return "";
17754
+ }
17755
+ const parts = [];
17756
+ for (const key of contentKeys(node)) {
17757
+ const tag = stripXmlOrderSuffix(key);
17758
+ for (const item of ensureArr(node[key])) {
17759
+ parts.push(elementToLatex(tag, item));
17760
+ }
17761
+ }
17762
+ return parts.join("");
17763
+ }
17764
+ function arg(node, key) {
17765
+ return childrenToLatex(childNode(node, key));
17766
+ }
17767
+ var emitter = { children: childrenToLatex, arg };
17768
+ function scriptBase(node) {
17769
+ const base = arg(node, "m:e");
17770
+ return isSingleAtom(childNode(node, "m:e")) || base.length <= 1 ? base : `{${base}}`;
17771
+ }
17772
+ function runToLatex(node) {
17773
+ const text = readRunText(node);
17774
+ if (text.length === 0) {
17775
+ return "";
17776
+ }
17777
+ if (isOn(childNode(childNode(node, "m:rPr"), "m:nor"))) {
17778
+ return `\\text{${escapeTextArgument(text)}}`;
17779
+ }
17780
+ return escapeMathText(text);
17781
+ }
17782
+ function fractionToLatex(node) {
17783
+ const type = attrVal(childNode(childNode(node, "m:fPr"), "m:type"));
17784
+ const num = arg(node, "m:num");
17785
+ const den = arg(node, "m:den");
17786
+ if (type === "lin") {
17787
+ return `\\sfrac{${num}}{${den}}`;
17788
+ }
17789
+ if (type === "noBar") {
17790
+ return `{${num} \\atop ${den}}`;
17791
+ }
17792
+ return `\\frac{${num}}{${den}}`;
17793
+ }
17794
+ function radicalToLatex(node) {
17795
+ const base = arg(node, "m:e");
17796
+ if (isOn(childNode(childNode(node, "m:radPr"), "m:degHide"))) {
17797
+ return `\\sqrt{${base}}`;
17798
+ }
17799
+ const deg = arg(node, "m:deg");
17800
+ return deg ? `\\sqrt[${deg}]{${base}}` : `\\sqrt{${base}}`;
17801
+ }
17802
+ function funcNameToLatex(fName) {
17803
+ const sole = soleChild(fName);
17804
+ let nameNode = null;
17805
+ let scripts = "";
17806
+ if (sole?.tag === "m:r") {
17807
+ nameNode = sole.node;
17808
+ } else if (sole && ["m:sSub", "m:sSup", "m:sSubSup", "m:limLow", "m:limUpp"].includes(sole.tag)) {
17809
+ const inner = soleChild(childNode(sole.node, "m:e"));
17810
+ if (inner?.tag === "m:r") {
17811
+ nameNode = inner.node;
17812
+ const sub = arg(sole.node, sole.tag === "m:limLow" ? "m:lim" : "m:sub");
17813
+ const sup = arg(sole.node, sole.tag === "m:limUpp" ? "m:lim" : "m:sup");
17814
+ scripts = `${sub ? `_{${sub}}` : ""}${sup ? `^{${sup}}` : ""}`;
17815
+ }
17816
+ }
17817
+ if (!nameNode) {
17818
+ return childrenToLatex(fName);
17819
+ }
17820
+ const name = readRunText(nameNode).trim();
17821
+ const spelled = FUNC_NAMES.has(name) ? `\\${name}` : `\\operatorname{${escapeTextArgument(name)}}`;
17822
+ return `${spelled}${scripts}`;
17823
+ }
17824
+ function accentToLatex(node) {
17825
+ const raw = attrVal(childNode(childNode(node, "m:accPr"), "m:chr")) || "\u0302";
17826
+ const chr = ACCENT_ALIASES[raw] ?? raw;
17827
+ const cmd = REVERSE_ACCENT[chr];
17828
+ const base = arg(node, "m:e");
17829
+ return cmd ? `${cmd}{${base}}` : `\\overset{${escapeMathText(chr)}}{${base}}`;
17830
+ }
17831
+ function groupChrToLatex(node, label = "") {
17832
+ const groupChrPr = childNode(node, "m:groupChrPr");
17833
+ const chr = attrVal(childNode(groupChrPr, "m:chr")) || "\u23DF";
17834
+ const top = attrVal(childNode(groupChrPr, "m:pos")) === "top";
17835
+ const base = arg(node, "m:e");
17836
+ if (chr === "\u23DF" && !top) {
17837
+ return `\\underbrace{${base}}${label ? `_{${label}}` : ""}`;
17838
+ }
17839
+ if (chr === "\u23DE" && top) {
17840
+ return `\\overbrace{${base}}${label ? `^{${label}}` : ""}`;
17841
+ }
17842
+ const wrapped = `\\${top ? "overset" : "underset"}{${escapeMathText(chr)}}{${base}}`;
17843
+ return label ? `\\${top ? "overset" : "underset"}{${label}}{${wrapped}}` : wrapped;
17844
+ }
17845
+ function limitToLatex(node, tag) {
17846
+ const lim = arg(node, "m:lim");
17847
+ const sole = soleChild(childNode(node, "m:e"));
17848
+ if (sole?.tag === "m:groupChr") {
17849
+ const top = attrVal(childNode(childNode(sole.node, "m:groupChrPr"), "m:pos")) === "top";
17850
+ if (top === (tag === "m:limUpp")) {
17851
+ return groupChrToLatex(sole.node, lim);
17852
+ }
17853
+ }
17854
+ return `\\${tag === "m:limLow" ? "underset" : "overset"}{${lim}}{${arg(node, "m:e")}}`;
17855
+ }
17856
+ function phantomToLatex(node) {
17857
+ const phantPr = childNode(node, "m:phantPr");
17858
+ const base = arg(node, "m:e");
17859
+ if (isOn(childNode(phantPr, "m:zeroWid"))) {
17860
+ return `\\vphantom{${base}}`;
17861
+ }
17862
+ if (isOn(childNode(phantPr, "m:zeroAsc")) || isOn(childNode(phantPr, "m:zeroDesc"))) {
17863
+ return `\\hphantom{${base}}`;
17864
+ }
17865
+ return `\\phantom{${base}}`;
17866
+ }
17867
+ function elementToLatex(tag, node) {
17868
+ switch (tag) {
17869
+ case "m:r":
17870
+ return runToLatex(node);
17871
+ case "m:f":
17872
+ return fractionToLatex(node);
17873
+ case "m:rad":
17874
+ return radicalToLatex(node);
17875
+ case "m:sSup":
17876
+ return `${scriptBase(node)}^{${arg(node, "m:sup")}}`;
17877
+ case "m:sSub":
17878
+ return `${scriptBase(node)}_{${arg(node, "m:sub")}}`;
17879
+ case "m:sSubSup":
17880
+ return `${scriptBase(node)}_{${arg(node, "m:sub")}}^{${arg(node, "m:sup")}}`;
17881
+ case "m:sPre":
17882
+ return `{}_{${arg(node, "m:sub")}}^{${arg(node, "m:sup")}}{${arg(node, "m:e")}}`;
17883
+ case "m:nary":
17884
+ return naryToLatex(emitter, node);
17885
+ case "m:d":
17886
+ return delimiterToLatex(emitter, node);
17887
+ case "m:func":
17888
+ return `${funcNameToLatex(childNode(node, "m:fName"))}{${arg(node, "m:e")}}`;
17889
+ case "m:m":
17890
+ return matrixToLatex(emitter, node, "matrix");
17891
+ case "m:eqArr":
17892
+ return eqArrToLatex(emitter, node);
17893
+ case "m:acc":
17894
+ return accentToLatex(node);
17895
+ case "m:bar":
17896
+ return `\\${attrVal(childNode(childNode(node, "m:barPr"), "m:pos")) === "bot" ? "underline" : "overline"}{${arg(node, "m:e")}}`;
17897
+ case "m:limLow":
17898
+ case "m:limUpp":
17899
+ return limitToLatex(node, tag);
17900
+ case "m:groupChr":
17901
+ return groupChrToLatex(node);
17902
+ case "m:borderBox":
17903
+ return `\\boxed{${arg(node, "m:e")}}`;
17904
+ case "m:phant":
17905
+ return phantomToLatex(node);
17906
+ case "m:box":
17907
+ return ensureArr(node["m:e"]).map((e) => childrenToLatex(e)).join("");
17908
+ case "m:oMath":
17909
+ return childrenToLatex(node);
17910
+ default:
17911
+ return collectText(node);
17912
+ }
17913
+ }
17914
+ function convertOmmlToLatex(omml) {
17915
+ if (!omml || typeof omml !== "object") {
17916
+ return "";
17917
+ }
17918
+ const para = omml["m:oMathPara"];
17919
+ const roots = para ? ensureArr(para).flatMap((p) => ensureArr(p["m:oMath"])) : [];
17920
+ if (roots.length > 0) {
17921
+ return roots.map((root) => childrenToLatex(root)).join(" ");
17922
+ }
17923
+ if (omml["m:oMath"]) {
17924
+ return ensureArr(omml["m:oMath"]).map((root) => childrenToLatex(root)).join(" ");
17925
+ }
17926
+ return childrenToLatex(omml);
17927
+ }
17928
+
17929
+ // src/math/latex-to-omml.ts
17930
+ var LatexParser = class {
17931
+ tokens;
17932
+ pos = 0;
17933
+ /** Set for one `parseAtom` call: the atom is a bare script argument and takes no scripts of its own. */
17934
+ bare = false;
17935
+ constructor(tokens) {
17936
+ this.tokens = tokens;
17937
+ }
17938
+ peek() {
17939
+ return this.tokens[this.pos];
17940
+ }
17941
+ next() {
17942
+ return this.tokens[this.pos++];
17943
+ }
17944
+ expect(type) {
17945
+ const tok = this.next();
17946
+ if (!tok || tok.type !== type) {
17947
+ throw new Error(`Expected ${type}, got ${tok?.type ?? "EOF"}`);
17948
+ }
17949
+ return tok;
17950
+ }
17951
+ parseGroup() {
17952
+ this.expect("group_start");
17953
+ const nodes = [];
17954
+ while (this.peek() && this.peek().type !== "group_end") {
17955
+ const tok = this.peek();
17956
+ if (tok.type === "command" && (tok.value === "\\atop" || tok.value === "\\over")) {
17957
+ this.next();
17958
+ const den = this.parseGroupRest();
17959
+ const frac = { "m:num": this.wrapE(nodes), "m:den": this.wrapE(den) };
17960
+ if (tok.value === "\\atop") {
17961
+ frac["m:fPr"] = { "m:type": { "@_val": "noBar" } };
17962
+ }
17963
+ return [{ "m:f": frac }];
17964
+ }
17965
+ const node = this.parseAtom();
17966
+ if (node) {
17967
+ nodes.push(node);
17968
+ }
17969
+ }
17970
+ this.expect("group_end");
17971
+ return nodes;
17972
+ }
17973
+ /** Parse atoms up to and including the closing brace of the current group. */
17974
+ parseGroupRest() {
17975
+ const nodes = [];
17976
+ while (this.peek() && this.peek().type !== "group_end") {
17977
+ const node = this.parseAtom();
17978
+ if (node) {
17979
+ nodes.push(node);
17980
+ }
17981
+ }
17982
+ this.expect("group_end");
17983
+ return nodes;
17984
+ }
17985
+ /**
17986
+ * A braced group, or a single bare atom. A bare atom does not take its own
17987
+ * scripts: in `x_i^2` the `^2` belongs to `x`, not to `i`.
17988
+ */
17989
+ parseSingleOrGroup() {
17990
+ if (this.peek()?.type === "group_start") {
17991
+ return this.parseGroup();
17992
+ }
17993
+ this.bare = true;
17994
+ const atom = this.parseAtom();
17995
+ this.bare = false;
17996
+ return atom ? [atom] : [];
17997
+ }
17998
+ wrapE(nodes) {
17999
+ if (nodes.length === 1) {
18000
+ return nodes[0];
18001
+ }
18002
+ return mergeSiblings(nodes);
18003
+ }
18004
+ makeRun(text, normal = false) {
18005
+ const run = { "m:t": text };
18006
+ if (normal) {
18007
+ run["m:rPr"] = { "m:nor": { "@_val": "1" } };
18008
+ }
18009
+ return { "m:r": run };
18010
+ }
18011
+ parseAtom() {
18012
+ const tok = this.peek();
18013
+ if (!tok) {
18014
+ return null;
18015
+ }
18016
+ if (tok.type === "whitespace") {
18017
+ this.next();
18018
+ return this.parseAtom();
18019
+ }
18020
+ const bare = this.bare;
18021
+ this.bare = false;
18022
+ const scripted = (node) => bare ? node : tryParseScripts(this, node);
18023
+ if (tok.type === "text") {
18024
+ this.next();
18025
+ return scripted(this.makeRun(tok.value));
18026
+ }
18027
+ if (tok.type === "group_start") {
18028
+ const group = this.parseGroup();
18029
+ if (group.length === 0) {
18030
+ const args = parseScriptArgs(this);
18031
+ if (args.hasSub || args.hasSup) {
18032
+ return buildPrescript(this, args.sub, args.sup);
18033
+ }
18034
+ return null;
18035
+ }
18036
+ const base = group.length === 1 ? group[0] : this.wrapE(group);
18037
+ return scripted(base);
18038
+ }
18039
+ if (tok.type === "command") {
18040
+ this.next();
18041
+ const node = parseCommand(this, tok.value);
18042
+ return node ? scripted(node) : null;
18043
+ }
18044
+ if (tok.type === "superscript" || tok.type === "subscript") {
18045
+ this.next();
18046
+ const arg2 = this.parseSingleOrGroup();
18047
+ const empty = this.makeRun("");
18048
+ if (tok.type === "superscript") {
18049
+ return {
18050
+ "m:sSup": {
18051
+ "m:e": this.wrapE([empty]),
18052
+ "m:sup": this.wrapE(arg2)
18053
+ }
18054
+ };
18055
+ }
18056
+ return {
18057
+ "m:sSub": {
18058
+ "m:e": this.wrapE([empty]),
18059
+ "m:sub": this.wrapE(arg2)
18060
+ }
18061
+ };
18062
+ }
18063
+ return null;
18064
+ }
18065
+ parseAll() {
18066
+ const nodes = [];
18067
+ while (this.peek()) {
18068
+ const node = this.parseAtom();
18069
+ if (node) {
18070
+ nodes.push(node);
18071
+ }
18072
+ }
18073
+ return nodes;
18074
+ }
18075
+ };
18076
+ function convertLatexToOmml(latex) {
18077
+ const trimmed = latex.replace(/^\s+/u, "").replace(/(?<!\\)\s+$/u, "");
18078
+ if (trimmed.length === 0) {
18079
+ return {};
18080
+ }
18081
+ const tokens = tokenize(trimmed);
18082
+ const parser = new LatexParser(tokens);
18083
+ const nodes = parser.parseAll();
18084
+ if (nodes.length === 0) {
18085
+ return {};
18086
+ }
18087
+ const oMath = mergeSiblings(nodes);
18088
+ return {
18089
+ "m:oMathPara": {
18090
+ "m:oMath": oMath
18091
+ }
18092
+ };
18093
+ }
18094
+
18095
+ // src/math/omml-color.ts
18096
+ function getOmmlMathColor(node) {
18097
+ if (!node || typeof node !== "object") {
18098
+ return void 0;
18099
+ }
18100
+ const drawingRunProperties = node["a:rPr"];
18101
+ if (drawingRunProperties && typeof drawingRunProperties === "object") {
18102
+ const solidFill = drawingRunProperties["a:solidFill"];
18103
+ const srgbColor = solidFill && typeof solidFill === "object" ? solidFill["a:srgbClr"] : void 0;
18104
+ const value = srgbColor?.["@_val"];
18105
+ if (typeof value === "string" && /^[0-9a-f]{6}$/iu.test(value)) {
18106
+ return `#${value.toUpperCase()}`;
18107
+ }
18108
+ }
18109
+ for (const value of Object.values(node)) {
18110
+ if (Array.isArray(value)) {
18111
+ for (const child2 of value) {
18112
+ if (child2 && typeof child2 === "object") {
18113
+ const color = getOmmlMathColor(child2);
18114
+ if (color) {
18115
+ return color;
18116
+ }
18117
+ }
18118
+ }
18119
+ } else if (value && typeof value === "object") {
18120
+ const color = getOmmlMathColor(value);
18121
+ if (color) {
18122
+ return color;
18123
+ }
18124
+ }
18125
+ }
18126
+ return void 0;
18127
+ }
18128
+ function getOmmlMathFontSize(node) {
18129
+ if (!node || typeof node !== "object") {
18130
+ return void 0;
18131
+ }
18132
+ const drawingRunProperties = node["a:rPr"];
18133
+ if (drawingRunProperties && typeof drawingRunProperties === "object") {
18134
+ const size = Number(drawingRunProperties["@_sz"]);
18135
+ if (Number.isFinite(size) && size > 0) {
18136
+ return size / 100;
18137
+ }
18138
+ }
18139
+ for (const value of Object.values(node)) {
18140
+ if (Array.isArray(value)) {
18141
+ for (const child2 of value) {
18142
+ if (child2 && typeof child2 === "object") {
18143
+ const size = getOmmlMathFontSize(child2);
18144
+ if (size) {
18145
+ return size;
18146
+ }
18147
+ }
18148
+ }
18149
+ } else if (value && typeof value === "object") {
18150
+ const size = getOmmlMathFontSize(value);
18151
+ if (size) {
18152
+ return size;
18153
+ }
18154
+ }
18155
+ }
18156
+ return void 0;
18157
+ }
18158
+
18159
+ // src/math/omml-mathml-helpers.ts
18160
+ function child(node, key) {
18161
+ if (!node) {
18162
+ return {};
18163
+ }
18164
+ const v = node[key];
18165
+ if (v && typeof v === "object" && !Array.isArray(v)) {
18166
+ return v;
18167
+ }
18168
+ return {};
18169
+ }
18170
+ function ensureArray(value) {
18171
+ if (value === void 0 || value === null) {
18172
+ return [];
18173
+ }
18174
+ if (Array.isArray(value)) {
18175
+ return value;
18176
+ }
18177
+ if (typeof value === "object") {
18178
+ return [value];
18179
+ }
18180
+ return [];
18181
+ }
18182
+ function attr3(node, name) {
18183
+ if (!node) {
18184
+ return "";
18185
+ }
18186
+ const v = node[`@_${name}`];
18187
+ return typeof v === "string" ? v : v !== void 0 ? String(v) : "";
18188
+ }
18189
+ function val(node) {
18190
+ return attr3(node, "val");
18191
+ }
18192
+ function escapeXml(text) {
18193
+ return text.replace(/&/gu, "&amp;").replace(/</gu, "&lt;").replace(/>/gu, "&gt;");
18194
+ }
18195
+ function readText(node) {
18196
+ const textNode = node["m:t"];
18197
+ if (typeof textNode === "string") {
18198
+ return textNode;
18199
+ }
18200
+ if (typeof textNode === "number" || typeof textNode === "boolean") {
18201
+ return String(textNode);
18202
+ }
18203
+ if (textNode && typeof textNode === "object" && !Array.isArray(textNode)) {
18204
+ const inner = textNode["#text"];
18205
+ return typeof inner === "string" ? inner : "";
18206
+ }
18207
+ return "";
18208
+ }
18209
+ var OPERATOR_CHARS = /* @__PURE__ */ new Set([
18210
+ "+",
18211
+ "-",
18212
+ "\u2212",
18213
+ "\xB1",
18214
+ "\u2213",
18215
+ "\xD7",
18216
+ "\xF7",
18217
+ "\xB7",
18218
+ "=",
18219
+ "\u2260",
18220
+ "\u2248",
18221
+ "\u2261",
18222
+ "\u2264",
18223
+ "\u2265",
18224
+ "<",
18225
+ ">",
18226
+ "\u226A",
18227
+ "\u226B",
18228
+ "\u2208",
18229
+ "\u2209",
18230
+ "\u2282",
18231
+ "\u2283",
18232
+ "\u2286",
18233
+ "\u2287",
18234
+ "\u222A",
18235
+ "\u2229",
18236
+ "\u2192",
18237
+ "\u2190",
18238
+ "\u2194",
18239
+ "\u21D2",
18240
+ "\u21D0",
18241
+ "\u21D4",
18242
+ "\u221E",
18243
+ "\u2234",
18244
+ "\u2235",
18245
+ "\u221D",
18246
+ "\u2200",
18247
+ "\u2203",
18248
+ ",",
18249
+ ";",
18250
+ ":",
18251
+ "!",
18252
+ "?",
18253
+ ".",
18254
+ "|",
18255
+ "/",
18256
+ "\\",
18257
+ "'",
18258
+ "(",
18259
+ ")",
18260
+ "[",
18261
+ "]",
18262
+ "{",
18263
+ "}",
18264
+ "\u27E8",
18265
+ "\u27E9"
18266
+ ]);
18267
+ function isOperator(ch) {
18268
+ return OPERATOR_CHARS.has(ch.trim());
18269
+ }
18270
+ function isNumeric(text) {
18271
+ return /^[0-9]+(?:[.,][0-9]+)?$/u.test(text.trim());
18272
+ }
18273
+ var ACCENT_MAP2 = {
18274
+ "\u0302": "^",
18275
+ // combining circumflex → hat
18276
+ "\u0303": "~",
18277
+ // combining tilde
18278
+ "\u0304": "\xAF",
18279
+ // combining macron → bar
18280
+ "\u0305": "\xAF",
18281
+ // combining overline → bar
18282
+ "\u0307": "\u02D9",
18283
+ // combining dot above
18284
+ "\u0308": "\xA8",
18285
+ // combining diaeresis
18286
+ "\u030C": "\u02C7",
18287
+ // combining caron
18288
+ "\u0332": "_",
18289
+ // combining underbar
18290
+ "\u20D7": "\u2192",
18291
+ // combining right arrow above → →
18292
+ "^": "^",
18293
+ "~": "~",
18294
+ "\xAF": "\xAF",
18295
+ "\u02D9": "\u02D9",
18296
+ "\xA8": "\xA8",
18297
+ "\u02C7": "\u02C7"
18298
+ };
18299
+ var NARY_CHAR_MAP = {
18300
+ "\u2211": "\u2211",
18301
+ // ∑
18302
+ "\u220F": "\u220F",
18303
+ // ∏
18304
+ "\u222B": "\u222B",
18305
+ // ∫
18306
+ "\u222C": "\u222C",
18307
+ // ∬
18308
+ "\u222D": "\u222D",
18309
+ // ∭
18310
+ "\u222E": "\u222E",
18311
+ // ∮
18312
+ "\u2210": "\u2210",
18313
+ // ∐
18314
+ "\u22C0": "\u22C0",
18315
+ // ⋀
18316
+ "\u22C1": "\u22C1",
18317
+ // ⋁
18318
+ "\u22C2": "\u22C2",
18319
+ // ⋂
18320
+ "\u22C3": "\u22C3"
18321
+ // ⋃
18322
+ };
18323
+ var DELIM_BEGIN_MAP = {
18324
+ "(": "(",
18325
+ "[": "[",
18326
+ "{": "{",
18327
+ "|": "|",
18328
+ "\u2016": "\u2016",
18329
+ "\u27E8": "\u27E8",
18330
+ "\u2308": "\u2308",
18331
+ "\u230A": "\u230A"
18332
+ };
18333
+ var DELIM_END_MAP = {
18334
+ ")": ")",
18335
+ "]": "]",
18336
+ "}": "}",
18337
+ "|": "|",
18338
+ "\u2016": "\u2016",
18339
+ "\u27E9": "\u27E9",
18340
+ "\u2309": "\u2309",
18341
+ "\u230B": "\u230B"
18342
+ };
18343
+
18344
+ // src/math/omml-mathml-converters.ts
18345
+ function convertRun(node) {
18346
+ const text = readText(node);
18347
+ if (text.length === 0) {
18348
+ return "";
18349
+ }
18350
+ const escaped = escapeXml(text);
18351
+ const rPr = child(node, "m:rPr");
18352
+ const norVal = val(child(rPr, "m:nor"));
18353
+ const isNormal = norVal === "1" || norVal === "on" || norVal === "true";
18354
+ if (isNumeric(text)) {
18355
+ return `<mn>${escaped}</mn>`;
18356
+ }
18357
+ if (isOperator(text)) {
18358
+ return `<mo>${escaped}</mo>`;
18359
+ }
18360
+ if (isNormal) {
18361
+ return `<mi mathvariant="normal">${escaped}</mi>`;
18362
+ }
18363
+ return `<mi>${escaped}</mi>`;
18364
+ }
18365
+ function convertFraction(node, cc) {
18366
+ const fPr = child(node, "m:fPr");
18367
+ const fracType = val(child(fPr, "m:type"));
18368
+ const num = `<mrow>${cc(child(node, "m:num"))}</mrow>`;
18369
+ const den = `<mrow>${cc(child(node, "m:den"))}</mrow>`;
18370
+ if (fracType === "lin") {
18371
+ return `<mrow>${num}<mo>/</mo>${den}</mrow>`;
18372
+ }
18373
+ if (fracType === "noBar") {
18374
+ return `<mfrac linethickness="0">${num}${den}</mfrac>`;
18375
+ }
18376
+ return `<mfrac>${num}${den}</mfrac>`;
18377
+ }
18378
+ function convertRadical(node, cc) {
18379
+ const radPr = child(node, "m:radPr");
18380
+ const degHide = val(child(radPr, "m:degHide"));
18381
+ const base = cc(child(node, "m:e"));
18382
+ const degree = cc(child(node, "m:deg"));
18383
+ if (degHide === "1" || degHide === "on" || degHide === "true" || degree.length === 0) {
18384
+ return `<msqrt><mrow>${base}</mrow></msqrt>`;
18385
+ }
18386
+ return `<mroot><mrow>${base}</mrow><mrow>${degree}</mrow></mroot>`;
18387
+ }
18388
+ function convertSuperscript(node, cc) {
18389
+ const base = cc(child(node, "m:e"));
18390
+ const sup = cc(child(node, "m:sup"));
18391
+ return `<msup><mrow>${base}</mrow><mrow>${sup}</mrow></msup>`;
18392
+ }
18393
+ function convertSubscript(node, cc) {
18394
+ const base = cc(child(node, "m:e"));
18395
+ const sub = cc(child(node, "m:sub"));
18396
+ return `<msub><mrow>${base}</mrow><mrow>${sub}</mrow></msub>`;
18397
+ }
18398
+ function convertSubSup(node, cc) {
18399
+ const base = cc(child(node, "m:e"));
18400
+ const sub = cc(child(node, "m:sub"));
18401
+ const sup = cc(child(node, "m:sup"));
18402
+ return `<msubsup><mrow>${base}</mrow><mrow>${sub}</mrow><mrow>${sup}</mrow></msubsup>`;
18403
+ }
18404
+ function convertPreSubSup(node, cc) {
18405
+ const base = cc(child(node, "m:e"));
18406
+ const sub = cc(child(node, "m:sub"));
18407
+ const sup = cc(child(node, "m:sup"));
18408
+ return `<mmultiscripts><mrow>${base}</mrow><mprescripts/><mrow>${sub}</mrow><mrow>${sup}</mrow></mmultiscripts>`;
18409
+ }
18410
+ function convertNary(node, cc) {
18411
+ const naryPr = child(node, "m:naryPr");
18412
+ const chrVal = val(child(naryPr, "m:chr"));
18413
+ const limLocVal = val(child(naryPr, "m:limLoc"));
18414
+ const subHide = val(child(naryPr, "m:subHide"));
18415
+ const supHide = val(child(naryPr, "m:supHide"));
18416
+ const operatorChar = chrVal ? NARY_CHAR_MAP[chrVal] || chrVal : "\u222B";
18417
+ const sub = cc(child(node, "m:sub"));
18418
+ const sup = cc(child(node, "m:sup"));
18419
+ const base = cc(child(node, "m:e"));
18420
+ const showSub = subHide !== "1" && subHide !== "on" && subHide !== "true" && sub.length > 0;
18421
+ const showSup = supHide !== "1" && supHide !== "on" && supHide !== "true" && sup.length > 0;
18422
+ let result;
18423
+ if (showSub && showSup) {
18424
+ if (limLocVal === "undOvr") {
18425
+ result = `<munderover><mo>${escapeXml(operatorChar)}</mo><mrow>${sub}</mrow><mrow>${sup}</mrow></munderover>`;
18426
+ } else {
18427
+ result = `<msubsup><mo>${escapeXml(operatorChar)}</mo><mrow>${sub}</mrow><mrow>${sup}</mrow></msubsup>`;
18428
+ }
18429
+ } else if (showSub) {
18430
+ if (limLocVal === "undOvr") {
18431
+ result = `<munder><mo>${escapeXml(operatorChar)}</mo><mrow>${sub}</mrow></munder>`;
18432
+ } else {
18433
+ result = `<msub><mo>${escapeXml(operatorChar)}</mo><mrow>${sub}</mrow></msub>`;
18434
+ }
18435
+ } else if (showSup) {
18436
+ if (limLocVal === "undOvr") {
18437
+ result = `<mover><mo>${escapeXml(operatorChar)}</mo><mrow>${sup}</mrow></mover>`;
18438
+ } else {
18439
+ result = `<msup><mo>${escapeXml(operatorChar)}</mo><mrow>${sup}</mrow></msup>`;
18440
+ }
18441
+ } else {
18442
+ result = `<mo>${escapeXml(operatorChar)}</mo>`;
18443
+ }
18444
+ return `<mrow>${result}<mrow>${base}</mrow></mrow>`;
18445
+ }
18446
+ function convertDelimiter(node, cc) {
18447
+ const dPr = child(node, "m:dPr");
18448
+ const begChrVal = val(child(dPr, "m:begChr"));
18449
+ const endChrVal = val(child(dPr, "m:endChr"));
18450
+ const sepChrVal = val(child(dPr, "m:sepChr"));
18451
+ const open = begChrVal.length > 0 ? begChrVal : "(";
18452
+ const close = endChrVal.length > 0 ? endChrVal : ")";
18453
+ const separator = sepChrVal.length > 0 ? sepChrVal : "";
18454
+ const openChar = DELIM_BEGIN_MAP[open] || open;
18455
+ const closeChar = DELIM_END_MAP[close] || close;
18456
+ const elements2 = ensureArray(node["m:e"]);
18457
+ const parts = [];
18458
+ for (let i = 0; i < elements2.length; i++) {
18459
+ if (i > 0 && separator.length > 0) {
18460
+ parts.push(`<mo>${escapeXml(separator)}</mo>`);
18461
+ }
18462
+ parts.push(`<mrow>${cc(elements2[i])}</mrow>`);
18463
+ }
18464
+ const openMo = open ? `<mo>${escapeXml(openChar)}</mo>` : "<mo></mo>";
18465
+ const closeMo = close ? `<mo>${escapeXml(closeChar)}</mo>` : "<mo></mo>";
18466
+ return `<mrow>${openMo}${parts.join("")}${closeMo}</mrow>`;
18467
+ }
18468
+ function convertMatrix(node, cc) {
18469
+ const rows = ensureArray(node["m:mr"]);
18470
+ const tableRows = [];
18471
+ for (const row of rows) {
18472
+ const cells = ensureArray(row["m:e"]);
18473
+ const tdParts = [];
18474
+ for (const cell of cells) {
18475
+ tdParts.push(`<mtd><mrow>${cc(cell)}</mrow></mtd>`);
18476
+ }
18477
+ tableRows.push(`<mtr>${tdParts.join("")}</mtr>`);
18478
+ }
18479
+ return `<mrow><mo>[</mo><mtable>${tableRows.join("")}</mtable><mo>]</mo></mrow>`;
18480
+ }
18481
+ function convertAccent(node, cc) {
18482
+ const accPr = child(node, "m:accPr");
18483
+ const chrVal = val(child(accPr, "m:chr"));
18484
+ const base = cc(child(node, "m:e"));
18485
+ const accentChar = chrVal.length > 0 ? ACCENT_MAP2[chrVal] || chrVal : "\u0302";
18486
+ return `<mover accent="true"><mrow>${base}</mrow><mo>${escapeXml(accentChar)}</mo></mover>`;
18487
+ }
18488
+ function convertBar(node, cc) {
18489
+ const barPr = child(node, "m:barPr");
18490
+ const posVal = val(child(barPr, "m:pos"));
18491
+ const base = cc(child(node, "m:e"));
18492
+ if (posVal === "bot") {
18493
+ return `<munder><mrow>${base}</mrow><mo>\xAF</mo></munder>`;
18494
+ }
18495
+ return `<mover><mrow>${base}</mrow><mo>\xAF</mo></mover>`;
18496
+ }
18497
+ function convertLimLow(node, cc) {
18498
+ const base = cc(child(node, "m:e"));
18499
+ const lim = cc(child(node, "m:lim"));
18500
+ return `<munder><mrow>${base}</mrow><mrow>${lim}</mrow></munder>`;
18501
+ }
18502
+ function convertLimUpp(node, cc) {
18503
+ const base = cc(child(node, "m:e"));
18504
+ const lim = cc(child(node, "m:lim"));
18505
+ return `<mover><mrow>${base}</mrow><mrow>${lim}</mrow></mover>`;
18506
+ }
18507
+ function convertGroupChr(node, cc) {
18508
+ const grpPr = child(node, "m:groupChrPr");
18509
+ const chrVal = val(child(grpPr, "m:chr"));
18510
+ const posVal = val(child(grpPr, "m:pos"));
18511
+ const base = cc(child(node, "m:e"));
18512
+ const chr = chrVal.length > 0 ? chrVal : "\u23DF";
18513
+ if (posVal === "top") {
18514
+ return `<mover><mrow>${base}</mrow><mo>${escapeXml(chr)}</mo></mover>`;
18515
+ }
18516
+ return `<munder><mrow>${base}</mrow><mo>${escapeXml(chr)}</mo></munder>`;
18517
+ }
18518
+ function convertEqArr(node, cc) {
18519
+ const elements2 = ensureArray(node["m:e"]);
18520
+ const rows = [];
18521
+ for (const el of elements2) {
18522
+ rows.push(`<mtr><mtd><mrow>${cc(el)}</mrow></mtd></mtr>`);
18523
+ }
18524
+ return `<mtable columnalign="left">${rows.join("")}</mtable>`;
18525
+ }
18526
+ function convertBox(node, cc) {
18527
+ return `<mrow>${cc(child(node, "m:e"))}</mrow>`;
18528
+ }
18529
+ function convertFunc(node, cc) {
18530
+ const fName = cc(child(node, "m:fName"));
18531
+ const base = cc(child(node, "m:e"));
18532
+ return `<mrow>${fName}<mo>&#x2061;</mo><mrow>${base}</mrow></mrow>`;
18533
+ }
18534
+
18535
+ // src/math/omml-to-mathml.ts
18536
+ function convertChildren(node) {
18537
+ if (!node || typeof node !== "object") {
18538
+ return "";
18539
+ }
18540
+ const parts = [];
18541
+ for (const key of Object.keys(node)) {
18542
+ if (key.startsWith("@_")) {
18543
+ continue;
18544
+ }
18545
+ const tag = stripXmlOrderSuffix(key);
18546
+ if (tag === "m:oMathPara") {
18547
+ continue;
18548
+ }
18549
+ const items = ensureArray(node[key]);
18550
+ for (const item of items) {
18551
+ const result = convertElement(tag, item);
18552
+ if (result) {
18553
+ parts.push(result);
18554
+ }
18555
+ }
18556
+ }
18557
+ return parts.join("");
18558
+ }
18559
+ function convertElement(tag, node) {
18560
+ switch (tag) {
18561
+ case "m:r":
18562
+ return convertRun(node);
18563
+ case "m:f":
18564
+ return convertFraction(node, convertChildren);
18565
+ case "m:rad":
18566
+ return convertRadical(node, convertChildren);
18567
+ case "m:sSup":
18568
+ return convertSuperscript(node, convertChildren);
18569
+ case "m:sSub":
18570
+ return convertSubscript(node, convertChildren);
18571
+ case "m:sSubSup":
18572
+ return convertSubSup(node, convertChildren);
18573
+ case "m:sPre":
18574
+ return convertPreSubSup(node, convertChildren);
18575
+ case "m:nary":
18576
+ return convertNary(node, convertChildren);
18577
+ case "m:d":
18578
+ return convertDelimiter(node, convertChildren);
18579
+ case "m:m":
18580
+ return convertMatrix(node, convertChildren);
18581
+ case "m:acc":
18582
+ return convertAccent(node, convertChildren);
18583
+ case "m:bar":
18584
+ return convertBar(node, convertChildren);
18585
+ case "m:limLow":
18586
+ return convertLimLow(node, convertChildren);
18587
+ case "m:limUpp":
18588
+ return convertLimUpp(node, convertChildren);
18589
+ case "m:groupChr":
18590
+ return convertGroupChr(node, convertChildren);
18591
+ case "m:eqArr":
18592
+ return convertEqArr(node, convertChildren);
18593
+ case "m:box":
18594
+ return convertBox(node, convertChildren);
18595
+ case "m:borderBox":
18596
+ return convertBox(node, convertChildren);
18597
+ case "m:func":
18598
+ return convertFunc(node, convertChildren);
18599
+ case "m:oMath":
18600
+ return `<mrow>${convertChildren(node)}</mrow>`;
18601
+ default:
18602
+ return "";
18603
+ }
18604
+ }
18605
+ function findOmathRoots(node) {
18606
+ if (node["m:oMath"]) {
18607
+ return ensureArray(node["m:oMath"]);
18608
+ }
18609
+ const para = node["m:oMathPara"];
18610
+ if (para) {
18611
+ const paraNode = Array.isArray(para) ? para[0] : para;
18612
+ if (paraNode["m:oMath"]) {
18613
+ return ensureArray(paraNode["m:oMath"]);
18614
+ }
18615
+ }
18616
+ const contentTags = /* @__PURE__ */ new Set(["m:r", "m:f", "m:rad", "m:sSup", "m:sSub", "m:box"]);
18617
+ if (Object.keys(node).some((key) => contentTags.has(stripXmlOrderSuffix(key)))) {
18618
+ return [node];
18619
+ }
18620
+ return [];
18621
+ }
18622
+ function convertOmmlToMathMl(ommlNode) {
18623
+ if (!ommlNode || typeof ommlNode !== "object") {
18624
+ return "";
18625
+ }
18626
+ const oMaths = findOmathRoots(ommlNode);
18627
+ if (oMaths.length === 0) {
18628
+ return "";
18629
+ }
18630
+ const innerParts = oMaths.map((om) => convertChildren(om));
18631
+ const inner = innerParts.join("");
18632
+ if (inner.length === 0) {
18633
+ return "";
18634
+ }
18635
+ const color = getOmmlMathColor(ommlNode);
18636
+ const colorAttribute = color ? ` mathcolor="${color}"` : "";
18637
+ const fontSize = getOmmlMathFontSize(ommlNode);
18638
+ const sizeAttribute = fontSize ? ` mathsize="${fontSize}pt"` : "";
18639
+ return `<math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"${colorAttribute}${sizeAttribute}>${inner}</math>`;
18640
+ }
18641
+ function ommlToMathml(omml) {
18642
+ if (typeof omml === "string") {
18643
+ return "";
18644
+ }
18645
+ return convertOmmlToMathMl(omml);
18646
+ }
18647
+
18648
+ // src/math/omml-dom.ts
18649
+ var PREFIXES = {
18650
+ "http://schemas.openxmlformats.org/officeDocument/2006/math": "m",
18651
+ "http://purl.oclc.org/ooxml/officeDocument/math": "m",
18652
+ "http://schemas.openxmlformats.org/drawingml/2006/main": "a",
18653
+ "http://schemas.openxmlformats.org/wordprocessingml/2006/main": "w"
18654
+ };
18655
+ function ommlFromElement(element) {
18656
+ const visit = (node) => {
18657
+ const prefix = PREFIXES[node.namespaceURI ?? ""];
18658
+ const name = prefix ? `${prefix}:${node.localName}` : node.tagName;
18659
+ const body = mergeSiblings(elements(node).map(visit));
18660
+ for (const attribute of Array.from(node.attributes)) {
18661
+ if (attribute.namespaceURI === "http://www.w3.org/2000/xmlns/") continue;
18662
+ body[`@_${attribute.localName}`] = attribute.value;
18663
+ }
18664
+ const text = Array.from(node.childNodes).filter((child2) => child2.nodeType === 3 || child2.nodeType === 4).map((child2) => child2.nodeValue ?? "").join("");
18665
+ if (text && (!elements(node).length || text.trim())) body["#text"] = text;
18666
+ return { [name]: body };
18667
+ };
18668
+ return visit(element);
18669
+ }
18670
+ function parseOmml(xml) {
18671
+ return ommlFromElement(parseXml(xml, { label: "OMML" }).documentElement);
18672
+ }
18673
+
16646
18674
  exports.color = color_exports;
16647
18675
  exports.diagram = diagram_exports;
16648
18676
  exports.geometry = geometry_exports;
18677
+ exports.math = math_exports;
16649
18678
  exports.opc = opc_exports;
16650
18679
  exports.units = units_exports;
16651
18680
  exports.xml = xml_exports;