Package org.jmathml

Source Code of org.jmathml.MathMLReader

package org.jmathml;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.List;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.Text;
import org.jdom.input.SAXBuilder;
import org.jmathml.ASTFunction.ASTFunctionType;
import org.jmathml.ASTLogical.ASTLogicalType;

/**
  * Class for generating an AST from a MathML representation
  * @author radams
  *
  */
public class MathMLReader {
  private ASTNode curr, root;
 
  /**
   * Static method to convert a <code>String</code> of MathML to a text representation.
   * @param mathml A <code>String</code> of valid MathML
   * @return A <code>String</code> of C-style math syntax, or an error string if it could not be converted.
   */
  public static String MathMLXMLToText(String mathml) {
    System.err.println(mathml);
    MathMLReader rdr = new MathMLReader();
    Element rt;
    try {
      rt = rdr.readXML(new StringReader(mathml));
      ASTNode node= rdr.parseMathML(rt);
      return new FormulaFormatter().formulaToString(node);
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    return "Could not be formatted";
   
  }
  /**
   * Given a <code>String</code> of MathML XML, will return an ASTNode
   * @param mathml A string of valid MathML
   * @return an {@link ASTNode}
   * @throws IOException if parsing or XML formatting errors are found
   */
  public ASTNode parseMathMLFromString (String mathml) throws IOException {
    Element rt =  readXML(new StringReader(mathml));
    return parseMathML(rt);
  }
 
  /**
   * Creates a JDOM document from the given XML string (via a Reader)
   * @param reader
   * @return
   * @throws IOException if the JDOM document could not be read.
   */
    public  Element readXML(Reader reader) throws IOException {
    try {
      SAXBuilder builder = new SAXBuilder(false);
     
      Document sDoc = builder.build(reader);
     
      Element root = sDoc.getRootElement();
   
      return root;
    }catch (JDOMException e){
      e.printStackTrace(System.out);
      throw new IOException(e.getMessage());
    }
  }
 
  public  ASTNode parseMathML(Element mathml) {

    if (mathml.getName().equals("math")) {
      root=new ASTRootNode();
      curr=root;
    }
   
    else if (mathml.getName().equals("plus")) {
      ASTPlus plus = new ASTPlus();
      curr.addChildNode(plus);
      curr=plus;
    }else if (mathml.getName().equals("minus")) {
      ASTMinus minus = new ASTMinus();
      curr.addChildNode(minus);
      curr=minus;
    }
    else if (mathml.getName().equals("times")) {
      ASTTimes times = new ASTTimes();
      curr.addChildNode(times);
      curr=times;
    }
    else if (mathml.getName().equals("divide")) {
      ASTDivide divide = new ASTDivide();
      curr.addChildNode(divide);
      curr=divide;
    }else if (mathml.getName().equals("ci")) {
      ASTCi  ci = new ASTCi(mathml.getText().trim());
      curr.addChildNode(ci);
    }else if (mathml.getName().equals("cn")) {
       parseNumberElement(mathml);
    }else if (mathml.getName().equals("csymbol")) {
      mathml.getValue();
      ASTSymbol  sym =SymbolRegistry.getInstance().createSymbolFor(mathml.getAttributeValue("definitionURL"));
      if(sym==null){
        throw new RuntimeException("Could not create symbol for "+mathml.getAttributeValue("definitionURL"));
      }
      sym.setDefinitionURL(mathml.getAttributeValue("definitionURL"));
      sym.setEncoding(mathml.getAttributeValue("encoding"));
      sym.setName(mathml.getValue());
     
      curr.addChildNode(sym);
      List<Element> siblingsAndThis = mathml.getParentElement().getChildren();
      Element firstChild = siblingsAndThis.get(0);
      if(firstChild.getName().equals("csymbol")){
        // is function
        curr=sym;
      }
     
     
     
     
     
    } else if (isLogical(mathml)){
      if (mathml.getName().equals("and") ){
        curr.addChildNode(new ASTLogical(ASTLogicalType.AND));
       
      } else  if (mathml.getName().equals("or") ){
        curr.addChildNode(new ASTLogical(ASTLogicalType.OR));
       
      }else  if (mathml.getName().equals("xor") ){
        curr.addChildNode(new ASTLogical(ASTLogicalType.XOR));
       
      }else  if (mathml.getName().equals("not") ){
        curr.addChildNode(new ASTLogical(ASTLogicalType.NOT));
       
      }
      curr=curr.getRightChild();
    }
    else if (isRelational(mathml)){
      if (mathml.getName().equals("eq") ){
        curr.addChildNode(new ASTRelational(ASTRelational.ASTRelationalType.EQ));
       
      } else  if (mathml.getName().equals("neq") ){
        curr.addChildNode(new ASTRelational(ASTRelational.ASTRelationalType.NEQ));
       
      }else if (mathml.getName().equals("gt") ){
        curr.addChildNode(new ASTRelational(ASTRelational.ASTRelationalType.GT));
       
      }else if (mathml.getName().equals("geq") ){
        curr.addChildNode(new ASTRelational(ASTRelational.ASTRelationalType.GEQ));
       
      }else if (mathml.getName().equals("lt") ){
        curr.addChildNode(new ASTRelational(ASTRelational.ASTRelationalType.LT));
       
      }else if (mathml.getName().equals("leq") ){
        curr.addChildNode(new ASTRelational(ASTRelational.ASTRelationalType.LEQ));
       
      }
      curr=curr.getRightChild();
    }
   
    else if (mathml.getName().equals("logbase")){
      Element baseValue=(Element)mathml.getChildren().get(0);
      int base =Integer.parseInt(baseValue.getText().trim());
      ((ASTFunction.ASTLog)curr).addChildNode(ASTNumber.createNumber(base));
    }
   
    else if (isFunction(mathml)){
      ASTFunctionType type = ASTFunction.getFunctionTypeForName(mathml.getName());
      ASTNode toAdd=null;
     
      if (type.equals(ASTFunctionType.LOG )) {
        List<Element> siblings = ((Element)mathml.getParent()).getChildren();
        for (Element siblin: siblings) {
          if(siblin.getName().equals("logbase")){
            Element baseValue=(Element)siblin.getChildren().get(0);
            int base =Integer.parseInt(baseValue.getText().trim());
            toAdd = ASTFunction.createASTLog(base);
          }
        }
       
      }else if (type.equals(ASTFunctionType.ROOT )) {
        List<Element> siblings = ((Element)mathml.getParent()).getChildren();
        for (Element siblin: siblings) {
          if(siblin.getName().equals("degree")){
            Element baseValue=(Element)siblin.getChildren().get(0);
            int degree =Integer.parseInt(baseValue.getText().trim());
            toAdd = ASTFunction.createASTRoot(degree);
          }
        }
       
      }
      if(toAdd == null){
          toAdd = ASTFunction.createFunctionNode(type);
      }
     
      curr.addChildNode(toAdd);
      curr=toAdd;
    }
   
    List<Element> els= mathml.getChildren();
    for (int i =0; i< mathml.getChildren().size(); i++){
      if(shouldIgnore(els.get(i).getName())){
        continue;
      }
       parseMathML(els.get(i));
       if(curr!=root &&  ((Element)els.get(i)).getName().equals("apply"))
         curr=curr.getParentNode();
     
    }
    return curr;
   
   
  }

  private boolean shouldIgnore(String name) {
    return name.equals("logbase") || name.equals("degree");
  }

  private boolean isLogical(Element mathml) {
    return mathml.getName().equals("and") ||mathml.getName().equals("or")||
      mathml.getName().equals("not") || mathml.getName().equals("xor");
  }
 
  private boolean isRelational(Element mathml) {
    return mathml.getName().equals("eq") ||mathml.getName().equals("neq")||
      mathml.getName().equals("geq") || mathml.getName().equals("gt")||
      mathml.getName().equals("leq") || mathml.getName().equals("lt");
  }

  private boolean isFunction(Element mathml) {
    return  ASTFunction.getFunctionTypeForName(mathml.getName()) != null  &&
           !ASTFunction.getFunctionTypeForName(mathml.getName()).equals(ASTFunctionType.MISCELLANEOUS);
  }

  private void parseNumberElement(final Element mathml) {
    if (mathml.getAttribute("type") != null && mathml.getAttribute("type").getValue().equals("integer")) {
      ASTNumber val = ASTNumber.createNumber(Integer.parseInt(mathml.getText().trim()));
      curr.addChildNode(val);
    } else if (mathml.getAttribute("type") != null && mathml.getAttribute("type").getValue().equals("rational")){
      if(mathml.getContent().size()==3){
       
        int numerator = Integer.parseInt(((Text)mathml.getContent().get(0)).getText());
        int denom = Integer.parseInt(((Text)mathml.getContent().get(2)).getText());

        ASTNumber frac = ASTNumber.createNumber(numerator, denom);
        curr.addChildNode(frac);
      }
    }else if (mathml.getAttribute("type") != null && mathml.getAttribute("type").getValue().equals("e-notation")){
      if(mathml.getContent().size()==3){
        double mantissa = Double.parseDouble(((Text)mathml.getContent().get(0)).getText());
        double  exp = Double.parseDouble(((Text)mathml.getContent().get(2)).getText());

        ASTNumber frac = ASTNumber.createNumber(mantissa, exp);
        curr.addChildNode(frac);
      }
    }
    else   {
      ASTNumber val=null;
      if (mathml.getText().trim().equalsIgnoreCase("pi")){
         val = ASTNumber.createNumber(Math.PI);
      } else if (mathml.getText().trim().equalsIgnoreCase("exponentiale")){
         val = ASTNumber.createNumber(Math.E);
      } else if (mathml.getText().trim().equalsIgnoreCase("notanumber")){
        val = ASTNumber.createNumber(Double.NaN);
             
            }else if (mathml.getText().trim().equalsIgnoreCase("infinity")){
        val = ASTNumber.createNumber(Double.POSITIVE_INFINITY);
             
            }else {
       val = ASTNumber.createNumber(Double.parseDouble(mathml.getText()));
      }
      curr.addChildNode(val);
    }
  }

}
TOP

Related Classes of org.jmathml.MathMLReader

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.