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.
- package/lib/mathml2latex.browser.cjs.js +47 -56
- package/lib/mathml2latex.browser.es.js +47 -56
- package/lib/mathml2latex.browser.umd.js +47 -56
- package/lib/mathml2latex.cjs.js +47 -56
- package/lib/mathml2latex.es.js +47 -56
- package/lib/mathml2latex.umd.js +47 -56
- package/package.json +1 -1
|
@@ -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
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
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
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1082
|
-
|
|
1083
|
-
if (overText === "→" && isAccent) {
|
|
1084
|
-
return `\\overrightarrow{${result}}`;
|
|
1061
|
+
if (overText === "→") {
|
|
1062
|
+
return `\\overrightarrow{0}`;
|
|
1085
1063
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
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
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
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
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1080
|
-
|
|
1081
|
-
if (overText === "→" && isAccent) {
|
|
1082
|
-
return `\\overrightarrow{${result}}`;
|
|
1059
|
+
if (overText === "→") {
|
|
1060
|
+
return `\\overrightarrow{0}`;
|
|
1083
1061
|
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
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
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
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
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1086
|
-
|
|
1087
|
-
if (overText === "→" && isAccent) {
|
|
1088
|
-
return `\\overrightarrow{${result}}`;
|
|
1065
|
+
if (overText === "→") {
|
|
1066
|
+
return `\\overrightarrow{0}`;
|
|
1089
1067
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
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/lib/mathml2latex.cjs.js
CHANGED
|
@@ -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
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
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
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1082
|
-
|
|
1083
|
-
if (overText === "→" && isAccent) {
|
|
1084
|
-
return `\\overrightarrow{${result}}`;
|
|
1061
|
+
if (overText === "→") {
|
|
1062
|
+
return `\\overrightarrow{0}`;
|
|
1085
1063
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
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){
|
package/lib/mathml2latex.es.js
CHANGED
|
@@ -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
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
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
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1080
|
-
|
|
1081
|
-
if (overText === "→" && isAccent) {
|
|
1082
|
-
return `\\overrightarrow{${result}}`;
|
|
1059
|
+
if (overText === "→") {
|
|
1060
|
+
return `\\overrightarrow{0}`;
|
|
1083
1061
|
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
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){
|
package/lib/mathml2latex.umd.js
CHANGED
|
@@ -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
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
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
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1086
|
-
|
|
1087
|
-
if (overText === "→" && isAccent) {
|
|
1088
|
-
return `\\overrightarrow{${result}}`;
|
|
1065
|
+
if (overText === "→") {
|
|
1066
|
+
return `\\overrightarrow{0}`;
|
|
1089
1067
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
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){
|