This is a replacement for https://wp.com/latex.php but instead of LaTeX, it uses MathJax.
Auttomatic's open-source Jetpack plugin has a LaTeX feature that is hardcoded
to call https://s0.wp.com/latex.php
It works like this:
I.e.
<img
src="https://s0.wp.com/latex.php?latex=%5Cdisplaystyle+P_%5Cnu%5E%7B-%5Cmu%7D%28z%29%3D%5Cfrac%7B%5Cleft%28z%5E2-1%5Cright%29%5E%7B%5Cfrac%7B%5Cmu%7D%7B2%7D%7D%7D%7B2%5E%5Cmu+%5Csqrt%7B%5Cpi%7D%5CGamma%5Cleft%28%5Cmu%2B%5Cfrac%7B1%7D%7B2%7D%5Cright%29%7D%5Cint_%7B-1%7D%5E1%5Cfrac%7B%5Cleft%281-t%5E2%5Cright%29%5E%7B%5Cmu+-%5Cfrac%7B1%7D%7B2%7D%7D%7D%7B%5Cleft%28z%2Bt%5Csqrt%7Bz%5E2-1%7D%5Cright%29%5E%7B%5Cmu-%5Cnu%7D%7Ddt&fg=000000"
>If we squint real hard, we can break down img src into $_GET parameters:
latex.php ? latex=<LaTeX> & fg=<ForegroundColor> & ...
Such a URL returns a PNG containing math rendered by LaTeX.
Prior to the existence of this microservice, we called wp.com/latex.php for our math needs. (Thanks WordPress!)
Pressbooks users wanted a MathJax solution.
MathJax's CommonHTML output works great in webbooks, but not in PDFs, EPUBs, MOBIs, ...
Nowadays, Pressbooks uses CommonHTML output in webbooks, SVGs in PDFs, and PNGs in MOBI/EPUBs.
The SVGs and PNGs are generated as follows:
http://localhost:3000/latex?latex=<LaTeX>- Foreground color:
http://localhost:3000/latex?latex=<LaTeX>&fg=00ff00 - Font:
http://localhost:3000/latex?latex=<LaTeX>&font=Gyre-Pagella - DPI:
http://localhost:3000/latex?latex=<LaTeX>&dpi=300
Mix and match fg=<RRGGBB>, font=<string> and dpi=<number> as needed.
http://localhost:3000/latex?latex=<LaTeX>&svg=1- Foreground color:
http://localhost:3000/latex?latex=<LaTeX>&fg=00ff00&svg=1 - Font:
http://localhost:3000/latex?latex=<LaTeX>&font=Gyre-Pagella&svg=1
Ie. same as PNG above with svg=1 added. Because SVGs are vector images, DPI is not used.
Same as LaTeX above but instead of latex?latex=<LaTeX> do:
- AsciiMath:
http://localhost:3000/asciimath?asciimath=<AsciiMath>... - MathML:
http://localhost:3000/mathml?mathml=<MathML>...
You can now pass base64 encoded formulas to avoid URL encoding issues with complex mathematical expressions:
- LaTeX:
http://localhost:3000/latex?latex=eF4yICsgeV4yID0gej4y&isBase64=true - AsciiMath:
http://localhost:3000/asciimath?asciimath=c3VtXyhpPTEpXm4gaV4zPSgobihuKzEpKS8yKV4y&isBase64=true - MathML:
http://localhost:3000/mathml?mathml=PG1hdGg-PG1pPng8L21pPjwvbWF0aD4&isBase64=true
The isBase64 parameter can be set to either true or 1. For URL safety, the base64 encoded formulas above don't include padding characters (==).
Here are some examples of formulas and their URL-safe base64 encoded versions (without padding):
| Formula | URL-safe Base64 Encoded |
|---|---|
x^2 + y^2 = z^2 |
eF4yICsgeV4yID0gej4y |
\frac{-b \pm \sqrt{b^2-4ac}}{2a} |
XGZyYWN7LWIgXHBtIFxzcXJ0e2JeMi00YWN9fXsyYX0 |
\int_0^\infty e^{-x^2} dx = \frac{\sqrt{\pi}}{2} |
XGludF8wXl5pbmZpbml0eSBlXnsteFxeMn0gZHggPSBcZnJhY3tcc3FydHtccGl9fXsyfQ |
When encoding formulas for use with this service:
- Convert your formula to base64
- Replace any
+with- - Replace any
/with_ - Remove any trailing
=padding characters
function urlSafeBase64Encode($string) {
$base64 = base64_encode($string);
$urlSafe = strtr($base64, '+/', '-_');
return rtrim($urlSafe, '='); // Remove padding
}
$formula = '\frac{-b \pm \sqrt{b^2-4ac}}{2a}';
$encodedFormula = urlSafeBase64Encode($formula);
$url = "http://localhost:3000/latex?latex={$encodedFormula}&isBase64=true";function urlSafeBase64Encode(string) {
const base64 = btoa(string);
const urlSafe = base64.replace(/\+/g, '-').replace(/\//g, '_');
return urlSafe.replace(/=+$/, ''); // Remove padding
}
const formula = '\\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}';
const encodedFormula = urlSafeBase64Encode(formula);
const url = `http://localhost:3000/latex?latex=${encodedFormula}&isBase64=true`;You can now customize the rendering with these additional parameters:
em: Font size in pixels (default: 16)ex: x-height in pixels (default: 8)width: Container width in pixels (default: 1000)lineWidth: Line width in pixels (default: 1000)scale: Scaling factor (default: 1)
- Larger font size:
http://localhost:3000/latex?latex=x^2+y^2=z^2&em=24&ex=12 - Custom width:
http://localhost:3000/latex?latex=x^2+y^2=z^2&width=800&lineWidth=800 - Scaled formula:
http://localhost:3000/latex?latex=x^2+y^2=z^2&scale=1.5 - Combined parameters:
http://localhost:3000/latex?latex=x^2+y^2=z^2&em=20&scale=1.2&fg=0000ff&svg=1
Install Node.js 18.x LTS, Then:
git clone git@github.com:pressbooks/pb-mathjax.git
cd pb-mathjax
npm install
npm start
Finally, go to: http://localhost:3000/
Install PM2 on your server, then:
cd ~/code/github/pressbooks/pb-mathjax
npm install --only=prod
pm2 start bin/www --name pb-mathjax
Pb-mathjax will be available at http://YOURSERVER:3000/ and will run forever (or until you kill PM2.) Use in Pressbooks as the value for PB_MATHJAX_URL
More info: http://pm2.keymetrics.io/docs/usage/quick-start/
This service is deployed automatically through AWS CodePipeline. Updates to the development, staging, or production branches trigger the pipeline to fetch the latest code, build and test it, and deploy the resulting ZIP package to the Lambda function. Deployment start and completion notifications are sent to the Slack bots channel.
For more details, see the Terraform directory.
This repository uses Release Please to automate versioning and changelog generation. See the CHANGELOG for a history of changes.
How it works:
-
Write commits to the
productionbranch using Conventional Commits format:feat: add new endpoint- triggers a minor version bumpfix: resolve svg rendering issue- triggers a patch version bumpfeat!: change API response formatorBREAKING CHANGE:in body - triggers a major version bump
-
Release Please automatically creates/updates a Release PR that includes:
- Version bump in
package.json - Auto-generated
CHANGELOG.mdentries
- Version bump in
-
When you merge the Release PR:
- A GitHub Release is created with a version tag (e.g.,
v1.2.0) - The merge triggers AWS CodePipeline to deploy to Lambda
- A GitHub Release is created with a version tag (e.g.,
Example commit messages:
feat: add support for custom fonts
fix: handle edge case in base64 decoding
docs: update API documentation
chore: update dependencies
feat!: remove deprecated latex endpoint