---
slug: mathyd-easy-tex-to-svg
title: "Mathyd: Easy TeX to SVG"
date: "2021-12-05T07:02:29-04:00"
---
A few weeks ago I released [Mathyd][], a [Docker][] image containing an
[HTTP][] daemon which converts [TeX][] to [SVG][].

[Mathyd][] includes a minimal command-line client which reads [TeX][]
from standard input and prints the generated [SVG][] to standard output,
like so:

```bash
# set URL and HMAC secret key
# (note: replace value of MATHYD_HMAC_KEY with your own randomly
# generated one)
export MATHYD_URL="http://whatever.example.com:3000/"
export MATHYD_HMAC_KEY="2dhXA3HTmfEMq2d5"

# render output
bin/mathy < cubic.tex > cubic.svg
```
&nbsp;

Given [this input file][cubic-tex], the command above produces the
following result:

{{< figure
  src="/files/posts/mathyd-easy-tex-to-svg/cubic.min.svg"
  class=image
  caption="The Cubic Formula, rendered by Mathyd."
>}}

### Installation

You can install and run the [Mathyd Docker image][mathyd-docker] with a
single command:

```bash
# run mathyd as a daemon on port 3000
# (note: replace value of MATHYD_HMAC_KEY with your own randomly
# generated one)
docker run --rm -d -e MATHYD_HMAC_KEY="2dhXA3HTmfEMq2d5" -p 3000:3000 pablotron/mathyd:latest
```
&nbsp;

**Notes:**
* Be sure to generate your own [HMAC][] secret key rather than
  reusing the key from the examples above.
* Don't expose [Mathyd][] via a publicly-accessible [URL][]; it does
  not support [TLS][] and [MathJax][] may use a lot of memory for large
  input files.  If you really do want to do this, then you'll need to
  proxy the [Mathyd][] endpoint behind [Apache][] or [nginx][] on an
  authenticated, [TLS][]-encrypted [URL][].

### Technical Details

Under the hood, [Mathyd][] is just:
1. a [container][] running an [Express][] [HTTP][] daemon that exposes a
   single endpoint that accepts a `PUT` request containing:

   * A [JSON][]-encoded body of input parameters.
   * A hex-encoded, [SHA-256 HMAC][hmac] of the body and the [HMAC][]
     secret key in the `x-mathyd-hmac-sha256` header.

   The endpoint does the following:

   1. Verifies the body [HMAC][].
   2. Parses the [JSON][] body and extracts the input parameters,
      including the source [TeX][].
   3. Converts the input [TeX][] to [SVG][] (via [MathJax][]).
   4. Returns a [JSON][]-encoded response containing the generated
      [SVG][].

2. A command-line client, written in [Ruby][], which:
   1. Reads [TeX][] from standard input and serializes it as [JSON][].
   2. Sends a `PUT` request to the [Mathyd][] daemon and parses the
      response.
   3. Extracts the generated [SVG][] from the response and writes it to
      standard output.

### Rationale

I wanted an easy way to generate static math [SVGs][svg] for
web pages from the command-line without installing a blizzard of
dependencies and without requiring [MathJax][] on the destination page.

I prefer [TeX][] over other formats because it's still the least-worst
format for complex math formulas.

I prefer [SVGs][svg] over bitmap images whenever possible because:

* [SVGs][svg] scale to any screen size and resolution.  This is
  particularly useful for [responsive design][].
* [SVGs][svg] are supported by all modern browsers, including mobile
  browsers.

Fun fact: even the [animated logo for this page][logo] is an [SVG][].

### Links

* [Mathyd GitHub Repository][mathyd]
* [Mathyd on Docker Hub][mathyd-docker]

**Note:** If you want a web interface to noodle around with [TeX][],
check out [Mathy][] instead.

[mathyd]: https://github.com/pablotron/mathyd
  "Dockerized TeX to SVG HTTP daemon."
[docker]: https://en.wikipedia.org/wiki/Docker_(software)
  "Docker"
[http]: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
  "HyperText Transfer Protocol"
[tex]: https://en.wikipedia.org/wiki/TeX
  "The TeX typesetting system."
[svg]: https://en.wikipedia.org/wiki/Scalable_Vector_Graphics
  "Scalable Vector Graphics"
[mathjax]: https://mathjax.org/
  "Math rendering library."
[cubic-tex]: /files/posts/mathyd-easy-tex-to-svg/cubic.tex.txt
  "Example Mathyd input TeX file containing the cubic formula."
[mathy]: https://mathy.pmdn.org/
  "Web-based LaTeX Math renderer, based on MathJax."
[express]: https://expressjs.com/
  "Minimal web framework for Node JS."
[hmac]: https://en.wikipedia.org/wiki/HMAC
  "Hashed Message Authentication Code"
[json]: https://json.org/
  "JavaScript Object Notation."
[mathyd-docker]: https://hub.docker.com/repository/docker/pablotron/mathyd
  "Mathyd on Docker Hub."
[container]: https://en.wikipedia.org/wiki/OS-level_virtualization
  "Operating System-level virtualization."
[Ruby]: https://ruby-lang.org/
  "Ruby programming language."
[url]: https://en.wikipedia.org/wiki/URL
  "Uniform Resource Locator"
[logo]: /files/posts/mathyd-easy-tex-to-svg/logo.svg
  "current pablotron.org site logo"
[responsive design]: https://en.wikipedia.org/wiki/Responsive_web_design
  "Responsive web design."
[tls]: https://en.wikipedia.org/wiki/Transport_Layer_Security
  "Transport Layer Security"
[apache]: https://apache.org/
  "Apache web server"
[nginx]: https://www.nginx.com/
  "nginx web server"