Using MathJax with Jekyll

I have a Jekyll blog and I want to use MathJax with it, in the sense that I want to be able to type something like

$$\sum_{n=1}^\infty 1/n^2 = \frac{\pi^2}{6}$$

in my markdown files, and have the correct LaTeX expression generated with MathJax, in a similar way to how it is done at math.stackexchange.

What is the easiest way to do this? Currently I have the file jsmath.js (GitHub gist) in my directory, and I thought I could have a simple file named mathjs in my _includes directory with the line

<script src="path/to/jsmath.js></script>

and include that in each post via

{% include mathjs %}

but this doesn't seem to work - when I run jekyll --server the page is generated, but none of the content is visible.

Am I going about this the right way? Is there a better way to use MathJax with Jekyll?

23881 次浏览

Certainly you can use mathjax with Jekyll. To get this working make sure that

  1. If you're writing your post in markdown, your markdown interpreter isn't hammering your mathjax input. The best way to protect it I have found is to always put display math in <div> elements and inline math in <span> elements, which most markdown interpreters will leave alone.
  2. Is the javascript line displaying correctly in the html source? I find it easier and faster to point to the mathjax CDN rather than provide my own copy. Try using the line

    <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

(Those configuration options allow you to use more tex notation to start your math environment, such as \begin{equation}, etc).

Perhaps there is some issue with your jsmath.js script; the CDN version will be faster and probably more reliable. (I have the javascript load in my footer on every page, but of course your strategy with include makes sense if you don't want to load the javascript when you don't need it.)

We could help more if you give us a link to your blog? You can see some examples on my blog (has link to Jekyll setup on github too if that helps).

You may try my static blog generator: Jekyde. Jekyde is similar to Jekyll, but it takes care of LaTeX in Markdown file well. You only need to put your formulas inside $...$ and $$...$$. Also Jekyde contains a markdown editor in browser with LaTeX preview.

I wrote a blog post about setting up MathJax a while back: Latex Math Magic

In essence you have to stop the Markdown from messing with the MathJax.

I ended up using code blocks, which worked fine for me. So either using at least 4 spaces before you write something or using the acute symbol: `; Unfortunately MathJax is skipping <code> tags by default since it doesn’t want to convert code that it shouldn’t.

So somewhere in your main layout file you have to add a little javascript code:

MathJax.Hub.Config({
tex2jax: {
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre']
}
});

Additionally we have to tell MathJax to ignore non-latex code-blocks or normal code blocks:

MathJax.Hub.Queue(function() {
var all = MathJax.Hub.getAllJax(), i;
for(i=0; i < all.length; i += 1) {
all[i].SourceElement().parentNode.className += ' has-jax';
}
});

At his point all our latex code blocks are going to have the has-jax string in their class name. Therefore we can apply some simple styling in our css sheets to give it our own styling.

code.has-jax {font: inherit; font-size: 100%; background: inherit; border: inherit;}

Might not be the best approach but it worked for my blog for the past years and I never encountered any further problem with it.

If you have sufficient control over the publishing process (e.g. you are running Jekyll yourself), an easy solution is to switch the markdown parser to one that supports TeX. For example, using kramdown:

gem install kramdown

Change the markdown line in _config.yml to

markdown: kramdown

and add something like

<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>

to _layouts/default.html. Now you can simply mark any mathematics in your posts with $$.

If you are using kramdown as your markdown flavor, it's easy. Kramdown has built-in support for mathjax.

  1. Add this before the </head> tag in your default layout.

    <script type="text/javascript" async
    src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?
    config=TeX-AMS-MML_HTMLorMML"></script>
    
  2. Set this to true at _config.yml, after the markdown: kramdown line.

    mathjax: true
    
  3. Done. For renedering Mathjax

    • inline, use \( ... \),
    • block, use \[ ... \].

      The only thing to look out for is the escaping of the backslash when using markdown, so the delimiters become \\( ... \\) and \\[ ... \\] for inline and block maths respectively.

  4. Here is an example of MathJax inline rendering \\( 1/x^{2} \\), and here is a block rendering: \\[ \frac{1}{n^{2}} \\].

I use this on my blog.

Some notes before trying either of the following options

Option 0 will increase build times even with --incremental and really option 1 should likely be used in most instances, however, this along with the extra space taken up maybe worth the costs if you're deploying on a network with clients that may not have access to CDNs.

Both options have been tested on a private server with kramdown as the markdown interpreter and mathjax: true set within the project's _config.yml file; see Step 2 of Soham Bhattacharyya's answer and their preface, and upto Caramdir's first two code blocks for the how-to for those bits.

Option 0 download and copy the unpacked source to project-name

  1. Download the source
cd ~
mkdir -p git/hub && cd git/hub
git clone --depth 1 https://github.com/mathjax/MathJax.git
  1. Make a directory path in your project's and copy files from MathJax/unpacked to this path
cd ~
mkdir -p git/lan/project-name/assets/JS_3rd_Party/MathJax
cp -r git/hub/MathJax/unpacked/* git/lan/project-name/assets/JS_3rd_Party/MathJax/
  1. Add the source to git tracking
cd git/lan/project-name/
git add assets/JS_3rd_Party/MathJax
git commit -m 'Added MathJax.js unpacked source to git tracking'
  1. Write an include file
tee ./_includes/MathJax.html 1>/dev/null <<EOF
{%- if jekyll.environment == 'production' and site.mathjax == true -%}
<script type="text/javascript" src="\{\{'/assets/javascripts/JS_3rd_Party/latest.js?config=TeX-AMS-MML_HTMLorMML' | relative_url}}"></script>
{%- elsif jekyll.environment != 'production' and site.mathjax == true -%}
<script type="text/javascript" src="\{\{'/assets/javascripts/JS_3rd_Party/MathJax.js?config=TeX-AMS-MML_HTMLorMML' | relative_url}}"></script>
{%- endif -%}
EOF

Private server builds will use MathJax.js where as production environment (GitHub) will use latest.js using the above Liquid if...elsif...endif statement.

  1. Write a post to test it
tee ./_posts/$(date +'%Y-%d-%m')-math-tests.markdown 1>/dev/null <<EOF
---
layout: post
title:  "Math Tests"
date:   $(date +'%Y-%d-%m %H:%M:%S %z')
categories: math
---
{%- include MathJax.html -%}


<span>


for $x,y,z \in \{1, 2,\dots 9\}$
</span>


<span>


$$
\sum_{i=1}^n X_n
$$
</span>
EOF

I've not tried it without <span>s because cboettig's suggestion seems to totally do the trick. Additionally that extra new-line within spans are no mistake, without'em there where still issues with rendered output.

  1. Add these latest files to git tracking
git add _posts/$(date +'%Y-%d-')math-tests.markdown
git add _includes/MathJax.html
  1. Build locally, or push and build on a remote server
bundle exec jekyll build --destination /tmp/www/project-name --config _config.yml --incremental

Option 1 copy just latest.js to use a CDN (Content Delivery Network)

  1. See Option 0 step 1.

  2. Make a directory path for third party JavaScripts and copy MathJax/unpacked/latest.js there

cd ~
mkdir -p git/lan/project-name/assets/JS_3rd_Party/MathJax
cp git/hub/MathJax/unpacked/latest.js git/lan/project-name/assets/JS_3rd_Party/MathJax/
  1. Write an include file
cd git/lan/project-name
tee ./_includes/MathJax.html 1>/dev/null <<EOF
<script type="text/javascript" src="\{\{'/assets/javascripts/JS_3rd_Party/latest.js?config=TeX-AMS-MML_HTMLorMML' | relative_url}}"></script>
EOF
  1. See Option 0 Step 5.

  2. Add these three files to git tracking

git add _includes/MathJax.html
git add _posts/$(date +'%Y-%d-')math-tests.markdown
git add assets/JS_3rd_Party/MathJax
git commit -m 'Added `MathJax.html`, `latest.js`, and a test post to git tracking'
  1. See Option 0 Step 7. for building locally

For either of the options

If deploying on a private server you may also need to define baseurl within your project's _config.yml file, especially if emulating the username.tld/project-name URL scheme that GitHub uses on your private server.

If deploying to both a private server and GitHub it may be better to use a separate config file and when building issue --config _config.yml,_config_baseurl.yml, eg...

# Write the special config file
tee ./_config_baseurl.yml 1>/dev/null <<EOF
baseurl: "project-name"
EOF


# Build with extra config
bundle exec jekyll build --destination /tmp/www/project-name --config _config.yml,_config_baseurl.yml --incremental

Hope that helps with loading assets via an include.

Jekyll uses kramdown as a default markdown converter from 2.0+. And It doesn't support the mathjax and so on, I think the below can help you.

jekyll-spaceship - 🚀 A Jekyll plugin to provide powerful supports for table, mathjax, plantuml, youtube, vimeo, dailymotion, etc.

https://github.com/jeffreytse/jekyll-spaceship

Put your math expression within $...$

$\LaTeX{}$
$\Pi$
$ a * b = c ^ b $
$ 2^{\frac{n-1}{3}} $
$ \int\_a^b f(x)\,dx. $

Code above would be parsed as:

enter image description here

For me adding this to my default _layout or head _include works (in combination with a front matter _page or _post variable):

---
mathjax: yes
---
    <!-- mathjax -->
{% if page.mathjax %}
<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.3/MathJax.js?config=TeX-MML-AM_CHTML">
MathJax.Hub.Config({
tex2jax: {
inlineMath: [["$", "$"], ["\\(", "\\)"]],
processEscapes: true
}
});
</script>
{% endif %}

working example

For those using the Jekyll Chirpy, you simply need to add math : true to the front matter of your post.

For website performance reasons, the mathematical feature won’t be loaded by default.

Source

At the time of this post, Jekyll Chirpy uses MathJax 3.2.