Skip to content
MDX logo
v1.5.9GitHub logoTwitter logo
GitHub logoTwitter logo

Writing a plugin

For a full-fledged introduction to plugins it’s recommended to read the remark guides and study up on syntax trees.

Now let’s consider an example where you want to pass all headings through the title module to ensure consistent capitalization. We can use unist-util-visit to visit all headings and change the text nodes with title(text).

Visiting heading nodes

The first thing you want to do is install the unist-util-visit library. This is a utility library that allows you to visit all heading (or any other type of nodes) without having to write a lot of boiler plate code. It handles that for you.

Then you can first log out the nodes to see it in action:

const visit = require('unist-util-visit')
module.exports = () => (tree, file) => {
visit(tree, 'heading', node => {
console.log(node)
})
}

This will log out all the nodes in your document that are headings. Inside heading nodes there are text nodes. These include the raw text included in the heading.

Note: The reason that heading nodes include multiple text node types is because there can be other “phrasing content” nodes. For example if your heading looked like # Hello, _world_. In addition to the text there is also an emphasis node.

Visiting text nodes

To walk the text nodes, you can use unist-util-visit again:

const visit = require('unist-util-visit')
module.exports = () => (tree, file) => {
visit(tree, 'heading', node => {
visit(node, 'text', textNode => {
console.log(textNode)
})
})
}

Using the title library

Now that you are logging out the text nodes, you can now manipulate them with the title library by reassigning the value to the node:

const title = require('title')
const visit = require('unist-util-visit')
module.exports = () => (tree, file) => {
visit(tree, 'heading', node => {
visit(node, 'text', textNode => {
const text = textNode.value ? textNode.value.trim() : ''
textNode.value = title(text)
})
})
}
Edit this page on GitHub
Previous:
Table of contents
Next:
Custom loader