1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
---
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
```
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
```
**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"
|