ed-mathml2tex 0.0.3 → 0.0.5

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.
@@ -617,20 +617,12 @@ function getRender_joinSeparators(template, separators) {
617
617
 
618
618
  function convert(mathmlHtml){
619
619
  const math = NodeTool.parseMath(mathmlHtml);
620
-
621
- // Debug input
622
- console.log("Converting MathML:", mathmlHtml);
623
-
624
620
  let result = toLatex(parse(math));
625
621
 
626
622
  // Last-chance post-processing for specific patterns
627
623
  if (mathmlHtml.includes("<munder>") &&
628
624
  mathmlHtml.includes("<mo>→</mo>") &&
629
625
  mathmlHtml.includes("<mrow/>")) {
630
-
631
- console.log("Found specific pattern, forcing correct output");
632
-
633
- // Look for arrow with limits in the result
634
626
  if (result.includes("\\limits")) {
635
627
  result = "\\underset{}{\\rightarrow}";
636
628
  }
@@ -816,7 +808,6 @@ function renderChildren(children) {
816
808
  if(Brackets.contains(op)){
817
809
  let stretchy = NodeTool.getAttr(node, 'stretchy', 'true');
818
810
  stretchy = ['', 'true'].indexOf(stretchy) > -1;
819
- // 操作符是括號
820
811
  if(Brackets.isRight(op)){
821
812
  const nearLeft = lefts[lefts.length - 1];
822
813
  if(nearLeft){
@@ -824,21 +815,15 @@ function renderChildren(children) {
824
815
  parts.push(Brackets.parseRight(op, stretchy));
825
816
  lefts.pop();
826
817
  } else {
827
- // some brackets left side is same as right side.
828
818
  if(Brackets.isLeft(op)) {
829
819
  parts.push(Brackets.parseLeft(op, stretchy));
830
820
  lefts.push(op);
831
- } else {
832
- console.error("bracket not match");
833
821
  }
834
822
  }
835
823
  }else {
836
- // some brackets left side is same as right side.
837
824
  if(Brackets.isLeft(op)) {
838
825
  parts.push(Brackets.parseLeft(op, stretchy));
839
826
  lefts.push(op);
840
- }else {
841
- console.error("bracket not match");
842
827
  }
843
828
  }
844
829
  } else {
@@ -852,7 +837,6 @@ function renderChildren(children) {
852
837
  parts.push(parse(node));
853
838
  }
854
839
  });
855
- // 這裏非常不嚴謹
856
840
  if(lefts.length > 0){
857
841
  for(let i=0; i < lefts.length; i++){
858
842
  parts.push("\\right.");
@@ -1044,50 +1028,57 @@ function renderMmultiscripts(node, children) {
1044
1028
  }
1045
1029
 
1046
1030
  function renderMover(node, children) {
1047
- const nodes = flattenNodeTreeByNodeName(node, 'mover');
1048
- let result = undefined;
1049
-
1050
- // Get the base node and check if it's a subscript or mrow
1051
- const baseNode = children[0];
1052
- const nodeName = NodeTool.getNodeName(baseNode);
1053
- const isSubscript = nodeName === 'msub';
1054
- const isMrow = nodeName === 'mrow';
1055
-
1056
- if (isSubscript) {
1057
- // Handle case like n₂ with arrow
1058
- const base = parse(baseNode);
1059
- return `\\overrightarrow{${base}}`;
1060
- }
1061
-
1062
- if (isMrow) {
1063
- // Handle case like AB or AI
1064
- const base = parse(baseNode);
1065
- const overNode = children[1];
1066
- const overText = NodeTool.getNodeText(overNode).trim();
1067
- const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1068
-
1069
- if (overText === "→" && isAccent) {
1070
- return `\\overrightarrow{${base}}`;
1031
+ const nodes = flattenNodeTreeByNodeName(node, 'mover');
1032
+ let result = undefined;
1033
+
1034
+ // Get the base node and check if it's a subscript or mrow
1035
+ const baseNode = children[0];
1036
+ const nodeName = NodeTool.getNodeName(baseNode);
1037
+ const isSubscript = nodeName === 'msub';
1038
+ const isMrow = nodeName === 'mrow';
1039
+
1040
+ if (isSubscript) {
1041
+ // Handle case like n₂ with arrow
1042
+ const base = parse(baseNode);
1043
+ return `\\overrightarrow{${base}}`;
1071
1044
  }
1072
- }
1073
-
1074
- for(let i = 0; i < nodes.length - 1; i++) {
1075
- if(!result) {
1076
- result = parse(nodes[i]);
1045
+
1046
+ if (isMrow) {
1047
+ // Handle case like 0 with arrow
1048
+ const base = parse(baseNode);
1049
+ const overNode = children[1];
1050
+ const overText = NodeTool.getNodeText(overNode).trim();
1051
+ const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1052
+
1053
+ if (overText === "→" && isAccent) {
1054
+ return `\\overrightarrow{${base}}`;
1055
+ }
1077
1056
  }
1078
-
1079
- const overNode = nodes[i + 1];
1057
+
1058
+ // Handle case where there is no base (like your example with just 0 and an arrow)
1059
+ const overNode = children[1];
1080
1060
  const overText = NodeTool.getNodeText(overNode).trim();
1081
- const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1082
-
1083
- if (overText === "→" && isAccent) {
1084
- return `\\overrightarrow{${result}}`;
1061
+ if (overText === "") {
1062
+ return `\\overrightarrow{0}`;
1085
1063
  }
1086
-
1087
- const over = parse(overNode);
1088
- result = `${result}^{${over}}`;
1089
- }
1090
- return result;
1064
+
1065
+ for (let i = 0; i < nodes.length - 1; i++) {
1066
+ if (!result) {
1067
+ result = parse(nodes[i]);
1068
+ }
1069
+
1070
+ const overNode = nodes[i + 1];
1071
+ const overText = NodeTool.getNodeText(overNode).trim();
1072
+ const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1073
+
1074
+ if (overText === "→" && isAccent) {
1075
+ return `\\overrightarrow{${result}}`;
1076
+ }
1077
+
1078
+ const over = parse(overNode);
1079
+ result = `${result}^{${over}}`;
1080
+ }
1081
+ return result;
1091
1082
  }
1092
1083
 
1093
1084
  function renderMunder(node, children){
@@ -615,20 +615,12 @@ function getRender_joinSeparators(template, separators) {
615
615
 
616
616
  function convert(mathmlHtml){
617
617
  const math = NodeTool.parseMath(mathmlHtml);
618
-
619
- // Debug input
620
- console.log("Converting MathML:", mathmlHtml);
621
-
622
618
  let result = toLatex(parse(math));
623
619
 
624
620
  // Last-chance post-processing for specific patterns
625
621
  if (mathmlHtml.includes("<munder>") &&
626
622
  mathmlHtml.includes("<mo>→</mo>") &&
627
623
  mathmlHtml.includes("<mrow/>")) {
628
-
629
- console.log("Found specific pattern, forcing correct output");
630
-
631
- // Look for arrow with limits in the result
632
624
  if (result.includes("\\limits")) {
633
625
  result = "\\underset{}{\\rightarrow}";
634
626
  }
@@ -814,7 +806,6 @@ function renderChildren(children) {
814
806
  if(Brackets.contains(op)){
815
807
  let stretchy = NodeTool.getAttr(node, 'stretchy', 'true');
816
808
  stretchy = ['', 'true'].indexOf(stretchy) > -1;
817
- // 操作符是括號
818
809
  if(Brackets.isRight(op)){
819
810
  const nearLeft = lefts[lefts.length - 1];
820
811
  if(nearLeft){
@@ -822,21 +813,15 @@ function renderChildren(children) {
822
813
  parts.push(Brackets.parseRight(op, stretchy));
823
814
  lefts.pop();
824
815
  } else {
825
- // some brackets left side is same as right side.
826
816
  if(Brackets.isLeft(op)) {
827
817
  parts.push(Brackets.parseLeft(op, stretchy));
828
818
  lefts.push(op);
829
- } else {
830
- console.error("bracket not match");
831
819
  }
832
820
  }
833
821
  }else {
834
- // some brackets left side is same as right side.
835
822
  if(Brackets.isLeft(op)) {
836
823
  parts.push(Brackets.parseLeft(op, stretchy));
837
824
  lefts.push(op);
838
- }else {
839
- console.error("bracket not match");
840
825
  }
841
826
  }
842
827
  } else {
@@ -850,7 +835,6 @@ function renderChildren(children) {
850
835
  parts.push(parse(node));
851
836
  }
852
837
  });
853
- // 這裏非常不嚴謹
854
838
  if(lefts.length > 0){
855
839
  for(let i=0; i < lefts.length; i++){
856
840
  parts.push("\\right.");
@@ -1042,50 +1026,57 @@ function renderMmultiscripts(node, children) {
1042
1026
  }
1043
1027
 
1044
1028
  function renderMover(node, children) {
1045
- const nodes = flattenNodeTreeByNodeName(node, 'mover');
1046
- let result = undefined;
1047
-
1048
- // Get the base node and check if it's a subscript or mrow
1049
- const baseNode = children[0];
1050
- const nodeName = NodeTool.getNodeName(baseNode);
1051
- const isSubscript = nodeName === 'msub';
1052
- const isMrow = nodeName === 'mrow';
1053
-
1054
- if (isSubscript) {
1055
- // Handle case like n₂ with arrow
1056
- const base = parse(baseNode);
1057
- return `\\overrightarrow{${base}}`;
1058
- }
1059
-
1060
- if (isMrow) {
1061
- // Handle case like AB or AI
1062
- const base = parse(baseNode);
1063
- const overNode = children[1];
1064
- const overText = NodeTool.getNodeText(overNode).trim();
1065
- const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1066
-
1067
- if (overText === "→" && isAccent) {
1068
- return `\\overrightarrow{${base}}`;
1029
+ const nodes = flattenNodeTreeByNodeName(node, 'mover');
1030
+ let result = undefined;
1031
+
1032
+ // Get the base node and check if it's a subscript or mrow
1033
+ const baseNode = children[0];
1034
+ const nodeName = NodeTool.getNodeName(baseNode);
1035
+ const isSubscript = nodeName === 'msub';
1036
+ const isMrow = nodeName === 'mrow';
1037
+
1038
+ if (isSubscript) {
1039
+ // Handle case like n₂ with arrow
1040
+ const base = parse(baseNode);
1041
+ return `\\overrightarrow{${base}}`;
1069
1042
  }
1070
- }
1071
-
1072
- for(let i = 0; i < nodes.length - 1; i++) {
1073
- if(!result) {
1074
- result = parse(nodes[i]);
1043
+
1044
+ if (isMrow) {
1045
+ // Handle case like 0 with arrow
1046
+ const base = parse(baseNode);
1047
+ const overNode = children[1];
1048
+ const overText = NodeTool.getNodeText(overNode).trim();
1049
+ const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1050
+
1051
+ if (overText === "→" && isAccent) {
1052
+ return `\\overrightarrow{${base}}`;
1053
+ }
1075
1054
  }
1076
-
1077
- const overNode = nodes[i + 1];
1055
+
1056
+ // Handle case where there is no base (like your example with just 0 and an arrow)
1057
+ const overNode = children[1];
1078
1058
  const overText = NodeTool.getNodeText(overNode).trim();
1079
- const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1080
-
1081
- if (overText === "→" && isAccent) {
1082
- return `\\overrightarrow{${result}}`;
1059
+ if (overText === "") {
1060
+ return `\\overrightarrow{0}`;
1083
1061
  }
1084
-
1085
- const over = parse(overNode);
1086
- result = `${result}^{${over}}`;
1087
- }
1088
- return result;
1062
+
1063
+ for (let i = 0; i < nodes.length - 1; i++) {
1064
+ if (!result) {
1065
+ result = parse(nodes[i]);
1066
+ }
1067
+
1068
+ const overNode = nodes[i + 1];
1069
+ const overText = NodeTool.getNodeText(overNode).trim();
1070
+ const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1071
+
1072
+ if (overText === "→" && isAccent) {
1073
+ return `\\overrightarrow{${result}}`;
1074
+ }
1075
+
1076
+ const over = parse(overNode);
1077
+ result = `${result}^{${over}}`;
1078
+ }
1079
+ return result;
1089
1080
  }
1090
1081
 
1091
1082
  function renderMunder(node, children){
@@ -621,20 +621,12 @@
621
621
 
622
622
  function convert(mathmlHtml){
623
623
  const math = NodeTool.parseMath(mathmlHtml);
624
-
625
- // Debug input
626
- console.log("Converting MathML:", mathmlHtml);
627
-
628
624
  let result = toLatex(parse(math));
629
625
 
630
626
  // Last-chance post-processing for specific patterns
631
627
  if (mathmlHtml.includes("<munder>") &&
632
628
  mathmlHtml.includes("<mo>→</mo>") &&
633
629
  mathmlHtml.includes("<mrow/>")) {
634
-
635
- console.log("Found specific pattern, forcing correct output");
636
-
637
- // Look for arrow with limits in the result
638
630
  if (result.includes("\\limits")) {
639
631
  result = "\\underset{}{\\rightarrow}";
640
632
  }
@@ -820,7 +812,6 @@
820
812
  if(Brackets.contains(op)){
821
813
  let stretchy = NodeTool.getAttr(node, 'stretchy', 'true');
822
814
  stretchy = ['', 'true'].indexOf(stretchy) > -1;
823
- // 操作符是括號
824
815
  if(Brackets.isRight(op)){
825
816
  const nearLeft = lefts[lefts.length - 1];
826
817
  if(nearLeft){
@@ -828,21 +819,15 @@
828
819
  parts.push(Brackets.parseRight(op, stretchy));
829
820
  lefts.pop();
830
821
  } else {
831
- // some brackets left side is same as right side.
832
822
  if(Brackets.isLeft(op)) {
833
823
  parts.push(Brackets.parseLeft(op, stretchy));
834
824
  lefts.push(op);
835
- } else {
836
- console.error("bracket not match");
837
825
  }
838
826
  }
839
827
  }else {
840
- // some brackets left side is same as right side.
841
828
  if(Brackets.isLeft(op)) {
842
829
  parts.push(Brackets.parseLeft(op, stretchy));
843
830
  lefts.push(op);
844
- }else {
845
- console.error("bracket not match");
846
831
  }
847
832
  }
848
833
  } else {
@@ -856,7 +841,6 @@
856
841
  parts.push(parse(node));
857
842
  }
858
843
  });
859
- // 這裏非常不嚴謹
860
844
  if(lefts.length > 0){
861
845
  for(let i=0; i < lefts.length; i++){
862
846
  parts.push("\\right.");
@@ -1048,50 +1032,57 @@
1048
1032
  }
1049
1033
 
1050
1034
  function renderMover(node, children) {
1051
- const nodes = flattenNodeTreeByNodeName(node, 'mover');
1052
- let result = undefined;
1053
-
1054
- // Get the base node and check if it's a subscript or mrow
1055
- const baseNode = children[0];
1056
- const nodeName = NodeTool.getNodeName(baseNode);
1057
- const isSubscript = nodeName === 'msub';
1058
- const isMrow = nodeName === 'mrow';
1059
-
1060
- if (isSubscript) {
1061
- // Handle case like n₂ with arrow
1062
- const base = parse(baseNode);
1063
- return `\\overrightarrow{${base}}`;
1064
- }
1065
-
1066
- if (isMrow) {
1067
- // Handle case like AB or AI
1068
- const base = parse(baseNode);
1069
- const overNode = children[1];
1070
- const overText = NodeTool.getNodeText(overNode).trim();
1071
- const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1072
-
1073
- if (overText === "→" && isAccent) {
1074
- return `\\overrightarrow{${base}}`;
1035
+ const nodes = flattenNodeTreeByNodeName(node, 'mover');
1036
+ let result = undefined;
1037
+
1038
+ // Get the base node and check if it's a subscript or mrow
1039
+ const baseNode = children[0];
1040
+ const nodeName = NodeTool.getNodeName(baseNode);
1041
+ const isSubscript = nodeName === 'msub';
1042
+ const isMrow = nodeName === 'mrow';
1043
+
1044
+ if (isSubscript) {
1045
+ // Handle case like n₂ with arrow
1046
+ const base = parse(baseNode);
1047
+ return `\\overrightarrow{${base}}`;
1075
1048
  }
1076
- }
1077
-
1078
- for(let i = 0; i < nodes.length - 1; i++) {
1079
- if(!result) {
1080
- result = parse(nodes[i]);
1049
+
1050
+ if (isMrow) {
1051
+ // Handle case like 0 with arrow
1052
+ const base = parse(baseNode);
1053
+ const overNode = children[1];
1054
+ const overText = NodeTool.getNodeText(overNode).trim();
1055
+ const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1056
+
1057
+ if (overText === "→" && isAccent) {
1058
+ return `\\overrightarrow{${base}}`;
1059
+ }
1081
1060
  }
1082
-
1083
- const overNode = nodes[i + 1];
1061
+
1062
+ // Handle case where there is no base (like your example with just 0 and an arrow)
1063
+ const overNode = children[1];
1084
1064
  const overText = NodeTool.getNodeText(overNode).trim();
1085
- const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1086
-
1087
- if (overText === "→" && isAccent) {
1088
- return `\\overrightarrow{${result}}`;
1065
+ if (overText === "") {
1066
+ return `\\overrightarrow{0}`;
1089
1067
  }
1090
-
1091
- const over = parse(overNode);
1092
- result = `${result}^{${over}}`;
1093
- }
1094
- return result;
1068
+
1069
+ for (let i = 0; i < nodes.length - 1; i++) {
1070
+ if (!result) {
1071
+ result = parse(nodes[i]);
1072
+ }
1073
+
1074
+ const overNode = nodes[i + 1];
1075
+ const overText = NodeTool.getNodeText(overNode).trim();
1076
+ const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1077
+
1078
+ if (overText === "→" && isAccent) {
1079
+ return `\\overrightarrow{${result}}`;
1080
+ }
1081
+
1082
+ const over = parse(overNode);
1083
+ result = `${result}^{${over}}`;
1084
+ }
1085
+ return result;
1095
1086
  }
1096
1087
 
1097
1088
  function renderMunder(node, children){
@@ -617,20 +617,12 @@ function getRender_joinSeparators(template, separators) {
617
617
 
618
618
  function convert(mathmlHtml){
619
619
  const math = NodeTool.parseMath(mathmlHtml);
620
-
621
- // Debug input
622
- console.log("Converting MathML:", mathmlHtml);
623
-
624
620
  let result = toLatex(parse(math));
625
621
 
626
622
  // Last-chance post-processing for specific patterns
627
623
  if (mathmlHtml.includes("<munder>") &&
628
624
  mathmlHtml.includes("<mo>→</mo>") &&
629
625
  mathmlHtml.includes("<mrow/>")) {
630
-
631
- console.log("Found specific pattern, forcing correct output");
632
-
633
- // Look for arrow with limits in the result
634
626
  if (result.includes("\\limits")) {
635
627
  result = "\\underset{}{\\rightarrow}";
636
628
  }
@@ -816,7 +808,6 @@ function renderChildren(children) {
816
808
  if(Brackets.contains(op)){
817
809
  let stretchy = NodeTool.getAttr(node, 'stretchy', 'true');
818
810
  stretchy = ['', 'true'].indexOf(stretchy) > -1;
819
- // 操作符是括號
820
811
  if(Brackets.isRight(op)){
821
812
  const nearLeft = lefts[lefts.length - 1];
822
813
  if(nearLeft){
@@ -824,21 +815,15 @@ function renderChildren(children) {
824
815
  parts.push(Brackets.parseRight(op, stretchy));
825
816
  lefts.pop();
826
817
  } else {
827
- // some brackets left side is same as right side.
828
818
  if(Brackets.isLeft(op)) {
829
819
  parts.push(Brackets.parseLeft(op, stretchy));
830
820
  lefts.push(op);
831
- } else {
832
- console.error("bracket not match");
833
821
  }
834
822
  }
835
823
  }else {
836
- // some brackets left side is same as right side.
837
824
  if(Brackets.isLeft(op)) {
838
825
  parts.push(Brackets.parseLeft(op, stretchy));
839
826
  lefts.push(op);
840
- }else {
841
- console.error("bracket not match");
842
827
  }
843
828
  }
844
829
  } else {
@@ -852,7 +837,6 @@ function renderChildren(children) {
852
837
  parts.push(parse(node));
853
838
  }
854
839
  });
855
- // 這裏非常不嚴謹
856
840
  if(lefts.length > 0){
857
841
  for(let i=0; i < lefts.length; i++){
858
842
  parts.push("\\right.");
@@ -1044,50 +1028,57 @@ function renderMmultiscripts(node, children) {
1044
1028
  }
1045
1029
 
1046
1030
  function renderMover(node, children) {
1047
- const nodes = flattenNodeTreeByNodeName(node, 'mover');
1048
- let result = undefined;
1049
-
1050
- // Get the base node and check if it's a subscript or mrow
1051
- const baseNode = children[0];
1052
- const nodeName = NodeTool.getNodeName(baseNode);
1053
- const isSubscript = nodeName === 'msub';
1054
- const isMrow = nodeName === 'mrow';
1055
-
1056
- if (isSubscript) {
1057
- // Handle case like n₂ with arrow
1058
- const base = parse(baseNode);
1059
- return `\\overrightarrow{${base}}`;
1060
- }
1061
-
1062
- if (isMrow) {
1063
- // Handle case like AB or AI
1064
- const base = parse(baseNode);
1065
- const overNode = children[1];
1066
- const overText = NodeTool.getNodeText(overNode).trim();
1067
- const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1068
-
1069
- if (overText === "→" && isAccent) {
1070
- return `\\overrightarrow{${base}}`;
1031
+ const nodes = flattenNodeTreeByNodeName(node, 'mover');
1032
+ let result = undefined;
1033
+
1034
+ // Get the base node and check if it's a subscript or mrow
1035
+ const baseNode = children[0];
1036
+ const nodeName = NodeTool.getNodeName(baseNode);
1037
+ const isSubscript = nodeName === 'msub';
1038
+ const isMrow = nodeName === 'mrow';
1039
+
1040
+ if (isSubscript) {
1041
+ // Handle case like n₂ with arrow
1042
+ const base = parse(baseNode);
1043
+ return `\\overrightarrow{${base}}`;
1071
1044
  }
1072
- }
1073
-
1074
- for(let i = 0; i < nodes.length - 1; i++) {
1075
- if(!result) {
1076
- result = parse(nodes[i]);
1045
+
1046
+ if (isMrow) {
1047
+ // Handle case like 0 with arrow
1048
+ const base = parse(baseNode);
1049
+ const overNode = children[1];
1050
+ const overText = NodeTool.getNodeText(overNode).trim();
1051
+ const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1052
+
1053
+ if (overText === "→" && isAccent) {
1054
+ return `\\overrightarrow{${base}}`;
1055
+ }
1077
1056
  }
1078
-
1079
- const overNode = nodes[i + 1];
1057
+
1058
+ // Handle case where there is no base (like your example with just 0 and an arrow)
1059
+ const overNode = children[1];
1080
1060
  const overText = NodeTool.getNodeText(overNode).trim();
1081
- const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1082
-
1083
- if (overText === "→" && isAccent) {
1084
- return `\\overrightarrow{${result}}`;
1061
+ if (overText === "") {
1062
+ return `\\overrightarrow{0}`;
1085
1063
  }
1086
-
1087
- const over = parse(overNode);
1088
- result = `${result}^{${over}}`;
1089
- }
1090
- return result;
1064
+
1065
+ for (let i = 0; i < nodes.length - 1; i++) {
1066
+ if (!result) {
1067
+ result = parse(nodes[i]);
1068
+ }
1069
+
1070
+ const overNode = nodes[i + 1];
1071
+ const overText = NodeTool.getNodeText(overNode).trim();
1072
+ const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1073
+
1074
+ if (overText === "→" && isAccent) {
1075
+ return `\\overrightarrow{${result}}`;
1076
+ }
1077
+
1078
+ const over = parse(overNode);
1079
+ result = `${result}^{${over}}`;
1080
+ }
1081
+ return result;
1091
1082
  }
1092
1083
 
1093
1084
  function renderMunder(node, children){
@@ -615,20 +615,12 @@ function getRender_joinSeparators(template, separators) {
615
615
 
616
616
  function convert(mathmlHtml){
617
617
  const math = NodeTool.parseMath(mathmlHtml);
618
-
619
- // Debug input
620
- console.log("Converting MathML:", mathmlHtml);
621
-
622
618
  let result = toLatex(parse(math));
623
619
 
624
620
  // Last-chance post-processing for specific patterns
625
621
  if (mathmlHtml.includes("<munder>") &&
626
622
  mathmlHtml.includes("<mo>→</mo>") &&
627
623
  mathmlHtml.includes("<mrow/>")) {
628
-
629
- console.log("Found specific pattern, forcing correct output");
630
-
631
- // Look for arrow with limits in the result
632
624
  if (result.includes("\\limits")) {
633
625
  result = "\\underset{}{\\rightarrow}";
634
626
  }
@@ -814,7 +806,6 @@ function renderChildren(children) {
814
806
  if(Brackets.contains(op)){
815
807
  let stretchy = NodeTool.getAttr(node, 'stretchy', 'true');
816
808
  stretchy = ['', 'true'].indexOf(stretchy) > -1;
817
- // 操作符是括號
818
809
  if(Brackets.isRight(op)){
819
810
  const nearLeft = lefts[lefts.length - 1];
820
811
  if(nearLeft){
@@ -822,21 +813,15 @@ function renderChildren(children) {
822
813
  parts.push(Brackets.parseRight(op, stretchy));
823
814
  lefts.pop();
824
815
  } else {
825
- // some brackets left side is same as right side.
826
816
  if(Brackets.isLeft(op)) {
827
817
  parts.push(Brackets.parseLeft(op, stretchy));
828
818
  lefts.push(op);
829
- } else {
830
- console.error("bracket not match");
831
819
  }
832
820
  }
833
821
  }else {
834
- // some brackets left side is same as right side.
835
822
  if(Brackets.isLeft(op)) {
836
823
  parts.push(Brackets.parseLeft(op, stretchy));
837
824
  lefts.push(op);
838
- }else {
839
- console.error("bracket not match");
840
825
  }
841
826
  }
842
827
  } else {
@@ -850,7 +835,6 @@ function renderChildren(children) {
850
835
  parts.push(parse(node));
851
836
  }
852
837
  });
853
- // 這裏非常不嚴謹
854
838
  if(lefts.length > 0){
855
839
  for(let i=0; i < lefts.length; i++){
856
840
  parts.push("\\right.");
@@ -1042,50 +1026,57 @@ function renderMmultiscripts(node, children) {
1042
1026
  }
1043
1027
 
1044
1028
  function renderMover(node, children) {
1045
- const nodes = flattenNodeTreeByNodeName(node, 'mover');
1046
- let result = undefined;
1047
-
1048
- // Get the base node and check if it's a subscript or mrow
1049
- const baseNode = children[0];
1050
- const nodeName = NodeTool.getNodeName(baseNode);
1051
- const isSubscript = nodeName === 'msub';
1052
- const isMrow = nodeName === 'mrow';
1053
-
1054
- if (isSubscript) {
1055
- // Handle case like n₂ with arrow
1056
- const base = parse(baseNode);
1057
- return `\\overrightarrow{${base}}`;
1058
- }
1059
-
1060
- if (isMrow) {
1061
- // Handle case like AB or AI
1062
- const base = parse(baseNode);
1063
- const overNode = children[1];
1064
- const overText = NodeTool.getNodeText(overNode).trim();
1065
- const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1066
-
1067
- if (overText === "→" && isAccent) {
1068
- return `\\overrightarrow{${base}}`;
1029
+ const nodes = flattenNodeTreeByNodeName(node, 'mover');
1030
+ let result = undefined;
1031
+
1032
+ // Get the base node and check if it's a subscript or mrow
1033
+ const baseNode = children[0];
1034
+ const nodeName = NodeTool.getNodeName(baseNode);
1035
+ const isSubscript = nodeName === 'msub';
1036
+ const isMrow = nodeName === 'mrow';
1037
+
1038
+ if (isSubscript) {
1039
+ // Handle case like n₂ with arrow
1040
+ const base = parse(baseNode);
1041
+ return `\\overrightarrow{${base}}`;
1069
1042
  }
1070
- }
1071
-
1072
- for(let i = 0; i < nodes.length - 1; i++) {
1073
- if(!result) {
1074
- result = parse(nodes[i]);
1043
+
1044
+ if (isMrow) {
1045
+ // Handle case like 0 with arrow
1046
+ const base = parse(baseNode);
1047
+ const overNode = children[1];
1048
+ const overText = NodeTool.getNodeText(overNode).trim();
1049
+ const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1050
+
1051
+ if (overText === "→" && isAccent) {
1052
+ return `\\overrightarrow{${base}}`;
1053
+ }
1075
1054
  }
1076
-
1077
- const overNode = nodes[i + 1];
1055
+
1056
+ // Handle case where there is no base (like your example with just 0 and an arrow)
1057
+ const overNode = children[1];
1078
1058
  const overText = NodeTool.getNodeText(overNode).trim();
1079
- const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1080
-
1081
- if (overText === "→" && isAccent) {
1082
- return `\\overrightarrow{${result}}`;
1059
+ if (overText === "") {
1060
+ return `\\overrightarrow{0}`;
1083
1061
  }
1084
-
1085
- const over = parse(overNode);
1086
- result = `${result}^{${over}}`;
1087
- }
1088
- return result;
1062
+
1063
+ for (let i = 0; i < nodes.length - 1; i++) {
1064
+ if (!result) {
1065
+ result = parse(nodes[i]);
1066
+ }
1067
+
1068
+ const overNode = nodes[i + 1];
1069
+ const overText = NodeTool.getNodeText(overNode).trim();
1070
+ const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1071
+
1072
+ if (overText === "→" && isAccent) {
1073
+ return `\\overrightarrow{${result}}`;
1074
+ }
1075
+
1076
+ const over = parse(overNode);
1077
+ result = `${result}^{${over}}`;
1078
+ }
1079
+ return result;
1089
1080
  }
1090
1081
 
1091
1082
  function renderMunder(node, children){
@@ -621,20 +621,12 @@
621
621
 
622
622
  function convert(mathmlHtml){
623
623
  const math = NodeTool.parseMath(mathmlHtml);
624
-
625
- // Debug input
626
- console.log("Converting MathML:", mathmlHtml);
627
-
628
624
  let result = toLatex(parse(math));
629
625
 
630
626
  // Last-chance post-processing for specific patterns
631
627
  if (mathmlHtml.includes("<munder>") &&
632
628
  mathmlHtml.includes("<mo>→</mo>") &&
633
629
  mathmlHtml.includes("<mrow/>")) {
634
-
635
- console.log("Found specific pattern, forcing correct output");
636
-
637
- // Look for arrow with limits in the result
638
630
  if (result.includes("\\limits")) {
639
631
  result = "\\underset{}{\\rightarrow}";
640
632
  }
@@ -820,7 +812,6 @@
820
812
  if(Brackets.contains(op)){
821
813
  let stretchy = NodeTool.getAttr(node, 'stretchy', 'true');
822
814
  stretchy = ['', 'true'].indexOf(stretchy) > -1;
823
- // 操作符是括號
824
815
  if(Brackets.isRight(op)){
825
816
  const nearLeft = lefts[lefts.length - 1];
826
817
  if(nearLeft){
@@ -828,21 +819,15 @@
828
819
  parts.push(Brackets.parseRight(op, stretchy));
829
820
  lefts.pop();
830
821
  } else {
831
- // some brackets left side is same as right side.
832
822
  if(Brackets.isLeft(op)) {
833
823
  parts.push(Brackets.parseLeft(op, stretchy));
834
824
  lefts.push(op);
835
- } else {
836
- console.error("bracket not match");
837
825
  }
838
826
  }
839
827
  }else {
840
- // some brackets left side is same as right side.
841
828
  if(Brackets.isLeft(op)) {
842
829
  parts.push(Brackets.parseLeft(op, stretchy));
843
830
  lefts.push(op);
844
- }else {
845
- console.error("bracket not match");
846
831
  }
847
832
  }
848
833
  } else {
@@ -856,7 +841,6 @@
856
841
  parts.push(parse(node));
857
842
  }
858
843
  });
859
- // 這裏非常不嚴謹
860
844
  if(lefts.length > 0){
861
845
  for(let i=0; i < lefts.length; i++){
862
846
  parts.push("\\right.");
@@ -1048,50 +1032,57 @@
1048
1032
  }
1049
1033
 
1050
1034
  function renderMover(node, children) {
1051
- const nodes = flattenNodeTreeByNodeName(node, 'mover');
1052
- let result = undefined;
1053
-
1054
- // Get the base node and check if it's a subscript or mrow
1055
- const baseNode = children[0];
1056
- const nodeName = NodeTool.getNodeName(baseNode);
1057
- const isSubscript = nodeName === 'msub';
1058
- const isMrow = nodeName === 'mrow';
1059
-
1060
- if (isSubscript) {
1061
- // Handle case like n₂ with arrow
1062
- const base = parse(baseNode);
1063
- return `\\overrightarrow{${base}}`;
1064
- }
1065
-
1066
- if (isMrow) {
1067
- // Handle case like AB or AI
1068
- const base = parse(baseNode);
1069
- const overNode = children[1];
1070
- const overText = NodeTool.getNodeText(overNode).trim();
1071
- const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1072
-
1073
- if (overText === "→" && isAccent) {
1074
- return `\\overrightarrow{${base}}`;
1035
+ const nodes = flattenNodeTreeByNodeName(node, 'mover');
1036
+ let result = undefined;
1037
+
1038
+ // Get the base node and check if it's a subscript or mrow
1039
+ const baseNode = children[0];
1040
+ const nodeName = NodeTool.getNodeName(baseNode);
1041
+ const isSubscript = nodeName === 'msub';
1042
+ const isMrow = nodeName === 'mrow';
1043
+
1044
+ if (isSubscript) {
1045
+ // Handle case like n₂ with arrow
1046
+ const base = parse(baseNode);
1047
+ return `\\overrightarrow{${base}}`;
1075
1048
  }
1076
- }
1077
-
1078
- for(let i = 0; i < nodes.length - 1; i++) {
1079
- if(!result) {
1080
- result = parse(nodes[i]);
1049
+
1050
+ if (isMrow) {
1051
+ // Handle case like 0 with arrow
1052
+ const base = parse(baseNode);
1053
+ const overNode = children[1];
1054
+ const overText = NodeTool.getNodeText(overNode).trim();
1055
+ const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1056
+
1057
+ if (overText === "→" && isAccent) {
1058
+ return `\\overrightarrow{${base}}`;
1059
+ }
1081
1060
  }
1082
-
1083
- const overNode = nodes[i + 1];
1061
+
1062
+ // Handle case where there is no base (like your example with just 0 and an arrow)
1063
+ const overNode = children[1];
1084
1064
  const overText = NodeTool.getNodeText(overNode).trim();
1085
- const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1086
-
1087
- if (overText === "→" && isAccent) {
1088
- return `\\overrightarrow{${result}}`;
1065
+ if (overText === "") {
1066
+ return `\\overrightarrow{0}`;
1089
1067
  }
1090
-
1091
- const over = parse(overNode);
1092
- result = `${result}^{${over}}`;
1093
- }
1094
- return result;
1068
+
1069
+ for (let i = 0; i < nodes.length - 1; i++) {
1070
+ if (!result) {
1071
+ result = parse(nodes[i]);
1072
+ }
1073
+
1074
+ const overNode = nodes[i + 1];
1075
+ const overText = NodeTool.getNodeText(overNode).trim();
1076
+ const isAccent = NodeTool.getAttr(node, "accent", "false") === "true";
1077
+
1078
+ if (overText === "→" && isAccent) {
1079
+ return `\\overrightarrow{${result}}`;
1080
+ }
1081
+
1082
+ const over = parse(overNode);
1083
+ result = `${result}^{${over}}`;
1084
+ }
1085
+ return result;
1095
1086
  }
1096
1087
 
1097
1088
  function renderMunder(node, children){
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ed-mathml2tex",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "Convert mathml to latex.",
5
5
  "author": "Mika",
6
6
  "license": "MIT",