Understanding remark

The tool for working with Markdown as ASTs.

What is remark?

What is unified?

Overview of unified “runtime”

| ........................ process ........................... |
| .......... parse ... | ... run ... | ... stringify ..........|

          +--------+                     +----------+
Input ->- | Parser | ->- Syntax Tree ->- | Compiler | ->- Output
          +--------+          |          +----------+
                              X
                              |
                       +--------------+
                       | Transformers |
                       +--------------+

When should I use which package?

Most code examples that I’ve seen end up using remark-parse and remark-stringify as plugins to the core unified library. For example, the following code is in the remark README as a small example of a custom plugin to automatically indent markdown headings:

import remarkParse from "remark-parse";
import remarkStringify from "remark-stringify";
import { unified } from "unified";
import { visit } from "unist-util-visit";

const file = await unified()
  .use(remarkParse)
  .use(myRemarkPluginToIncreaseHeadings)
  .use(remarkStringify)
  .process("# Hi, Saturn!");

console.log(String(file)); // => '## Hi, Saturn!'

function myRemarkPluginToIncreaseHeadings() {
  /**
   * @param {import('mdast').Root} tree
   */
  return function (tree) {
    visit(tree, function (node) {
      if (node.type === "heading") {
        node.depth++;
      }
    });
  };
}

However, here’s what the Github repo says about the various packages included:

Example of Just Remark + Plugins

Here’s a quick example of using remark instead of unified, plus some additional plugins. This example includes the use of plugins that check markdown code style:

import { remark } from "remark";
import remarkPresetLintConsistent from "remark-preset-lint-consistent";
import remarkPresetLintRecommended from "remark-preset-lint-recommended";
import { reporter } from "vfile-reporter";

const file = await remark()
  .use(remarkPresetLintConsistent)
  .use(remarkPresetLintRecommended)
  .process("1) Hello, _Jupiter_ and *Neptune*!");

console.error(reporter(file));

This code yields the following in the terminal:

          warning Missing newline character at end of file final-newline             remark-lint
1:1-1:35  warning Marker style should be `.`               ordered-list-marker-style remark-lint
1:4       warning Incorrect list-item indent: add 1 space  list-item-indent          remark-lint
1:25-1:34 warning Emphasis should use `_` as a marker      emphasis-marker           remark-lint

⚠ 4 warnings

remark Plugins

There’s still a lot that I have to learn about remark plugins, but here are some quick highlights based on the small amount of research that I’ve done:

Additional Resources

References