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