Michael Mikovsky, September 30, 2025

RusTeX: Math rendering in Rust

Source code

Description

Katex has effectively become the standard in rendering math. It is an implementation of the TeX standard, and was originally based off of the tool: LaTeX. The problem being that the vast majority of math renders are built as Electron apps, basically webpages as desktop apps. Electron apps are historically very inefficient. Other older languages have their own implementation of TeX expressions, but specifically the language Rust does not. This is why I started to work on a way to render TeX inside Rust.

Text Parsing

TeX supports a whole ton of different functions such as fractions, matrices, integrals, and so much more.

Some examples:

Name TeX expression
Pythagorean identity a^2+b^2=c^2
Quadratic formula x=\frac{-b\pm\sqrt{b^2-4ac}}{2a}
Integral of unreal unit circle \int_0^{2\pi}e^{i\pi\theta}=0

This might seem really complicated, but you can recognise some things like the ^2 being squared, functions having arguments grouped by {...} fractions taking two arguments, etc.

The parser is the part of the program that raw text into an intermediary format, and then into the format that is used for rendering. It detects TeX functions, which are denoted by a starting '\', and then attempting to obtain the various arguments. Currently, there is only the '\frac' function for fractions, and the '\pm' for the plus-and-minus symbol.

It kind of lacking in interpreting more complex functions like \frac12 meaning the same thing as \frac{1}{2}, but nevertheless its a working proof of concept.

Rasterization

Rasterization is the more fleshed out part of this project. The program will take in the parsed structure of the expression from the parser, and then figure out where to put each line and letter.

I built the rasterizrer on the Rust library: fontdue, which claims to be the fastest text rasterization library in the world.

The rasterizer uses the recursive format that the parser ouputs, A fraction would have two groups of symbols, one above and below, and so it draws a line and renders the sub-components slightly scaled down, and with some padding. A similar thing happens with superscript. For letters and numbers, it simply uses fontdue to render them in the output.

Display

Although how the resulting image isn't really important to the rendering process, I still think it's interesting enough to mention.
The sixel standard is an ancient format used for displaying images in terminals over dial-up connections. A few terminal programs on Linux do have support for this, although it’s very uncommon for programs to actually use. Sixel was semi-revived in the libsixel project which was ported to rust in the library icy_sixel which was randomly created by some guy and turns out to be very performant.
Turns out, displaying an image in the terminal was extremely useful for this project, so I wrote some code to utilize this sixel library to print the image for debug purposes.

Output

Review

Going into this project, I didn't really know what to expect. The rendering, I thought, would be the hardest part. In actualality, the text parsing was by far the hardest component, with

I'm probably not going to work on this in the future. I think this would be a useful library, but I'm going insane over making the parser work properly.