79

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?

Chris Taylor
  • 46,912
  • 15
  • 110
  • 154
  • 2
    Just for reference, I wrote a small tutorial about using MathJax with Jekyll. Works pretty well for me. http://cwoebker.com/posts/latex-math-magic – cwoebker Nov 23 '12 at 16:23
  • 1
    @cwoebker You should make it an answer (copying some parts from your blog). – Piotr Migdal Jun 23 '13 at 23:29
  • 1
    There you go:) you are welcome. Its only a bare minimum answer for reference, hope its enough. – cwoebker Jun 26 '13 at 09:03
  • 1
    Here is the simplest explanation I found: http://christopherpoole.github.io/using-mathjax-on-github-pages/ – JohnRos Jun 03 '15 at 13:00
  • 2
    @JohnRos, that link is dead; try https://alan97.github.io/random/mathjax/ -- 2 minute read, 2017. – denis Jun 19 '17 at 14:54

9 Answers9

53

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).

cboettig
  • 12,377
  • 13
  • 70
  • 113
  • Thanks - I'll try this out and let you know how it goes. – Chris Taylor Jun 19 '12 at 16:08
  • any luck with the mathjax CDN? – cboettig Jun 28 '12 at 16:20
  • I only just got around to doing this(!) but it works great - thanks! – Chris Taylor Sep 12 '12 at 07:33
  • @cboettig I have put your code in /_layout/post. However, it seems does not work. Could you please have a look at it? http://tengpeng.github.com/2012/11/10/recognize-vague-words.html – Jill Clover Nov 10 '12 at 13:32
  • your equations are displaying correctly for me on that page. Perhaps your browser is blocking the javascript for you (or you have already fixed this). – cboettig Nov 14 '12 at 19:11
  • This works great, but I need to be connected to the internet for the script to be loaded, and it'd be nice to test offline. I tried to wget the src and link it directly, but that fails to display the math... – VF1 Oct 04 '15 at 03:48
  • Note from the future: cdn.mathjax.org is nearing its end-of-life, check https://www.mathjax.org/cdn-shutting-down/ for migration tips. – Peter Krautzberger Apr 12 '17 at 08:40
  • Look out -- if your site is served over https, the mixed-origin content blocking in most modern browsers will cause mathjax to silently fail to load. Tack an `s` on and it works for me. – Soren Bjornstad Jun 13 '19 at 23:13
  • 1
    Where do I put ``? – Gilfoyle Nov 28 '19 at 14:58
52

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 $$.

Caramdir
  • 689
  • 5
  • 9
  • 1
    For me, this is not enough. Some equations get messed up. For example, \begin{align} m_a(t) = \begin{cases} 0, \quad 0 < t < t_a \\ m_a^0 e^{-t/T_{1b}} \text{(pulsed)}, \quad t_a< t< \tau + \Delta t \\ m_a^0 e^{-t_a/T_{1b}} \text{(continuous)} \\ 0, \quad t> t_a + \tau \end{cases} \end{align} – nos Jun 03 '16 at 16:19
  • 11
    Newer versions of Jekyll don't have a `_layouts` directory. In this case, where should we put the ` – Ian Goodfellow Nov 07 '16 at 01:16
  • 2
    Note from the future: cdn.mathjax.org is nearing its end-of-life, check https://www.mathjax.org/cdn-shutting-down/ for migration tips. – Peter Krautzberger Apr 12 '17 at 08:40
  • 1
    Added the last line suggested to my `_layouts/default.html` file, after the first `something` block. As @PeterKrautzberger pointed out, I changed the `src` reference to `src="https://cdn.rawgit.com/mathjax/MathJax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"`. It works! – FaCoffee May 15 '17 at 12:34
  • 4
    @IanGoodfellow you can override default theme by copying over the _layouts folder into your app directory. Find the path to the theme's source files with the command `bundle show minima`. And add ` – chittychitty Sep 24 '17 at 15:32
12

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.

  • Can you add a link to your blog? I want to see how exactly you set this up :) – Rylan Schaeffer May 18 '20 at 03:20
  • @RylanSchaeffer Sure. sohambhattacharyya.github.io – Soham Bhattacharyya May 18 '20 at 10:24
  • 2
    I found that in current Jekyll versions in combination with `github-pages`, the lines `markdown: kramdown` and `mathjax: true` are not necessary. Furthermore, to use the latest MathJax version 3, the [code from the official MathJax documentation](https://www.mathjax.org/#gettingstarted) included in the layout header works just fine. – cbrnr Sep 25 '20 at 07:18
6

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.

cwoebker
  • 3,158
  • 5
  • 27
  • 43
  • 1
    I think I did everything what you've suggested, but it doesn't work: [example that doesn't work](http://martinthoma.github.io/fibonacci-recursion-decorators/#tocAnchor-1-2) – Martin Thoma Dec 10 '13 at 19:11
  • [Another example](http://martinthoma.github.io/part-iv-multiply-matrix-transpose-python-cpp/). – Martin Thoma Dec 10 '13 at 19:16
2

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.

Z.H.
  • 259
  • 1
  • 14
2

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

J.T.
  • 864
  • 9
  • 17
1

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.

Bunny
  • 1,180
  • 8
  • 22
0

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.

S0AndS0
  • 860
  • 1
  • 7
  • 20
0

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

Ar May
  • 1
  • 2