# Arithmatex

## Overview

Arithmatex is an extension that preserves LaTeX math equations during the Markdown conversion process so that they can be used with libraries like MathJax. If you prefer to use something other than MathJax, Arithmatex can output a more generic format suitable for other libraries like KaTeX.

Arithmatex searches for the patterns $...$ and $$...$$ for inline math, and $$...$$, $...$, and \begin{}...\end{} for block math. By default, all formats are enabled, but each format can individually be disabled if desired.

The Arithmatex extension can be included in Python Markdown by using the following:

import markdown
md = markdown.Markdown(extensions=['pymdownx.arithmatex'])


By default, smart_dollar mode is enabled for the $...$ inline variant. With smart_dollar it is expected that the opening token ($) is to be followed by a non-whitespace character, and the closing to be preceded by a non-white-space character. This is to help avoid false positives when using the dollar sign in traditional ways such as: I have$2.00 and Bob has $10.00. The previous statement requires no escaping of the $ character. But when needed, the $ character can be escaped using \$. smart_dollar can be disabled and will capture any $...$ whose dollar symbols are not escaped (\$). Inline Examples $p(x|y) = \frac{p(y|x)p(x)}{p(y)}$, $p(x|y) = \frac{p(y|x)p(x)}{p(y)}$. $p(x|y) = \frac{p(y|x)p(x)}{p(y)}$, $$p(x|y) = \frac{p(y|x)p(x)}{p(y)}$$.  Inline Configuration When using MathJax, for best results, it is advised to not use generic mode, and configure MathJax without the text2jax extension since MathJax automatically detects Arithmatex's default output. If using generic mode (for libraries like KaTeX), Arithmatex will convert dollars to the form $$...$$ in the HTML output. This is because $...$ is extremely problematic to scan for, which is why MathJax and KaTeX disable $...$ by default in their plain text scanners, and why Arithmatex enables smart_dollar by default when scanning for $...$. It is advised that if you are outputting in in generic mode that you do not configure your JavaScript library to look for $...$ and instead look for $$...$$, and let Arithmatex's handle $.... For block forms, the block must start with the appropriate opening for the block type: , $, and \begin{} for the respective search pattern. The block must also end with the proper respective end: , $, and \end{}. A block also must contain no empty lines and should be both preceded and followed by an empty line. Block Examples E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j 3 < 4 \begin{align} p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\ p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right) \end{align}  E(\mathbf{v}, \mathbf{h}) = -\sum_{i,j}w_{ij}v_i h_j - \sum_i b_i v_i - \sum_j c_j h_j $3 < 4$ \begin{align} p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\ p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right) \end{align}  ## MathJax Output Format The math equations will be wrapped in a special MathJax script tag and embedded into the HTML. This format does not require the tex2jax.js extension when setting up MathJax. The tag will be in the form of <script type="math/tex"></script> for inline and <script type="math/tex; mode=display"></script> for block. By default, Arithmatex will also generate a preview span with the class MathJax_Preview that can/should be hidden when the math content is actually loaded. If you do not want to generate the preview, simply set preview to False. ## Generic Output Format If generic is enabled, the extension will escape necessary symbols and normalize all output to be wrapped in the more reliable $$...$$ for inline math and $...$ for display math (unless changed via tex_inline_wrap and tex_block_wrap in the options). Lastly, everything is inserted into a <span> or <div> for inline and display math respectively. With the default settings, if in your Markdown you used ... for inline math, it would be converted to <span class="arithmatex">$$...$$</span> in the HTML. Blocks would be normalized from ...$$ to <div class="arithmatex">$...$</div>. In the case of \begin{}...\end{}, begins and ends will not be replaced, only wrapped: <div class="arithmatex">$\begin{}...\end{}$</div>. ## Loading MathJax Arithmatex requires you to provide the MathJax library and provide and configure it to your liking. The recommended way of including MathJax is to use the CDN. Latest version at time of writing this is found below. <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script> <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>  <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js"></script>  Generally, it is best to add your own configuration to get exactly what you want. Here we show some simple examples of configurations done in JavaScript. We've provided two basic configurations below: one that is configured for Arithmatex's MathJax Output Format, and one that works with the Generic Output Format by using tex2jax. These are a good starting point, so feel free to take them and configure them further. Please see the MathJax site for more info on using MathJax extensions/plugins and configuring those extensions/plugins. window.MathJax = { options: { ignoreHtmlClass: 'tex2jax_ignore', processHtmlClass: 'tex2jax_process', renderActions: { find: [10, function (doc) { for (const node of document.querySelectorAll('script[type^="math/tex"]')) { const display = !!node.type.match(/; *mode=display/); const math = new doc.options.MathItem(node.textContent, doc.inputJax, display); const text = document.createTextNode(''); const sibling = node.previousElementSibling; node.parentNode.replaceChild(text, node); math.start = {node: text, delim: '', n: 0}; math.end = {node: text, delim: '', n: 0}; doc.math.push(math); if (sibling && sibling.matches('.MathJax_Preview')) { sibling.parentNode.removeChild(sibling); } } }, ''] } } };  window.MathJax = { tex: { inlineMath: [ ["\$$","\$$"] ], displayMath: [ ["\$","\$"] ], processEscapes: true, processEnvironments: true }, options: { ignoreHtmlClass: ".*|", processHtmlClass: "arithmatex" } };  MathJax.Hub.Config({ config: ["MMLorHTML.js"], jax: ["input/TeX", "output/HTML-CSS", "output/NativeMML"], extensions: ["MathMenu.js", "MathZoom.js"] });  MathJax.Hub.Config({ config: ["MMLorHTML.js"], extensions: ["tex2jax.js"], jax: ["input/TeX", "output/HTML-CSS", "output/NativeMML"], tex2jax: { inlineMath: [ ["\$$","\$$"] ], displayMath: [ ["\$","\$"] ], processEscapes: true, processEnvironments: true, ignoreClass: ".*|", processClass: "arithmatex" }, });  Notice that in our generic configuration, we set up tex2jax to only load arithmatex classes by excluding all elements and adding an exception for the arithmatex class. We also don't bother adding ... and $$...$$ to the inlineMath and displayMath options as Arithmatex converts them respectively to $$...$$ and $...$ in the HTML output (unless altered in Options). But we do have to enable processEnvironments to properly process \begin{}...\end{} blocks. ## Loading KaTeX In order to use KaTeX, the generic output format is required. You will need to include the KaTeX library: <script src="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0/katex.min.js"></script>  And the KaTeX CSS: <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.9.0/katex.min.css">  Though KaTeX does have its own auto load script, we want to ensure it only loads math content from elements with the arithmatex class. Below is a script that would do just that. Notice we check for and strip wrappers $$...$$ and $...$ off the content of the elements and send it through the renderer. We also don't bother adding ... and $$... to the inlineMath and displayMath options as Arithmatex converts them respectively to $$...$$ and $...$ in the HTML output (unless altered in Options). (function () { 'use strict'; var katexMath = (function () { var maths = document.querySelectorAll('.arithmatex'), tex; for (var i = 0; i < maths.length; i++) { tex = maths[i].textContent || maths[i].innerText; if (tex.startsWith('\$$') && tex.endsWith('\$$')) { katex.render(tex.slice(2, -2), maths[i], {'displayMode': false}); } else if (tex.startsWith('\$') && tex.endsWith('\$')) { katex.render(tex.slice(2, -2), maths[i], {'displayMode': true}); } } }); (function () { var onReady = function onReady(fn) { if (document.addEventListener) { document.addEventListener("DOMContentLoaded", fn); } else { document.attachEvent("onreadystatechange", function () { if (document.readyState === "interactive") { fn(); } }); } }; onReady(function () { if (typeof katex !== "undefined") { katexMath(); } }); })(); }());  ## Alternative Math Blocks Alternate Math Format The alternate math format functions use the default style that embeds math content in scripts, not the generic format that just escapes the content in plain text. InlineHilite and SuperFences both have a feature where you can specify your own custom inline and fence blocks respectively. Arithmatex provides a number of compatible formats that can be used in conjunction with InlineHilite and SuperFences to create an alternative (and possibly more preferable) syntax for math. In InlineHilite, by simply providing the following configuration (no need to include pymdownx.arithmatex as an extension), you can create a familiar inline math format: import pymdownx.arithmatex as arithmatex extensions = [ "pymdownx.inlinehilite" ] extension_config = { "pymdownx.inlinehilite": { "custom_inline": [ {"name": "math", "class": "arithmatex", "format": arithmatex.inline_mathjax_format} ] } }  Inline Math $p(x|y) = \frac{p(y|x)p(x)}{p(y)}$ #!math p(x|y) = \frac{p(y|x)p(x)}{p(y)}  In SuperFences, by providing the following configuration (no need to include pymdownx.arithmatex as an extension), you can create math fences: import pymdownx.arithmatex as arithmatex extensions = [ "pymdownx.superfences" ] extension_config = { "pymdownx.superfences": { "custom_fences": [ {"name": "math", "class": "arithmatex", arithmatex.fence_mathjax_format} ] } }  Math Fences math \begin{align} p(v_i=1|\mathbf{h}) & = \sigma\left(\sum_j w_{ij}h_j + b_i\right) \\ p(h_j=1|\mathbf{v}) & = \sigma\left(\sum_i w_{ij}v_i + c_j\right) \end{align}   Provided formats are found below: Name Description inline_mathjax_preview_format Inline format suitable for InlineHilite that preserves math in MathJax script format with an appropriate preview. inline_mathjax_format Inline format suitable for InlineHilite that preserves math in MathJax script format without a preview. inline_generic_format Inline format suitable for InlineHilite that preserves math in generic spans with arithmatex class. Content will be wrapped with $$ and $$, so your math library should target those for conversion. block_mathjax_preview_format Display/block format suitable for SuperFences that preserves math in MathJax script format with an appropriate preview. block_mathjax_format Display/block format suitable for SuperFences that preserves math in MathJax script format without a preview. block_generic_format Display/block format suitable for SuperFences that preserves math in generic spans with arithmatex class. Content will be wrapped with $ and $, so your math library should target those for conversion. ## Options Option Type Default Description inline_syntax [string] ['dollar', 'round'] Syntax to search for: dollar=...$ and round=$$...$$. block_syntax [string] ['dollar', 'square', 'begin'] Syntax to search for: dollar=$...$, square=$...$, and \begin{}...\end{}. generic bool False Output in a generic format suitable for non MathJax libraries. tex_inline_wrap [string] ['\$$', '\$$'] An array containing the opening and closing portion of the generic wrap. tex_block_wrap [string] ['\$', '\$'] An array containing the opening and closing portion of the generic wrap. smart_dollar bool True Enable Arithmatex's smart dollar logic to minimize math detection issues with $.
preview bool True Insert a preview to show until MathJax finishes loading the equations.

Last update: May 8, 2021