Home

Awesome

Mathematical

Quickly convert math equations into beautiful SVGs (or PNGs/MathML).

Build Status Gem Version

Mathematical

⚠️ Maintenance Status ⚠️

SVG and especially PNG generation is currently unmaintained. This library should primarily be used for MathML generation.

Please reach out if you would like to mantain SVG and PNG portions of the library.

Installation

Add this line to your application's Gemfile:

gem 'mathematical'

And then execute:

$ bundle

Or install it yourself as:

$ gem install mathematical

Note: you'll probably need to run script/bootstrap to fetch all the necessary dependencies.

Usage

The simplest way to do this is

require 'mathematical'

Mathematical.new.render(string_with_math)

string_with_math should just be a string of TeX math. The default delimiters are $..$ for inline and $$..$$ for display. These can be changed by options--see below.

The output will be a hash, with keys that depend on the format you want:

Note: If you pass in invalid TeX, an error is not raised, but a message is printed to STDERR. It is the caller's responsibility to check for :exception and act on it.

render just converts a single equation. There are several other methods you can use:

Array of equations

Rather than just a string, you can also provide an array of math inputs:

inputs = []
inputs << '$\pi$'
inputs << '$not__thisisnotreal$'
inputs << '$\alpha$'

Mathematical.new.render(inputs)

This returns an array of hashes, rendering the indices. For example, for the above, you will receive the following output:

[ {:data => "...", :width => ... }, { :data => '$not__thisisnotreal$', :exception => "...", {:data => "...", :width => ... }]

That is, while the first and last elements are valid TeX math, the middle one is not, so the same string is returned. As with single strings, the error message is printed to STDERR, but not raised.

Options

Mathematical.new takes an optional hash to define a few options:

NameDescriptionDefault
:ppiA double determining the pixels per inch of the resulting SVG72.0
:zoomA double determining the zoom level of the resulting SVG1.0
:base64A boolean determining whether Mathematical's output should be a base64-encoded SVG stringfalse
:maxsizeA numeral indicating the MAXSIZE the output string can be.unsigned long
:formatA symbol indicating whether you want an :svg, :png, or :mathml output.:svg
:delimiterA symbol indicating whether you want an :DOLLAR for inline ($..$), :DOUBLE for display ($$..$$), :PARENS for inline (\(..\)), :BRACKETS for display ([..\]), or :ENVIRONMENTS for parsing bare \\begin..\\end environments. You can also pass in an array of symbols to have multiple delimiters considered.[:DOLLAR, :DOUBLE]

Pass these in like this:

options = { :ppi => 200.0, :zoom => 5.0, :base64 => true }
renderer = Mathematical.new(options)
renderer.render('$a \ne b$')

Supported commands and symbols

Check out SUPPORTED.md on the mtex2MML website.

Note: This library makes a few assumptions about the strings that you pass in. It assumes that $..$ is inline math and $$..$$ is display math.

Building

Before building this gem, you must install the following libraries:

After cloning the repo, you can fetch dependencies and run the library by typing:

script/bootstrap
bundle exec rake compile

If there were no errors, you're done! Otherwise, make sure to follow the dependency instructions.

Fonts and special notices for Mac OS X

Install the fonts with:

cd ~/Library/Fonts
curl -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/cmex10.ttf \
     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/cmmi10.ttf \
     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/cmr10.ttf \
     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/cmsy10.ttf \
     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/esint10.ttf \
     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/eufm10.ttf \
     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/msam10.ttf \
     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/msbm10.ttf

Troubleshooting

Issues building Lasem

If you're having issues building Lasem, or have Lasem already preinstalled, you should set the MATHEMATICAL_USE_SYSTEM_LASEM environment variable to skip the build:

Issues building mtex2mml

If you're having issues building mtex2mml, or have mtex2mml already preinstalled, you should set the MATHEMATICAL_USE_SYSTEM_MTEX2MML environment variable to skip the build:

Benchmark

Run benchmarks with bundle exec rake benchmark:

Benchmarking....
Count: 3868 equations
Iterations: 1
                                               user     system      total        real
Rendering...                               3.280000   0.070000   3.350000 (  4.324458)

History

There are a smattering of libraries written in various languages to convert math into a variety of formats. But there needs to be a sane way to show math equations in the browser. With browser support for MathML under attack, it's unfortunately not a sustainable solution. A PNG or SVG representation of the equation is the safest way to go.

Most advice suggests using MathJax. While extremely popular I dislike the "stuttering" effect caused by pages loading math. JavaScript shouldn't be used in situations where server-rendering is a possibility, in my opinion.

To that end, I obsessed over the problem of server-side math rendering for over a week. Here was my journey:

And thus a wrapper was born.

More math stuff

Check out math-to-itex, which quickly parses out TeX notation from strings.

With it, you could do something fun like:

MathToItex(string).convert do |eq, type|
  svg_content = Mathematical.new(:base64 => true).render(eq)

  # create image tags of math with base64-encoded SVGs
  %|<img class="#{type.to_s}-math" data-math-type="#{type.to_s}-math" src="#{svg_content}"/>|
end