Project Icon

remark

多功能Markdown处理器 支持插件系统

remark是一个强大的Markdown处理工具,通过插件系统可以检查和转换Markdown内容。它支持多种运行环境,完全兼容CommonMark和GFM规范,提供抽象语法树操作能力。remark拥有150多个可选插件,可用于Markdown的解析、检查和格式化等多种任务。作为当前最流行的Markdown处理器,remark为开发者提供了灵活而强大的Markdown处理能力。

![remark][logo]

[![Build][build-badge]][build] [![Coverage][coverage-badge]][coverage] [![Downloads][downloads-badge]][downloads] [![Size][size-badge]][size] [![Sponsors][sponsors-badge]][collective] [![Backers][backers-badge]][collective] [![Chat][chat-badge]][chat]

remark is a tool that transforms markdown with plugins. These plugins can inspect and change your markup. You can use remark on the server, the client, CLIs, deno, etc.

Feature highlights

  • [compliant][syntax] — 100% to CommonMark, 100% to GFM or MDX with a plugin
  • [ASTs][syntax-tree] — inspecting and changing content made easy
  • [popular][] — world’s most popular markdown parser
  • [plugins][] — 150+ plugins you can pick and choose from

Intro

remark is an ecosystem of plugins that work with markdown as structured data, specifically ASTs (abstract syntax trees). ASTs make it easy for programs to deal with markdown. We call those programs plugins. Plugins inspect and change trees. You can use the many existing plugins or you can make your own.

  • to learn markdown, see this [cheatsheet and tutorial][cheat]
  • for more about us, see [unifiedjs.com][site]
  • for updates, see [Twitter][]
  • for questions, see [support][]
  • to help, see [contribute][] or [sponsor][] below

Contents

What is this?

With this project and a plugin, you can turn this markdown:

# Hello, *Mercury*!

…into the following HTML:

<h1>Hello, <em>Mercury</em>!</h1>
Show example code
import rehypeStringify from 'rehype-stringify'
import remarkParse from 'remark-parse'
import remarkRehype from 'remark-rehype'
import {unified} from 'unified'

const file = await unified()
  .use(remarkParse)
  .use(remarkRehype)
  .use(rehypeStringify)
  .process('# Hello, *Mercury*!')

console.log(String(file)) // => '<h1>Hello, <em>Mercury</em>!</h1>'

With another plugin, you can turn this markdown:

# Hi, Saturn!

…into the following markdown:

## Hi, Saturn!
Show example code
/**
 * @import {Root} from 'mdast'
 */

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 {Root} tree
   */
  return function (tree) {
    visit(tree, function (node) {
      if (node.type === 'heading') {
        node.depth++
      }
    })
  }
}

You can use remark for many different things. [unified][] is the core project that transforms content with ASTs. remark adds support for markdown to unified. [mdast][] is the markdown AST that remark uses.

This GitHub repository is a monorepo that contains the following packages:

  • [remark-parse][remark-parse] — plugin to take markdown as input and turn it into a syntax tree (mdast)
  • [remark-stringify][remark-stringify] — plugin to take a syntax tree (mdast) and turn it into markdown as output
  • [remark][remark-core] — unified, remark-parse, and remark-stringify, useful when input and output are markdown
  • [remark-cli][remark-cli] — CLI around remark to inspect and format markdown in scripts

When should I use this?

Depending on the input you have and output you want, you can use different parts of remark. If the input is markdown, you can use remark-parse with unified. If the output is markdown, you can use remark-stringify with unified If both the input and output are markdown, you can use remark on its own. When you want to inspect and format markdown files in a project, you can use remark-cli.

If you just want to turn markdown into HTML (with maybe a few extensions), we recommend [micromark][micromark] instead.

If you don’t use plugins and want to deal with syntax trees manually, you can use [mdast-util-from-markdown][mdast-util-from-markdown] and [mdast-util-to-markdown][mdast-util-to-markdown].

Plugins

remark plugins deal with markdown. Some popular examples are:

  • [remark-gfm][remark-gfm] — add support for GFM (GitHub flavored markdown)
  • [remark-lint][remark-lint] — inspect markdown and warn about inconsistencies
  • [remark-toc][remark-toc] — generate a table of contents
  • [remark-rehype][remark-rehype] — turn markdown into HTML

These plugins are exemplary because what they do and how they do it is quite different, respectively to extend markdown syntax, inspect trees, change trees, and transform to other syntax trees.

You can choose from the 150+ plugins that already exist. Here are three good ways to find plugins:

  • [awesome-remark][awesome-remark] — selection of the most awesome projects
  • [List of plugins][list-of-plugins] — list of all plugins
  • [remark-plugin topic][topic] — any tagged repo on GitHub

Some plugins are maintained by us here in the @remarkjs organization while others are maintained by folks elsewhere. Anyone can make remark plugins, so as always when choosing whether to include dependencies in your project, make sure to carefully assess the quality of remark plugins too.

Examples

Example: turning markdown into HTML

remark is an ecosystem around markdown. A different ecosystem is for HTML: [rehype][]. The following example turns markdown into HTML by combining both ecosystems with [remark-rehype][remark-rehype]:

import rehypeSanitize from 'rehype-sanitize'
import rehypeStringify from 'rehype-stringify'
import remarkParse from 'remark-parse'
import remarkRehype from 'remark-rehype'
import {unified} from 'unified'

const file = await unified()
  .use(remarkParse)
  .use(remarkRehype)
  .use(rehypeSanitize)
  .use(rehypeStringify)
  .process('# Hello, Neptune!')

console.log(String(file))

Yields:

<h1>Hello, Neptune!</h1>

Example: support for GFM and frontmatter

remark supports CommonMark by default. Non-standard markdown extensions can be enabled with plugins. The following example adds support for GFM (autolink literals, footnotes, strikethrough, tables, tasklists) and frontmatter (YAML):

import rehypeStringify from 'rehype-stringify'
import remarkFrontmatter from 'remark-frontmatter'
import remarkGfm from 'remark-gfm'
import remarkParse from 'remark-parse'
import remarkRehype from 'remark-rehype'
import {unified} from 'unified'

const doc = `---
layout: solar-system
---

# Hi ~~Mars~~Venus!
`

const file = await unified()
  .use(remarkParse)
  .use(remarkFrontmatter)
  .use(remarkGfm)
  .use(remarkRehype)
  .use(rehypeStringify)
  .process(doc)

console.log(String(file))

Yields:

<h1>Hi <del>Mars</del>Venus!</h1>

Example: checking markdown

The following example checks that markdown code style is consistent and follows recommended best practices:

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))

Yields:

          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

Example: checking and formatting markdown on the CLI

The following example checks and formats markdown with remark-cli, which is the CLI (command line interface) of remark that you can use in your terminal. This example assumes you’re in a Node.js package.

First, install the CLI and plugins:

npm install remark-cli remark-preset-lint-consistent remark-preset-lint-recommended remark-toc --save-dev

…then add an npm script in your package.json:

  /* … */
  "scripts": {
    /* … */
    "format": "remark . --output",
    /* … */
  },
  /* … */

💡 Tip: add ESLint and such in the format script too.

The above change adds a format script, which can be run with npm run format. It runs remark on all markdown files (.) and rewrites them (--output). Run ./node_modules/.bin/remark --help for more info on the CLI.

Then, add a remarkConfig to your package.json to configure remark:

  /* … */
  "remarkConfig": {
    "settings": {
      "bullet": "*", // Use `*` for list item bullets (default)
      // See <https://github.com/remarkjs/remark/tree/main/packages/remark-stringify> for more options.
    },
    "plugins": [
      "remark-preset-lint-consistent", // Check that markdown is consistent.
      "remark-preset-lint-recommended", // Few recommended rules.
      [
        // Generate a table of contents in `## Contents`
        "remark-toc",
        {
          "heading": "contents"
        }
      ]
    ]
  },
  /* … */

👉 Note: you must remove the comments in the above examples when copy/pasting them as comments are not supported in package.json files.

Finally, you can run the npm script to check and format markdown files in your project:

npm run format

Syntax

Markdown is parsed and serialized according to CommonMark. Other plugins can add support for syntax extensions.

We use [micromark][micromark] for our parsing. See its documentation for more information on markdown, CommonMark, and extensions.

Syntax tree

The syntax tree used in remark is [mdast][]. It represents markdown constructs as JSON objects.

This markdown:

## Hello *Pluto*!

…yields the following tree (positional info remove for brevity):

{
  type: 'heading',
  depth: 2,
  children: [
    {type: 'text', value: 'Hello '},
    {type: 'emphasis', children: [{type: 'text', value: 'Pluto'}]}
    {type: 'text', value: '!'}
  ]
}

Types

The remark organization and the unified collective as a whole is fully typed with [TypeScript][]. Types for mdast are available in [@types/mdast][types-mdast].

For TypeScript to work, it is important to type your plugins. For example:

/**
 * @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 {undefined}
   *   Nothing.
   */
  return function (tree, file) {
    // Do things.
  }
}

Compatibility

Projects maintained by the unified collective are compatible with maintained versions of Node.js.

When we cut a new major release, we drop support for unmaintained versions of Node. This means we try to keep the current release line compatible with Node.js 16.

Security

As markdown can be turned into HTML and improper use of HTML can open you up to [cross-site scripting (XSS)][xss] attacks, use of remark can be unsafe. When going to HTML, you will combine remark with [rehype][], in which case you should use [rehype-sanitize][rehype-sanitize].

Use of remark plugins could also open you up to other attacks. Carefully assess each plugin and the risks involved in using them.

For info on how to submit a report, see our [security policy][security].

Contribute

See [contributing.md][contributing] in [remarkjs/.github][health] for ways to get started. See [support.md][support] for ways to get help. Join us in [Discussions][chat] to chat with the community and contributors.

This project has a [code of conduct][coc]. By interacting with this repository, organization, or community you agree to abide by its terms.

Sponsor

Support this effort and give back by sponsoring on [OpenCollective][collective]!

项目侧边栏1项目侧边栏2
推荐项目
Project Cover

豆包MarsCode

豆包 MarsCode 是一款革命性的编程助手,通过AI技术提供代码补全、单测生成、代码解释和智能问答等功能,支持100+编程语言,与主流编辑器无缝集成,显著提升开发效率和代码质量。

Project Cover

AI写歌

Suno AI是一个革命性的AI音乐创作平台,能在短短30秒内帮助用户创作出一首完整的歌曲。无论是寻找创作灵感还是需要快速制作音乐,Suno AI都是音乐爱好者和专业人士的理想选择。

Project Cover

有言AI

有言平台提供一站式AIGC视频创作解决方案,通过智能技术简化视频制作流程。无论是企业宣传还是个人分享,有言都能帮助用户快速、轻松地制作出专业级别的视频内容。

Project Cover

Kimi

Kimi AI助手提供多语言对话支持,能够阅读和理解用户上传的文件内容,解析网页信息,并结合搜索结果为用户提供详尽的答案。无论是日常咨询还是专业问题,Kimi都能以友好、专业的方式提供帮助。

Project Cover

阿里绘蛙

绘蛙是阿里巴巴集团推出的革命性AI电商营销平台。利用尖端人工智能技术,为商家提供一键生成商品图和营销文案的服务,显著提升内容创作效率和营销效果。适用于淘宝、天猫等电商平台,让商品第一时间被种草。

Project Cover

吐司

探索Tensor.Art平台的独特AI模型,免费访问各种图像生成与AI训练工具,从Stable Diffusion等基础模型开始,轻松实现创新图像生成。体验前沿的AI技术,推动个人和企业的创新发展。

Project Cover

SubCat字幕猫

SubCat字幕猫APP是一款创新的视频播放器,它将改变您观看视频的方式!SubCat结合了先进的人工智能技术,为您提供即时视频字幕翻译,无论是本地视频还是网络流媒体,让您轻松享受各种语言的内容。

Project Cover

美间AI

美间AI创意设计平台,利用前沿AI技术,为设计师和营销人员提供一站式设计解决方案。从智能海报到3D效果图,再到文案生成,美间让创意设计更简单、更高效。

Project Cover

稿定AI

稿定设计 是一个多功能的在线设计和创意平台,提供广泛的设计工具和资源,以满足不同用户的需求。从专业的图形设计师到普通用户,无论是进行图片处理、智能抠图、H5页面制作还是视频剪辑,稿定设计都能提供简单、高效的解决方案。该平台以其用户友好的界面和强大的功能集合,帮助用户轻松实现创意设计。

投诉举报邮箱: service@vectorlightyear.com
@2024 懂AI·鲁ICP备2024100362号-6·鲁公网安备37021002001498号