0

I'm building a math application and I want to show math formulas written with a good design in javascript (nodejs). So I would transorm plain text to TEX format. From formula like this:

(25*5)/6

To formula like this:

\frac{(25 \cdot 5)}{6}

To good design:

math_formula

If there are other known methods you advise me. Many thanks in advance!

Carlo
  • 813
  • 1
  • 15
  • 34

1 Answers1

4

I've rewritten this expression parser from java to javascript. not the most straightforward way. Note that this is not extensively tested.

function texFromExpression(str){
    var pos = -1, ch;
    function nextChar(){
        ch = (++pos < str.length) ? str.charAt(pos) : -1;
    }
    function eat(charToEat) {
        while (ch == ' ') nextChar();
        if (ch == charToEat) {
            nextChar();
            return true;
        }
        return false;
    }
    function parse(){
        nextChar();
        var x = parseExpression();
        if (pos < str.length) throw `Unexpected: ${ch}`
        return x;
    }
    function parseExpression() {
        var x = parseTerm();
        for (;;) {
            if      (eat('+')) x = `${x} + ${parseTerm()}` // addition
            else if (eat('-')) x = `${x} - ${parseTerm()}` // subtraction
            else return x;
        }
    }
    function parseTerm() {
        var x = parseFactor();
        for (;;) {
            if      (eat('*')) x=`${x} \\cdot ${parseTerm()}`; // multiplication
            else if (eat('/')) x= `\\frac{${x}}{${parseTerm()}}`; // division
            else return x;
        }
    }
    function parseFactor() {
        if (eat('+')) return `${parseFactor()}`; // unary plus
        if (eat('-')) return `-${parseFactor()}`; // unary minus

        var x;
        var startPos = pos;
        if (eat('(')) { // parentheses
            x = `{(${parseExpression()})}`
            eat(')');
        } else if ((ch >= '0' && ch <= '9') || ch == '.') { // numbers
            while ((ch >= '0' && ch <= '9') || ch == '.') nextChar();
            x = str.substring(startPos, pos);
        } else if (ch >= 'a' && ch <= 'z') { // variables
            while (ch >= 'a' && ch <= 'z') nextChar();
            x= str.substring(startPos, pos);
            if(x.length>1){
                x = `\\${x} {${parseFactor()}}`;
            }
        } else {
            throw `Unexpected: ${ch}`
        }
        if (eat('^')) x = `${x} ^ {${parseFactor()}}` //superscript
        if(eat('_')) x = `${x}_{${parseFactor()}}`;

        return x;
    }
    return `$${parse()}$`;
}