Convert expression to Latex format or MathML

44 views
Skip to first unread message

Andrés Mauricio Barragán Sarmiento

unread,
Mar 16, 2015, 6:46:36 PM3/16/15
to jep-...@googlegroups.com
Good afternoon

I want to know how to convert a format anyone Latex, or MathML function, or a similar format.

I'm using an external library, and I can make expressions like x ^ 3 + 2x - 3 ie simple functions.

But I want to know how to display any function.

For example, if I write the quadratic function as follows: (-b +/- sqrt (b ^ 2 - 4ac)) / (2a), how he would convert to latext format or MathML.

Thank you very much

Richard Morris

unread,
Mar 17, 2015, 7:17:51 AM3/17/15
to jep-...@googlegroups.com
The two questions require quite different solutions.

Converting to Latex

The correct latex for is (-b +/- sqrt (b ^ 2 - 4ac)) / (2a)

\frac{-b \pm \sqrt{ b^2 - 4 a c } }{ 2 a}

This is not too different to the standard output produced by the PrintVisitor. This has facilities to modify how different operators and functions are printed
using the PrintVisitor.addSpecialRule() method. To modify the PrintVisitor to work for the quadratic formula you need to add rules for sqrt, multiplication and division. 

package com.singularsys.jeptests.system;

import java.text.NumberFormat;

import org.junit.Before;
import org.junit.Test;

import com.singularsys.jep.Jep;
import com.singularsys.jep.JepException;
import com.singularsys.jep.OperatorTableI;
import com.singularsys.jep.ParseException;
import com.singularsys.jep.PrintVisitor;
import com.singularsys.jep.PrintVisitor.PrintRulesI;
import com.singularsys.jep.parser.Node;


public class LatexTest {
 
Jep jep;
 
 
@Before
 
public void setUp() throws Exception {
 jep
= new Jep();
 
PrintVisitor pv = jep.getPrintVisitor();
 
OperatorTableI ot = jep.getOperatorTable();
 
 pv
.addSpecialRule(ot.getDivide(), new PrintRulesI() {


 
@Override
 
public void append(Node node, PrintVisitor pv) throws JepException {
 pv
.append("\\frac{");
 node
.jjtGetChild(0).jjtAccept(pv, null);
 pv
.append("}{");
 node
.jjtGetChild(1).jjtAccept(pv, null);
 pv
.append("}");
 
}});


 pv
.addSpecialRule(ot.getMultiply(), new PrintRulesI() {


 
@Override
 
public void append(Node node, PrintVisitor pv) throws JepException {
 node
.jjtGetChild(0).jjtAccept(pv, null);
 pv
.append(" ");
 node
.jjtGetChild(1).jjtAccept(pv, null);
 
}});


 pv
.addSpecialRule("sqrt",new PrintRulesI() {


 
@Override
 
public void append(Node node, PrintVisitor pv) throws JepException {
 pv
.append("\\sqrt{");
 node
.jjtGetChild(0).jjtAccept(pv, null);
 pv
.append("}");
 
}});
 
       
NumberFormat format = NumberFormat.getInstance();
        format
.setMaximumFractionDigits(3);
        format
.setMinimumFractionDigits(0);
        jep
.getPrintVisitor().setNumberFormat(format);


 
}


 
@Test
 
public void test() throws ParseException {
 
Node n = jep.parse("(-b + sqrt (b ^ 2 - 4a c)) / (2a)");
 jep
.println(n);
 
}


}


For a complete solution you would need to add rules for sin, cos and various other functions. Note the above does not work with +/- as this operator is not defined as standard. It would be possible to add a new operator to add this.

A solution to convert to MathML is more complex. I have developed an extension to Jep which can do this. Contact me if your interested in getting this extension.

Andrés Mauricio Barragán Sarmiento

unread,
Mar 17, 2015, 4:21:58 PM3/17/15
to jep-...@googlegroups.com
Thank you very much for the reply

But I wonder if this can also be done with version 2.4, as it is with that story.

Thank you very much

Richard Morris

unread,
Mar 17, 2015, 4:25:06 PM3/17/15
to jep-...@googlegroups.com
Yes it should be possible. You can find the PrintVisitor at org.lsmp.djep.xjep.PrintVisitor. The MathML extension is not compatible with the 2.4 branch.

Andrés Mauricio Barragán Sarmiento

unread,
Mar 17, 2015, 6:35:14 PM3/17/15
to jep-...@googlegroups.com
Thank you very much for the reply

How could make the rule for the function sqrt() since version 2.4 can not be passed as a parameter a String.

I tried with:

pv.addSpecialRule(new Operator("sqrt" new SquareRoot()), new PrintRulesI() {})

But I do not get the desired result.

Thank you very much

Richard Morris

unread,
Mar 17, 2015, 6:51:30 PM3/17/15
to jep-...@googlegroups.com
Ah yes. In that case you will need to subclass PrintVisitor and override 


public Object visit(ASTFunNode node, Object data) throws ParseException

You would first need to detect the functions you need and take the appropriate action. If the function does not match then call the superclass method


public class MyPrintVisitor extends PrintVisitor {


   
@Override
   
public Object visit(ASTFunNode node, Object data) throws ParseException {

       
if(node..getName().equals("sqrt")) {
           
...
       
} else {
           
super.visit(node,data);
       
}
   
}
}

Andrés Mauricio Barragán Sarmiento

unread,
Mar 18, 2015, 2:56:45 PM3/18/15
to jep-...@googlegroups.com
Thanks for the reply

However, it could be how to implement this, as in version 2.4, the following code does not show me the square root or another function, because in this version can not pass a String as a parameter in the method addSpecialRule

pv.addSpecialRule("sqrt", new PrintRulesI() {

   
@Override
   
public void append(Node node, PrintVisitor pv) throws ParseException {

        pv
.append("\\sqrt{");
        node
.jjtGetChild(0).jjtAccept(pv, null);
        pv
.append("}");
   
}
});

How would it then in version 2.4?

Thank you very much for your help
Reply all
Reply to author
Forward
0 new messages