Skip to content

A replacement for wp.com/latex.php but instead of LaTeX, it uses MathJax.

License

Notifications You must be signed in to change notification settings

pressbooks/pb-mathjax

Repository files navigation

Synopsis

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&amp;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.

Hot Swap

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:

LaTeX

PNG:

  • 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.

SVG:

  • 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.

AsciiMath and MathML

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> ...

Base64 Encoded Formulas

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 (==).

Base64 Encoding Examples

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:

  1. Convert your formula to base64
  2. Replace any + with -
  3. Replace any / with _
  4. Remove any trailing = padding characters

Example of Base64 Encoding in PHP

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";

Example of Base64 Encoding in JavaScript

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`;

Additional Rendering Parameters

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)

Examples with Additional Parameters

  • 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

Installation

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/

Deploy to a Production Server

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/

Deploy to AWS Lambda

Automated Deploy Pipeline

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.

Releases and Versioning

This repository uses Release Please to automate versioning and changelog generation. See the CHANGELOG for a history of changes.

How it works:

  1. Write commits to the production branch using Conventional Commits format:

    • feat: add new endpoint - triggers a minor version bump
    • fix: resolve svg rendering issue - triggers a patch version bump
    • feat!: change API response format or BREAKING CHANGE: in body - triggers a major version bump
  2. Release Please automatically creates/updates a Release PR that includes:

    • Version bump in package.json
    • Auto-generated CHANGELOG.md entries
  3. 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

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

About

A replacement for wp.com/latex.php but instead of LaTeX, it uses MathJax.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 8

Languages