This article will introduce how to make Typecho support on-demand rendering of LaTeX format.

You may open this demo webpage to get some ideas.

Why LaTeX?

LaTeX is a powerful document preparation system similar to Microsoft Word. Due to its strong support for mathematical formulas, it is sometimes used exclusively for entering mathematical formulas. We will only discuss how to use LaTeX to input mathematical formulas in Typecho (Markdown) and render them correctly, NOT discuss how to use LaTeX for typesetting. Be aware, that LaTeX is not just for entering mathematical formulas!

How to Render LaTeX on a Website?

We can use two LaTeX rendering libraries, KaTeX or MathJax, to achieve this. This article will use KaTeX as an example.

Note: LaTeX is a document preparation system. KaTeX or MathJax are the names of two libraries used for rendering LaTeX.

Why Not Use Plugins?

Plugins are convenient, and there are many plugins available online for supporting LaTeX in Typecho. However, most of them have a common issue: they cannot render LaTeX on-demand.

Most Typecho plugins are based on frontend rendering solutions using KaTeX or MathJax, essentially adding relevant JavaScript code and CSS stylesheets to the header, allowing the browser to render LaTeX source code when loading. However, even the most minimal LaTeX rendering library, KaTeX, is still a relatively large library.

If you choose to render LaTeX globally, it means that every page of your website (including the homepage) will load resources related to KaTeX. (Even if there is no LaTeX syntax present). This includes several JavaScript codes, some CSS stylesheets, and many font files. However, I don't use LaTeX that often, and global rendering will inevitably result in resource wastage and slow down the overall loading speed of the website.

Therefore, I choose to use Typecho's custom fields to manually determine whether a page needs to render LaTeX syntax.

Getting Started

Since I found that the values of custom fields cannot be retrieved by Typecho plugins, we can only achieve this by modifying the theme files.

Using KaTeX

KaTeX auto-rendering documentation: https://katex.org/docs/autorender.html

Add the following code to the theme's header.php file:

<script defer type="text/javascript" src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" />
<script defer type="text/javascript" src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"></script>
To avoid potential rendering blocking issues, we can use the defer keyword. For more information about blocking, you can refer to the relevant official documentation.

Add the following code to the theme's footer.php file:

<script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function() {
    renderMathInElement(document.body, {
      delimiters: [{
          left: "$$",
          right: "$$",
          display: true
      }, {
          left: "$",
          right: "$",
          display: false
      }],
      ignoredTags: ["script", "noscript", "style", "textarea", "pre", "code"],
      ignoredClasses: ["nokatex"]
    });
  });
</script>

So far, we have only achieved global rendering, so we need to retrieve some values from custom fields to determine whether to add KaTeX.

Rendering LaTeX on Demand

To avoid manually entering custom fields, we need to add an automatically input field. Open the theme's functions.php file and add or modify themeFields function:

function themeFields($layout) {
    $isLatex = new Typecho_Widget_Helper_Form_Element_Radio('isLatex', 
    array(1 => _t('Enable'),
    0 => _t('Disable')),
    0, _t('LaTeX Rendering'), _t('Default is disabled to improve website loading speed; enable it if there are LaTeX syntax in the article'));
    $layout->addItem($isLatex);
}

Modify the header.php file to add some logics:

<?php if ($this->is('post') && $this->fields->isLatex == 1): ?>
<script defer type="text/javascript" src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css" />
<script defer type="text/javascript" src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"></script>
<?php endif; ?>

Modify the footer.php file to add some logics:

<?php if ($this->is('post') && $this->fields->isLatex == 1): ?>
<script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function() {
    renderMathInElement(document.body, {
      delimiters: [{
          left: "$$",
          right: "$$",
          display: true
      }, {
          left: "$",
          right: "$",
          display: false
      }],
      ignoredTags: ["script", "noscript", "style", "textarea", "pre", "code"],
      ignoredClasses: ["nokatex"]
    });
  });
</script>
<?php endif; ?>

With these modifications, KaTeX rendering library will only be loaded when the page is a post (not in home page) and the custom field LaTeX option is enabled.

References

TOC