{"id":28462233,"url":"https://github.com/pressbooks/pb-mathjax","last_synced_at":"2025-07-03T16:31:18.081Z","repository":{"id":36454116,"uuid":"189244317","full_name":"pressbooks/pb-mathjax","owner":"pressbooks","description":"A replacement for wp.com/latex.php but instead of LaTeX, it uses MathJax.","archived":false,"fork":false,"pushed_at":"2025-06-17T16:26:38.000Z","size":966,"stargazers_count":4,"open_issues_count":23,"forks_count":1,"subscribers_count":10,"default_branch":"dev","last_synced_at":"2025-06-21T16:26:42.757Z","etag":null,"topics":["asciimath","latex","mathjax","mathml","microservice"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pressbooks.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-05-29T14:42:44.000Z","updated_at":"2025-06-17T16:26:21.000Z","dependencies_parsed_at":"2024-03-15T02:31:34.605Z","dependency_job_id":"9ceef97e-9f55-4a93-9362-fa61f3d34b8f","html_url":"https://github.com/pressbooks/pb-mathjax","commit_stats":{"total_commits":105,"total_committers":5,"mean_commits":21.0,"dds":0.5238095238095238,"last_synced_commit":"e2d255fa17ad515f9e9db6db24af0322f0489b5e"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pressbooks/pb-mathjax","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressbooks%2Fpb-mathjax","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressbooks%2Fpb-mathjax/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressbooks%2Fpb-mathjax/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressbooks%2Fpb-mathjax/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pressbooks","download_url":"https://codeload.github.com/pressbooks/pb-mathjax/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pressbooks%2Fpb-mathjax/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261991017,"owners_count":23241271,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asciimath","latex","mathjax","mathml","microservice"],"created_at":"2025-06-07T04:08:45.527Z","updated_at":"2025-07-03T16:31:18.067Z","avatar_url":"https://github.com/pressbooks.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Synopsis\r\n\r\nThis is a replacement for `https://wp.com/latex.php`  but instead of LaTeX, it uses [MathJax](https://www.mathjax.org/).\r\n\r\nAuttomatic's open-source Jetpack plugin has a [LaTeX feature](https://en.support.wordpress.com/latex/) that [is hardcoded](https://github.com/Automattic/jetpack/blob/45a6dfefbd8f4239cd61cbd28f361e9ef6036cac/modules/latex.php#L87)\r\nto call `https://s0.wp.com/latex.php`\r\n\r\nIt works like this:\r\n\r\n\u003cp\u003e\u003cimg 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\u0026amp;fg=000000\u0026bg=T\" \u003e\u003c/p\u003e\r\n\r\nI.e.\r\n\r\n```html\r\n\u003cimg\r\nsrc=\"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\u0026amp;fg=000000\"\r\n\u003e\r\n```\r\n\r\nIf we squint real hard, we can break down `img src` into `$_GET` parameters:\r\n\r\n`latex.php ? latex=\u003cLaTeX\u003e \u0026 fg=\u003cForegroundColor\u003e \u0026 ...`\r\n\r\nSuch a URL returns a PNG containing math rendered by LaTeX.\r\n\r\n# Hot Swap\r\n\r\nPrior to the existence of this microservice, we called `wp.com/latex.php` for our math needs. _(Thanks WordPress!)_\r\n\r\nPressbooks users wanted a [MathJax](https://www.mathjax.org/) solution.\r\n\r\nMathJax's [CommonHTML output](http://docs.mathjax.org/en/latest/options/output-processors/CommonHTML.html) works great in webbooks, but not in PDFs, EPUBs, MOBIs, ...\r\n\r\nNowadays, Pressbooks uses CommonHTML output in webbooks, SVGs in PDFs, and PNGs in MOBI/EPUBs.\r\n\r\nThe SVGs and PNGs are generated as follows:\r\n\r\n## LaTeX\r\n\r\n### PNG:\r\n\r\n+ `http://localhost:3000/latex?latex=\u003cLaTeX\u003e`\r\n+ Foreground color: `http://localhost:3000/latex?latex=\u003cLaTeX\u003e\u0026fg=00ff00`\r\n+ Font: `http://localhost:3000/latex?latex=\u003cLaTeX\u003e\u0026font=Gyre-Pagella`\r\n+ DPI: `http://localhost:3000/latex?latex=\u003cLaTeX\u003e\u0026dpi=300`\r\n\r\nMix and match `fg=\u003cRRGGBB\u003e`, `font=\u003cstring\u003e` and `dpi=\u003cnumber\u003e` as needed.\r\n\r\n### SVG:\r\n\r\n+ `http://localhost:3000/latex?latex=\u003cLaTeX\u003e\u0026svg=1`\r\n+ Foreground color: `http://localhost:3000/latex?latex=\u003cLaTeX\u003e\u0026fg=00ff00\u0026svg=1`\r\n+ Font: `http://localhost:3000/latex?latex=\u003cLaTeX\u003e\u0026font=Gyre-Pagella\u0026svg=1`\r\n\r\nIe. same as PNG above with `svg=1` added. Because SVGs are vector images, DPI is not used.\r\n\r\n## AsciiMath and MathML\r\n\r\nSame as LaTeX above but instead of `latex?latex=\u003cLaTeX\u003e` do:\r\n\r\n+ AsciiMath: `http://localhost:3000/asciimath?asciimath=\u003cAsciiMath\u003e` `...`\r\n+ MathML: `http://localhost:3000/mathml?mathml=\u003cMathML\u003e` `...`\r\n\r\n## Base64 Encoded Formulas\r\n\r\nYou can now pass base64 encoded formulas to avoid URL encoding issues with complex mathematical expressions:\r\n\r\n+ LaTeX: `http://localhost:3000/latex?latex=eF4yICsgeV4yID0gej4y\u0026isBase64=true`\r\n+ AsciiMath: `http://localhost:3000/asciimath?asciimath=c3VtXyhpPTEpXm4gaV4zPSgobihuKzEpKS8yKV4y\u0026isBase64=true`\r\n+ MathML: `http://localhost:3000/mathml?mathml=PG1hdGg-PG1pPng8L21pPjwvbWF0aD4\u0026isBase64=true`\r\n\r\nThe `isBase64` parameter can be set to either `true` or `1`. For URL safety, the base64 encoded formulas above don't include padding characters (`==`).\r\n\r\n### Base64 Encoding Examples\r\n\r\nHere are some examples of formulas and their URL-safe base64 encoded versions (without padding):\r\n\r\n| Formula | URL-safe Base64 Encoded |\r\n|---------|----------------|\r\n| `x^2 + y^2 = z^2` | `eF4yICsgeV4yID0gej4y` |\r\n| `\\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}` | `XGZyYWN7LWIgXHBtIFxzcXJ0e2JeMi00YWN9fXsyYX0` |\r\n| `\\int_0^\\infty e^{-x^2} dx = \\frac{\\sqrt{\\pi}}{2}` | `XGludF8wXl5pbmZpbml0eSBlXnsteFxeMn0gZHggPSBcZnJhY3tcc3FydHtccGl9fXsyfQ` |\r\n\r\nWhen encoding formulas for use with this service:\r\n1. Convert your formula to base64\r\n2. Replace any `+` with `-`\r\n3. Replace any `/` with `_`\r\n4. Remove any trailing `=` padding characters\r\n\r\n### Example of Base64 Encoding in PHP\r\n\r\n```php\r\nfunction urlSafeBase64Encode($string) {\r\n    $base64 = base64_encode($string);\r\n    $urlSafe = strtr($base64, '+/', '-_');\r\n    return rtrim($urlSafe, '='); // Remove padding\r\n}\r\n\r\n$formula = '\\frac{-b \\pm \\sqrt{b^2-4ac}}{2a}';\r\n$encodedFormula = urlSafeBase64Encode($formula);\r\n$url = \"http://localhost:3000/latex?latex={$encodedFormula}\u0026isBase64=true\";\r\n```\r\n\r\n### Example of Base64 Encoding in JavaScript\r\n\r\n```javascript\r\nfunction urlSafeBase64Encode(string) {\r\n    const base64 = btoa(string);\r\n    const urlSafe = base64.replace(/\\+/g, '-').replace(/\\//g, '_');\r\n    return urlSafe.replace(/=+$/, ''); // Remove padding\r\n}\r\n\r\nconst formula = '\\\\frac{-b \\\\pm \\\\sqrt{b^2-4ac}}{2a}';\r\nconst encodedFormula = urlSafeBase64Encode(formula);\r\nconst url = `http://localhost:3000/latex?latex=${encodedFormula}\u0026isBase64=true`;\r\n```\r\n\r\n## Additional Rendering Parameters\r\n\r\nYou can now customize the rendering with these additional parameters:\r\n\r\n+ `em`: Font size in pixels (default: 16)\r\n+ `ex`: x-height in pixels (default: 8)\r\n+ `width`: Container width in pixels (default: 1000)\r\n+ `lineWidth`: Line width in pixels (default: 1000)\r\n+ `scale`: Scaling factor (default: 1)\r\n\r\n### Examples with Additional Parameters\r\n\r\n+ Larger font size: `http://localhost:3000/latex?latex=x^2+y^2=z^2\u0026em=24\u0026ex=12`\r\n+ Custom width: `http://localhost:3000/latex?latex=x^2+y^2=z^2\u0026width=800\u0026lineWidth=800`\r\n+ Scaled formula: `http://localhost:3000/latex?latex=x^2+y^2=z^2\u0026scale=1.5`\r\n+ Combined parameters: `http://localhost:3000/latex?latex=x^2+y^2=z^2\u0026em=20\u0026scale=1.2\u0026fg=0000ff\u0026svg=1`\r\n\r\n# Installation\r\n\r\nInstall Node.js 18.x LTS, Then:\r\n\r\n    git clone git@github.com:pressbooks/pb-mathjax.git\r\n    cd pb-mathjax\r\n    npm install\r\n    npm start\r\n\r\nFinally, go to: `http://localhost:3000/`\r\n\r\n## Deploy to a Production Server\r\n\r\nInstall [PM2](http://pm2.keymetrics.io/) on your server, then:\r\n\r\n    cd ~/code/github/pressbooks/pb-mathjax\r\n    npm install --only=prod\r\n    pm2 start bin/www --name pb-mathjax\r\n\r\nPb-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`\r\n\r\nMore info: http://pm2.keymetrics.io/docs/usage/quick-start/\r\n\r\n\r\n## Deploy to AWS Lambda\r\n\r\nInstall [Claudia.js](https://claudiajs.com/), then:\r\n\r\n    cd ~/code/github/pressbooks/pb-mathjax\r\n    claudia create --handler lambda.handler --deploy-proxy-api --region us-east-1 --timeout 15 --memory 256 --profile yourself --use-local-dependencies\r\n\r\nWhere `us-east-1` is your AWS region and `yourself` corresponds to an identity in your `~/.aws/credentials` file.\r\n\r\nIf everything goes well, the above command will finish after a few moments and print a response with a URL. Use in Pressbooks as the value for `PB_MATHJAX_URL`\r\n\r\nMore info: https://claudiajs.com/tutorials/installing.html https://github.com/claudiajs/claudia/blob/master/docs/\r\n\r\nIf you are deploying not for the first time, use\r\n\r\n```\r\nrm -rf node_modules package-lock.json\r\nnpm install --arch=x64 --platform=linux\r\nclaudia update --use-local-dependencies\r\n```\r\n\r\nThis will download the dependencies needed for Linux and deploy to AWS Lambda.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpressbooks%2Fpb-mathjax","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpressbooks%2Fpb-mathjax","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpressbooks%2Fpb-mathjax/lists"}