Auto loading Katex only when needed

I wanted to use the Katex library to display maths on this site but as I’m not planning to use much maths I only wanted to load it when needed. So to do it I’ve created this small script:

function katexAutoLoad(opts) {
  var nodeList = document.getElementsByClassName('katex-auto');
  if (!nodeList.length) {
    return;
  }

  var head   = document.getElementsByTagName('head')[0];
  var style  = document.createElement('link');
  var script = document.createElement('script');
  var nodes  = [];

  for (var i = 0; i < nodeList.length; i++) {
    nodes[i] = nodeList[i];
  }

  style.href = opts.styleUrl;
  style.rel = 'stylesheet';

  script.src = opts.scriptUrl;
  script.onload = function () {
    for (var i = 0; i < nodes.length; i++) {
      var node = nodes[i];
      var isBlock = !/span/i.test(node.tagName)

      try {
        node.outerHTML = katex.renderToString(node.textContent, {
          displayMode: isBlock
        });
      } catch (ex) {
        var tag = isBlock ? 'div' : 'span';

        node.outerHTML = '<' + tag + ' class="katex-error">' +
            ex.message +
          '</' + tag + '>';
      }
    }
  };

  head.appendChild(style);
  head.appendChild(script);
}

katexAutoLoad({
  scriptUrl: 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.js',
  styleUrl: 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.css'
});

It will load Katex only when needed and replace any node that has the katex-auto class with the rendered Katex output.

It will also display <span> tags as inline and any other tag as a block, e.g.:

<span class="katex-auto">[inline equation]</span>
<div class="katex-auto">[block equation]</div>

It uses a wrapper class instead of markers used by TeX and LaTeX ($, $$, \[ and \() to avoid any conflicts. Using wrapper classes also has the benefit of being more efficient and requires less code.

Demo

These \frac{12}{e^{-1}} are examples \int_0^1 x^2,dx of inline c = \pm\sqrt{a^2 + b^2} equations.

Example using \displaystyle: \displaystyle\int_0^1 x^2,dx.

Example of blocks:

\frac{12}{e^{-1}}
\begin{aligned} \dot{x} & = \sigma(y-x) \\ \dot{y} & = \rho x - y - xz \\ \dot{z} & = -\beta z + xy \end{aligned}

Comments