A markdown-it plugin for implementing docutils style roles (inline extension point) and directives (block extension point).
See https://executablebooks.github.io/markdown-it-docutils/ for a demonstration!
As a Node module:
import MarkdownIt from "markdown-it"
import docutilsPlugin from "markdown-it-docutils"
const text = MarkdownIt().use(docutilsPlugin).render("*a*")
In the browser:
<!DOCTYPE html>
<html>
<head>
<title>Example Page</title>
<script src="https://cdn.jsdelivr.net/npm/markdown-it@12/dist/markdown-it.min.js"></script>
<script src="https://unpkg.com/markdown-it-docutils"></script>
<link rel="stylesheet" type="text/css" media="screen" href="https://unpkg.com/markdown-it-docutils/dist/css/style.min.css" />
</head>
<body>
<div id="demo"></div>
<script>
const text = window.markdownit().use(window.markdownitDocutils).render("*a*");
document.getElementById("demo").innerHTML = text
</script>
</body>
</html>
Roles are any token in the token, within an inline
token's children with the role
type:
Token.meta = { name }
should contain the name of the roleToken.content
should contain the content of the role
By default (see parseRoles
option), roles are parsed according to the MyST syntax: {name}`content`
.
All roles have a fallback renderer, but the the following are specifically handled:
raw
Directives are any token in the token stream with the directive
type:
Token.info
should contain the name of the directiveToken.meta = { arg: "" }
should contain the argument (first line) of the directiveToken.content
should contain the body of the directiveToken.map
should be set
By default (see replaceFences
option), all fences with a language delimited in braces will be converted to directive
tokens, e.g.
```{name} argument
:option: value
content
```
All directives have a fallback renderer, but the the following are specifically handled:
- Admonitions:
admonition
note
attention
caution
danger
error
important
hint
note
seealso
tip
warning
- Image:
image
figure
- Code:
code
code-block
code-cell
- Tables:
list-table
TODO improve this:
- Parsing all directives/roles to "generic" directive/role tokens first (with fallback renderer), then "run" the directives/roles
- this separates the logic for parsing these syntaxes, from the logic for interpreting their content, i.e. the syntax for a directive/role can in theory be anything, as long as it can be converted to the necessary token
- TypeScript
- Code Formatting (prettier)
- Code Linting (eslint)
- Testing and coverage (jest)
- 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 master
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"
, 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.