{"id":13719106,"url":"https://github.com/gjtorikian/mathematical","last_synced_at":"2025-05-07T11:30:58.920Z","repository":{"id":16083470,"uuid":"18828120","full_name":"gjtorikian/mathematical","owner":"gjtorikian","description":"Convert mathematical equations to SVGs, PNGs, or MathML. A general wrapper to Lasem and mtex2MML.","archived":true,"fork":false,"pushed_at":"2024-08-14T13:48:54.000Z","size":31596,"stargazers_count":166,"open_issues_count":11,"forks_count":31,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-04-21T16:46:19.636Z","etag":null,"topics":["math","mathml","rubydatascience","svg","tex-math"],"latest_commit_sha":null,"homepage":"https://gjtorikian.github.io/mathematical/","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gjtorikian.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"gjtorikian","patreon":"gjtorikian","open_collective":"garen-torikian","issuehunt":"gjtorikian"}},"created_at":"2014-04-16T05:36:49.000Z","updated_at":"2024-12-28T14:51:06.000Z","dependencies_parsed_at":"2023-11-29T19:30:14.836Z","dependency_job_id":"37113761-ec74-4f7a-a82b-a51ff6fa09be","html_url":"https://github.com/gjtorikian/mathematical","commit_stats":{"total_commits":650,"total_committers":15,"mean_commits":"43.333333333333336","dds":"0.15230769230769226","last_synced_commit":"ec94ba8f0fe40d81996e12e6a07ad3a07836d332"},"previous_names":[],"tags_count":52,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gjtorikian%2Fmathematical","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gjtorikian%2Fmathematical/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gjtorikian%2Fmathematical/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gjtorikian%2Fmathematical/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gjtorikian","download_url":"https://codeload.github.com/gjtorikian/mathematical/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252868687,"owners_count":21816908,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["math","mathml","rubydatascience","svg","tex-math"],"created_at":"2024-08-03T01:00:42.541Z","updated_at":"2025-05-07T11:30:58.291Z","avatar_url":"https://github.com/gjtorikian.png","language":"Ruby","funding_links":["https://github.com/sponsors/gjtorikian","https://patreon.com/gjtorikian","https://opencollective.com/garen-torikian","https://issuehunt.io/r/gjtorikian"],"categories":["Visualization","Ruby"],"sub_categories":[],"readme":"# Mathematical\n\nQuickly convert math equations into beautiful SVGs (or PNGs/MathML).\n\n[![Build Status](https://travis-ci.org/gjtorikian/mathematical.svg?branch=master)](https://travis-ci.org/gjtorikian/mathematical) [![Gem Version](https://badge.fury.io/rb/mathematical.svg)](http://badge.fury.io/rb/mathematical)\n\n![Mathematical](https://i.imgur.com/JC7HT32.gif)\n\n## ⚠️ Maintenance Status ⚠️\n\nSVG and especially PNG generation is currently unmaintained. This library should primarily be used for MathML generation.\n\nPlease reach out if you would like to mantain SVG and PNG portions of the library.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n    gem 'mathematical'\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install mathematical\n\n**Note:** you'll probably need to run [`script/bootstrap`](script/bootstrap) to fetch all the necessary dependencies.\n\n## Usage\n\nThe simplest way to do this is\n\n``` ruby\nrequire 'mathematical'\n\nMathematical.new.render(string_with_math)\n```\n\n`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.\n\nThe output will be a hash, with keys that depend on the format you want:\n\n* If you asked for an SVG, you'll get:\n  * `:width`: the width of the resulting image\n  * `:height`: the height of the resulting image\n  * `:data`: the actual string of SVG\n* If you asked for a PNG, you'll get:\n  * `:width`: the width of the resulting image\n  * `:height`: the height of the resulting image\n  * `:data`: the PNG data\n* If you asked for MathML, you'll get:\n  * `:data`: the MathML data\n* If you pass in invalid TeX, you'll get:\n  * `:data`: the original invalid TeX\n  * `:exception`: the error class (with message)\n\n**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.\n\n`render` just converts a single equation. There are several other methods you can use:\n\n* `filter`:  Given a string with a mix of TeX math and non-math elements, this returns a single string containing just the converted math elements.\n* `text_filter`: Given a string with a mix of TeX math and non-math elements, this converts all the math and leaves the rest of the string unmodified.\n* `strict_filter`:  Given a string with a mix of TeX math and non-math elements, this converts all the math and leaves the rest of the string unmodified. HTML tags are removed completely.\n\n### Array of equations\n\nRather than just a string, you can also provide an array of math inputs:\n\n``` ruby\ninputs = []\ninputs \u003c\u003c '$\\pi$'\ninputs \u003c\u003c '$not__thisisnotreal$'\ninputs \u003c\u003c '$\\alpha$'\n\nMathematical.new.render(inputs)\n```\n\nThis returns an array of hashes, rendering the indices. For example, for the above, you will receive the following output:\n\n```\n[ {:data =\u003e \"...\", :width =\u003e ... }, { :data =\u003e '$not__thisisnotreal$', :exception =\u003e \"...\", {:data =\u003e \"...\", :width =\u003e ... }]\n```\n\nThat 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.\n\n### Options\n\n`Mathematical.new` takes an optional hash to define a few options:\n\n| Name | Description | Default\n|------|-------------|--------\n| `:ppi` | A double determining the pixels per inch of the resulting SVG | `72.0`\n| `:zoom` | A double determining the zoom level of the resulting SVG | `1.0`\n| `:base64` | A boolean determining whether Mathematical's output should be a base64-encoded SVG string | `false`\n| `:maxsize` | A numeral indicating the `MAXSIZE` the output string can be. | `unsigned long`\n| `:format` | A symbol indicating whether you want an `:svg`, `:png`, or `:mathml` output. | `:svg`\n| `:delimiter` | A 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]`\n\nPass these in like this:\n\n``` ruby\noptions = { :ppi =\u003e 200.0, :zoom =\u003e 5.0, :base64 =\u003e true }\nrenderer = Mathematical.new(options)\nrenderer.render('$a \\ne b$')\n```\n\n### Supported commands and symbols\n\nCheck out [SUPPORTED.md on the mtex2MML website](https://github.com/gjtorikian/mtex2MML/blob/master/SUPPORTED.md).\n\n**Note**: This library makes a few assumptions about the strings that you pass in. It assumes that `$..$` is inline math and `$$..$$` is display math.\n\n## Building\n\nBefore building this gem, you must install the following libraries:\n\n* Ruby 2.1 or higher (you'll need Ruby header files, so a `*-dev` version is also required)\n* GNU make\n* glib-2.0\n* gdk-pixbuf-2.0\n* xml2\n* cairo\n* pango\n* [Dependencies for mtex2MML](https://github.com/gjtorikian/mtex2MML#building)\n\nAfter cloning the repo, you can fetch dependencies and run the library by typing:\n\n```\nscript/bootstrap\nbundle exec rake compile\n```\n\nIf there were no errors, you're done! Otherwise, make sure to follow the dependency instructions.\n\n### Fonts and special notices for Mac OS X\n\nInstall the fonts with:\n\n```\ncd ~/Library/Fonts\ncurl -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/cmex10.ttf \\\n     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/cmmi10.ttf \\\n     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/cmr10.ttf \\\n     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/cmsy10.ttf \\\n     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/esint10.ttf \\\n     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/eufm10.ttf \\\n     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/msam10.ttf \\\n     -LO http://mirrors.ctan.org/fonts/cm/ps-type1/bakoma/ttf/msbm10.ttf\n```\n\n## Troubleshooting\n\n### Issues building Lasem\n\nIf 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:\n\n* If you use bundler:\n\n        MATHEMATICAL_USE_SYSTEM_LASEM=1 bundle install\n\n* If you use gem install:\n\n        MATHEMATICAL_USE_SYSTEM_LASEM=1 gem install mathematical\n\n### Issues building mtex2mml\n\nIf 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:\n\n* If you use bundler:\n\n        MATHEMATICAL_USE_SYSTEM_MTEX2MML=1 bundle install\n\n* If you use gem install:\n\n        MATHEMATICAL_USE_SYSTEM_MTEX2MML=1 gem install mathematical\n\n## Benchmark\n\nRun benchmarks with `bundle exec rake benchmark`:\n\n```\nBenchmarking....\nCount: 3868 equations\nIterations: 1\n                                               user     system      total        real\nRendering...                               3.280000   0.070000   3.350000 (  4.324458)\n```\n\n## History\n\nThere are a smattering of libraries written in various languages to convert math\ninto a variety of formats. But there needs to be a sane way to show math\nequations in the browser. With browser support for MathML under attack, it's\nunfortunately not a sustainable solution. A PNG or SVG representation of the\nequation is the safest way to go.\n\nMost advice suggests using [MathJax](http://www.mathjax.org/). While extremely popular\nI dislike the \"stuttering\" effect caused by pages loading math. JavaScript\nshouldn't be used in situations where server-rendering is a possibility, in my opinion.\n\nTo that end, I obsessed over the problem of server-side math rendering for over a\nweek. Here was my journey:\n\n* I started out with [`blahtexml`](https://github.com/gvanas/blahtexml), which takes\nTeX equations and converts them to PNG. This wasn't a bad idea, but it took too long;\nfor twelve equations, it took eight seconds. It was slow because it shelled out\nto [`LaTeX`](http://www.latex-project.org/), *then* [`dvipng`](http://www.nongnu.org/dvipng/).\n\n  In fact, as I discovered, most projects on the 'Net shell out to `LaTeX`, then\nsomething else, which makes performance absolutely horrid. I had to find something\nbetter, with preferably no dependency on `LaTeX`.\n\n* [`mimetex`](http://www.forkosh.com/mimetex.html) was my next attempt. It looked\ngreat: a pure C implementation that turned TeX equations into a rasterized representation,\nand then into a PNG. The speed was there, but the output image was pretty jagged.\nI tweaked the program to output BMPs, and tried to sharpen those with [`potrace`](http://potrace.sourceforge.net/),\nbut the results were less then pleasant. The \"update\" to `mimetex` is [`mathtex`](http://www.forkosh.com/mathtex.html),\nbut it, too, depends on `LaTeX` and `dvipng` binaries to produce images.\n\n* [`pmml2svg`](http://pmml2svg.sourceforge.net/) had potential. It's a set of\nXSLT stylesheets to convert MathML to SVG. Unfortunately, it relies on XSLT 2.0,\nof which there are no Ruby bindings (at the time of this writing, April '14). It\nhad to rely on [Saxon](http://saxon.sourceforge.net/) and Java.\n\n* [`tth`](http://hutchinson.belmont.ma.us/tth/) converts TeX to HTML, but the\noutput is aesthetically unpleasing, so I passed.\n\n* Wikipedia uses [`texvc`](https://github.com/dlitz/texvc), which is written in OCaml,\na language I am utterly unfamiliar with. In any event, I could not get the code\nto compile on my machine.\n\n* It took me forever to finally compile [`gtkmathview`](https://github.com/khaledhosny/gtkmathview),\nand when it did, I got a bunch of SVG images with screwed up fonts.\n\n* [`dvisvgm`](http://dvisvgm.sourceforge.net/) worked well, but still depended\non two external binaries (`LaTeX` to convert the text to dvi, and `dvisvgm` to turn\nit into SVG)\n\n* At one point, I began to try and convert the MathJax code to Ruby to figure out\nhow it accomplished its `toSVG` methods. The MathJax codebase, while written by\ngeniuses, is incomprehensible, due in part to JavaScript's inability\nto possess a coherent structure.\n\n* Near the end of my wits, I mimicked the behavior of [`mathrender2`](https://github.com/quipper/mathrender2),\nwhich uses [PhantomJS](http://phantomjs.org/) to embed MathJax onto a fake\nHTML page. This produced exactly what I needed: a bunch of accurate SVG files with\nno intermediate binaries. It was, unfortunately, a bit slow: for an arbitrary\ncomposition of 880 equations, it took about eight seconds to complete. Could I\ndo better?\n\n* I came across [Lasem](https://github.com/LasemProject/lasem),\nwhich met every need. It has no external binary dependencies (only library packages),\ncan convert directly to SVG, and it's fast. The same arbitrary 880 equations were\nrendered in moments.\n\nAnd thus a wrapper was born.\n\n## More math stuff\n\nCheck out [math-to-itex](https://github.com/gjtorikian/math-to-itex/), which quickly\nparses out TeX notation from strings.\n\nWith it, you could do something fun like:\n\n``` ruby\nMathToItex(string).convert do |eq, type|\n  svg_content = Mathematical.new(:base64 =\u003e true).render(eq)\n\n  # create image tags of math with base64-encoded SVGs\n  %|\u003cimg class=\"#{type.to_s}-math\" data-math-type=\"#{type.to_s}-math\" src=\"#{svg_content}\"/\u003e|\nend\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgjtorikian%2Fmathematical","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgjtorikian%2Fmathematical","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgjtorikian%2Fmathematical/lists"}