Project

plurimath

0.01
The project is in a healthy, maintained state
Converts LaTeX math into MathML.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Runtime

 Project Readme

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

  1. Parse the UnitsML Expression

  2. Customize and Convert to AsciiMath

  3. Customize and Convert to MathML

  4. Customize and Convert to UnicodeMath

  5. 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:

  1. Ox: (default) A fast XML parser

  2. 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 Ribose. BSD 2-clause license.