WillDrevo

Rendering LaTeX in Javascript with KaTeX and Jekyll

Published October 4, 2014

MathJax is really slow. You've probably pulled up a site before, rich with LaTeX equations, and waited as the page slowly rendered, moving the text all around and creating a bad user experience for the page.

KaTeX is a cool library for doing rendering for equations right in the browser -- and doing it much faster. See below for a comparison from the KaTeX website.

KaTeX is on the left, MathJax is on the right.

KaTeX vs. MathJax

Since this is something we'd like to avoid, let's see how to use KaTeX. I'll be talking about using KaTeX with Jekyll, but the same technique apply to use KaTeX anywhere.

Download the CSS and JS from the KaTeX releases page, and you are ready to start.

Including KaTeX in Posts

First, we have to include the KaTeX library. From the release we downloaded, we just move the minified JS and CSS files into Jekyll's public folder.

For reference, using the tree commend, Jekyll's setup look similar to the following:

$ tree /path/to/jekyll/folder
/path/to/jekyll/folder
├── 404.html
├── Gemfile
├── Gemfile.lock
├── _config.yml
├── _includes
│   ├── google_analytics.html
│   └── head.html
├── _layouts
│   ├── default.html
│   ├── page.html
│   └── post.html
├── _posts
│   └── 2014-10-04-katex-rendering-in-jekyll.md
├── _site
├── index.html
└── public

For those not using Jekyll, just put the KaTeX JS/CSS files anywhere static files are served. Once the files are in place, note the path you used. You'll be able to import KaTeX with the following:

<!-- KaTeX -->
<link rel="stylesheet" href="/public/path/to/katex.min.css">
<script src="/public/path/to/katex.min.js"></script>

Great, now let's add an equation.

First, let's add an element to our markdown post file, in this case (of this post) I've added the post entry _posts/2014-10-04-katex-rendering-in-jekyll.md. Somewhere in that file after the metadata header, add the an element like the following:

{% raw %}
<!-- The Normal Distribution -->
<div class="equation" data-expr="\displaystyle P(x)=\frac{1}{\sigma\sqrt{2\pi}}e^{-\frac{(x-\mu)^2}{2\sigma ^2}}"></div>
{% endraw }

You need the raw tags because otherwise LaTeX commands and Jekyll's Liquid templating don't play nice together and Jekyll will fail to compile.

Also make sure you add the final % sign to the endraw tag. I can't add it here since Jekyll interprets that as an actual endraw.

Prettifying with CSS

Right out of the box, our equations will get smashed into the next lines of HTML text, use a small font size, and aren't centered in the text column. Let's fix that.

For Jekyll, I added the following lines to public/css/site.css:

/*
 * Equations with KaTeX
 *
 * Center the equation content.
 */
.equation {
  padding-bottom:  1rem;
  padding-top:     1rem;
  text-align:      center;
  font-size:       1.5em;
}

but you could add that to any CSS file and get the same result.

Rendering the equations using Javascript

We now actually have to render these HTML elements somehow. We'll need to do this in Javascript, and we'll now actually make use of the KaTeX Javascript library.

At the bottom of your markdown post file, put the following code:

<script type="text/javascript">

    // grab all elements in DOM with the class 'equation'
    var tex = document.getElementsByClassName("equation");

    // for each element, render the expression attribute
    Array.prototype.forEach.call(tex, function(el) {
        katex.render(el.getAttribute("data-expr"), el);
    });

</script>

This script will grab all the equation elements and call the rendering library on them. Here's our equation for the the Normal Distribution below:

And that's all it takes!

Using Includes

You might want to include LaTeX equations in some, but not all, of the posts you make. Including it in all the pages would uneccessarily slow the loading of those other pages, and we don't want that. To fix this, we'll use Jekyll's includes templates.

In the Jekyll _includes folder, create two new files:

$ touch katex_import.html
$ touch katex_render.html

Then for _includes/katex_import.html, paste the our import code:

<!-- KaTeX -->
<link rel="stylesheet" href="/public/path/to/katex.min.css">
<script src="/public/path/to/katex.min.js"></script>

and for _includes/katex_render.html, our rendering code:

<script type="text/javascript">
    var tex = document.getElementsByClassName("equation");
    Array.prototype.forEach.call(tex, function(el) {
        katex.render(el.getAttribute("data-expr"), el);
    });
</script>

Then for each post, using the format:

---
layout: post
title: Rendering LaTeX in Javascript with KaTeX and Jekyll
permalink: latex-equation-rendering-in-javascript-with-jekyll-and-katex
---
{% include katex_import.html %} 
... content of post here
<div class="equation" data-expr="...."></div>
<div class="equation" data-expr="...."></div>   
... more content
{% include katex_render.html %} 

which should cause Jekyll to render everything properly.

Conclusion

KaTeX is a great way to get LaTeX equations rendered quickly in your website using only Javascript and CSS. It also plays nice with Jekyll, and makes it easy to include them in only the posts you need it in.

If you liked this post, feel free to share it with your followers or follow me on Twitter!


comments powered by Disqus