ed-mathml2tex 0.1.5 → 0.1.7

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.
@@ -588,10 +588,10 @@
588
588
  }
589
589
  };
590
590
 
591
- function getRender_joinSeparator(template, separator = '') {
591
+ function getRender_joinSeparator(template, separator = "") {
592
592
  return function (node, children) {
593
593
  const parts = renderChildren(children);
594
- return template.replace('@content', parts.join(separator));
594
+ return template.replace("@content", parts.join(separator));
595
595
  };
596
596
  }
597
597
 
@@ -603,9 +603,11 @@
603
603
  result = result.replace(/\\right\.\./g, "\\right."); // Loại bỏ dấu chấm trùng lặp
604
604
  result = result.replace(/\.\s*\./g, "."); // Loại bỏ dấu chấm trùng lặp
605
605
 
606
- if (mathmlHtml.includes("<munder>") &&
606
+ if (
607
+ mathmlHtml.includes("<munder>") &&
607
608
  mathmlHtml.includes("<mo>→</mo>") &&
608
- mathmlHtml.includes("<mrow/>")) {
609
+ mathmlHtml.includes("<mrow/>")
610
+ ) {
609
611
  if (result.includes("\\limits")) {
610
612
  result = "\\underset{}{\\rightarrow}";
611
613
  }
@@ -614,38 +616,71 @@
614
616
  // Thêm xử lý cho các thẻ MathML khác
615
617
  result = result
616
618
  .replace(/∞/g, "\\infty") // Vô cực
617
- .replace(/∑/g, "\\sum") // Tổng
618
- .replace(/∏/g, "\\prod") // Tích
619
- .replace(/∫/g, "\\int"); // Tích phân
619
+ .replace(/∑/g, "\\sum") // Tổng
620
+ .replace(/∏/g, "\\prod") // Tích
621
+ .replace(/∫/g, "\\int"); // Tích phân
620
622
 
621
623
  return result;
622
624
  }
623
625
 
624
626
  function toLatex(result) {
625
627
  // Xử lý binomial coefficients
626
- result = result.replace(/\\left\(\\DELETE_BRACKET_L/g, '');
627
- result = result.replace(/\\DELETE_BRACKET_R\\right\)/g, '');
628
- result = result.replace(/\\DELETE_BRACKET_L/g, '');
629
- result = result.replace(/\\DELETE_BRACKET_R/g, '');
628
+ result = result.replace(/\\left\(\\DELETE_BRACKET_L/g, "");
629
+ result = result.replace(/\\DELETE_BRACKET_R\\right\)/g, "");
630
+ result = result.replace(/\\DELETE_BRACKET_L/g, "");
631
+ result = result.replace(/\\DELETE_BRACKET_R/g, "");
630
632
 
631
633
  // Xử lý các trường hợp mũi tên với giới hạn
632
634
  result = result.replace(/→\\limits_{}/g, "\\underset{}{\\rightarrow}");
633
635
  result = result.replace(/→\\limits_{(\s*)}/g, "\\underset{}{\\rightarrow}");
634
- result = result.replace(/\\rightarrow\\limits_{}/g, "\\underset{}{\\rightarrow}");
635
- result = result.replace(/\\rightarrow\\limits_{(\s*)}/g, "\\underset{}{\\rightarrow}");
636
-
637
- result = result.replace(/→\\limits_\{([^}]*)\}/g, "\\underset{$1}{\\rightarrow}");
638
- result = result.replace(/\\rightarrow\\limits_\{([^}]*)\}/g, "\\underset{$1}{\\rightarrow}");
639
-
640
- result = result.replace(/→\\limits_\{([^}]*)\}\^\{([^}]*)\}/g, "\\overset{$2}{\\underset{$1}{\\rightarrow}}");
641
- result = result.replace(/\\rightarrow\\limits_\{([^}]*)\}\^\{([^}]*)\}/g, "\\overset{$2}{\\underset{$1}{\\rightarrow}}");
636
+ result = result.replace(
637
+ /\\rightarrow\\limits_{}/g,
638
+ "\\underset{}{\\rightarrow}"
639
+ );
640
+ result = result.replace(
641
+ /\\rightarrow\\limits_{(\s*)}/g,
642
+ "\\underset{}{\\rightarrow}"
643
+ );
644
+
645
+ result = result.replace(
646
+ /→\\limits_\{([^}]*)\}/g,
647
+ "\\underset{$1}{\\rightarrow}"
648
+ );
649
+ result = result.replace(
650
+ /\\rightarrow\\limits_\{([^}]*)\}/g,
651
+ "\\underset{$1}{\\rightarrow}"
652
+ );
653
+
654
+ result = result.replace(
655
+ /→\\limits_\{([^}]*)\}\^\{([^}]*)\}/g,
656
+ "\\overset{$2}{\\underset{$1}{\\rightarrow}}"
657
+ );
658
+ result = result.replace(
659
+ /\\rightarrow\\limits_\{([^}]*)\}\^\{([^}]*)\}/g,
660
+ "\\overset{$2}{\\underset{$1}{\\rightarrow}}"
661
+ );
642
662
 
643
663
  // Xử lý vector và các ký hiệu đặc biệt
644
- result = result.replace(/([^{}\s]+)\^\{\\rightarrow\}/g, "\\overrightarrow{$1}");
645
- result = result.replace(/\{([^{}]+)\}\^\{\\rightarrow\}/g, "\\overrightarrow{$1}");
646
- result = result.replace(/([A-Za-z0-9]+)_\{([^{}]+)\}\^\{\\rightarrow\}/g, "\\overrightarrow{$1_{$2}}");
647
- result = result.replace(/([A-Za-z0-9]+)_([0-9])\^\{\\rightarrow\}/g, "\\overrightarrow{$1_$2}");
648
- result = result.replace(/(\([^()]+\))\^\{\\rightarrow\}/g, "\\overrightarrow{$1}");
664
+ result = result.replace(
665
+ /([^{}\s]+)\^\{\\rightarrow\}/g,
666
+ "\\overrightarrow{$1}"
667
+ );
668
+ result = result.replace(
669
+ /\{([^{}]+)\}\^\{\\rightarrow\}/g,
670
+ "\\overrightarrow{$1}"
671
+ );
672
+ result = result.replace(
673
+ /([A-Za-z0-9]+)_\{([^{}]+)\}\^\{\\rightarrow\}/g,
674
+ "\\overrightarrow{$1_{$2}}"
675
+ );
676
+ result = result.replace(
677
+ /([A-Za-z0-9]+)_([0-9])\^\{\\rightarrow\}/g,
678
+ "\\overrightarrow{$1_$2}"
679
+ );
680
+ result = result.replace(
681
+ /(\([^()]+\))\^\{\\rightarrow\}/g,
682
+ "\\overrightarrow{$1}"
683
+ );
649
684
 
650
685
  // Remove or comment out these lines in toLatex function
651
686
  // Thêm xử lý các ký hiệu toán học phổ biến
@@ -673,7 +708,7 @@
673
708
  // @see https://www.w3.org/TR/MathML3/chapter7.html
674
709
  // Cải tiến parseLeaf để hỗ trợ thêm các ký hiệu
675
710
  function parseLeaf(node) {
676
- let r = '';
711
+ let r = "";
677
712
  const nodeName = NodeTool.getNodeName(node);
678
713
 
679
714
  if (nodeName === "mrow" && NodeTool.getNodeText(node).trim() === "") {
@@ -681,32 +716,32 @@
681
716
  }
682
717
 
683
718
  switch (nodeName) {
684
- case 'mi':
719
+ case "mi":
685
720
  r = parseElementMi(node);
686
721
  break;
687
- case 'mn':
722
+ case "mn":
688
723
  r = parseElementMn(node);
689
724
  break;
690
- case 'mo':
725
+ case "mo":
691
726
  r = parseOperator(node);
692
727
  break;
693
- case 'ms':
728
+ case "ms":
694
729
  r = parseElementMs(node);
695
730
  break;
696
- case 'mtext':
731
+ case "mtext":
697
732
  r = parseElementMtext(node);
698
733
  break;
699
- case 'mglyph':
734
+ case "mglyph":
700
735
  r = parseElementMglyph(node);
701
736
  break;
702
- case 'mprescripts':
703
- r = '';
737
+ case "mprescripts":
738
+ r = "";
704
739
  break;
705
- case 'mspace':
740
+ case "mspace":
706
741
  r = parseElementMspace();
707
742
  break;
708
- case 'none':
709
- r = '\\:';
743
+ case "none":
744
+ r = "\\:";
710
745
  break;
711
746
  default:
712
747
  r = escapeSpecialChars(NodeTool.getNodeText(node).trim());
@@ -715,10 +750,10 @@
715
750
  return r;
716
751
  }
717
752
 
718
- // Cải tiến parseOperator để hỗ trợ thêm toán tử
753
+ // --- PATCH by AI: Fix for set-builder notation and fraction output ---
754
+ // 1. Extend operatorMap and add π->\pi, |->\mid
719
755
  function parseOperator(node) {
720
756
  let it = NodeTool.getNodeText(node).trim();
721
-
722
757
  const operatorMap = {
723
758
  "→": " \\rightarrow ",
724
759
  "←": " \\leftarrow ",
@@ -737,12 +772,14 @@
737
772
  ">": " > ",
738
773
  "=": " = ",
739
774
  ",": ", ", // Dấu phẩy trong tập hợp
740
- ";": ";", // Dấu chấm phẩy không cần khoảng trắng
741
- "Ω": "\\Omega" // Thêm ký hiệu Omega
775
+ ";": ";",
776
+ Ω: "\\Omega",
777
+ "|": " \\mid ", // PATCH: set-builder mid
778
+ π: " \\pi ", // PATCH: Greek letter
742
779
  };
743
-
744
780
  return operatorMap[it] || escapeSpecialChars(MathSymbol.parseOperator(it));
745
781
  }
782
+ // --- END PATCH ---
746
783
 
747
784
  // Math identifier
748
785
  function parseElementMi(node) {
@@ -750,7 +787,7 @@
750
787
 
751
788
  // Handle vectors (e.g. AB', AI)
752
789
  if (it.includes("'")) {
753
- return it; // Return as is to handle in mrow
790
+ return it; // Return as is to handle in mrow
754
791
  }
755
792
 
756
793
  // Handle subscripts (e.g. n₂)
@@ -774,27 +811,41 @@
774
811
  function parseElementMs(node) {
775
812
  const content = NodeTool.getNodeText(node).trimRight();
776
813
  const it = escapeSpecialChars(content);
777
- return ['"', it, '"'].join('');
814
+ return ['"', it, '"'].join("");
778
815
  }
779
816
 
780
817
  // Math Text
781
818
  function parseElementMtext(node) {
782
819
  let content = NodeTool.getNodeText(node)
783
820
  // Handle operators and spacing only
784
- .replace(/\s*=\s*/g, ' = ')
785
- .replace(/\s*\.\s*/g, ' \\cdot ')
821
+ .replace(/\s*=\s*/g, " = ")
822
+ .replace(/\s*\.\s*/g, " \\cdot ")
786
823
  .trim();
787
824
 
825
+ const specialMTextMap = {
826
+ ℝ: "\\mathbb{R}",
827
+ ℤ: "\\mathbb{Z}",
828
+ ℕ: "\\mathbb{N}",
829
+ ℚ: "\\mathbb{Q}",
830
+ ℂ: "\\mathbb{C}",
831
+ "\\": "\\setminus ",
832
+ "|": "\\mid ",
833
+ " ": "",
834
+ };
835
+ if (specialMTextMap[content]) return specialMTextMap[content];
836
+
788
837
  // Handle units with proper \mathrm formatting
789
- if (content.includes('(') && content.includes(')')) {
838
+ if (content.includes("(") && content.includes(")")) {
790
839
  const parts = content.split(/(\([^)]+\))/);
791
- content = parts.map(part => {
792
- if (part.startsWith('(') && part.endsWith(')')) {
793
- // Keep original characters in units
794
- return `\\mathrm{${part}}`;
795
- }
796
- return part;
797
- }).join('');
840
+ content = parts
841
+ .map((part) => {
842
+ if (part.startsWith("(") && part.endsWith(")")) {
843
+ // Keep original characters in units
844
+ return `\\mathrm{${part}}`;
845
+ }
846
+ return part;
847
+ })
848
+ .join("");
798
849
  }
799
850
 
800
851
  return content;
@@ -802,84 +853,124 @@
802
853
 
803
854
  // Math glyph (image)
804
855
  function parseElementMglyph(node) {
805
- const it = ['"', NodeTool.getAttr(node, 'alt', ''), '"'].join('');
856
+ const it = ['"', NodeTool.getAttr(node, "alt", ""), '"'].join("");
806
857
  return escapeSpecialChars(it);
807
858
  }
808
859
 
809
860
  // TODO need or not
810
861
  function parseElementMspace(node) {
811
- return '';
862
+ return "";
812
863
  }
813
864
 
814
865
  function escapeSpecialChars(text) {
866
+ // Don't escape pi, Greek, or just a-z0-9 or Unicode Greek, or empty
867
+ if (
868
+ /^\\?[a-zA-Z0-9]+$/.test(text) ||
869
+ /^\\(?:pi|alpha|beta|gamma|Omega)$/.test(text) ||
870
+ /^π$/.test(text) ||
871
+ !text
872
+ ) {
873
+ return text;
874
+ }
875
+ // Otherwise escape only true reserved LaTeX
815
876
  const specialChars = /\$|%|_|&|#|\{|\}/g;
816
- text = text.replace(specialChars, char => `\\${char}`);
877
+ text = text.replace(specialChars, (char) => `\\${char}`);
817
878
  return text;
818
879
  }
819
880
 
820
-
821
881
  function parseContainer(node, children) {
822
882
  const render = getRender(node);
823
883
  if (render) {
824
884
  return render(node, children);
825
885
  } else {
826
- throw new Error(`Couldn't get render function for container node: ${NodeTool.getNodeName(node)}`);
886
+ throw new Error(
887
+ `Couldn't get render function for container node: ${NodeTool.getNodeName(
888
+ node
889
+ )}`
890
+ );
827
891
  }
828
892
  }
829
893
 
830
894
  function renderChildren(children) {
831
895
  const parts = [];
832
896
  let lefts = [];
833
- Array.prototype.forEach.call(children, (node) => {
834
- if (NodeTool.getNodeName(node) === 'mo') {
897
+
898
+ // PATCH: Special case for set-builder style: leading { ... trailing }
899
+ if (
900
+ children.length >= 3 &&
901
+ NodeTool.getNodeName(children[0]) === "mo" &&
902
+ NodeTool.getNodeText(children[0]).trim() === "{" &&
903
+ NodeTool.getNodeName(children[children.length - 1]) === "mo" &&
904
+ NodeTool.getNodeText(children[children.length - 1]).trim() === "}"
905
+ ) {
906
+ // Render inner content
907
+ const innerContent = Array.prototype.slice
908
+ .call(children, 1, -1)
909
+ .map((child) => parse(child))
910
+ .join("");
911
+ return `\\left\\{${innerContent}\\right\\}`;
912
+ }
913
+
914
+ Array.prototype.forEach.call(children, (node, idx) => {
915
+ // PATCH: Thin space between variables/numbers in mfrac numerator (k 2 π)
916
+ if (
917
+ NodeTool.getNodeName(node) === "mrow" &&
918
+ node.parentNode &&
919
+ NodeTool.getNodeName(node.parentNode) === "mfrac"
920
+ ) {
921
+ const mrowKids = Array.from(NodeTool.getChildren(node));
922
+ if (
923
+ mrowKids.every((n) =>
924
+ ["mi", "mn", "mo"].includes(NodeTool.getNodeName(n))
925
+ )
926
+ ) {
927
+ // Only vars, nums, ops (possibly Greek); join with thin space
928
+ const str = mrowKids.map((k) => parse(k)).join("\\,");
929
+ parts.push(str);
930
+ return;
931
+ }
932
+ }
933
+ // END PATCH
934
+ if (NodeTool.getNodeName(node) === "mo") {
835
935
  const op = NodeTool.getNodeText(node).trim();
836
936
  if (Brackets.contains(op)) {
837
- let stretchy = NodeTool.getAttr(node, 'stretchy', 'true');
838
- stretchy = ['', 'true'].indexOf(stretchy) > -1;
937
+ let stretchy = NodeTool.getAttr(node, "stretchy", "true");
938
+ stretchy = ["", "true"].indexOf(stretchy) > -1;
939
+
940
+ // Luôn escape dấu ngoặc nhọn cho LaTeX
941
+ let escapedOp = op;
942
+ if (op === "{" || op === "}") {
943
+ escapedOp = `\\${op}`;
944
+ }
839
945
 
840
946
  if (Brackets.isRight(op)) {
841
947
  const nearLeft = lefts[lefts.length - 1];
842
- if (nearLeft) {
843
- if (Brackets.isPair(nearLeft, op)) {
844
- // Kiểm tra xem có phải là một phần của biểu thức mũ không
845
- const parentNode = node.parentNode;
846
- const nextSibling = node.nextSibling;
847
- const prevSibling = node.previousSibling;
848
-
849
- const isInPower = parentNode && (
850
- NodeTool.getNodeName(parentNode) === 'msup' ||
851
- (nextSibling && NodeTool.getNodeName(nextSibling) === 'msup') ||
852
- (prevSibling && NodeTool.getNodeName(prevSibling) === 'msup')
853
- );
854
-
855
- if (isInPower) {
856
- parts.push(op); // Không thêm \right cho ngoặc trong mũ
857
- } else {
858
- parts.push(op); // Chỉ thêm dấu ngoặc đơn giản
859
- }
860
- lefts.pop();
948
+ if (nearLeft && Brackets.isPair(nearLeft, op)) {
949
+ const parentNode = node.parentNode;
950
+ const isInPower =
951
+ parentNode && NodeTool.getNodeName(parentNode) === "msup";
952
+
953
+ if (stretchy && !isInPower) {
954
+ parts.push(`\\right${escapedOp}`); // Dùng escapedOp
861
955
  } else {
862
- parts.push(op);
956
+ parts.push(escapedOp); // Dùng escapedOp
863
957
  }
958
+ lefts.pop();
864
959
  } else {
865
- parts.push(op);
960
+ parts.push(escapedOp); // Ngoặc phải không khớp
866
961
  }
867
962
  } else {
868
- // Kiểm tra cho dấu ngoặc mở
963
+ // ngoặc trái
869
964
  const parentNode = node.parentNode;
870
- const nextSibling = node.nextSibling;
871
-
872
- const isInPower = parentNode && (
873
- NodeTool.getNodeName(parentNode) === 'msup' ||
874
- (nextSibling && NodeTool.getNodeName(nextSibling) === 'msup')
875
- );
876
-
877
- if (isInPower) {
878
- parts.push(op); // Không thêm \left cho ngoặc trong mũ
965
+ const isInPower =
966
+ parentNode && NodeTool.getNodeName(parentNode) === "msup";
967
+
968
+ if (stretchy && !isInPower) {
969
+ parts.push(`\\left${escapedOp}`); // Dùng escapedOp
879
970
  } else {
880
- parts.push(op); // Chỉ thêm dấu ngoặc đơn giản
971
+ parts.push(escapedOp); // Dùng escapedOp
881
972
  }
882
- lefts.push(op);
973
+ lefts.push(op); // Dùng `op` gốc để so sánh cặp
883
974
  }
884
975
  } else {
885
976
  parts.push(parseOperator(node));
@@ -888,7 +979,6 @@
888
979
  parts.push(parse(node));
889
980
  }
890
981
  });
891
-
892
982
  lefts = undefined;
893
983
  return parts;
894
984
  }
@@ -898,41 +988,49 @@
898
988
  const nodeName = NodeTool.getNodeName(node);
899
989
 
900
990
  switch (nodeName) {
901
- case 'mrow':
991
+ case "mrow":
902
992
  render = function (node, children) {
903
993
  const childrenArray = Array.from(children);
904
- if (childrenArray.length >= 2 &&
905
- NodeTool.getNodeName(childrenArray[0]) === 'mo' &&
906
- NodeTool.getNodeName(childrenArray[childrenArray.length - 1]) === 'mo') {
994
+ if (
995
+ childrenArray.length >= 2 &&
996
+ NodeTool.getNodeName(childrenArray[0]) === "mo" &&
997
+ NodeTool.getNodeName(childrenArray[childrenArray.length - 1]) === "mo"
998
+ ) {
907
999
  const firstOp = NodeTool.getNodeText(childrenArray[0]).trim();
908
- const lastOp = NodeTool.getNodeText(childrenArray[childrenArray.length - 1]).trim();
1000
+ const lastOp = NodeTool.getNodeText(
1001
+ childrenArray[childrenArray.length - 1]
1002
+ ).trim();
909
1003
 
910
1004
  // Xử lý đặc biệt cho dấu ngoặc nhọn chứa mtable
911
- if (firstOp === '{' && childrenArray.some(child =>
912
- NodeTool.getNodeName(child) === 'mtable')) {
1005
+ if (
1006
+ firstOp === "{" &&
1007
+ childrenArray.some(
1008
+ (child) => NodeTool.getNodeName(child) === "mtable"
1009
+ )
1010
+ ) {
913
1011
  const innerContent = childrenArray
914
1012
  .slice(1, -1)
915
- .map(child => parse(child))
916
- .join('');
1013
+ .map((child) => parse(child))
1014
+ .join("");
917
1015
  return `\\left\\{${innerContent}\\right.`;
918
1016
  }
919
1017
 
920
1018
  // Xử lý cho trường hợp [a;b) và [a,b)
921
- if (firstOp === '[' && lastOp === ')') {
1019
+ if (firstOp === "[" && lastOp === ")") {
922
1020
  const innerContent = childrenArray
923
1021
  .slice(1, -1)
924
- .map(child => parse(child))
925
- .join('');
1022
+ .map((child) => parse(child))
1023
+ .join("");
926
1024
  return `\\left[${innerContent}\\right)`;
927
1025
  }
928
1026
 
929
1027
  // Xử lý ngoặc nhọn bình thường
930
- if (firstOp === '{' && lastOp === '}') {
1028
+ if (firstOp === "{" && lastOp === "}") {
931
1029
  const innerContent = childrenArray
932
1030
  .slice(1, -1)
933
- .map(child => parse(child))
934
- .join('');
935
- return `\\{${innerContent}\\}`;
1031
+ .map((child) => parse(child))
1032
+ .join("");
1033
+ return `\\left\\{${innerContent}\\right\\}`;
936
1034
  }
937
1035
 
938
1036
  // Bỏ qua nếu firstOp là rỗng (trường hợp <mo></mo>)
@@ -940,33 +1038,55 @@
940
1038
  return getRender_joinSeparator("@content")(node, childrenArray);
941
1039
  }
942
1040
 
1041
+ if (firstOp === "[" && lastOp === "]") {
1042
+ const innerContent = childrenArray
1043
+ .slice(1, -1)
1044
+ .map((child) => parse(child))
1045
+ .join("");
1046
+ return `[${innerContent}]`;
1047
+ }
1048
+
943
1049
  // Xử lý đặc biệt cho dấu ngoặc vuông chứa mtable
944
- if (firstOp === '[') {
1050
+ if (firstOp === "[") {
945
1051
  const innerContent = childrenArray
946
1052
  .slice(1, -1) // Bỏ dấu ngoặc mở và đóng
947
- .map(child => {
1053
+ .map((child) => {
948
1054
  const parsed = parse(child);
949
1055
  // Nếu child là mtable, trả về nội dung đã được định dạng với \begin{array}{l} ... \end{array}
950
- if (NodeTool.getNodeName(child) === 'mtable') {
951
- const rows = Array.from(NodeTool.getChildren(child)).map(row => {
952
- const rowChildren = Array.from(NodeTool.getChildren(row));
953
- return rowChildren.map(cell => parse(cell)).join('');
954
- });
955
- return `\\begin{array}{l} ${rows.join(' \\\\ ')} \\end{array}`;
1056
+ if (NodeTool.getNodeName(child) === "mtable") {
1057
+ const rows = Array.from(NodeTool.getChildren(child)).map(
1058
+ (row) => {
1059
+ const rowChildren = Array.from(NodeTool.getChildren(row));
1060
+ return rowChildren.map((cell) => parse(cell)).join("");
1061
+ }
1062
+ );
1063
+ return `\\begin{array}{l} ${rows.join(
1064
+ " \\\\ "
1065
+ )} \\end{array}`;
956
1066
  }
957
1067
  // Nếu child là mrow chứa mtable, xử lý tương tự
958
- if (NodeTool.getNodeName(child) === 'mrow' &&
959
- Array.from(NodeTool.getChildren(child)).some(c => NodeTool.getNodeName(c) === 'mtable')) {
960
- const mtableChild = Array.from(NodeTool.getChildren(child)).find(c => NodeTool.getNodeName(c) === 'mtable');
961
- const rows = Array.from(NodeTool.getChildren(mtableChild)).map(row => {
1068
+ if (
1069
+ NodeTool.getNodeName(child) === "mrow" &&
1070
+ Array.from(NodeTool.getChildren(child)).some(
1071
+ (c) => NodeTool.getNodeName(c) === "mtable"
1072
+ )
1073
+ ) {
1074
+ const mtableChild = Array.from(
1075
+ NodeTool.getChildren(child)
1076
+ ).find((c) => NodeTool.getNodeName(c) === "mtable");
1077
+ const rows = Array.from(
1078
+ NodeTool.getChildren(mtableChild)
1079
+ ).map((row) => {
962
1080
  const rowChildren = Array.from(NodeTool.getChildren(row));
963
- return rowChildren.map(cell => parse(cell)).join('');
1081
+ return rowChildren.map((cell) => parse(cell)).join("");
964
1082
  });
965
- return `\\begin{array}{l} ${rows.join(' \\\\ ')} \\end{array}`;
1083
+ return `\\begin{array}{l} ${rows.join(
1084
+ " \\\\ "
1085
+ )} \\end{array}`;
966
1086
  }
967
1087
  return parsed;
968
1088
  })
969
- .join('');
1089
+ .join("");
970
1090
 
971
1091
  // Giữ nguyên dấu ngoặc vuông lớn
972
1092
  return `\\left[${innerContent}\\right.`;
@@ -975,36 +1095,41 @@
975
1095
  if (Brackets.isPair(firstOp, lastOp)) {
976
1096
  const innerContent = childrenArray
977
1097
  .slice(1, -1)
978
- .map(child => parse(child))
979
- .join('');
1098
+ .map((child) => parse(child))
1099
+ .join("");
980
1100
  return `\\left${firstOp}${innerContent}\\right${lastOp}`;
981
1101
  }
982
1102
 
983
1103
  // Giữ nguyên dấu ngoặc nhọn trong MathML
984
- if (firstOp === '{' || lastOp === '}') {
1104
+ if (firstOp === "{" || lastOp === "}") {
985
1105
  const innerContent = childrenArray
986
- .slice(1, lastOp === '}' ? -1 : undefined)
987
- .map(child => parse(child))
988
- .join('');
989
- return `${firstOp === '{' ? '\\{' : ''}${innerContent}${lastOp === '}' ? '\\}' : ''}`;
1106
+ .slice(1, lastOp === "}" ? -1 : undefined)
1107
+ .map((child) => parse(child))
1108
+ .join("");
1109
+ return `${firstOp === "{" ? "\\{" : ""}${innerContent}${
1110
+ lastOp === "}" ? "\\}" : ""
1111
+ }`;
990
1112
  }
991
1113
  }
992
1114
  return getRender_joinSeparator("@content")(node, childrenArray);
993
1115
  };
994
1116
  break;
995
1117
 
996
- case 'msub':
1118
+ case "msub":
997
1119
  render = function (node, children) {
998
1120
  const childrenArray = Array.from(children);
999
- if (!childrenArray || childrenArray.length < 2) return '';
1000
- const base = parse(childrenArray[0]) || '';
1121
+ if (!childrenArray || childrenArray.length < 2) return "";
1122
+ const base = parse(childrenArray[0]) || "";
1001
1123
  const sub = childrenArray[1];
1002
1124
  if (!sub) return base;
1003
1125
 
1004
- if (NodeTool.getNodeName(sub) === 'msub' &&
1126
+ if (
1127
+ NodeTool.getNodeName(sub) === "msub" &&
1005
1128
  sub.firstChild &&
1006
- NodeTool.getNodeName(sub.firstChild) === 'mrow' &&
1007
- (!NodeTool.getNodeText(sub.firstChild) || NodeTool.getNodeText(sub.firstChild).trim() === '')) {
1129
+ NodeTool.getNodeName(sub.firstChild) === "mrow" &&
1130
+ (!NodeTool.getNodeText(sub.firstChild) ||
1131
+ NodeTool.getNodeText(sub.firstChild).trim() === "")
1132
+ ) {
1008
1133
  const lastChild = sub.lastChild;
1009
1134
  return lastChild ? `${base}_${parse(lastChild)}` : base;
1010
1135
  }
@@ -1012,52 +1137,57 @@
1012
1137
  };
1013
1138
  break;
1014
1139
 
1015
- case 'msup':
1140
+ case "msup":
1016
1141
  render = function (node, children) {
1017
1142
  const childrenArray = Array.from(children);
1018
- if (!childrenArray || childrenArray.length < 2) return '';
1019
- const base = parse(childrenArray[0]) || '';
1020
- const sup = parse(childrenArray[1]) || '';
1143
+ if (!childrenArray || childrenArray.length < 2) return "";
1144
+ const base = parse(childrenArray[0]) || "";
1145
+ const sup = parse(childrenArray[1]) || "";
1021
1146
  return `${base}^{${sup}}`;
1022
1147
  };
1023
1148
  break;
1024
1149
 
1025
- case 'msubsup':
1150
+ case "msubsup":
1026
1151
  render = function (node, children) {
1027
1152
  const childrenArray = Array.from(children);
1028
- if (!childrenArray || childrenArray.length < 3) return '';
1153
+ if (!childrenArray || childrenArray.length < 3) return "";
1029
1154
  const base = parse(childrenArray[0]);
1030
1155
  const sub = parse(childrenArray[1]);
1031
1156
  const sup = parse(childrenArray[2]);
1032
1157
 
1033
1158
  const lastChild = childrenArray[0].lastElementChild;
1034
- if (lastChild && NodeTool.getNodeName(lastChild) === 'mo' &&
1035
- NodeTool.getNodeText(lastChild).trim() === '|') {
1159
+ if (
1160
+ lastChild &&
1161
+ NodeTool.getNodeName(lastChild) === "mo" &&
1162
+ NodeTool.getNodeText(lastChild).trim() === "|"
1163
+ ) {
1036
1164
  const content = Array.from(childrenArray[0].children)
1037
1165
  .slice(0, -1)
1038
- .map(child => parse(child))
1039
- .join('');
1166
+ .map((child) => parse(child))
1167
+ .join("");
1040
1168
  return `\\left.${content}\\right|_{${sub}}^{${sup}}`;
1041
1169
  }
1042
1170
  return `${base}_{${sub}}^{${sup}}`;
1043
1171
  };
1044
1172
  break;
1045
1173
 
1046
- case 'mover':
1174
+ case "mover":
1047
1175
  render = function (node, children) {
1048
1176
  const childrenArray = Array.from(children);
1049
- if (!childrenArray || childrenArray.length < 2) return '';
1050
- const base = parse(childrenArray[0]) || '';
1051
- const over = parse(childrenArray[1]) || '';
1052
- const overText = NodeTool.getNodeText(childrenArray[1])?.trim() || '';
1177
+ if (!childrenArray || childrenArray.length < 2) return "";
1178
+ const base = parse(childrenArray[0]) || "";
1179
+ const over = parse(childrenArray[1]) || "";
1180
+ const overText = NodeTool.getNodeText(childrenArray[1])?.trim() || "";
1053
1181
  const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1054
1182
 
1055
1183
  // Handle biology notation (double overline)
1056
1184
  if (overText === "¯") {
1057
1185
  const parentNode = node.parentNode;
1058
1186
  // Check if this is part of a double overline structure
1059
- if (NodeTool.getNodeName(parentNode) === 'mover' &&
1060
- NodeTool.getNodeText(parentNode.lastChild)?.trim() === '¯') {
1187
+ if (
1188
+ NodeTool.getNodeName(parentNode) === "mover" &&
1189
+ NodeTool.getNodeText(parentNode.lastChild)?.trim() === "¯"
1190
+ ) {
1061
1191
  return `\\overline{${base}}`;
1062
1192
  }
1063
1193
  return `\\overline{${base}}`;
@@ -1069,55 +1199,68 @@
1069
1199
  };
1070
1200
  break;
1071
1201
 
1072
- case 'munder':
1202
+ case "munder":
1073
1203
  render = function (node, children) {
1074
1204
  const childrenArray = Array.from(children);
1075
- if (!childrenArray || childrenArray.length < 2) return '';
1076
- const base = parse(childrenArray[0]) || '';
1077
- const under = parse(childrenArray[1]) || '';
1078
- const isUnderAccent = NodeTool.getAttr(node, "accentunder", "false") === "true";
1205
+ if (!childrenArray || childrenArray.length < 2) return "";
1206
+ const base = parse(childrenArray[0]) || "";
1207
+ const under = parse(childrenArray[1]) || "";
1208
+ const isUnderAccent =
1209
+ NodeTool.getAttr(node, "accentunder", "false") === "true";
1079
1210
 
1080
1211
  if (base === "∫") return `\\int_{${under}}`;
1081
1212
  return `\\underset{${under}}{${base}}`;
1082
1213
  };
1083
1214
  break;
1084
1215
 
1085
- case 'munderover':
1216
+ case "munderover":
1086
1217
  render = function (node, children) {
1087
1218
  const childrenArray = Array.from(children);
1088
- if (!childrenArray || childrenArray.length < 3) return '';
1219
+ if (!childrenArray || childrenArray.length < 3) return "";
1089
1220
  const base = parse(childrenArray[0]);
1090
1221
  const under = parse(childrenArray[1]);
1091
1222
  const over = parse(childrenArray[2]);
1092
1223
  const baseText = NodeTool.getNodeText(childrenArray[0]).trim();
1093
1224
 
1094
- if (baseText === '∫') return `\\int_{${under}}^{${over}}`;
1095
- if (baseText === '∑') return `\\sum_{${under}}^{${over}}`;
1096
- if (baseText === '∏') return `\\prod_{${under}}^{${over}}`;
1097
- if (baseText === '|') return `\\big|_{${under}}^{${over}}`;
1225
+ // Special handling for chemical reaction arrow
1226
+ if (
1227
+ baseText === "→" &&
1228
+ NodeTool.getNodeName(childrenArray[1]) === "msup"
1229
+ ) {
1230
+ return `\\xrightarrow[${under}]{${over}}`;
1231
+ }
1232
+
1233
+ if (baseText === "∫") return `\\int_{${under}}^{${over}}`;
1234
+ if (baseText === "∑") return `\\sum_{${under}}^{${over}}`;
1235
+ if (baseText === "∏") return `\\prod_{${under}}^{${over}}`;
1236
+ if (baseText === "|") return `\\big|_{${under}}^{${over}}`;
1098
1237
  return `${base}_{${under}}^{${over}}`;
1099
1238
  };
1100
1239
  break;
1101
1240
 
1102
- case 'mmultiscripts':
1241
+ case "mmultiscripts":
1103
1242
  render = function (node, children) {
1104
1243
  const childrenArray = Array.from(children);
1105
- if (!childrenArray || childrenArray.length < 1) return '';
1244
+ if (!childrenArray || childrenArray.length < 1) return "";
1106
1245
  const base = parse(childrenArray[0]);
1107
- let prescripts = '';
1108
- let postscripts = '';
1246
+ let prescripts = "";
1247
+ let postscripts = "";
1109
1248
  let i = 1;
1110
1249
 
1111
1250
  while (i < childrenArray.length) {
1112
- if (NodeTool.getNodeName(childrenArray[i]) === 'mprescripts') {
1251
+ if (NodeTool.getNodeName(childrenArray[i]) === "mprescripts") {
1113
1252
  i++;
1114
1253
  if (i + 1 < childrenArray.length) {
1115
- prescripts = `_{${parse(childrenArray[i])}}^{${parse(childrenArray[i + 1])}}`;
1254
+ prescripts = `_{${parse(childrenArray[i])}}^{${parse(
1255
+ childrenArray[i + 1]
1256
+ )}}`;
1116
1257
  i += 2;
1117
1258
  }
1118
1259
  } else {
1119
1260
  if (i + 1 < childrenArray.length) {
1120
- postscripts += `_{${parse(childrenArray[i])}}^{${parse(childrenArray[i + 1])}}`;
1261
+ postscripts += `_{${parse(childrenArray[i])}}^{${parse(
1262
+ childrenArray[i + 1]
1263
+ )}}`;
1121
1264
  i += 2;
1122
1265
  } else break;
1123
1266
  }
@@ -1126,33 +1269,35 @@
1126
1269
  };
1127
1270
  break;
1128
1271
 
1129
- case 'mlongdiv':
1272
+ case "mlongdiv":
1130
1273
  render = function (node, children) {
1131
1274
  const childrenArray = Array.from(children);
1132
- if (!childrenArray || childrenArray.length < 2) return '';
1133
- return `\\longdiv{${parse(childrenArray[0])}}{${parse(childrenArray[1])}}`;
1275
+ if (!childrenArray || childrenArray.length < 2) return "";
1276
+ return `\\longdiv{${parse(childrenArray[0])}}{${parse(
1277
+ childrenArray[1]
1278
+ )}}`;
1134
1279
  };
1135
1280
  break;
1136
1281
 
1137
- case 'mroot':
1282
+ case "mroot":
1138
1283
  render = function (node, children) {
1139
1284
  const childrenArray = Array.from(children);
1140
- if (!childrenArray || childrenArray.length < 2) return '';
1285
+ if (!childrenArray || childrenArray.length < 2) return "";
1141
1286
  const base = parse(childrenArray[0]);
1142
1287
  const index = parse(childrenArray[1]);
1143
1288
  return `\\sqrt[${index}]{${base}}`;
1144
1289
  };
1145
1290
  break;
1146
1291
 
1147
- case 'msqrt':
1292
+ case "msqrt":
1148
1293
  render = function (node, children) {
1149
1294
  const childrenArray = Array.from(children);
1150
- const content = renderChildren(childrenArray).join('');
1295
+ const content = renderChildren(childrenArray).join("");
1151
1296
  return `\\sqrt{${content}}`;
1152
1297
  };
1153
1298
  break;
1154
1299
 
1155
- case 'mtable':
1300
+ case "mtable":
1156
1301
  render = function (node, children) {
1157
1302
  const childrenArray = Array.from(children);
1158
1303
 
@@ -1160,7 +1305,7 @@
1160
1305
  let isNestedTable = false;
1161
1306
  let parent = node.parentNode;
1162
1307
  while (parent) {
1163
- if (NodeTool.getNodeName(parent) === 'mtable') {
1308
+ if (NodeTool.getNodeName(parent) === "mtable") {
1164
1309
  isNestedTable = true;
1165
1310
  break;
1166
1311
  }
@@ -1168,25 +1313,27 @@
1168
1313
  }
1169
1314
 
1170
1315
  // Xử lý mỗi mtr như một hàng
1171
- const rows = childrenArray.map(row => {
1316
+ const rows = childrenArray.map((row) => {
1172
1317
  const rowChildren = Array.from(NodeTool.getChildren(row));
1173
- return rowChildren.map(cell => parse(cell)).join('');
1318
+ return rowChildren.map((cell) => parse(cell)).join("");
1174
1319
  });
1175
1320
 
1176
1321
  // Nếu là mtable con, chỉ trả về các hàng mà không bao bọc trong \begin{array}...\end{array}
1177
1322
  if (isNestedTable) {
1178
- return rows.join(' \\\\ ');
1323
+ return rows.join(" \\\\ ");
1179
1324
  }
1180
1325
 
1181
1326
  // Nếu mtable nằm trong mrow với dấu ngoặc vuông, sẽ được xử lý ở mrow
1182
1327
  let isInsideSquareBrackets = false;
1183
1328
  parent = node.parentNode;
1184
1329
  while (parent) {
1185
- if (NodeTool.getNodeName(parent) === 'mrow') {
1330
+ if (NodeTool.getNodeName(parent) === "mrow") {
1186
1331
  const childrenOfParent = Array.from(NodeTool.getChildren(parent));
1187
- if (childrenOfParent.length >= 2 &&
1188
- NodeTool.getNodeName(childrenOfParent[0]) === 'mo' &&
1189
- NodeTool.getNodeText(childrenOfParent[0]).trim() === '[') {
1332
+ if (
1333
+ childrenOfParent.length >= 2 &&
1334
+ NodeTool.getNodeName(childrenOfParent[0]) === "mo" &&
1335
+ NodeTool.getNodeText(childrenOfParent[0]).trim() === "["
1336
+ ) {
1190
1337
  isInsideSquareBrackets = true;
1191
1338
  break;
1192
1339
  }
@@ -1195,151 +1342,166 @@
1195
1342
  }
1196
1343
 
1197
1344
  if (isInsideSquareBrackets) {
1198
- return rows.join(' \\\\ ');
1345
+ return rows.join(" \\\\ ");
1199
1346
  }
1200
1347
 
1201
1348
  // Nếu là mtable chính, bao bọc trong \begin{array}...\end{array}
1202
- const arrayContent = rows.join(' \\\\ ');
1349
+ const arrayContent = rows.join(" \\\\ ");
1203
1350
  return `\\begin{array}{l} ${arrayContent} \\end{array}`;
1204
1351
  };
1205
1352
  break;
1206
1353
 
1207
- case 'mtr':
1354
+ case "mtr":
1208
1355
  render = getRender_joinSeparator("@content", " & ");
1209
1356
  break;
1210
1357
 
1211
- case 'mtd':
1358
+ case "mtd":
1212
1359
  render = getRender_joinSeparator("@content");
1213
1360
  break;
1214
1361
 
1215
- case 'mfrac':
1362
+ case "mfrac":
1216
1363
  render = function (node, children) {
1217
1364
  const childrenArray = Array.from(children);
1218
- if (!childrenArray || childrenArray.length < 2) return '';
1365
+ if (!childrenArray || childrenArray.length < 2) return "";
1219
1366
  const num = parse(childrenArray[0]);
1220
1367
  const den = parse(childrenArray[1]);
1221
- const linethickness = NodeTool.getAttr(node, 'linethickness', 'medium');
1222
- if (linethickness === '0') return `\\binom{${num}}{${den}}`;
1368
+ const linethickness = NodeTool.getAttr(node, "linethickness", "medium");
1369
+ if (linethickness === "0") return `\\binom{${num}}{${den}}`;
1223
1370
  return `\\frac{${num}}{${den}}`;
1224
1371
  };
1225
1372
  break;
1226
1373
 
1227
- case 'mfenced':
1374
+ case "mfenced":
1228
1375
  render = function (node, children) {
1229
1376
  const childrenArray = Array.from(children);
1230
- const open = NodeTool.getAttr(node, 'open', '(');
1231
- const close = NodeTool.getAttr(node, 'close', ')');
1232
- const separators = NodeTool.getAttr(node, 'separators', ',').split('');
1377
+ const open = NodeTool.getAttr(node, "open", "(");
1378
+ const close = NodeTool.getAttr(node, "close", ")");
1379
+ const separators = NodeTool.getAttr(node, "separators", ",").split("");
1233
1380
 
1234
1381
  // Xử lý đặc biệt cho trường hợp dấu ngoặc đơn |
1235
- if (open === '|') {
1236
- const content = childrenArray.map(child => {
1237
- const parsed = parse(child);
1238
- // Loại bỏ các dấu | thừa và các \left|, \right| không cần thiết
1239
- return parsed
1240
- .replace(/\\left\|/g, '')
1241
- .replace(/\\right\|/g, '')
1242
- .replace(/\\left\./g, '')
1243
- .replace(/\|/g, '');
1244
- }).join('');
1245
-
1382
+ if (open === "|") {
1383
+ const content = childrenArray
1384
+ .map((child) => {
1385
+ const parsed = parse(child);
1386
+ // Loại bỏ các dấu | thừa và các \left|, \right| không cần thiết
1387
+ return parsed
1388
+ .replace(/\\left\|/g, "")
1389
+ .replace(/\\right\|/g, "")
1390
+ .replace(/\\left\./g, "")
1391
+ .replace(/\|/g, "");
1392
+ })
1393
+ .join("");
1394
+
1246
1395
  if (!close) {
1247
1396
  return `\\left|${content}\\right|`;
1248
- } else if (close === '|') {
1397
+ } else if (close === "|") {
1249
1398
  return `\\left|${content}\\right|`;
1250
1399
  }
1251
1400
  }
1252
1401
 
1253
1402
  // Xử lý đặc biệt cho mfenced chứa mtable
1254
- if (open === '{' && !close) {
1403
+ if (open === "{" && !close) {
1255
1404
  // Kiểm tra xem có phải là một phần của biểu thức mũ không
1256
- const hasMtable = childrenArray.some(child => {
1405
+ const hasMtable = childrenArray.some((child) => {
1257
1406
  // Kiểm tra trực tiếp mtable
1258
- if (NodeTool.getNodeName(child) === 'mtable') return true;
1407
+ if (NodeTool.getNodeName(child) === "mtable") return true;
1259
1408
  // Kiểm tra mtable trong mrow
1260
- if (NodeTool.getNodeName(child) === 'mrow') {
1409
+ if (NodeTool.getNodeName(child) === "mrow") {
1261
1410
  return Array.from(NodeTool.getChildren(child)).some(
1262
- grandChild => NodeTool.getNodeName(grandChild) === 'mtable'
1411
+ (grandChild) => NodeTool.getNodeName(grandChild) === "mtable"
1263
1412
  );
1264
1413
  }
1265
1414
  return false;
1266
1415
  });
1267
1416
 
1268
1417
  if (hasMtable) {
1269
- const content = childrenArray.map(child => parse(child)).join('');
1418
+ const content = childrenArray.map((child) => parse(child)).join("");
1270
1419
  return `\\left\\{${content}\\right.`;
1271
1420
  }
1272
1421
  }
1273
1422
 
1274
1423
  // Xử lý cho trường hợp [a;b)
1275
- if (open === '[' && close === ')') {
1424
+ if (open === "[" && close === ")") {
1276
1425
  const parts = [];
1277
1426
  childrenArray.forEach((child, index) => {
1278
1427
  parts.push(parse(child));
1279
- if (index < childrenArray.length - 1 && separators[index % separators.length]) {
1428
+ if (
1429
+ index < childrenArray.length - 1 &&
1430
+ separators[index % separators.length]
1431
+ ) {
1280
1432
  parts.push(separators[index % separators.length]);
1281
1433
  }
1282
1434
  });
1283
- return `\\left[${parts.join('')}\\right)`;
1435
+ return `\\left[${parts.join("")}\\right)`;
1284
1436
  }
1285
1437
 
1286
1438
  // Giữ nguyên xử lý cho các trường hợp khác
1287
1439
  const parts = [];
1288
1440
  childrenArray.forEach((child, index) => {
1289
1441
  parts.push(parse(child));
1290
- if (index < childrenArray.length - 1 && separators[index % separators.length]) {
1442
+ if (
1443
+ index < childrenArray.length - 1 &&
1444
+ separators[index % separators.length]
1445
+ ) {
1291
1446
  parts.push(separators[index % separators.length]);
1292
1447
  }
1293
1448
  });
1294
- const content = parts.join('');
1449
+ const content = parts.join("");
1295
1450
 
1296
- if (open === '{' && close === '}') return `\\{${content}\\}`;
1297
- if (open === '|' && close === '|') return `\\left|${content}\\right|`;
1451
+ if (open === "{" && close === "}") return `\\{${content}\\}`;
1452
+ if (open === "|" && close === "|") return `\\left|${content}\\right|`;
1298
1453
  if (!close) return `\\left${open}${content}\\right.`;
1299
1454
  if (!open) return `\\left.${content}\\right${close}`;
1300
1455
  return `\\left${open}${content}\\right${close}`;
1301
1456
  };
1302
1457
  break;
1303
1458
 
1304
- case 'menclose':
1459
+ case "menclose":
1305
1460
  render = function (node, children) {
1306
1461
  const childrenArray = Array.from(children);
1307
- const notation = NodeTool.getAttr(node, 'notation', 'longdiv');
1308
- const content = renderChildren(childrenArray).join('');
1462
+ const notation = NodeTool.getAttr(node, "notation", "longdiv");
1463
+ const content = renderChildren(childrenArray).join("");
1309
1464
  switch (notation) {
1310
- case 'box': return `\\boxed{${content}}`;
1311
- case 'circle': return `\\enclose{circle}{${content}}`;
1312
- case 'roundedbox': return `\\fbox{${content}}`;
1313
- default: return content;
1465
+ case "box":
1466
+ return `\\boxed{${content}}`;
1467
+ case "circle":
1468
+ return `\\enclose{circle}{${content}}`;
1469
+ case "roundedbox":
1470
+ return `\\fbox{${content}}`;
1471
+ default:
1472
+ return content;
1314
1473
  }
1315
1474
  };
1316
1475
  break;
1317
1476
 
1318
- case 'mi':
1319
- case 'mn':
1320
- case 'mo':
1321
- case 'ms':
1322
- case 'mtext':
1477
+ case "mi":
1478
+ case "mn":
1479
+ case "mo":
1480
+ case "ms":
1481
+ case "mtext":
1323
1482
  render = getRender_joinSeparator("@content");
1324
1483
  break;
1325
1484
 
1326
- case 'mphantom':
1485
+ case "mphantom":
1327
1486
  render = function (node, children) {
1328
1487
  const childrenArray = Array.from(children);
1329
- const content = renderChildren(childrenArray).join('');
1488
+ const content = renderChildren(childrenArray).join("");
1330
1489
  return `\\phantom{${content}}`;
1331
1490
  };
1332
1491
  break;
1333
1492
 
1334
- case 'mstyle':
1493
+ case "mstyle":
1335
1494
  render = function (node, children) {
1336
1495
  const childrenArray = Array.from(children);
1337
- const mathsize = NodeTool.getAttr(node, 'mathsize', 'normal');
1338
- const content = renderChildren(childrenArray).join('');
1496
+ const mathsize = NodeTool.getAttr(node, "mathsize", "normal");
1497
+ const content = renderChildren(childrenArray).join("");
1339
1498
  switch (mathsize) {
1340
- case 'big': return `\\large{${content}}`;
1341
- case 'small': return `\\small{${content}}`;
1342
- default: return content;
1499
+ case "big":
1500
+ return `\\large{${content}}`;
1501
+ case "small":
1502
+ return `\\small{${content}}`;
1503
+ default:
1504
+ return content;
1343
1505
  }
1344
1506
  };
1345
1507
  break;
@@ -1353,7 +1515,7 @@
1353
1515
 
1354
1516
  // Export the convert function
1355
1517
  var mathml2latex = {
1356
- convert: convert
1518
+ convert: convert,
1357
1519
  };
1358
1520
 
1359
1521
  return mathml2latex;