# just-latex
**How do you render LaTeX fragments on the Web? MathJaX? KaTeX? Why not ... just use LaTeX?**
![license](https://img.shields.io/badge/license-MIT-red)
[![shield](https://img.shields.io/badge/crates.io-0.1.3-green)](https://crates.io/crates/just-latex)
Just-latex is a simple [Pandoc](https://pandoc.org/) filter that chains a bunch of existing tools in the TeX ecosystem, to enable the use of actual LaTeX engines to render LaTeX fragments when converting a document to HTML. It aims to occupy a niche and provide a new option for users hampered by MathJaX or KaTeX.
## Features
* Full TeX/LaTeX compatibility because we are just calling them under the hood. This means you can define macros, change fonts, use `tikz`, etc. -- just like what you do with a LaTeX document.
* Uses Pandoc so it supports a wide variety of input formats and can be embedded into various workflows relatively easily, e.g. `hexo-renderer-pandoc` if you have a blog powered by Hexo (like me).
* Fragments are converted to SVG images which looks great regardless of scaling.
* Compresses the SVG so the resulting page does not get bloated by a lot.
## Demo
![demo](examples/demo.png)
Please see `examples/demo.md` and `examples/demo.html` for a showcase of this program. The demo features the use of `cmbright` package to change the font, `tikz` to make a plot, and `algpseudocode` to typeset some pseudocode. The command to produce `demo.html` is (run it under `examples/`)
```bash
pandoc demo.md --filter ../target/debug/just-latex -o demo.html
```
(assuming you have a debug build)
The demo is partially adapted from [here](https://tex.stackexchange.com/questions/425098/which-opentype-math-fonts-are-available).
Another demo `examples/fwht.md` is actually a [blog post](https://danglingpointer.fun/2020/08/07/FWHT/) I wrote years ago. It has more maths and should be considered a realistic use case of this program.
The `examples` folder also contains a sample configuration file.
*Note: Github limits preview of hosted HTML files for security reasons. If you want to check the htmls, you may use services such as https://htmlpreview.github.io. [Link to the demo page](https://htmlpreview.github.io/?https://github.com/ma-chengyuan/just-latex/blob/main/examples/demo.html).*
## Comparison with ...
### MathJaX and KaTeX
I create this program with a different set of goals in mind from MathJaX and KaTeX. The latter work great in their comfort zones, but essentially they are still just partial JS ports of TeX, so both come with limitations.
For instance, as a serif font the Computer Modern family actually does not look that good on screen, but neither MathJaX 3 nor KaTeX gives you another option (though MathJaX does fine-tune the CM fonts they use for screen display). In LaTeX we are free to use packages like `cmbright`, `arev`, `beamer`, or load OTF math fonts with `unicode-math` to solve the issue, wouldn't it be great if we could do that on the Web?
Another example would be the use of macros. MathJaX and KaTeX can deal with macros but things can be a little bit tricky if you define a macro in one block and use it in another.
This project is originally intended for bloggers like me, where most contents are created statically and can be rendered statically. MathJaX and KaTeX are still unbeatable when it comes to real-time and dynamic rendering of TeX equations.
Basically, if you have been happy with MathJaX and KaTeX, use them. If you want to explore breaking the limitations imposed by either libraries, check this out!
### TeX4ht, LaTeXML, Tralics, etc.
These programs convert LaTeX *documents* to HTML whereas just-latex deals with LaTeX *fragments* in formats like Markdown or Org. Surely one can use Pandoc to convert a Markdown document into LaTeX and call these tools to then convert it into HTML, but this seems to me to be a little bit complicated. These tools are also big systems that require some setup. In addition, to my knowledge, LaTeXML and Tralics are TeX *emulators* so there might be compatibility issues too.
Also note that these systems aim to be clever by trying to identify certain elements in the input document and do them "the Web way," e.g. maths are converted to MathML or handed over to MathJaX and texts are extracted to be reflowed by the browser. That, in itself, seems like a source of troubles.
In comparison, just-latex are **small, simple and dumb**. It has just about 1000 lines of code in Rust and uses mature libraries in the TeX community so you can fully understand how it works in 10 minutes (you will see below) and be 99% confident the rendered result will be identical to the one you see in a PDF.
### SwiftLaTeX
SwiftLaTeX is the entire TeX engine compiled to WebAssembly and running in the browser. It shouldn't really be compared to this program because the former runs in the client's browser where the latter does all the rendering on server side.
## How it Works
1. Just-latex is a Pandoc filter, so Pandoc will take care of the parsing of the input document -- be it a Markdown, a RestructuredText, an Org, or really anything Pandoc supports.
2. The program identifies the `MathInline` elements in the document tree given by Pandoc.
3. It then joins these fragments together in the order they appear (with some deduplication), surrounds the result with a user-defined preamble and postamble, and writes the result to `.tex` file in a temp directory. For example, the preamble could be
```latex
\documentclass[12pt]{article}
\usepackage{amsmath, amssymb, amsthm, bm}
\begin{document}
```
with the postamble
```latex
\end{document}
```
4. It calls (La)TeX (can be either pdfTeX, XeTeX, or LuaTeX) to compile that `.tex` into a PDF file.
5. It then calls [dvisvgm](https://dvisvgm.de/) to convert the PDF into an SVG. Dvisvgm is shipped with modern TeX distros.
6. For each fragment, the programs uses the SyncTeX library to compute where it ends up in the PDF and hence the SVG. SyncTeX has been built into modern TeX engines for years and is what nearly all TeX editors use to achieve source-output synchronization.
7. The regions are refined with the usvg library by looking at the actual paths.
8. The `MathInline` nodes are replaced by `RawInline` nodes with ``s properly styled to display computed regions of the SVG. E.g.
```html
```
For inline fragments, care will be taken to align the baseline of the image to the baseline of the surrounding text.
9. The SVG itself is LZMA-compressed, then base64-encoded and then stuffed into a short Javascript code that decompresses the SVG, generates an object URL and fills in the `...` part in the `` tags above when the page loads. This code, along with the `