I spoke too soon. Shortly after thinking I’d be happy in the Gutenberg editor for everything, I found that it pushed me towards not writing complicated documents effectively – it’s hard to move sentences that cross paragraph boundaries around, and hard to set information aside when it doesn’t work well – and started writing in Markdown again.
Preparing to publish one of these stories, I turned on server-side Markdown:
- install the Classic Editor plugin
- enable Markdown in Jetpack
- create a post in the Classic Editor.
since it’s closer to the Markdown dialects I’m familiar with than Jetpack’s Markdown block. I did some quick tests, and found that footnotes work1, but syntax highlighting and math don’t:
And then I remembered that I’d only gotten them working with syntax highlighting and MathML Gutenberg blocks. Oops.
What was I supposed to do?
Markdown code blocks output classes compatible with SyntaxHighlighter Evolved, which seems instructive: it looks like I’m meant to handle this in JavaScript.
I can’t, though, because I’m using AMP. This is by design: it’s how AMP is cacheable on third-party servers, and how it defends against XSS. I don’t get enough traffic for caching to matter but I do like having baked-in XSS defense, especially if I want to turn on comments later, and I’m hoping not to turn off AMP.
Instead, if I want to use these with server-side Markdown and AMP, I’ll need to either:
- use alternatives to native Markdown syntax to embed these in posts, like:
- GitHub Gists
- Carbon images of code
- LaTeX in Jetpack
- render these in JavaScript on the server side. this is seldom done in WordPress, but Wikipedia has been doing this at scale with Mathoid for some time now
- or glue together Markdown and the server-side logic I’m already using
I don’t like the way LaTeX in Jetpack renders to images – they’re blurry on the monitor I use most often for this – and I don’t want to upgrade my server in order to run Node, so I started exploring what it would take to render math here. With any luck this will be a superset of the work needed to get syntax highlighting working, too, and I’ll be able to do both quickly once I’ve done one.
Inline math is hard
The normal way of denoting math is $...$
for inline math, and $$
for display math.
...
$$
Double dollar signs are uncommon, so it’s pretty safe to use regexes to match them.
It’s just my $0.02, but I want to type single dollar signs often enough I wouldn’t want them to introduce a math context every time I use them. There are a couple ways of dealing with this:
- Wrap them in inline code, following Yihui Xie
- Tighten up the parser, since Marked, Pandoc and Rmarkdown don’t have this problem.
I think I’d rather tighten up the parser, since I’m already using Marked to preview Markdown on the Mac. Marked is closed source, so I can’t be sure what it does. But Pandoc is open-source, and instructive: it uses careful rules to restrict where single dollar signs introduce math contexts, and parser combinators to implement them (source).
A sketch of getting inline math working
- Dust off my local development environment, since it tends to bitrot.
- Set up a core functionality plugin for my site. Right now I’ve got this logic scattered throughout a Genesis child theme and a bunch of two or three line plugins.
- Port the CommonMark Math extension from Haskell to PHP. A straight port is possible, since PHP has parser combinator libraries nowadays like Parsica.
- Write a filter that replaces
$...$
with<span class="math inline">...</span>
and$$...$$
with<span class="math display">...</span>
- Write a filter that conditionally replaces
<span class="math ...">
with the corresponding<amp-mathml>
tags when AMP is enabled - Wire them together in an AMP Custom Sanitizer
It seems simple enough. But I haven’t actually done any step after the first before, and recognize there are ways things could go wrong at each, or all, of the levels2. And I’ll likely need to ask for help along the way if I pick this up; it’ll be the most PHP I’ve written in a decade.
So I might as well write this down and go looking for help before things go wrong rather than after 😛
- and are amazing ↩
- “it’s in PHP” is not one of them. I’d much rather deal with this than figure out how to build photo essays from scratch in Django or Flask. ↩