A markdown-it plugin for $-delimited math environments.
See https://executablebooks.github.io/markdown-it-dollarmath/ for a demonstration!
Note there is a similar plugin markdown-it-texmath.
markdown-it-dollarmath
package differs in that it is optimised for dollar math:
it is more performant, handles backslash \\
escaping properly, and allows for more configuration.
Options:
allow_space
: Parse inline math when there is space after/before the opening/closing$
, e.g.$ a $
allow_digits
: Parse inline math when there is a digit before/after the opening/closing$
, e.g.1$
or$2
double_inline
: Search for double-dollar math within inline contextsallow_labels
: Capture math blocks with label suffix, e.g.$$a=1$$ (eq1)
labelNormalizer
: Function to normalize the label, by default replaces whitespace with-
(to align with HTML5 ids)
You should "bring your own" math render, provided as an option to the plugin. This function should take the string plus (optional) options, and return a string. For example, below the KaTeX render is used.
As a Node module:
import { renderToString } from "katex"
import MarkdownIt from "markdown-it"
import dollarmathPlugin from "markdown-it-dollarmath"
const mdit = MarkdownIt().use(dollarmathPlugin, {
allow_space: true,
allow_digits: true,
double_inline: true,
allow_labels: true,
labelNormalizer(label) {
return label.replace(/[\s]+/g, "-")
},
renderer(content, { displayMode }) {
return renderToString(content, { displayMode, throwOnError: false })
},
labelRenderer(label) {
return `<a href="#${label}" class="mathlabel" title="Permalink to this equation">¶<a>`
}
})
const text = mdit.render("$a = 1$")
In the browser:
<!doctype html>
<html>
<head>
<title>Example Page</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/katex/dist/katex.min.css"
/>
<script src="https://cdn.jsdelivr.net/npm/markdown-it@12/dist/markdown-it.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/katex/dist/katex.min.js"></script>
<script src="https://unpkg.com/markdown-it-dollarmath"></script>
</head>
<body>
<div id="demo"></div>
<script>
const options = {
renderer: (content, { displayMode }) =>
katex.renderToString(content, { displayMode, throwOnError: false })
}
const text = markdownit()
.use(window.markdownitDollarmath, options)
.render("$a = 1$")
document.getElementById("demo").innerHTML = text
</script>
</body>
</html>
- TypeScript
- Code Formatting (prettier)
- Code Linting (eslint)
- Testing and coverage (vitest)
- Continuous Integration (GitHub Actions)
- Bundled as both UMD and ESM (rollup)
- Upload as NPM package and unpkg CDN
- Simple demonstration website (GitHub Pages)
- Create a GitHub repository from the template.
- Replace package details in the following files:
package.json
LICENSE
README.md
rollup.config.js
- Install the
node_module
dependencies:npm install
ornpm ci
(see Install a project with a clean slate). - Run code formatting;
npm run format
, and linting:npm run lint:fix
. - Run the unit tests;
npm test
, or with coverage;npm test -- --coverage
.
Now you can start to adapt the code in src/index.ts
for your plugin, starting with the markdown-it development recommendations.
Modify the test in tests/fixtures.spec.ts
, to load your plugin, then the "fixtures" in tests/fixtures
, to provide a set of potential Markdown inputs and expected HTML outputs.
On commits/PRs to the main
branch, the GH actions will trigger, running the linting, unit tests, and build tests.
Additionally setup and uncomment the codecov action in .github/workflows/ci.yml
, to provide automated CI coverage.
Finally, you can update the version of your package, e.g.: npm version patch -m "🚀 RELEASE: v%s"
(patch/minor/major), push to GitHub; git push --follow-tags
, build; npm run build
, and publish; npm publish
.
Finally, you can adapt the HTML document in docs/
, to load both markdown-it and the plugin (from unpkg), then render text from an input area.
This can be deployed by GitHub Pages.