Marked

2024-06-25 16:06:53 273
Marked 是一个快速、灵活的 Markdown 解析器,支持将 Markdown 文本转换为 HTML。它由 JavaScript 编写,适用于浏览器和 Node.js 环境。Marked 提供了高性能和扩展性,适合处理大量 Markdown 内容的应用程序。

特点

  • 高性能: 解析速度快,能够高效处理大规模 Markdown 文本。
  • 灵活性: 提供丰富的配置选项和插件机制,满足各种定制需求。
  • 兼容性: 支持 CommonMark 和 GitHub Flavored Markdown (GFM),兼容性强。
  • 安全性: 提供防止 XSS 攻击的选项,确保生成的 HTML 安全。
  • 开源: 源代码公开,社区活跃,持续维护和更新。

使用场景

  • Markdown解析
  • Markdown 编辑器

安装方式

使用 npm 或 yarn 安装

npm install marked
# 或者
yarn add marked

使用示例

在 Node.js 环境中使用 Marked 将 Markdown 转换为 HTML

const marked = require('marked');

const markdownString = '# Hello, Marked!';
const htmlString = marked(markdownString);

console.log(htmlString);

在浏览器环境中使用

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Marked Example</title>
  <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
</head>
<body>
  <h1>Marked Example</h1>
  <div id="content"></div>
  <script>
    const markdownString = '# Hello, Marked!';
    const htmlString = marked.parse(markdownString);
    document.getElementById('content').innerHTML = htmlString;
  </script>
</body>
</html>

es模块导入

<script type="module">
  import { marked } from "https://cdn.jsdelivr.net/npm/marked/lib/marked.esm.js";
  document.getElementById('content').innerHTML =
    marked.parse('# Marked in the browser\n\nRendered by **marked**.');
</script>

常用 API 介绍

1. marked.parse(markdownString, options)

描述: 将 Markdown 字符串解析为 HTML 字符串。

参数:

  • markdownString: 字符串,包含要解析的 Markdown 内容。
  • options: 可选参数,对象,包含解析选项。

示例:

const markdownString = '# Hello, Marked!';
const htmlString = marked.parse(markdownString, {
  gfm: true,
  breaks: true,
});

console.log(htmlString);

2. marked.setOptions(options)

描述: 设置全局解析选项。

参数:

  • options: 对象,包含解析选项。

示例:

marked.setOptions({
  gfm: true,
  breaks: true,
  sanitize: true,
});

3. marked.use(extensions)

描述: 使用插件扩展 Marked 的功能。

参数:

  • extensions: 对象或数组,包含插件扩展。

示例:

const myExtension = {
  name: 'myExtension',
  level: 'block', // or 'inline'
  start(src) { return src.match(/myExtension/)?.index },
  tokenizer(src, tokens) {
    const rule = /^myExtension:(.*)/;
    const match = rule.exec(src);
    if (match) {
      return {
        type: 'myExtension',
        raw: match[0],
        text: match[1].trim(),
      };
    }
  },
  renderer(token) {
    return `<div class="myExtension">${token.text}</div>`;
  }
};

marked.use({ extensions: [myExtension] });

const markdownString = 'myExtension: Hello, custom extension!';
const htmlString = marked.parse(markdownString);

console.log(htmlString);

4. marked.Renderer

描述: 自定义渲染器,可以定制 Markdown 各个元素的渲染方式。

示例:

const renderer = new marked.Renderer();
renderer.heading = function (text, level) {
  return `<h${level} class="my-heading">${text}</h${level}>`;
};

const htmlString = marked.parse('# Hello, Marked!', { renderer });

console.log(htmlString);

5. marked.Parser

描述: 解析 Markdown 抽象语法树 (AST) 为 HTML。

示例:

const lexer = marked.lexer('# Hello, Marked!');
const parser = new marked.Parser();
const htmlString = parser.parse(lexer);

console.log(htmlString);

6. marked.Lexer

描述: 将 Markdown 字符串解析为抽象语法树 (AST)。

示例:

const lexer = new marked.Lexer();
const tokens = lexer.lex('# Hello, Marked!');

console.log(tokens);

7. marked.Tokenizer

描述: 自定义词法分析器,可以定制 Markdown 词法分析规则。

示例:

class MyTokenizer extends marked.Tokenizer {
  codespan(src) {
    const match = /^`([^`]+)`/.exec(src);
    if (match) {
      return {
        type: 'codespan',
        raw: match[0],
        text: match[1],
      };
    }
  }
}

const tokenizer = new MyTokenizer();
const lexer = new marked.Lexer({ tokenizer });
const tokens = lexer.lex('`code` example');

console.log(tokens);

高级用法

使用扩展和插件: Marked 提供了灵活的扩展机制,可以通过插件扩展其功能。例如,可以自定义解析规则或增加新功能。

示例:

const customExtension = {
  name: 'custom',
  level: 'inline',
  start(src) { return src.indexOf('~'); },
  tokenizer(src, tokens) {
    const rule = /^~([^~]+)~/;
    const match = rule.exec(src);
    if (match) {
      return {
        type: 'custom',
        raw: match[0],
        text: match[1].trim(),
      };
    }
  },
  renderer(token) {
    return `<span class="custom">${token.text}</span>`;
  }
};

marked.use({ extensions: [customExtension] });

const markdownString = 'This is ~custom~ text.';
const htmlString = marked.parse(markdownString);

console.log(htmlString);

官方资料