UnitsML is a markup language for representing units of measurement in a machine-readable format.
It is designed to be used in various applications, including scientific computing, data analysis, and engineering.
The UnitsML Ruby library provides the following components:
XML syntax for:
-
representing units and quantity information Composite units
-
Parser for the UnitsML parser - Parses UnitsML expressions.
-
Unit Converter - Converts units between formats.
-
Formatter - Formats units for display in various formats.
The UnitsML Ruby library is a gem for parsing, manipulating, and converting unit expressions based on the Units Markup Language (UnitsML) specification. This library provides functionality to handle units of measurement in a standardized way across different formats.
The UnitsML Ruby library consists of several key components:
-
Parser: Parses string expressions into structured data
-
Transform: Transforms parsed data into domain objects
-
Formula: Represents compound unit expressions
-
Unit: Represents individual units
-
Prefix: Represents unit prefixes (k, m, μ, etc.)
-
Dimension: Represents physical dimensions
The library also includes the full UnitsDB units database, which contains standard units, prefixes, and dimensions.
The UnitsML Ruby library supports AsciiUnits, a text-based syntax for representing units of measurement in a compact and human-readable format.
The UnitsML Ruby library supports all available units defined in the official UnitsDB database.
A basic unit is a unit that has an entry in the UnitsDB database with a unique identifier.
Basic units are represented in the library as Unitsml::Unit
objects.
require 'unitsml'
unit = Unitsml.parse("m") # Parse a unit expression
unit.to_s # => "m"
unit.to_xml
# =>
<Unit xmlns="https://schema.unitsml.org/unitsml/1.0" xml:id="U_NISTu1" dimensionURL="#NISTd1">
<UnitSystem name="SI" type="SI_derived" xml:lang="en-US"/>
<UnitName xml:lang="en">meter</UnitName>
<UnitSymbol type="HTML">m</UnitSymbol>
<UnitSymbol type="MathMl">
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<mi mathvariant="normal">m</mi>
</math>
</UnitSymbol>
</Unit>
<Dimension xmlns="https://schema.unitsml.org/unitsml/1.0" xml:id="NISTd1">
<Length symbol="L" powerNumerator="1"/>
</Dimension>
A prefixed unit is a unit that has a prefix (like kilo, milli, micro, etc.) that modifies its value.
Prefixed units are represented in the library as Unitsml::Prefix
objects.
The library supports the full range of prefixes defined in the UnitsDB database.
require 'unitsml'
unit = Unitsml.parse("um") # Parse a unit expression
unit.to_s # => "um"
unit.to_xml
# =>
<Unit xmlns="https://schema.unitsml.org/unitsml/1.0" xml:id="U_um" dimensionURL="#NISTd1">
<UnitSystem name="SI" type="SI_derived" xml:lang="en-US"/>
<UnitName xml:lang="en">um</UnitName>
<UnitSymbol type="HTML">µm</UnitSymbol>
<UnitSymbol type="MathMl"><math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<mi mathvariant='normal'>µm</mi>
</math>
</UnitSymbol>
<RootUnits>
<EnumeratedRootUnit unit="meter" prefix="u"/>
</RootUnits>
</Unit>
<Prefix xmlns="https://schema.unitsml.org/unitsml/1.0" prefixBase="10" prefixPower="-6" xml:id="NISTp10_-6">
<PrefixName xml:lang="en">micro</PrefixName>
<PrefixSymbol type="ASCII">u</PrefixSymbol>
<PrefixSymbol type="unicode">μ</PrefixSymbol>
<PrefixSymbol type="LaTeX">$mu$</PrefixSymbol>
<PrefixSymbol type="HTML">µ</PrefixSymbol>
</Prefix>
<Dimension xmlns="https://schema.unitsml.org/unitsml/1.0" xml:id="NISTd1">
<Length symbol="L" powerNumerator="1"/>
</Dimension>
Prefixed units: mm, kg, μm
A composite unit is a unit that is derived from two or more basic units conjoined by multiplication or division.
Composite units are created using the Unitsml.parse
method.
Compound units with operations: kg*s^-2 Units with powers: C^3 Square roots: sqrt(Hz) Units with prefixes: m/s, m2/s2
The library supports representation of UnitsML-encoded units in various formats.
These formats include:
-
MathML
-
LaTeX
-
AsciiMath
-
HTML
-
Unicode
-
XML (in UnitsML)
Units can be converted to multiple formats as follows:
unit = Unitsml.parse("m/s")
unit.to_mathml # MathML representation
unit.to_latex # LaTeX representation
unit.to_asciimath # AsciiMath representation
unit.to_html # HTML representation
unit.to_unicode # Unicode representation
unit.to_xml # XML (in UnitsML) representation
When converting units to formats like MathML or LaTeX, you can specify whether to use explicit parentheses for clarity in complex expressions.
A pair of parentheses is typically used for two purposes:
-
For grouping to indicate operator precedence in mathematical expressions. When expressing units, most of the time, parentheses are used to indicate operator precedence, parentheses are only kept in cases where it indicates precedence. When parentheses are not needed for precedence, such as in the expression
(m/s)
, the parentheses can be removed whilch simplifies the expression intom/s
. -
For indicating that an expression is a compound unit. These parentheses are explicit parentheses that cannot be removed without changing the meaning of the expression.
UnitsML Ruby provides an option explicit_parenthesis
to control the inclusion
of parentheses in the output.
In an expression:
-
(…)
is considered an implicit parenthesis for grouping and operator precedence and can be removed without changing the meaning of the expression. -
…
is considered an explicit parenthesis, which indicates that the parentheses need to be preserved in the output regardless of operator precedence.
The explicit_parenthesis
option allows you to control how parentheses are
considered in the output formats. It can be set to true
or false
.
Syntax for using explicit_parenthesis
is as follows:
unit.to_asciimath(explicit_parenthesis: true) # or false
unit.to_mathml(explicit_parenthesis: true) # or false
unit.to_latex(explicit_parenthesis: true) # or false
When explicit_parenthesis
is set to:
true
-
(default) the usage of
(…)
and…
is differentiated as implicit and explicit parentheses, respectively. false
-
all parentheses are treated as grouping parentheses, there is no difference between
(…)
and…
.
explicit_parenthesis
is true
and double parentheses are considered explicit parenthesesUnitsml.parse("((m/s))").to_asciimath
> "(m/s^-1)" # Only one of the two pairs of parentheses are included in the output
If an extra pair of parentheses is included, it will be considered as grouping parentheses and will not be included in the Unitsml::Formula or the output.
explicit_parenthesis
is true
and double parentheses are considered explicit parenthesesUnitsml.parse("(((m/s)))").to_asciimath
> "(m/s^-1)" # the third pair of parentheses are ignored as grouping parentheses
Unitsml.parse("(((((m/s)))))").to_asciimath
> "((m/s^-1))" # the fifth pair of parentheses are ignored as grouping parentheses
unit = Unitsml.parse("((m/s))")
unit.to_asciimath # equivalent to (explicit_parenthesis: true) => "(m/s^-1)"
unit = Unitsml.parse("((m/s))*((m/s))")
unit.to_asciimath(explicit_parenthesis: true) # "(m/s^-1)*(m/s^-1)"
When explicit_parenthesis
is false
, all parentheses are treated as grouping parentheses
and therefore will be reduced to only the necessary parentheses for operator precedence.
explicit_parenthesis
is false
, all parentheses are treated as grouping parenthesesunit = Unitsml.parse("(m/s)")
unit.to_asciimath(explicit_parenthesis: false) # => "m/s"
unit = Unitsml.parse("((m/s))*((m/s))")
unit.to_asciimath(explicit_parenthesis: false) # "m/s^-1*m/s^-1"
Add this line to your application’s Gemfile:
gem 'unitsml'
And then execute:
$ bundle install
Or install it yourself with:
$ gem install unitsml
UnitsML Ruby provides functionality to represent and convert units between different formats including MathML, LaTeX, AsciiMath, HTML, Unicode, and XML(Unitsml schema based elements).
Units can be converted to different formats:
unit = Unitsml.parse("m/s") # Create a unit example
# Convert to different formats
unit.to_mathml
unit.to_latex
unit.to_asciimath
unit.to_html
unit.to_unicode
unit.to_xml
An Extender
is the symbol between units (like multiplication or division):
formula = Unitsml.parse("m*m") # the '*' is the extender
formula.to_mathml
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
<mi mathvariant="normal">m</mi>
<mo>⋅</mo>
<mi mathvariant="normal">m</mi>
</math>
The output of extenders can be customized by passing the multiplier
argument:
formula = Unitsml.parse("m/m")
formula.to_asciimath(multiplier: "·") # the '·' is the extender for the output
> "m·m^-1"
The multiplier
argument is supported in all supported conversions.
This gem requires the Plurimath gem to provide to_plurimath
method
functionality. You need to explicitly install it, please follow the installtion
instructions in the
Plurimath
repository.
After checking out the repo, run bin/setup
to install dependencies. Then, run
bundle exec spec
to run the tests. You can also run bin/console
for an
interactive prompt that will allow you to experiment.
When developing or contributing to UnitsML Ruby, you’ll need to ensure the submodules are available. After cloning the repository, verify that the submodules exist in the directory.
If not, populate the submodules by running:
$ git submodule update --init --recursive
unitsdb
is the only submodule required in this gem for now.
Everyone interacting in the Unitsml project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.
This project is licensed under the BSD 2-clause License.
See the LICENSE.md file for details.
Copyright Ribose.