Skip to article frontmatterSkip to article content

Create directives, roles, and transforms

This page provides minimal examples of how to create roles and directives in plugins. It focuses on the JavaScript plugin architecture, rather than the Executable Plugin architecture.

For each of the plugins below, you can register them by adding configuration to your myst.yml file like the following:

myst.yml
project:
  plugins:
    - src/myplugin.mjs

And then re-building your MyST site:

$ myst start

Create a directive

Below is boilerplate code for how to create a directive.

src/myplugin.mjs
const myDirective = {
  name: "mydirective",
  doc: "My new directive!",
  arg: { type: String, doc: "The argument of the directive.", required: true },
  body: { type: String, doc: "The body of the directive." },
  options: {
    option1: { type: String, doc: "An option of the directive." },
    option2: { type: Boolean, doc: "Another option of the directive." },
  },
  run(data, vfile, ctx) {
    const arg = data.arg;
    const body = data.body || "";
    const option1 = data.options.option1 || "mystring";
    const option2 = data.options.option2 || false;

    const sentence = {
      type: "text",
      value: `Arg: ${arg}\nBody: ${body}\nOption 1: ${option1}\nOption 2: ${option2}`
    };
    return [sentence];
  },
};

const plugin = {
  name: "My cool plugin",
  directives: [myDirective],
};

export default plugin;

Example usage:

myplugindemo.md
```{mydirective} myword
:option1: foo
:option2: true
My body
```

Create a role

Below is boilerplate code for how to create a role. This one shows how to use ctx to parse the role’s body as MyST.

src/myplugin.mjs
const myRole = {
  name: "myrole",
  doc: "My new role!",
  body: { type: String, doc: "The body of the role.", required: true },
  run(data, vfile, ctx) {
    const ast = ctx.parseMyst(data.body);
    return [ast.children[0]];
  },
};

const plugin = {
  name: "My cool plugin",
  roles: [myRole],
};

export default plugin;

Example usage:

This content {myrole}`will be **parsed as myst**` and inserted.

Create a transform

Transforms allow you to modify the AST in place during your build. Below is a sample transform that searches for the word “up” and changes it to “down”.

src/myplugin.mjs
const myTransform = {
  name: "updown",
  doc: "Turn up to down.",
  stage: "document",
  plugin: (opts, utils) => (tree) => {
    const textNodes = utils.selectAll("text", tree);
    textNodes.forEach((text, index) => {
        text.value = text.value.replace("up", "down");
    });
  }
};

const plugin = {
  name: "My cool plugin",
  transforms: [myTransform],
};

export default plugin;

Example usage: register this plugin for your MyST project, and put the word “up” in your text anywhere. When you view your MyST build output, all instances of “up” should be replace with “down”.

More information on plugins

For more information on writing plugins, see: