remark

repository·main·Indexed 27 days ago

https://github.com/remarkjs/remark

A markdown processor that uses a syntax tree (mdast) to transform markdown content. The ecosystem includes remark-parse for parsing markdown into mdast, remark-stringify for serializing mdast back into markdown, and remark-cli for processing files via the terminal. It integrates with the unified processor and supports a wide range of plugins for tasks such as linting, adding tables of contents, and converting markdown to other formats like HTML or roff.

Tokens
6.8K
Snippets
21
Records
43
Agent score
92%

What's inside remark

  1. Overview of remark

    main

    remark is a tool that transforms markdown using a plugin ecosystem. It works by treating markdown as structured data through Abstract Syntax Trees (ASTs), specifically the mdast format. Plugins can inspect, change, or transform these trees.

    Remark can be used on the server, client, CLI, or in environments like Deno. It is built on top of the unified ecosystem.

  2. Use remarkParse with unified

    main

    Add support for parsing markdown by using .use(remarkParse) within a unified pipeline. This plugin turns markdown input into an mdast syntax tree.

    To create a full pipeline (e.g., Markdown to HTML), you typically chain remark-parse with other plugins like remark-gfm (for GitHub Flavored Markdown), remark-rehype (to convert mdast to hast), and rehype-stringify (to serialize to HTML).

    import rehypeStringify from 'rehype-stringify'
    import remarkGfm from 'remark-gfm'
    import remarkParse from 'remark-parse'
    import remarkRehype from 'remark-rehype'
    import {unified} from 'unified'
    
    const value = `
    # Mercury
    
    **Mercury** is the first planet from the [Sun](https://en.wikipedia.org/wiki/Sun)
    and the smallest planet in the Solar System.
    `
    
    const file = await unified()
      .use(remarkParse)
      .use(remarkGfm)
      .use(remarkRehype)
      .use(rehypeStringify)
      .process(value)
    
    console.log(String(file))
  3. Secure remark usage against XSS and DDoS

    main

    When using remark, consider the following security practices:

    Cross-Site Scripting (XSS)

    If you are converting markdown to HTML, you are likely using remark in combination with rehype. To prevent XSS attacks from improper HTML usage, you should use rehype-sanitize.

    Denial of Service (DDoS)

    Large files or complex structures (e.g., thousands of nested lists or links) can cause crashes or performance degradation. To mitigate this:

    • Cap the accepted size of input (e.g., 500kb).
    • Process content in a separate thread or worker so it can be terminated if necessary.

    Plugin Security

    Carefully assess the risk of any third-party remark plugins before including them in your project.

  4. Use remark plugins with remark-cli

    main

    When using the remark-cli tool from the terminal, you can include plugins in two ways:

    1. Use the --use flag to pass the plugin name directly.
    2. Specify the plugins in a configuration file supported by the unified engine.
  5. Use TypeScript with remark plugins

    main

    The remark organization and the unified collective are fully typed with TypeScript. To use TypeScript effectively, you should type your plugins using types from mdast and vfile.

    Types for the Markdown Abstract Syntax Tree (mdast) are available in the @types/mdast package.

    /**
     * @import {Root} from 'mdast'
     * @import {VFile} from 'vfile'
     */
    
    /**
     * @typedef Options
     *   Configuration.
     * @property {boolean | null | undefined} [someField]
     *   Some option (optional).
     */
    
    /**
     * My plugin.
     *
     * @param {Options | null | undefined} [options]
     *   Configuration (optional).
     * @returns
     *   Transform.
     */
    export function myRemarkPluginAcceptingOptions(options) {
      /**
       * Transform.
       *
       * @param {Root} tree
       *   Tree.
       * @param {VFile} file
       *   File.
       * @returns
       *   Nothing.
       */
      return function (tree, file) {
        // Do things.
      }
    }
  6. Best practices for creating and publishing remark plugins

    main

    To properly publish a remark plugin, follow these steps:

    1. Implementation: Use default exports to expose your plugin from its package.
    2. Metadata: Add remark-plugin keywords to your package.json.
    3. Discovery: Add a remark-plugin topic to your GitHub repository.
    4. Documentation: Contribute your plugin to the official remark plugin list.
  7. Choose the right remark package

    main

    Depending on your input and output requirements, select the appropriate package:

    • remark: Use this if both your input and output are markdown. It includes unified, remark-parse, and remark-stringify.
    • remark-parse: Use with unified if your input is markdown and you want to work with the AST.
    • remark-stringify: Use with unified if you want to turn an AST into markdown output.
    • remark-cli: Use to inspect and format markdown files via the command line.

    Note: If you only need to turn markdown into HTML (without complex AST manipulation), consider using micromark instead. If you want to handle syntax trees manually without the full remark ecosystem, use mdast-util-from-markdown and mdast-util-to-markdown.

  8. Use remark-cli to process markdown files

    main

    You can use remark-cli to inspect or change markdown files via the terminal or npm scripts.

    Common tasks:

    • Add a Table of Contents: Use remark-toc with the --output flag.

      remark --output --use remark-toc readme.md
    • Lint markdown files: Use a preset like remark-preset-lint-markdown-style-guide on a directory.

      remark --use remark-preset-lint-markdown-style-guide .
    • Rewrite all files in a directory:

      remark . -o
    remark --output --use remark-toc readme.md
  9. Install remark-stringify

    main

    Install remark-stringify as an ESM-only package.

    Node.js (version 16+):

    npm install remark-stringify

    Deno:

    import remarkStringify from 'https://esm.sh/remark-stringify@11'

    Browsers:

    <script type="module">
      import remarkStringify from 'https://esm.sh/remark-stringify@11?bundle'
    </script>
    npm install remark-stringify