const form = document.forms[
'latex-add'
];
const container = document.querySelector(
'#expression-list'
);
const expressions = [
'\frac{a}{b}'
,
'\frac{{(25 \cdot 5)}}{6}'
];
const main = () => {
form.elements.expression.value =
'(25*5)/b'
;
form.addEventListener(
'submit'
, handleAdd);
renderExpressions();
};
const handleAdd = (e) => {
e.preventDefault();
const expression = e.target.elements.expression.value.trim();
const tex = texFromExpression(expression);
console.log(tex);
expressions.push(tex);
renderExpressions();
e.target.reset();
};
const renderExpressions = () => {
container.innerHTML =
''
;
expressions.forEach(expression => {
const wrapper = document.createElement(
'div'
);
wrapper.classList.add(
'expression'
);
const tex = document.createElement(
'div'
);
tex.classList.add(
'tex'
);
tex.textContent = expression;
wrapper.append(tex);
wrapper.append(MathJax.tex2chtml(expression));
container.append(wrapper);
});
};
const texFromExpression = (str) => {
let pos = -1, ch;
const nextChar = () => {
ch = (++pos < str.length) ? str.charAt(pos) : -1;
};
const eat = (charToEat) => {
while
(ch ==
' '
) nextChar();
if
(ch == charToEat) {
nextChar();
return
true
;
}
return
false
;
};
const parse = () => {
nextChar();
const x = parseExpression();
if
(pos < str.length)
throw
new
Error(`Unexpected: ${ch}`)
return
x;
};
const parseExpression = () => {
let x = parseTerm();
while
(
true
) {
if
(eat(
'+'
)) x = `${x} + ${parseTerm()}`
else
if
(eat(
'-'
)) x = `${x} - ${parseTerm()}`
else
return
x;
}
};
const parseTerm = () => {
var
x = parseFactor();
while
(
true
) {
if
(eat(
'*'
)) x = `${x} \cdot ${parseTerm()}`;
else
if
(eat(
'/'
)) x = `\frac{${x}}{${parseTerm()}}`;
else
return
x;
}
};
const parseFactor = () => {
if
(eat(
'+'
))
return
parseFactor();
if
(eat(
'-'
))
return
`-${parseFactor()}`;
let x;
const startPos = pos;
if
(eat(
'('
)) {
x = `{(${parseExpression()})}`
eat(
')'
);
}
else
if
((ch >=
'0'
&& ch <=
'9'
) || ch ==
'.'
) {
while
((ch >=
'0'
&& ch <=
'9'
) || ch ==
'.'
) nextChar();
x = str.substring(startPos, pos);
}
else
if
(ch >=
'a'
&& ch <=
'z'
) {
while
(ch >=
'a'
&& ch <=
'z'
) nextChar();
x = str.substring(startPos, pos);
if
(x.length > 1) {
x = `\${x} {${parseFactor()}}`;
}
}
else
{
throw
new
Error(`Unexpected: ${ch}`);
}
if
(eat(
'^'
)) x = `${x} ^ {${parseFactor()}}`
if
(eat(
'_'
)) x = `${x}_{${parseFactor()}}`;
return
x;
}
return
parse();
}
main();