首页 > 解决方案 > How to convert latex to normal/raw mathematical equations?

问题描述

Can anyone suggest me any method or library which can convert a latex math to normal expression (x^2+2x+sin(x)). So far I've found a code which can do it but it cannot convert \sqrt[3]{....} to cuberoot(....) or root(3,....)

The code:

 function MQtoAM(tex,display) {
        var nested,lb,rb,isfuncleft,curpos,c,i;
          tex = tex.replace(/\\:/g,' ');
        tex = tex.replace(/\\operatorname{(\w+)}/g,' $1');
          if (!display) {
          while ((i = tex.lastIndexOf('\\left|'))!=-1) { //found a left |)
            rb = tex.indexOf('\\right|',i+1);
                if (rb!=-1) {  //have a right |  - replace with abs( )
              isfuncleft = tex.substring(0,i).match(/(arcsinh|arccosh|arctanh|arcsech|arccsch|arccoth|arcsin|arccos|arctan|arcsec|arccsc|arccot|sinh|cosh|tanh|sech|csch|coth|ln|log|exp|sin|cos|tan|sec|csc|cot)(\^\d+)?$/);
                    tex = tex.substring(0,rb) + ")" + (isfuncleft?')':'') + tex.substring(rb+7);
                    tex = tex.substring(0,i) + (isfuncleft?'(':'') + "abs(" + tex.substring(i+6);
                } else {
                    tex = tex.substring(0,i) + "|" + tex.substring(i+6);
                }
            }
            tex = tex.replace(/\\text{\s*or\s*}/g,' or ');
            tex = tex.replace(/\\text{all\s+real\s+numbers}/g,'all real numbers');
          tex = tex.replace(/\\text{DNE}/g,'DNE');
            tex = tex.replace(/\\varnothing/g,'DNE');
            tex = tex.replace(/\\Re/g,'all real numbers');
          } else {
            tex = tex.replace(/\\Re/g,'RR');
          }
        tex = tex.replace(/\\begin{.?matrix}(.*?)\\end{.?matrix}/g, function(m, p) {
          return '[(' + p.replace(/\\\\/g,'),(').replace(/&/g,',') + ')]';
        });
          tex = tex.replace(/\\le(?=(\b|\d))/g,'<=');
          tex = tex.replace(/\\ge(?=(\b|\d))/g,'>=');
        tex = tex.replace(/\\ne(?=(\b|\d))/g,'!=');
        tex = tex.replace(/\\pm/g,'+-');
          tex = tex.replace(/\\approx/g,'~~');
          tex = tex.replace(/(\\arrow|\\rightarrow)/g,'rarr');
        tex = tex.replace(/\\cup/g,'U');
        tex = tex.replace(/\\times/g,'xx');
          tex = tex.replace(/\\left\\{/g,'lbrace').replace(/\\right\\}/g,'rbrace');
          tex = tex.replace(/\\left/g,'');
          tex = tex.replace(/\\right/g,'');
          tex = tex.replace(/\\langle/g,'<<');
          tex = tex.replace(/\\rangle/g,'>>');
          tex = tex.replace(/\\cdot/g,'*');
          tex = tex.replace(/\\infty/g,'oo');
          tex = tex.replace(/\\nthroot/g,'root');
        tex = tex.replace(/\\mid/g,'|');
          tex = tex.replace(/\\/g,'');
          tex = tex.replace(/sqrt\[(.*?)\]/g,'root($1)');
          tex = tex.replace(/(\d)frac/g,'$1 frac');
          while ((i=tex.indexOf('frac{'))!=-1) { //found a fraction start
            nested = 1;
            curpos = i+5;
            while (nested>0 && curpos<tex.length-1) {
                curpos++;
                c = tex.charAt(curpos);
                if (c=='{') { nested++;}
                else if (c=='}') {nested--;}
            }
            if (nested==0) {
                tex = tex.substring(0,i)+"("+tex.substring(i+5,curpos)+")/"+tex.substring(curpos+1);
            } else {
                tex = tex.substring(0,i) + tex.substring(i+4);
            }
          }
        //separate un-braced subscripts using latex rules
        tex = tex.replace(/_(\w)(\w)/g, '_$1 $2');
        tex = tex.replace(/(\^|_)([+\-])([^\^])/g, '$1$2 $3');  
          tex = tex.replace(/\^(\w)(\w)/g, '^$1 $2');
          tex = tex.replace(/_{([\d\.]+)}\^/g,'_$1^');
          tex = tex.replace(/_{([\d\.]+)}([^\^])/g,'_$1 $2');
          tex = tex.replace(/_{([\d\.]+)}$/g,'_$1');
        tex = tex.replace(/_{(\w+)}$/g,'_($1)');
          tex = tex.replace(/{/g,'(').replace(/}/g,')');
          tex = tex.replace(/lbrace/g,'{').replace(/rbrace/g,'}');
          tex = tex.replace(/\(([\d\.]+)\)\/\(([\d\.]+)\)/g,'$1/$2');  //change (2)/(3) to 2/3
          tex = tex.replace(/\/\(([\d\.]+)\)/g,'/$1');  //change /(3) to /3
          tex = tex.replace(/\(([\d\.]+)\)\//g,'$1/');  //change (3)/ to 3/
          tex = tex.replace(/\/\(([\a-zA-Z])\)/g,'/$1');  //change /(x) to /x
          tex = tex.replace(/\(([\a-zA-Z])\)\//g,'$1/');  //change (x)/ to x/
        tex = tex.replace(/\^\(-1\)/g,'^-1');
          tex = tex.replace(/\^\((-?[\d\.]+)\)/g,'^$1');
        tex = tex.replace(/\/\(([\a-zA-Z])\^([\d\.]+)\)/g,'/$1^$2');  //change /(x^n) to /x^n
          tex = tex.replace(/\(([\a-zA-Z])\^([\d\.]+)\)\//g,'$1^$2/');  //change (x^n)/ to x^n/
        tex = tex.replace(/\+\-/g,'+ -'); // ensure spacing so it doesn't interpret as +-
        tex = tex.replace(/text\(([^)]*)\)/g, '$1');
        return tex;
      }

标签: latexmathjaxtex

解决方案


我将为这种特定情况提供一个解决方案,但这并不总是可行的,因为 LaTeX 不保证数学表达式是有效的1。LaTeX 也是图灵完备的编程语言,所以总有人可以写出你无法转换的方程式。

在这种特殊情况下,您需要替换该行:

tex = tex.replace(/sqrt\[(.*?)\]/g,'root($1)');

tex = tex.replace(/sqrt\[(.*?)\]\{(.*?)\}/g,'root($1, $2)');

右侧的“$number”部分表示“从左侧复制第一个括号中的内容”。在这里,我只是告诉它查找方括号/大括号中的内容并采取相应措施。这种搜索和替换方式称为正则表达式解析。我建议您学习编写自己的代码,这样您就可以增加解析器理解的内容的数量。

例如,您可以添加一行:

tex = tex.replace(/sqrt\{(.*?)\}/g,'squareroot($1)');

处理简单的平方根。

可悲的是,每种语言实现正则表达式的方式都不同(尤其是哪些东西前面需要一个“\”),所以你必须做一些试验才能找到在 JavaScript 中有效的方法。

1这就是为什么在撰写文章时最好将公式自动转换为 LaTeX 而不是直接在 LaTeX 中编写的原因之一。找到数学无效的已发表论文是非常常见的,因为人们直接用 LaTeX 编写,然后由于在原始 LaTeX 源代码中发现错误非常困难,因此错误不可见。


推荐阅读