MathML parser/builder
The MathMLContentParser
parses XML input containing Content-MathML and produces a jep expression.
The MathMLContentBuilder
converts Jep expressions to org.w3c.dom.Document objects
containing Content-MathML
which can be output to Files, String and other sources using a javax.xml.transform.Transformer.
Jep jep = new Jep();
MathMLContentParser mcp = MathMLContentParser(jep);
MathMLContentBuilder mcb = new MathMLContentBuilder(jep);
MathMLTransformerFactory mft = new MathMLTransformerFactory();
// Convert xml to a jep node
String xml="<math><apply><sin/><cn>1.23</cn></apply></math>";
Node node = mcp.parseSingle(xml);
// Convert a jep expression to xml
Node eqn = jep.parse("sin(1.23)");
Document doc = mcb.buildDocument(eqn);
// Produce a string representation
TransformerFactory ft = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new StringWriter());
t.transform(source, result);
String res = result.toString();
Other methods are available to parse/produce xml containing more than one
equation; xml with namespace and dtd declerations.
The standard configuration for the builder parser which can be modified and extended.
Tranforming documents
The javax.xml.transform package contains classes to manage transformation of documents.
TransformerFactory creates Transformer objects which perform the actual transformation.
The Source and Result specifiy the source an destination of transformation, in particular
the javax.xml.transform.dom.DOMSource is a source for DOM documents produced by the MathMLContentBuilder,
the javax.xml.transform.stream.StreamResult is used to produce results to
a File, OutputStream, or Writer. A simple usage is
TransformerFactory ft = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
Document doc = contentBuilder.buildDocument(node);
DOMSource source = new DOMSource(doc);
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
t.transform(source, result);
String res = sr.toString();
To output to a File
File f = new File(...);
StreamResult result = new StreamResult(f);
t.transform(source, result);
and similar for an OutputStream or Writer.
The output of the Transformer can be configure by using
setOutputProperty(String key,String value)
method. The
javax.xml.transform.OutputKeys
class contains valid keys
and com.singularsys.extensions.mathml.MathMLConstants
contains MathML related constants. A Transformer could be configured to
use output the xml deceleration, the standard MathML DTD, and indent the output
using
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,"no");
t.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,MathMLConstants.MATHML_PUBLIC_ID);
t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,MathMLConstants.MATHML_SYSTEM_ID);
t.setOutputProperty(OutputKeys.INDENT,"yes");
Transformer can also be used to apply xslt style sheets, in particular an number of
xslt style sheets are available which can convert Content MathML to presentation MathML.
For example the mmlctop2_0.xsl
from http://www.orcca.on.ca/MathML/software/mmlctop2_0.zip
.
To use this the document must be built using the mml
namespace prefix
and a Transformer built with the style sheet.
Document doc = mcb.buildDocument(node,"mml");
File sheet = new File(LOCAL_STYLESHEETS_DIR + "mmlctop2_0.xsl");
StreamSource style = new StreamSource(sheet);
Transformer t = tf.newTransformer(style);
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new StringWriter());
t.transform(source, result);
Standard builder configuration
- Math elements
-
The builder can produce:
- Simple xml - <math><apply><sin/><cn>1.23</cn></apply></math>
- Xml with the MathML namespace - <math xmlns="http://www.w3.org/1998/Math/MathML"><apply><sin/><cn>1.23</cn></apply></math>
- Xml with the MathML namespace and a namespace prefix - <m:math xmlns:m="http://www.w3.org/1998/Math/MathML"><m:apply><m:sin/><m:cn>1.23</m:cn></m:apply></m:math>
- MathML fragment - <apply><sin/><cn>1.23</cn></apply>
- Xml with a single math tag containing multiple expressions
- Numeric constants
- Numeric constants like "3.2" are typically converted to <cn> elements. Special cases:
- NaN - <notanumber>
- Double.POSITIVE_INFINITY - <infinity>
- Double.NEGATIVE_INFINITY - <apply><minus/><infinity/></apply>
- Boolean.TRUE - <true/>
- Boolean.FALSE - <false/>
- Integer values - <cn type="integer">
- Complex values - <cn type="complex-cartesian">a<sep/>b</cn>.
- Double values representing integers - <cn type="integer">. This can be switched off by calling
if
setUseTypeInteger(false)
on the StandardMathMLDocumentBuilder object in which case a <cn> is created.
- Double values for which Double.toString() gives a result in exponential notation -
<cn type="e-notation">mantissa<sep/>exponant</cn>
- All other double values - <cn>3.2</cn> with the content as Double.toString()
- String and other data types - a JepException is thrown
- Variables
- Typically a jep variable "a" is converted to <ci>a</ci>. Some constant variables have special behaviour
- pi - <pi/>
- e - <ExponentialE/>
- i - <ImaginaryI/>
- true - <true/>
- false - <false/>
- Operators
-
Most operators like "x+1" are converted to <apply><plus/><ci>x<ci/><cn>1<cn/><apply/>
in particular
- a+b -> <apply><plus/><ci>a<ci/><ci>b<ci/><apply/>
- a-b -> <apply><minus/><ci>a<ci/><ci>b<ci/><apply/>
- -a -> <apply><minus/><ci>a<ci/><apply/>
- a*b -> <apply><times/><ci>a<ci/><ci>b<ci/><apply/>
- a/b -> <apply><divide/><ci>a<ci/><ci>b<ci/><apply/>
- a%b -> <apply><rem/><ci>a<ci/><ci>b<ci/><apply/>
- a^b -> <apply><power/><ci>a<ci/><ci>b<ci/><apply/>
- a==b -> <apply><eq/><ci>a<ci/><ci>b<ci/><apply/>
- a!=b -> <apply><neq/><ci>a<ci/><ci>b<ci/><apply/>
- a<=b -> <apply><leq/><ci>a<ci/><ci>b<ci/><apply/>
- a<b -> <apply><lt/><ci>a<ci/><ci>b<ci/><apply/>
- a>=b -> <apply><geq/><ci>a<ci/><ci>b<ci/><apply/>
- a>b -> <apply><gt/><ci>a<ci/><ci>b<ci/><apply/>
- a&&b -> <apply><and/><ci>a<ci/><ci>b<ci/><apply/>
- a||b -> <apply><or/><ci>a<ci/><ci>b<ci/><apply/>
- !a -> <apply><not/><ci>a<ci/><<apply/>
- a.b -> <apply><scalarproduct/><ci>a<ci/><ci>b<ci/><apply/>
- a^^b -> <apply><vectorproduct/><ci>a<ci/><ci>b<ci/><apply/>
There are some special cases
- a=3.2 -> <declare><ci>a</ci><cn>3.2</cn></declare>
- A[3] -> <apply><selector/><ci>A</ci><cn type=\"integer\">3</cn></apply>
- [1.2,2.3,3.4] -> <vector><cn>1.2</cn><cn>2.3</cn><cn>3.4</cn></vector>
- [[x,y],[z,w]] -> <matrix><matrixrow><ci>x</ci><ci>y</ci></matrixrow><matrixrow><ci>z</ci><ci>w</ci></matrixrow></matrix>
- Functions
-
Most functions "sin(x)" are converted to <apply><sin/><ci>x</ci></apply>
In particular the folowing are converted to <apply> with the following first element
- sin -> <sin/>
- cos -> <cos/>
- tan -> <tan/>
- sec -> <sec/>
- csc -> <csc/>
- cot -> <cot/>
- sinh -> <sinh/>
- cosh -> <cosh/>
- tanh -> <tanh/>
- sech -> <sech/>
- csch -> <csch/>
- coth -> <coth/>
- arcsin -> <arcsin/>
- arccos -> <arccos/>
- arctan -> <arctan/>
- arccosh -> <arccosh/>
- arccot -> <arccot/>
- arccoth -> <arccoth/>
- arccsc -> <arccsc/>
- arccsch -> <arccsch/>
- arcsec -> <arcsec/>
- arcsech -> <arcsech/>
- arcsinh -> <arcsinh/>
- arctanh -> <arctanh/>
- exp -> <exp/>
- ln -> <ln/>
- log -> <log/>
- sqrt -> <root/>
- atan -> <arctan/>
- asin -> <arcsin/>
- acos -> <arccos/>
- atanh -> <arctanh/>
- asinh -> <arcsinh/>
- acosh -> <arccosh/>
- floor -> <floor/>
- ceil -> <ceiling/>
- re -> <real/>
- im -> <imaginary/>
- conj -> <conjugate/>
- arg -> <arg/>
- cmod -> <abs/>
- pow -> <power/>
- abs -> <abs/>
- min -> <min/>
- max -> <max/>
- mod -> <rem/>
The following have special behaviour:
- lg(1.23) -> <apply><log/><logbase><cn>2</cn></logbase><cn>1.23</cn></apply>
These jep functions are not currently converted to mathml: complex, sum, round, atan2, if, rand, avg, polar, binom, str
Standard parser configuration
- Main math tag
- <math>
- <math xmlns="http://www.w3.org/1998/Math/MathML"> with standard name space.
- <m:math xmlns:m="http://www.w3.org/1998/Math/MathML"> explicit namespace prefix, all mathml elements and atributes must start with m, eg. <m:cn>123</m:cn>.
- Supported Token elements
- <cn> creates an ASTConstant node, attribute
base
is supported. <cn>123.4</cn>
- <cn type="real"> an ASTConstant with a Double value
- <cn type="rational">a<sep/>b</cn> jep equation a/b
- <cn type="integer"> an ASTConstant with an Integer value
- <cn type="complex-cartesian> an ASTConstant with a
Complex
value
- <cn type="complex-polar"> an ASTConstant with a
Complex
value
- <cn type="e-notation"> an ATSConstant with a Double value.
- <cn type="constant"> child is one of ⅇ ⅈ π &true; &false; a constant variable e, i, pi, true, false is produced
- <ci> a variable all attributes are ignored. Child must be a string presentation markup for child is not supported.
- <sep/> can be used to separate items in <cn>.
- Un-supported Token elements
- Supported constant elements
- <exponentiale/> the jep variable e
- <imaginaryi/> the jep variable i
- <true/> the jep variable true
- <false/> the jep variable false
- <pi/> the jep variable pi
- <infinity/> jep numeric constant with value Double.POSITIVE_INFINITY
- <notanumber/> jep numeric constant with value Double.NAN
- Un-supported constant elements
- <emptyset/>
- <eulergamma/>
- Supported basic content elements
- <apply> applies functions/operators to its children, jep function/operator nodes are created. <apply><sin/><cn>123.4</cn></apply>
- <reln> (deprecated) works as apply
- <declare> only two child version is supported, type attribute is ignored
- <fn> only one <ci> child is supported
- Un-supported basic content elements
- <interval>
- <inverse>
- <condition>
- <lambda>
- <compose>
- <ident>
- <domain>
- <codomain>
- <image>
- <domainofapplication>
- <piecewise>
- <piece>
- <otherwise>
- Supported operator
- <divide/> jep operator Divide "/"
- <minus/> either the subtract or unitary minus operator, "-"
- <plus/> jep operator Add "+"
- <power/> jep operator Power "^"
- <rem/> jep operator Mod "%"
- <times/> jep operator Multiply "*"
- <and/> jep operator And "&&
- <or/> jep operator Or "||"
- <not/> jep operator Not "!"
- <eq/> jep operator EQ "=="
- <neq/> jep operator NE "!="
- <gt/> jep operator GT ">"
- <lt/> jep operator LT "<"
- <geq/> jep operator ">="
- <leq/> jep operator "<="
- <selector/> jep operator Ele "x[4]"
- <vectorproduct/> jep operator Cross "^^"
- <scalarproduct/> jep operator "."
- Supported functions
- <max/> jep function "max"
- <min/> jep function "min"
- <root/> becomes "sqrt(x)" or "x^(1/degree)" if degree child is present
- - <degree/> specifies degree of a root element, eg <apply><root/><degree><cn>3</cn></degree><ci>x</ci></apply> becomes "x^(1/3)"
- <abs/> jep function "abs"
- <arg/> jep function "arg"
- <real/> jep function "re"
- <imaginary/> jep function "im"
- <floor/> jep function "floor"
- <ceiling/> jep function "ceil"
- <sum/> jep function "sum"
- <exp/> jep function "exp"
- <ln/> jep function "ln"
- <log> jep function "log" or "lg" if <logbase> is 2
- - <logbase> specifies base for logarithm, only base 2 is supported
- <sin/> jep function "sin"
- <cos/> jep function "cos"
- <tan/> jep function "tan"
- <sinh/> jep function "sinh"
- <cosh/> jep function "cosh"
- <tanh/> jep function "tanh"
- <arcsin/> jep function "asin"
- <arccos/> jep function "acos"
- <arctan/> jep function "atan"
- <arccosh/> jep function "acosh"
- <arcsinh/> jep function "asinh"
- <arctanh/> jep function "atanh"
- <mean/> jep function "avg"
- Vectors, matricies lists and sets
- All are converted to jep lists or lists of lists.
- <vector>
- <matrix>
- <matrixrow>
- <set>
- <list>
- Un-supported operators/functions
- <quotient>
- <factorial>
- <gcd>
- <xor>
- <implies>
- <forall>
- <exists>
- <conjugate>
- <lcm>
- <equivalent>
- <approx>
- <factorof>
- <int>
- <diff>
- <partialdiff>
- <lowlimit>
- <uplimit>
- <bvar>
- <divergence>
- <grad>
- <curl>
- <laplacian>
- <union>
- <intersect>
- <in>
- <notin>
- <subset>
- <prsubset>
- <notsubset>
- <notprsubset>
- <setdiff>
- <card>
- <cartesianproduct>
- <product>
- <limit>
- <tendsto>
- <sec>
- <csc>
- <cot>
- <sech>
- <csch>
- <coth>
- <arccot>
- <arccoth>
- <arccsc>
- <arccsch>
- <arcsec>
- <arcsech>
- <sdev>
- <variance>
- <median>
- <mode>
- <moment>
- <momentabout>
- <determinant>
- <transpose>
- <outerproduct>
- Other un-supported elements
- <annotation> - ignored
- <semantics> - treated like content elements
- <annotation-xml> - ignored
- Other un-supported elements
- <integers>
- <reals>
- <rationals>
- <naturalnumbers>
- <complexes>
- <primes>
- Supported entities
- ⅇ unicode "\u2147" jep variable "e"
- ⅈ unicode "\u2148" jep variable "i"
- π unicode "\u03c0" jep variable "pi"