Integrating mathjax and markdown in django

20 Apr 2013

I’ve moved the blog to Github Pages which means that my content management system is now Jekyll, not Django. I’m leaving this post up, but I no longer use the hack described below.

The simple way to make MathJax work with a blog written in Markdown is to simply escape all the underscores and asterisks (along with some slashes). For example, to generate the equation at the bottom of this page you’d ordinarily write the MathJax code:

$$\text{SSR} = \sum \limits_{i=1}^n \left( y_i - \boldsymbol{x}'_i \hat{\boldsymbol{\beta}} \right)^2$$

Markdown, though, thinks everything between the two underscores is supposed to be italic. But if you escape the underscores (that is, replace each appearance of _ with \_), then it just works!

You will need to do the same with asterisks (* becomes \*), newlines (\\ becomes \\\\), and some other marks, too (\left\{ becomes \left\\{).

Original post follows:

I’m a JavaScript noob so it took a couple days of hacking but I finally integrated mathjax and markdown into my django blog (this one!) together.

The basic problem is that markdown is a sleek little markup language that was designed to be totally minimal so that it’s natural for humans to read and write it. But being minimal, it is hard to customize. And since some markdown syntax clobbers mathjax syntax (e.g. the underscore), we need to customize markdown, telling it to ignore the text that is meant for mathjax.

The solution is to follow four steps:

  1. Strip the mathjax out of the markdown input, store it, and replace it with placeholder text ("@@<blocknumber>@@" in this case)
  2. Convert the remaining text (all markdown) to html
  3. Process the mathjax to html
  4. Reinsert the processed mathjax into the processed markdown at the locations indicated by the placeholders

This post was super helpful. I had to look through the linked code many times, comparing it to the contents of django-pagedown. Finally, I saw that the answer would be quite simple:

  • Install django-pagedown
  • Link to the mathjax javascript library by adding this code to my base.html template:
<script type="text/javascript" src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
  • Save this code (hat tip to David Cervone for his answer to this stackoverflow question) to a file called mathjax-editing.js
  • Add the following code to mathjax-editing.js, just after 'use strict'; : window.StackExchange = {};
  • In pagedown/widgets.py, after the line var editor = new Markdown.Editor(converter, "", selectors); (which is line 44 in the version I downloaded April 15, 2013), add these two lines:
var postfix = "";
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\\\(","\\\\)"]]);
  • Add these two items to the js tuple in the Meta subclass of the PagedownWidgetclass in pagedown/widgets.py:
'https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'
'%s/js/mathjax-editing.js' % settings.STATIC\_URL

Then you just need to run python manage.py collectstatic and restart your server - boom! MathJaxxy goodness like this:

$$ \text{SSR} = \sum\limits_{i=1}^n \left(y_i - \boldsymbol{x}'_i\hat{\boldsymbol{\beta}}\right)^2 $$

Markdown is allowed. Email addresses will not be published.