高级用法
默认情况下,Marked 在全局作用域中存储选项和扩展。这意味着在一个脚本中修改选项会同时影响其他脚本的选项,因为它们共享同一个实例。
如果不想修改全局作用域,可以创建新的 Marked 实例来确保选项和扩展作用域在本地范围内:
import { Marked } from 'marked';
const marked = new Marked([options, extension, ...]); // 新建实例
参数 | 类型 | 说明 |
---|---|---|
options | object | 与 marked.use 可传递的参数相同 |
重要提示:marked.use(...)
不应在循环或函数内使用,仅应在创建 new Marked
实例后或导入 marked
后直接调用。
parse 解析函数
import { marked } from 'marked';
marked.parse(markdownString [,options]) // 核心解析方法
参数 | 类型 | 说明 |
---|---|---|
markdownString | string | 待编译的 Markdown 源码字符串 |
options | object | 选项哈希表,也可用 marked.use 设置全局选项 |
引用式用法示例
import { marked } from 'marked';
// 设置全局选项
marked.use({
async: true, // 启用异步支持
pedantic: false, // 禁用严格模式
gfm: true, // 启用 GFM 规范
});
// 编译并输出结果
console.log(marked.parse(markdownString));
核心选项
选项成员 | 类型 | 默认值 | 版本 | 说明 |
---|---|---|---|---|
async | boolean | false | 4.1.0 | 为 true 时,walkTokens 函数可异步执行,marked.parse 返回 Promise |
breaks | boolean | false | v0.2.7 | 为 true 时,单行换行转 <br> (模拟 GitHub 评论行为),需启用 gfm |
gfm | boolean | true | v0.2.1 | 为 true 时,遵循 GitHub Flavored Markdown (GFM) 规范 |
pedantic | boolean | false | v0.2.1 | 为 true 时,尽可能兼容原始 markdown.pl 行为,覆盖 gfm 设置 |
renderer | object | new Renderer() | v0.3.0 | 包含将 token 渲染为 HTML 的函数的对象 |
silent | boolean | false | v0.2.7 | 为 true 时,解析器不抛出异常,错误以字符串形式返回 |
tokenizer | object | new Tokenizer() | v1.0.0 | 包含从 Markdown 创建 token 的函数的对象 |
walkTokens | function | null | v1.1.0 | 每个 token 解析时调用的函数 |
已废弃选项
选项成员 | 类型 | 默认值 | 废弃版本 | 替代方案 |
---|---|---|---|---|
smartLists | boolean | false | v3.0.0 | 已移除 |
baseUrl | string | null | v8.0.0 | 使用 https://github.com/markedjs/marked-base-url 为相对链接添加前缀 |
headerIds | boolean | true | v8.0.0 | 使用 https://github.com/markedjs/marked-gfm-heading-id 为标题添加 ID |
headerPrefix | string | '' | v8.0.0 | 同上 |
highlight | function | null | v8.0.0 | 使用 https://github.com/markedjs/marked-highlight 高亮代码块 |
langPrefix | string | 'language-' | v8.0.0 | 同上 |
mangle | boolean | true | v8.0.0 | 使用 https://github.com/markedjs/marked-mangle 混淆邮箱地址 |
sanitize | boolean | false | v8.0.0 | 在输出 HTML 上使用 DOMPurify/sanitize-html/insane 等净化库 |
sanitizer | function | null | v8.0.0 | 同上 |
smartypants | boolean | false | v8.0.0 | 使用 https://github.com/markedjs/marked-smartypants 优化标点符号 |
xhtml | boolean | false | v8.0.0 | 使用 https://github.com/markedjs/marked-xhtml 输出 XHTML 兼容标签 |
官方扩展库列表
Marked 可通过自定义扩展增强功能,以下为兼容 marked.use(extension)
的扩展库:
扩展名称 | 包名 | 说明 |
---|---|---|
Admonition | marked-admonition-extension | 批注扩展 |
Alert | marked-alert | 支持 GFM 警告框 |
Base URL | marked-base-url | 为相对链接添加基础 URL |
Bidi | marked-bidi | 为 HTML 添加双向文本支持 |
CJK Breaks | marked-cjk-breaks | 禁止中日韩字符间的软换行 |
Code Format | marked-code-format | 使用 Prettier 格式化代码块 |
Code JSX Renderer | marked-code-jsx-renderer | 用自定义渲染器和组件渲染 JSX 代码块 |
Code Preview | marked-code-preview | 将代码块转换为代码预览 |
Custom Heading ID | marked-custom-heading-id | 通过 # heading {#custom-id} 语法为标题指定自定义 ID |
Directive | marked-directive | 支持指令语法 |
Emoji | marked-emoji | 添加类 GitHub 的 emoji 支持 |
Extended Tables | marked-extended-tables | 扩展 GFM 表格功能(跨列/跨行/多行表头) |
Footnote | marked-footnote | 支持 GFM 脚注 |
GFM Heading ID | marked-gfm-heading-id | 使用 github-slugger 生成标题 ID,支持自定义前缀 |
Highlight | marked-highlight | 代码块语法高亮 |
HTML Renderer | marked-html-renderer | 输出 HTML 元素而非字符串 |
Katex Code | marked-katex-extension | 渲染 Katex 数学公式 |
LinkifyIt | marked-linkify-it | 使用 linkify-it 解析 URL |
Mangle | marked-mangle | 混淆 mailto 链接 |
Misskey-flavored Markdown | marked-mfm | Misskey 风格的自定义扩展 |
More Lists | marked-more-lists | 支持字母和罗马数字排序列表 |
Plaintify | marked-plaintify | 将 Markdown 转为纯文本 |
Shiki | marked-shiki | 整合 Shiki 语法高亮 |
Sequential Hooks | marked-sequential-hooks | 支持顺序预处理和后处理钩子 |
Smartypants | marked-smartypants | 智能优化标点符号(引号/破折号等) |
Smartypants lite | marked-smartypants-lite | 轻量版智能标点优化(无外部依赖) |
Typograf | marked-typograf | 更强大的智能标点替代方案(支持多语言) |
XHTML | marked-xhtml | 输出 XHTML 兼容的自闭合标签(如 <br/> ) |
内联 Markdown 解析
使用 marked.parseInline
可解析内联 Markdown(无段落包装):
const blockHtml = marked.parse('**strong** _em_');
console.log(blockHtml); // <p><strong>strong</strong> <em>em</em></p>
const inlineHtml = marked.parseInline('**strong** _em_');
console.log(inlineHtml); // <strong>strong</strong> <em>em</em>
代码高亮
使用 https://github.com/markedjs/marked-highlight 扩展实现代码块高亮。
Worker 线程安全方案
为防止 ReDoS 攻击,可将 Marked 运行在 Worker 中并设置超时终止机制,支持 Node Worker 和 Web Worker。
Node Worker 示例
markedWorker.js
import { marked } from 'marked';
import { parentPort } from 'worker_threads';
// 监听主线程消息并解析
parentPort.on('message', (markdownString) => {
parentPort.postMessage(marked.parse(markdownString));
});
index.js
import { Worker } from 'worker_threads';
const markedWorker = new Worker('./markedWorker.js');
// 设置超时强制终止
const timeoutLimit = 5000; // 超时阈值(毫秒)
const markedTimeout = setTimeout(() => {
markedWorker.terminate();
throw new Error('Marked 解析超时');
}, timeoutLimit);
// 处理结果并清理
markedWorker.on('message', (html) => {
clearTimeout(markedTimeout);
console.log(html);
markedWorker.terminate();
});
markedWorker.postMessage(markdownString); // 发送解析任务
Web Worker 示例
markedWorker.js
importScripts('path/to/marked.umd.js'); // 引入 Marked
// 消息处理逻辑(注意数据在 e.data 中)
onmessage = (e) => {
const html = marked.parse(e.data); // 解析 Markdown
postMessage(html); // 返回结果
};
script.js
const markedWorker = new Worker('./markedWorker.js');
const timeoutLimit = 5000;
// 超时强制终止
const markedTimeout = setTimeout(() => {
markedWorker.terminate();
throw new Error('Marked 解析超时');
}, timeoutLimit);
// 接收结果(数据在 e.data 中)
markedWorker.onmessage = (e) => {
clearTimeout(markedTimeout);
console.log(e.data); // 输出HTML
markedWorker.terminate();
};
markedWorker.postMessage(markdownString); // 发送任务
CLI 扩展集成
可通过新建 CLI 脚本来集成扩展:
#!/usr/bin/env node
import { marked } from 'marked';
import customHeadingId from 'marked-custom-heading-id';
// 应用扩展
marked.use(customHeadingId());
// 导入原CLI逻辑
import 'marked/bin/marked';
运行效果:
$ ./myMarked -s "# heading {#custom-id}"
# 输出: <h1 id="custom-id">heading</h1>
总结
- 实例隔离:通过
new Marked()
创建独立实例避免全局污染 - 核心方法:
marked.parse()
用于完整解析(生成块级HTML)marked.parseInline()
用于内联解析(无段落包裹)
- 选项演进:
- 废弃选项需用https://github.com/markedjs替代
- 新增异步(
async
)、安全模式(silent
)等现代化特性
- 扩展生态:覆盖语法增强(表格/数学公式)、安全(链接混淆)、渲染(JSX/HTML)等场景
- 安全实践:
- Worker线程+超时机制防御ReDoS攻击
- 净化库处理用户生成内容
- 工具链集成:支持通过CLI自定义扩展链