How to use LaTeX in Ghost
The Markdown parser in Ghost does not parse , but you can parse it separately using other tools and post them on your Ghost blog.
In this tutorial, I'll show you how to use with Ghost. is a fast typesetting library that helps you print on the web.
Easy way
The easiest way to publish in Ghost is to use the Append Editor. Paste your Markdown in the Append Editor, open the menu in the top right, then under Share, click Copy rendered HTML. Then paste the HTML in an HTML card in Ghost.
Then copy the following link into the header or footer of your website or post as a code injection:
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/katex@0.12.0/dist/katex.min.css"
integrity="sha384-AfEj0r4/OFrOo5t7NnNe46zW/tFgW6x/bCJG8FqQCEo3+Aro6EYUG4+cU+KJWu/X"
crossorigin="anonymous"
/>
The latest links are available on GitHub.
The Hard Way
Set up
- Install Node.js
- Create a
package.json
with this content:
{
"name": "compiler-for-ghost",
"version": "1.0.0",
"description": "Compile Markdown to HTML for Ghost",
"main": "src/compiler.js",
"dependencies": {
"rehype-highlight": "^4.0.0",
"rehype-katex": "^3.0.0",
"rehype-raw": "^4.0.2",
"rehype-react": "^6.0.0",
"rehype-stringify": "^8.0.0",
"remark-emoji": "^2.1.0",
"remark-external-links": "^6.1.0",
"remark-footnotes": "^1.0.0",
"remark-math": "^2.0.1",
"remark-parse": "^8.0.2",
"remark-rehype": "^7.0.0",
"remark-slug": "^6.0.0",
"remark-toc": "^7.0.0",
"unified": "^9.0.0"
},
"devDependencies": {},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
- Run
sudo npm install -g npm-check-updates
. - Run
ncu -u
. - Run
npm install
.
Create a Compiler
Create a compilers.js
file with the following content:
'use strict';
const unified = require('unified');
const parse = require('remark-parse');
const remark2rehype = require('remark-rehype');
const math = require('remark-math');
const rehypeKatex = require('rehype-katex');
const highlight = require('rehype-highlight');
const emoji = require('remark-emoji');
const externalLinks = require('remark-external-links');
const toc = require('remark-toc');
const footnotes = require('remark-footnotes');
const slug = require('remark-slug');
const raw = require('rehype-raw');
const stringify = require('rehype-stringify');
const processor = unified()
.use(parse, { commonmark: true })
.use(slug)
.use(toc, { maxDepth: 2 })
.use(externalLinks, { rel: ['noopener'] })
.use(footnotes, { inlineNotes: true })
.use(remark2rehype, { allowDangerousHtml: true })
.use(raw)
.use(math)
.use(rehypeKatex)
.use(highlight, { ignoreMissing: true })
.use(emoji)
.use(stringify);
Command Line Approach
To run the compiler without specifying your .md
and .html
files within compiler.js
, add this code to the bottom of compiler.js
:
/**
* stdin = './path/to/BlogPost.md';
* stdout = './path/to/BlogPost.html';
* node compiler.js < ./path/to/BlogPost.md > ./path/to/BlogPost.html
*/
process.stdin.pipe(stream(processor)).pipe(process.stdout);
To compile your Markdown to HTML, run this command:
node compiler.js < ./path/to/BlogPost.md > ./path/to/BlogPost.html
This approach will overwrite your ./path/to/BlogPost.html
file if it already exists.
File System Approach
To specify the .md
and .html
files within compiler.js
, add this code to the bottom of compiler.js
:
const fs = require('fs');
const fileIn = './path/to/BlogPost.md';
const fileOut = './path/to/BlogPost.html';
const text = fs.readFileSync(fileIn, { encoding: 'utf-8' });
const html = processor.processSync(text);
fs.writeFileSync(fileOut, html, { encoding: 'utf-8' });
To compile your Markdown to HTML, run this command:
node compiler
This approach will overwrite your ./path/to/BlogPost.html
file if it already exists.
Stylesheets
Finally, add the stylesheets to your Ghost blog as a code injection to the header. You can add it globally if you need to use it often, or to the code injection for each individual post. You can find the latest links to the CDN on GitHub:
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/katex@0.11.1/dist/katex.min.css"
integrity="sha384-zB1R0rpPzHqg7Kpt0Aljp8JPLqbXI3bhnPWROx27a9N0Ll6ZP/+DiW/UqRcLbRjq"
crossorigin="anonymous"
/>
Examples
Further Resources
Give back
The techniques described in this tutorial depend heavily on free and open-source plugins developed by the Unifiedjs Collective. If you think their plugins are useful, please support their work on Open Collective.