Plurimath
Purpose
Plurimath provides a common data model for mathematical representation languages and allows conversion between various math representation languages.
Plurimath aims to streamline the process of converting mathematical expressions between different representation languages. This facilitates easier integration across different systems and platforms, ensuring that mathematical content remains consistent and accurate regardless of the format it is presented in.
Supported math representational languages:
-
MathML
-
AsciiMath
-
UnicodeMath
-
LaTeX math
-
OMML
Supported units representation languages:
-
UnitsML
Benefits
- Suitability
-
Convert mathematical content to the required format for different tools and platforms.
- Correctness
-
Ensure mathematical expressions are correctly formatted for print and digital publications.
- Interoperability
-
Facilitate the integration of mathematical expressions across various software systems and platforms.
- Accessibility
-
Convert mathematical content into formats that are more accessible for screen readers and other assistive technologies.
Installation
Add this line to your application’s Gemfile:
gem "plurimath"
And then execute:
$ bundle install
Or install it yourself with:
$ gem install plurimath
Command Line Interface (CLI) usage
General
Plurimath provides a Command Line Interface (CLI) tool for converting between different math formats.
Note
|
Before continuing please ensure you have the gem installed. |
To convert math equations between formats, use the following command followed by appropriate options.
plurimath convert [options]
Options available are:
-
-i
,--input <INPUT>
-
Specifies the input math equation. Should be provided within double quotes.
-
-f
,--input-format <FORMAT>
-
Specifies the input format of the equation. Defaults to
asciimath
. -
-p
,--file-path <FILE_PATH>
-
Reads input from a file instead of the command line input. Use this for larger inputs or when input contains special characters.
-
-t
,--output-format <FORMAT>
-
Specifies the output format type. Defaults to
mathml
. -
-m
,--math-rendering
-
Renders the converted equation as a math zone display tree. Boolean option (
true
,false
). -
-d
,--display-style
-
Specifies the DisplayStyle for OMML and MathML outputs only. Boolean option (
true
,false
). -
-s
,--split-on-linebreak
-
Splits MathML and OMML output into multiple equations. Boolean option (
true
,false
).
Convert an AsciiMath equation to MathML
plurimath convert -i "sqrt(x^2 + y^2)" -f asciimath -t mathml
Convert an OMML equation to MathML with DisplayStyle
plurimath convert -i "equation" -f omml -t mathml -d true
Convert equations from a file and output as UnicodeMath
plurimath convert -e <file_path> -t unicodemath
For more detailed information and additional options, use:
plurimath help convert
Ruby API
The central data model in Plurimath is the Plurimath::Formula
class, which
allows you to transform any math representation language into any other
representation language.
Conversion examples
AsciiMath Formula example
asciimath = "sin(1)"
formula = Plurimath::Math.parse(asciimath, :asciimath)
MathML Formula example
mathml = <<~MATHML
<math xmlns='http://www.w3.org/1998/Math/MathML'>
<mstyle displaystyle='true'>
<mi>sin</mi>
<mn>1</mn>
</mstyle>
</math>
MATHML
formula = Plurimath::Math.parse(mathml, :mathml)
LaTeX Formula example
latex = "\\sin{1}"
formula = Plurimath::Math.parse(latex, :latex)
UnicodeMath Formula example
unicodemath = "sin(1)"
formula = Plurimath::Math.parse(unicodemath, :unicodemath)
OMML Formula example
omml = <<~OMML
<m:oMathPara xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math">
<m:oMath>
<m:f>
<m:fPr>
<m:ctrlPr />
</m:fPr>
<m:num>
<m:r>
<m:t>sin</m:t>
</m:r>
</m:num>
<m:den>
<m:r>
<m:t>1</m:t>
</m:r>
</m:den>
</m:f>
</m:oMath>
</m:oMathPara>
OMML
formula = Plurimath::Math.parse(omml, :omml)
Converting to other formats
Once you have a Plurimath::Math::Formula
object, you can convert it to
AsciiMath, MathML, LaTeX, UnicodeMath, or OMML by calling the respective
conversion function on the Formula
object.
AsciiMath output conversion
formula.to_asciimath
# => "sin(1)"
Note
|
AsciiMath doesn’t support certain symbols that LaTeX does. During conversion from LaTeX to AsciiMath, if a symbol is not supported in AsciiMath, the LaTeX symbol will be returned. |
LaTeX output conversion
formula.to_latex
# => "\\sin1"
MathML output conversion
formula.to_mathml
# => "<math xmlns='http://www.w3.org/1998/Math/MathML'><mstyle displaystyle='true'><mi>sin</mi><mn>1</mn></mstyle></math>"
UnicodeMath output conversion
formula.to_unicodemath
# => "sin(1)"
OMML output conversion
formula.to_omml
# => "<m:oMathPara xmlns:m=\"http://schemas.openxmlformats.org/officeDocument/2006/math\"><m:oMath><m:f><m:fPr><m:ctrlPr /></m:fPr><m:num><m:r><m:t>sin</m:t></m:r></m:num><m:den><m:r><m:t>1</m:t></m:r></m:den></m:f></m:oMath></m:oMathPara>"
Complex mathematical expressions
Plurimath is capable of handling complex mathematical expressions with nested functions and operators.
This feature is particularly useful for application that requires consistent and accurate conversion of intricate mathematical content.
Example. Consider the following complex LaTeX expression:
\frac{\sqrt{a^2 + b^2}}{\sin(\theta) + \cos(\theta)}
You can parse and convert this complex expression with Plurimath:
complex_latex = "\\frac{\\sqrt{a^2 + b^2}}{\\sin(\\theta) + \\cos(\\theta)}"
formula = Plurimath::Math.parse(complex_latex, :latex)
# Convert to AsciiMath
asciimath = formula.to_asciimath
# => "frac(sqrt(a^2 + b^2))(sin(theta) + cos(theta))"
# Convert to MathML
mathml = formula.to_mathml
# => "<math xmlns='http://www.w3.org/1998/Math/MathML'><mfrac><msqrt><mrow><msup><mi>a</mi><mn>2</mn></msup><mo>+</mo><msup><mi>b</mi><mn>2</mn></msup></mrow></msqrt><mrow><mi>sin</mi><mo>(</mo><mi>θ</mi><mo>)</mo><mo>+</mo><mi>cos</mi><mo>(</mo><mi>θ</mi><mo>)</mo></mrow></mfrac></math>"
# Convert to UnicodeMath
unicodemath = formula.to_unicodemath
# => "frac(√(a^2 + b^2))(sin(θ) + cos(θ))"
# Convert to OMML
omml = formula.to_omml
# => "<omml representation of the expression>"
Math parse trees
General
Plurimath allows you to display the math parse tree both as Formula
objects
and in the math language of expression.
Displaying as Formula objects
You can display the parse tree as Formula
objects to understand the structure
of the parsed mathematical expression.
formula = Plurimath::Math.parse("sin(1)", :asciimath)
formula.to_display(:formula)
# ...
Displaying in the math language of expression
You can also display the parse tree in the math language of expression to see how the expression is represented in that language.
formula = Plurimath::Math.parse("sin(1)", :asciimath)
formula.to_display(:asciimath)
# |_ Math zone
# |_ "sin(1)"
# |_ "sin" function apply
# |_ "1" argument
formula.to_display(:latex)
# |_ Math zone
# |_ "\\sin1"
# |_ "sin" function apply
# |_ "1" argument
formula.to_display(:mathml)
# |_ Math zone
# |_ "<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mstyle displaystyle="true"><mrow><mi>sin</mi><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></mrow></mstyle></math>"
# |_ "<mrow><mi>sin</mi><mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow></mrow>" function apply
# |_ "sin" function name
# |_ "<mrow><mo>(</mo><mn>1</mn><mo>)</mo></mrow>" argument
# |_ "<mtext>1</mtext>" text
Working with UnitsML
General
Plurimath supports UnitsML, a markup language used to express units of measure in a way that can be understood by humans and machines. This allows you to handle mathematical expressions involving units of measure seamlessly.
UnitsML can be used with the following math representation languages:
-
MathML
-
AsciiMath
For detailed information on supported units and symbols in UnitsML, refer to the UnitsML Supported Data documentation.
Parsing and Converting UnitsML Expressions
Plurimath can parse UnitsML expressions and convert them to other mathematical representation languages. Here’s an example of how to work with UnitsML in Plurimath.
Example: Parsing and Converting UnitsML
Consider the following UnitsML expression in AsciiMath syntax:
h = 6.62607015 xx 10^(-34) "unitsml(kg*m^2*s^(-1))"
Step-by-Step Customization
-
Parse the UnitsML Expression
-
Customize and Convert to AsciiMath
-
Customize and Convert to MathML
-
Customize and Convert to UnicodeMath
-
Customize and Convert to OMML
Parse the UnitsML Expression
First, parse the UnitsML expression using Plurimath:
require 'plurimath'
asciimath_unitsml = 'h = 6.62607015 xx 10^(-34) "unitsml(kg*m^2*s^(-1))"'
formula = Plurimath::Math.parse(asciimath_unitsml, :asciimath)
Customize and Convert to AsciiMath
You can customize the output by modifying the resulting string after conversion:
asciimath = formula.to_asciimath
# Customization logic (if any)
puts asciimath
# Output: 'h = 6.62607015 xx 10^(-34) "unitsml(kg*m^2*s^(-1))"'
Customize and convert to MathML
To customize the MathML output, you can use additional attributes and options:
mathml = formula.to_mathml
# Customization logic (if any)
puts mathml
# Output: "<math xmlns='http://www.w3.org/1998/Math/MathML'><mrow><mi>h</mi><mo>=</mo><mn>6.62607015</mn><mo>×</mo><msup><mn>10</mn><mrow><mo>−</mo><mn>34</mn></mrow></msup><mtext>kg·m²·s⁻¹</mtext></mrow></math>"
Customize and convert to UnicodeMath
Similarly, customize the UnicodeMath output:
unicodemath = formula.to_unicodemath
# Customization logic (if any)
puts unicodemath
# Output: 'h = 6.62607015 × 10^(−34) kg·m²·s⁻¹'
Customize and convert to OMML
For OMML output, you can customize the XML structure:
omml = formula.to_omml
# Customization logic (if any)
puts omml
# Output: "<m:oMathPara xmlns:m='http://schemas.openxmlformats.org/officeDocument/2006/math'><m:oMath><m:r><m:t>h</m:t></m:r><m:r><m:t>=</m:t></m:r><m:r><m:t>6.62607015</m:t></m:r><m:r><m:t>×</m:t></m:r><m:sSup><m:sSupPr><m:ctrlPr /></m:sSupPr><m:e><m:r><m:t>10</m:t></m:r></m:e><m:sup><m:r><m:t>−34</m:t></m:r></m:sup></m:sSup><m:r><m:t>kg·m²·s⁻¹</m:t></m:r></m:oMath></m:oMathPara>"
Complete example code with customization
Here’s the complete code for parsing, converting, and customizing the UnitsML expression between different formats:
require 'plurimath'
# Step 1: Parse the UnitsML Expression
asciimath_unitsml = 'h = 6.62607015 xx 10^(-34) "unitsml(kg*m^2*s^(-1))"'
formula = Plurimath::Math.parse(asciimath_unitsml, :asciimath)
# Step 2: Convert to AsciiMath
asciimath = formula.to_asciimath
# Customization logic for AsciiMath (if needed)
puts "AsciiMath: #{asciimath}"
# Output: 'h = 6.62607015 xx 10^(-34) "unitsml(kg*m^2*s^(-1))"'
# Step 3: Convert to MathML
mathml = formula.to_mathml
# Customization logic for MathML (if needed)
puts "MathML: #{mathml}"
# Output: "<math xmlns='http://www.w3.org/1998/Math/MathML'><mrow><mi>h</mi><mo>=</mo><mn>6.62607015</mn><mo>×</mo><msup><mn>10</mn><mrow><mo>−</mo><mn>34</mn></mrow></msup><mtext>kg·m²·s⁻¹</mtext></mrow></math>"
# Step 4: Convert to UnicodeMath
unicodemath = formula.to_unicodemath
# Customization logic for UnicodeMath (if needed)
puts "UnicodeMath: #{unicodemath}"
# Output: 'h = 6.62607015 × 10^(−34) kg·m²·s⁻¹'
# Step 5: Convert to OMML
omml = formula.to_omml
# Customization logic for OMML (if needed)
puts "OMML: #{omml}"
# Output: "<m:oMathPara xmlns:m='http://schemas.openxmlformats.org/officeDocument/2006/math'><m:oMath><m:r><m:t>h</m:t></m:r><m:r><m:t>=</m:t></m:r><m:r><m:t>6.62607015</m:t></m:r><m:r><m:t>×</m:t></m:r><m:sSup><m:sSupPr><m:ctrlPr /></m:sSupPr><m:e><m:r><m:t>10</m:t></m:r></m:e><m:sup><m:r><m:t>−34</m:t></m:r></m:sup></m:sSup><m:r><m:t>kg·m²·s⁻¹</m:t></m:r></m:oMath></m:oMathPara>"
Compatibility
General
Not every math representation language supports expressing all symbols and
primitives supported by another. For example, the backepsilon
symbol is
supported by LaTeX and UnicodeMath, but not AsciiMath.
Plurimath implements a "compatibility wrapper" syntax for each math
representation language to allow all symbols usable by Plurimath to be expressed
in a side-effect-free wrapper in those languages. For example, in AsciiMath, the
"{symbol-name}"
is side-effect-free because it is considered a single symbol
as a text string of "
{symbol-name}"
. Plurimath can recognize it, but other
renderers or processors would treat it as a single symbol, which is accurate.
Usage of the compatibility wrapper
For a symbol like backepsilon
.
In AsciiMath:
"__{backepsilon}"
In LaTeX:
"\\backepsilon"
In UnicodeMath:
"∍"
In MathML:
<mi>∍</mi>
XML engines
Plurimath supports two XML engines:
-
Ox: (default) A fast XML parser
-
Oga: A pure Ruby XML parser
By default, Ox is used.
To switch to Oga, use the following syntax:
require "plurimath/xml_engines/oga"
Plurimath.xml_engine = Plurimath::XmlEngine::Oga
You can switch back to Ox similarly.
Supported content
General
Consult the following tables for details on supported symbols and parentheses:
The following table shows the classes that support MathML "intent" encoding:
Note
|
To regenerate these files, delete them and run:
bundle exec rake supported_symbols_list.adoc .
|
Copyright and license
Copyright Ribose. BSD 2-clause license.