Jekyll KaTeX Block

If you follow Hacker News, then you might’ve seen the latest development from Khan Academy: KATEX.

Although it hasn’t yet implemented the full set of mathematical symbols, KATEX promises to replace MathJax as the web technology for displaying mathematical expressions. This plugin utilises Jekyll’s plugin system to enable you to easily add mathematical equations to your statically generated site, by adding a Liquid block corresponding to content to be rendered by KATEX.

It’s as simple as adding this plugin to your _plugins folder, pointing the plugin to your KATEX JavaScript file in _config.yml, and including the KATEX CSS in the resulting web pages.

Why KaTeX?

The Jekyll KaTeX plugin

So how does this Jekyll plugin fit in?

Well, there are three types of Jekyll plugins:

Generators

Converters

Tags

A subset of the Tags plugin is the Block plugin. What this does is provides access to a Liquid block, that takes the content inside the block and does with it as you specify in your plugin. Here’s an example of a Liquid block:

{%myblock%}This is the content inside the block!
{%endmyblock%}

The Jekyll KATEX block then provides the {% latex %} block, which uses KATEX to compile the contents of the block into an equation. So this is how you’d use it in your post:

{%latex%}E = \gamma mc^2
{%endlatex%}

In addition, you can pass tokens to blocks like so:

{%myblockmytoken%}Block contents
{%endmyblock%}

So if you pass the centred token to the latex block like so:

{%latexcentred%}E = \gamma mc^2
{%endlatex%}

Then the equation will also be cented on the page, with some space above and below. This is achieved using a little bit of inline CSS injected into the equation.

How to install it

If you’ve already got the KATEX JavaScript installed on your system, as well as the CSS files and the font files, then all you need to do is drop jekyll-katex-block.rb into your _plugins directory in your project, and you’re ready to go!

Just make sure that you’re loading the CSS in your web page (but not the JavaScript) and have the font files available.

Options

You can specify where to tell the plugin to look for your JavaScript file in your _config.yml with the following:

katex:path_to_js:"./the/path/to/your/js"

Troubleshooting

If you’re seeing a bunch of weird symbols instead of your equations, then it’s probably because you’re not using UTF-8. This is what it’ll look like:

Put the following in the head of your HTML to sort it out:

<metacharset=utf-8>

If you’re seeing your equations, but they don’t have any special formatting and just look like weird, squished, ugly versions of what you want, like this:

Then it’s probably because your server can’t find the font files. You can test this out by doing the following:

$ jekyll build
$cd _site
$ python -m SimpleHTTPServer

Go to your web page in question with your web browser, and look at the output of your Python session. It should say something like:

To solve this, put all your KATEX font files in in the same directory as your KATEX CSS file, that way it’ll automatically look for and find it. If you’re still having problems, have a look at the example Jekyll site on the GitHub repo, or comment below.

Now you should be back to how it’s supposed to look:

K​0​​=√​​iht​​m​​​​​e​−​i​2π​​h​​t​​m(x−x​′​​)​2​​​​​​

How it works

The plugin basically works by compiling KATEX within the Ruby script using the ExecJS module. The JavaScript function renderToString is then called from this compiled JavaScript on the content inside the block. This converts the content from LATEX to HTML.

The @ sign indicates that the katex variable is an instance variable, which basically means that it’s available to all the methods within the current class. The block itself is a class inheriting from Liquid::Block. It’s a member of the Jekyll::Tags module, which makes it accessible to Jekyll on runtime.

As with all tags, it then needs to be registered. This is where you tell Liquid what identifier the tag should have, i.e. what string inside the {% and %} brackets should activate the plugin. This looks like the following: