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.
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
:::warning 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
:::warning 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/[email protected]/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.