apulSoft Blog
For this blog, I wanted a way to display math equations nicely and inline in the middle of my blog entries. For the main text I use markdown parsed by the php script ParseDown. My blog entries are simple utf-8 text files with a bit of markdown.
First I found ASCIImath, a standardized and human-readable way to write math in text files. Initially, I used MathJax, an online service that can convert the ASCIImath to nice-looking equations on your site.
Example: \$xi ~~ sqrt(t - 84/t - 14)\$ becomes $xi ~~ sqrt(t - 84/t - 14)$.
After being happy with MathJax for a while, I realized there are a few downsides:
- It relies on the MathJax homepage being reachable, so no offline math rendering for me working on the blog without internet access.
- It is a bit slow.
- The way it converts the page using JavaScript after loading is global, the entire page Html gets scanned for math. This can have unintended side-effects on menus, comments,...
- Its main focus are MathML and TeX math, ASCIIMath uses old code (as of MathJax v3.1.2)
So I wanted an offline compatible local solution. After some searching I found two projects that solved everything:
A script to convert ASCIIMath to TeX inside the ASCIIMath repository called ASCIIMathTexImg.js.
https://github.com/asciimath/asciimathml/tree/master/asciimath-based
The resulting TeX-style math can be converted to html using the awesome KaTeX project.
It's just one javascript file and one css file plus a bunch of fonts. I placed everything on my server:
|-- js
| |-- ASCIIMathTexImg.js
| |-- katex.js
|-- css
| |-- fonts
| |-- KaTeX_(*).tff
| |-- KaTeX_(*).woff
| |-- katex.css
Now I needed some client-side javascript to do the actual work once the page has been loaded. I wanted to limit the conversion to <p> tags inside a div with the id "blogtext". The \u000B shenanigan is to enable escaping of \$ using \\$. KaTeX needed an extra \displaystyle upfront to render tall equations nicely.
<link href="css/katex.css" rel="stylesheet">
<script src="js/ASCIIMathTeXImg.js"></script>
<script src="js/katex.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
var blogelement = document.getElementById('blogtext');
if (!blogelement) return;
var c = blogelement.getElementsByTagName('P');
for (var j = 0; j < c.length; ++j) {
// replace \$ with tmp char
txt = c[j].innerHTML.replaceAll('\\$', '\u000B');
var parts = txt.split('$');
for (var i = 0; i < parts.length; ++i) {
// replace tmp char with unescaped $
parts[i] = parts[i].replaceAll('\u000B', '$');
// odd parts are math
if ((i & 1) == 1) {
// convert to TeX
var math = AMTparseAMtoTeX(parts[i]);
// convert to html string
math = katex.renderToString('\\displaystyle ' + math, {
output: "html",
displaymode: true,
throwOnError: false
});
parts[i] = '<span>' + math + '</span>';
}
}
c[j].innerHTML = parts.join(' ');
}
});
</script>
Comments
Latest Blog Posts
Aug 21st, 2024Windows .msi Plugin Installer using WiX v5
Jun 1st, 2024Matched Digital Allpass IIR Filters
Oct 27th, 2022Clang-Format Xcode Automator Quick Action
Mar 16th, 2022Tags
math(7)dsp(4)
filters(3)
cpp(3)
blog(2)
webdesign(1)
gui(1)
macOS(1)
optimization(1)
lessonslearned(1)
Windows(1)
WiX(1)