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:
-
LaTeX math
-
Microsoft Office Math Markup Language (OMML) "OfficeMath"
Supported units representation languages:
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
).
plurimath convert -i "sqrt(x^2 + y^2)" -f asciimath -t mathml
plurimath convert -i "equation" -f omml -t mathml -d true
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>"
Number formatting
Introduction
Number formatting is an essential aspect of presenting numerical data in a way that is consistent with regional conventions and user preferences. There are myriad number formatting conventions and standards that are widely used in various cultures and fields.
To address these needs, Plurimath now allows precise control over how numbers are presented through its number formatting feature.
Plurimath’s number formatter allows users to format numbers based on locale, ensuring that the formatting adheres to regional conventions and enhances both readability and precision.
For more details, please refer to the blog post Number formatting support in Plurimath
Existing conventions
Traditional conventions
Different cultures, orthographies and organizations have different conventions for formatting numbers.
These include practices on how to represent decimal points, digit grouping, digit grouping separators, and various mathematical notations.
- Decimal point symbol
-
In the United States, a full stop (
.
) is used as the decimal point separator, while in many European countries, a comma (,
) is used instead. - Digit grouping delimiter
-
In the United States, numbers are often grouped in sets of three digits using commas, such as 1,234,567.89. In some European countries, numbers are grouped using periods, such as 1.234.567,89, or a thin space, such as 1 234 567,89.
- Digit grouping practices
-
In Western cultures, numbers ahead of the decimal are often grouped threes. Numbers behind the decimal are less standardized, but are often grouped in sets of two or three.
- Mathematical notation
-
In scientific and engineering contexts, numbers are often formatted using scientific notation, which expresses numbers as a coefficient multiplied by a power of 10. For example, the number 123,456,789 can be expressed in scientific notation as 1.23456789 x 10^8.
Standardized conventions
Standardization organizations have established standards for number formatting to ensure uniformity and accuracy.
The SI system (International System of Units), by the BIPM (Bureau International des Poids et Mesures), specifies rules regarding the decimal point symbol, digit grouping delimiter and digit groupings.
ISO 80000-2, the international standard for quantities and units, used by all ISO and IEC standards, also provides guidelines for number formatting in a different manner than the SI system.
Using the number formatter
General
The number formatting feature is implemented in the Plurimath::NumberFormatter
class, which allows users to re-use a single formatter class for formatting
multiple numbers.
A simple two-step process to format numbers:
-
Create a new
Plurimath::NumberFormatter
object, passing the desired locale and overriding options as arguments. -
Call the
localized_number
method on the formatter object, passing the number to be formatted as a string and any additional options.
The final formatted number is formatted according to the following configuration priority, ordered from highest to lowest precedence:
-
The
format
hash given toPlurimath::NumberFormatter#localized_number
-
The
localize_number
string in the creation of aPlurimath::NumberFormatter
-
The
localizer_symbols
hash in the creation of aPlurimath::NumberFormatter
-
The default configuration of the locale of the
Plurimath::NumberFormatter
formatter = Plurimath::NumberFormatter.new(:en)
formatted_number = formatter.localized_number(
"1234567.89",
format: {
group_digits: 2,
# other support options
}
)
# => "1,23,45,67.89"
Creating a number formatter
The NumberFormatter
is used to format numbers based on the locale and the
formatting configuration provided.
Syntax:
Plurimath::NumberFormatter
objectformatter = Plurimath::NumberFormatter.new(
<locale-symbol>, # mandatory (1)
localize_number: <localize-string>, # optional (2)
localizer_symbols: <format-hash>, # optional (3)
precision: <precision-number>, # optional (4)
)
-
Locale to be used for number formatting.
-
String pattern to define the number formatting.
-
Hash containing relevant options for number formatting.
-
Number of decimal places to round.
Where,
<locale-symbol>
-
(optional, default
:en
) The locale to be used for number formatting. Accepted values are listed in thePlurimath::Formatter::SupportedLocales::LOCALES
constant. localize_number: <localize-string>
-
(optional, default
nil
) A string containing a specific sequence of characters that defines the number formatting. Use eitherlocalize_number
orlocalizer_symbols
to set the number formatting pattern.See
localize_number
for details. localizer_symbols: <format-hash>
-
(optional, default
{}
) A hash containing the relevant options for number formatting. Use eitherlocalize_number
orlocalizer_symbols
to set the number formatting pattern.See format options hash for details.
precision: <precision-number>
-
(optional, default
nil
) Number of decimal places to round. Accepts an integer value.Example 5. Specifying a precision of 6 digits"32232.232" ⇒ "32232.232000"
Plurimath::NumberFormatter
object using the :en
localeformatter = Plurimath::NumberFormatter.new(:en)
# => #<Plurimath::NumberFormatter:0x00007f8b1b8b3b10 @locale=:en>
Configuring the number formatter
The Plurimath::NumberFormatter
object can be configured using either the
localize_number
or localizer_symbols
options.
Via "format options" using localizer_symbols
The localizer_symbols
key is used to set the number formatting pattern
through a Hash object containing specified options.
This Hash object is called the "format options Hash".
Available options are explained below.
Note
|
Each option takes an input of a certain specified type (String or
Numeric ). Using an input type other than the specified type will result in
errors or incorrect output.
|
The values passed to localizer_symbols
persist as long as the initialized
NumberFormatter
instance is accessible. It is therefore useful in scenarios
when configuration will be static or changes are not required very often.
decimal
-
(
String
value) Symbol to use for the decimal point. Accepts a character.Example 7. Using the ',' "comma" symbol as the decimal point"32232.232" ⇒ "32232,232"
Example 8. Using the '.' "full stop" symbol as the decimal point"32232.232" ⇒ "32232.232"
digit_count
-
(
Numeric
value) Total number of digits to render, with the value truncated. Accepts an integer value.Example 9. Specifying a total of 6 digits in rendering the number"32232.232" ⇒ "32232.2"
group
-
(
String
value) Delimiter to use between groups of digits specified ingroup_digits
. Accepts a character. (default is not to group digits.)Example 10. Using the unicode thin space (THIN SPACE, U+2009) as the grouping delimiter"32232.232" ⇒ "32 232.232"
group_digits
-
(
Numeric
value) Number of digits to group the integer portion, grouping from right to left. Accepts an integer value. (default is 3 in most locales.)Example 11. Using the unicode thin space as the grouping delimiter, and grouping every 2 digits"32232.232" ⇒ "3 22 32.232"
fraction_group
-
(
String
value) Delimiter to use between groups of fractional digits specified infraction_group_digits
. Accepts a character.Example 12. Using the unicode thin space as the fraction grouping delimiter"32232.232131" ⇒ "32232.232 131".
fraction_group_digits
-
(
Numeric
value) Number of digits in each group of fractional digits, grouping from left to right. Accepts an integer value.Example 13. Using the unicode thin space as the fraction grouping delimiter, and grouping every 2 fraction digits"32232.232131" ⇒ "32232.23 21 31"
significant
-
(
Numeric
value) Sets the number of significant digits to show, with the value rounded. notation
-
(
String
value) Specifies the mathematical notation to be used. Accepts the following values.e
-
Use exponent notation.
Example 14. Example of using exponent notation1.23456789e8
scientific
-
Use scientific notation.
Example 15. Example of using scientific notation1.23456789 × 10⁸
engineering
-
Use engineering notation, where the exponent of ten is always selected to be divisible by three to match the common metric prefixes.
Example 16. Example of using engineering notation123.456789 × 10⁶
e
-
(
String
value) Symbol to use for exponents in E notation (default valueE
). (used in the mode:e
only).Example 17. Using the lowercase 'e' symbol as the exponent symbol3.2232232e5
times
-
(
String
value) Symbol to use for multiplication where required by the notation (used in the modes:scientific
andengineering
). Defaults to×
.Example 18. Using the '·' "middle dot" symbol as the multiplication symbol32.232232 · 104
exponent_sign
-
(
String
value) Whether to use a plus sign to indicate positive exponents, in exponent-based notation (used in the modes:e
,scientific
,engineering
). Legal values are:plus
-
The
+
symbol is used.Example 19. Using the plus sign to indicate positive exponents32.232232 × 10⁺⁴
These options are to be grouped under a single Hash object.
localizer_symbols
{
decimal: ",", # replaces the decimal point with the passed string
group_digits: 2, # groups integer part into passed integer
group: "'", # places the string between grouped parts of the integer
fraction_group_digits: 3, # groups fraction part into passed integer
fraction_group: ",", # places the string between grouped parts of the fraction
}
Via the localize_number
option
The localize_number
option accepts a formatting pattern specified as a string,
using the hash symbol #
to represent a digit placeholder.
The localize_number
option is useful when you want to format numbers in a
specific way that is not covered by the localizer_symbols
option.
A sample value of #,##0.### ###
is interpreted as the following
configuration in the format options hash:
group
-
This parameter is set to the very first non-hash character before 0. If there is no non-hash character before
#
+0
, then the default group delimiter will be nil.In this example, it is
,
. group_digits
-
This parameter is set to the "count of all hashes + 1" (including the zero). Minimum 1 hash symbol is required.
In this example,
##0
sets the value to 3. decimal
-
This parameter is set to the character immediately to the right of
0
. This is mandatory.In this example, it is
.
. fraction_group_digits
-
This parameter is set to "count of all the hashes right next to decimal". Minimum 1 hash symbol is required.
In our example, '###' sets the value to 3.
fraction_group
-
This parameter is set to the first character after
fraction_group_digits
. If there is no non-hash character afterfraction_group_digits
, it is set to nil.In this example it is
' '
(a space).
localize_number
optionformatter = Plurimath::NumberFormatter.new(:en, localize_number: "#,##0.### ###")
formatter.localized_number("1234.56789")
# => "1,234.568 9"
Formatting a number using NumberFormatter
The localized_number
method is used to format a number given a
NumberFormatter
instance.
Syntax:
localized_number
formatter.localized_number(
<number>, # mandatory (1)
locale: <locale-symbol>, # optional (2)
precision: <precision-number>, # optional (3)
format: <format-hash> # optional (4)
)
-
The number to be formatted.
-
The locale to be used for number formatting.
-
The number of decimal places to round the number to.
-
Hash containing the relevant options for number formatting.
Where,
<number>
-
(mandatory) The number to be formatted. Value should be a Numeric, i.e. Integer, Float, or BigDecimal. If not provided, an
ArgumentError
will be raised. locale: <locale-symbol>
-
(optional) The locale to be used for number formatting. Value is a symbol. Overrides the locale set during the creation of the
NumberFormatter
object. If not provided, the locale of theNumberFormatter
instance will be used. precision: <precision-number>
-
(optional) The number of decimal places to round the number to. If not provided, the precision of the
NumberFormatter
instance will be used. format: <format-hash>
-
(optional, default
{}
) A Hash containing the relevant options for number formatting, that overrides thelocalizer_symbols
configuration of theNumberFormatter
. Takes a Hash in the form of the format options hash. precision: <precision-number>
-
Number of decimal places to round. Accepts an integer value.
Example 21. Specifying a precision of 6 digits"32232.232" ⇒ "32232.232000"
localized_number
method for the English localeformatter = Plurimath::NumberFormatter.new(:en)
formatter.localized_number("1234.56789")
# => "1,234.56789"
localized_number
method for the French localeformatter = Plurimath::NumberFormatter.new(:fr)
formatter.localized_number("1234.56789")
# => "1 234,56789"
The locale and precision set in the NumberFormatter
can be overridden by
passing the locale
and precision
options to the localized_number
method.
localized_number
formatter = Plurimath::NumberFormatter.new(:en)
formatter.localized_number("1234.56789", locale: :de, precision: 6)
# => "1.234,567890"
Overriding specified NumberFormatter
options using the format
key
The format
option is used to override the specified configuration of the
NumberFormatter
object.
It expects a Hash in the form of the format options hash.
formatter = Plurimath::NumberFormatter.new(:en)
formatter.localized_number(
"1234.56789",
format: {
decimal: "x",
# other supported options
}
)
# => "1,234x56789"
format
key in the localized_number
methodformatter = Plurimath::NumberFormatter.new(:en)
formatter.localized_number(
"1234.56789",
format: {
decimal: "x",
group_digits: 2,
group: "'",
fraction_group_digits: 3,
fraction_group: ","
}
)
# => "12'34x567,89"
Supported locales
Plurimath supports the following locales for number formatting. The locale values are sourced from the Unicode CLDR repository.
The list of locales and their values are given in the file
lib/plurimath/formatter/supported_locales.rb
.
The locales and their values can be obtained through the following code.
Plurimath::Formatter::SupportedLocales::LOCALES[:en]
# => { decimal: ".", group: "," }
Locale | Decimal delimiter | Group delimiter |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Formatting numbers in a formula
General
Plurimath supports number formatting within formulas for all supported languages. This feature allows you to apply custom number formatting when converting formulas to any of the supported format.
Note
|
For details, check out our blog post: Number formatting now supported in formulas across all math representation languages. |
The steps to format numbers within a formula are:
-
Create a number formatter that can be configured;
-
Apply the number formatter to a formula through the
Formula.to_{format}
method using aformatter
option, which serializes the formula into an math representation language.
The formatter should be an instance of Plurimath::NumberFormatter
or a custom
formatter derived from Plurimath::Formatter::Standard
.
The quick example below demonstrates how to format a number in a formula.
The following code applies number formatting to a LaTeX math formula.
formula = Plurimath::Math.parse('\sum_{i=1}^{10000} i^2121221', :latex) (1)
formatter = Plurimath::Formatter::Standard.new (2)
formula.to_latex(formatter: formatter) (3)
# => '\sum_{i = 1}^{10,000} i^{2,121,221}'
-
The formula is parsed into a
Formula
object using thePlurimath::Math.parse
method. -
A
Plurimath::Formatter
is created. -
The
Formula.to_latex
method is called with theformatter
option to format the formula.
formula = Plurimath::Math.parse("e^(i*pi) + 1.1 = 0.2", :asciimath)
custom_formatter = Plurimath::Formatter::Standard.new(
locale: :fr,
options: { number_sign: :plus },
precision: 3
)
print formula.to_mathml(formatter: custom_formatter)
# <math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
# <mstyle displaystyle="true">
# <msup>
# <mi>e</mi>
# <mrow>
# <mi>i</mi>
# <mo>⋅</mo>
# <mi>π</mi>
# </mrow>
# </msup>
# <mo>+</mo>
# <mn>+1.100</mn>
# <mo>=</mo>
# <mn>+0.200</mn>
# </mstyle>
# </math>
Defining a number formatter
A "number formatter" is a class that formats numbers in a specific way. It contains the configuration for formatting numbers, such as the number of digits in a group, the decimal separator, and the group separator.
Plurimath offers a standard formatter class called
Plurimath::Formatter::Standard
that includes a comprehensive
standard configuration.
Plurimath::Formatter::Standard
object> formatter = Plurimath::Formatter::Standard.new (1)
-
Creates a
Plurimath::Formatter
object that uses standard configuration.
The number formatting configuration can be changed in these ways:
-
Pass options to the
Plurimath::Formatter::Standard
class initializer (with options explained in the number formatter blog post). -
Create a custom formatter inheriting from the
Plurimath::Formatter::Standard
class.
Changing number formatting configuration
The typical way to change the number formatting configuration is to create a
Plurimath::Formatter::Standard
object with the desired configuration options.
There are two types of number formatting configuration to change:
-
Arguments passed to the
Plurimath::Formatter::Standard
class initializer. -
Overriding options through the
options
argument.
The arguments are:
locale
-
(default:
:en
for English) a symbol or string value. The supported locales are listed in the number formatter blog post. options
-
(default: empty) a hash of options (
localizer_symbols
). The options are listed in the number formatter blog post. format_string
-
(default:
nil
, disabled) a string value (localize_number) precision
-
(default:
nil
, disabled) an integer value.
Plurimath::Formatter::Standard
class initializer> options = {
fraction_group_digits: 2,
fraction_group: ".",
group_digits: 2,
decimal: ";",
group: ",",
}
> formatter = Plurimath::Formatter::Standard.new(locale: :hy, options: options, precision: 2)
# format_string: <string value> if provided
> Plurimath::Math.parse('2121221.3434', :latex).to_latex(formatter: formatter)
# => '2,12,12,21;34'
The precision = 2
option in the initializer causes the formatted value to have
decimal places truncated from 4 to 2.
Creating a custom formatter
In cases where the standard formatter’s available options do not meet the needs for number presentation, a custom formatter can be created to apply new mechanisms of formatting numbers.
The custom formatter is to be subclassed from Plurimath::Formatter::Standard
.
class MyCustomFormatter < Plurimath::Formatter::Standard (1)
def initialize(locale:, precision:, options:, format_string:) (2)
super
end
end
-
The custom formatter class inherits from
Plurimath::Formatter::Standard
. -
The arguments can be overridden in the
initialize
method.
The default options of the custom formatter are set using the
set_default_options
method.
set_default_options
methodclass MyCustomFormatter < Plurimath::Formatter::Standard
def initialize(locale:, precision:, options:, format_string:)
super
end
def set_default_options(options = {}) (1)
options = {
fraction_group_digits: 2,
fraction_group: ".",
...
}
end
end
-
The
set_default_options
method is overridden to set the default options. The shown options are ones inherited from thePlurimath::Formatter::Standard
class, but additional ones understood by the class can be set.
It is used in the following manner.
CustomFormatter
object and using it to format numbers in a formulaclass MyCustomFormatter < Plurimath::Formatter::Standard
def initialize(locale: :fr)
super
end
def set_default_options(options = {})
{
fraction_group_digits: 2,
fraction_group: ".",
group_digits: 2,
decimal: ";",
group: ",",
...
}
end
end
> formula = Plurimath::Math.parse('\sum_{i=1}^{1000.001} i^2121221.3434', :latex)
# => Plurimath::Math::Formula...
> formula.to_latex(formatter: formatter)
# => '\sum_{i = 1}^{10,00;00.1} i^{2,12,12,21;34.34}'
> formula.to_asciimath(formatter: formatter)
# => 'sum_(i = 1)^(10,00;00.1) i^(2,12,12,21;34.34)'
Default number formatting configuration
The default configuration for formatting numbers is as follows, set in the
Plurimath::Formatter::Standard
class.
Option key | Description | Value |
---|---|---|
|
The locale used for number formatting |
|
|
The number of digits in each group of the fraction part |
|
|
The sign used for the exponent part of the number |
|
|
The character used to separate groups of digits in the fraction part |
|
|
The notation used for the number formatting |
|
|
The number of digits in each group of the integer part |
|
|
The number of significant digits to display |
|
|
The number of digits to display |
|
|
The number of decimal places to display |
|
|
The character used as the decimal separator |
|
|
The character used to separate groups of digits in the integer part |
|
|
The character used for multiplication |
|
|
The character used for exponentiation |
|
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.