-
Notifications
You must be signed in to change notification settings - Fork 51
Open
Description
Description
I found a bunch of edge cases for parsing LaTeX expressions, specifically when dealing with variables that have multiple non-numeric symbols in their subscript. They either yield inconsistent results with expected cases or raise a MathJSON "incompaticle type" parsing error. This was tested on the mathlive.io demo website as of 10-10-2025.
Steps to Reproduce
import { ComputeEngine } from "@cortex-js/compute-engine";
const ce = new ComputeEngine();
const BATCH_1 = [
'A_1',
'A_1+1',
'2A_1',
'2\\cdot A_1',
'\\frac{A_1}{4}',
'A_1^2',
];
const BATCH_2 = [
'A_{B}',
'A_{B}+1',
'2A_{B}',
'2\\cdot A_{B}',
'\\frac{A_{B}}{4}',
'A_{B}^2',
];
const BATCH_3 = [
'A_{CD}',
'A_{CD}+1',
'2A_{CD}',
'2\\cdot A_{CD}',
'\\frac{A_{CD}}{4}',
'A_{CD}^2',
];
const BATCH_4 = [
'AB_{CD}',
'AB_{CD}+1',
'2AB_{CD}',
'2\\cdot AB_{CD}',
'\\frac{AB_{CD}}{4}',
'AB_{CD}^2',
];
function convertLatexToMathJson(latex) {
const parsedExpr = ce.parse(latex);
const boxedExpr = ce.box(parsedExpr, { canonical: true });
return boxedExpr.json;
}
// Run testing
console.log('Batch 1 Testing');
for (const expr of BATCH_1) {
const mjson = convertLatexToMathJson(expr);
console.log(expr, ' => ', JSON.stringify(mjson, null, 2));
}
console.log();
console.log('Batch 2 Testing');
for (const expr of BATCH_2) {
const mjson = convertLatexToMathJson(expr);
console.log(expr, ' => ', JSON.stringify(mjson, null, 2));
}
console.log();
console.log('Batch 3 Testing');
for (const expr of BATCH_3) {
const mjson = convertLatexToMathJson(expr);
console.log(expr, ' => ', JSON.stringify(mjson, null, 2));
}
console.log();
console.log('Batch 4 Testing');
for (const expr of BATCH_4) {
const mjson = convertLatexToMathJson(expr);
console.log(expr, ' => ', JSON.stringify(mjson, null, 2));
}Raw Script Output
Batch 1 Testing (Working)
A_1 => "A_1"
A_1+1 => [
"Add",
"A_1",
1
]
2A_1 => [
"Multiply",
2,
"A_1"
]
2\cdot A_1 => [
"Multiply",
2,
"A_1"
]
\frac{A_1}{4} => [
"Multiply",
[
"Rational",
1,
4
],
"A_1"
]
A_1^2 => [
"Power",
"A_1",
2
]
Batch 2 Testing (Working)
A_{B} => "A_B"
A_{B}+1 => [
"Add",
"A_B",
1
]
2A_{B} => [
"Multiply",
2,
"A_B"
]
2\cdot A_{B} => [
"Multiply",
2,
"A_B"
]
\frac{A_{B}}{4} => [
"Multiply",
[
"Rational",
1,
4
],
"A_B"
]
A_{B}^2 => [
"Power",
"A_B",
2
]
Batch 3 Testing
A_{CD} => [
"Subscript",
"A",
[
"InvisibleOperator",
"C",
"D"
]
]
A_{CD}+1 => [
"Add",
[
"Error",
[
"ErrorCode",
"'incompatible-type'",
"number",
"symbol"
]
],
1
]
2A_{CD} => [
"Tuple",
2,
[
"Subscript",
"A",
[
"InvisibleOperator",
"C",
"D"
]
]
]
2\cdot A_{CD} => [
"Multiply",
2,
[
"Error",
[
"ErrorCode",
"'incompatible-type'",
"number",
"symbol"
]
]
]
\frac{A_{CD}}{4} => [
"Divide",
[
"Error",
[
"ErrorCode",
"'incompatible-type'",
"number",
"symbol"
]
],
4
]
A_{CD}^2 => [
"Power",
[
"Error",
[
"ErrorCode",
"'incompatible-type'",
"number",
"symbol"
]
],
2
]
Batch 4 Testing
AB_{CD} => [
"Tuple",
"A",
[
"Subscript",
"B",
[
"InvisibleOperator",
"C",
"D"
]
]
]
AB_{CD}+1 => [
"Add",
[
"Error",
[
"ErrorCode",
"'incompatible-type'",
"number",
"'tuple<unknown, symbol>'"
]
],
1
]
2AB_{CD} => [
"Tuple",
2,
"A",
[
"Subscript",
"B",
[
"InvisibleOperator",
"C",
"D"
]
]
]
2\cdot AB_{CD} => [
"Multiply",
2,
[
"Error",
[
"ErrorCode",
"'incompatible-type'",
"number",
"'tuple<unknown, symbol>'"
]
]
]
\frac{AB_{CD}}{4} => [
"Divide",
[
"Error",
[
"ErrorCode",
"'incompatible-type'",
"number",
"'tuple<unknown, symbol>'"
]
],
4
]
AB_{CD}^2 => [
"Tuple",
"A",
[
"Power",
[
"Error",
[
"ErrorCode",
"'incompatible-type'",
"number",
"symbol"
]
],
2
]
]
Environment
Screenshots are from mathlive.io demo website: https://mathlive.io/mathfield/demo/ using compute engine v0.30.2.
Testing code is ran against Node.js v22.20.0 and NPM v10.9.3 using compute engine v0.30.2.
Metadata
Metadata
Assignees
Labels
No labels