markdown-it是目前使用最广泛的markdown解析器工具
。它将markdown语法的文件,解析为最终的html文件。绝大部分文档中心框架工具如Vuepress,处理markdown文件部分都是使用该工具以及扩展出的插件。了解它的解析过程,是进行自定义markdown插件的前提。
解析主要分两步:
var md = require('markdown-it')();
// render函数包含了parser和renderer阶段
var result = md.render('# markdown-it rulezz!');
创建一个 Core Parser,这个 Core Parser 包含一系列的缺省 Rules。这些 Rules 将顺序执行,每个 Rule 都在前面的 Tokens 的基础上,要么修改原来的 Token,要么添加新的 Token。这个 Rules 的链条被称为Core Chain
。Core Rules 如下:
Block Chain
又是一堆 Rules 的执行。Inline Chain
处理。Rule Chain核心代码:
// 定义parse
var Ruler = require('./ruler');
var _rules = [
[ 'normalize', require('./rules_core/normalize') ],
[ 'block', require('./rules_core/block') ],
[ 'inline', require('./rules_core/inline') ],
[ 'linkify', require('./rules_core/linkify') ],
[ 'replacements', require('./rules_core/replacements') ],
[ 'smartquotes', require('./rules_core/smartquotes') ]
];
function Core() {
// Ruler类在Block Chain和Inline Chain都有应用
this.ruler = new Ruler();
for (var i = 0; i < _rules.length; i++) {
this.ruler.push(_rules[i][0], _rules[i][1]);
}
}
Core.prototype.process = function (state) {
var i, l, rules;
rules = this.ruler.getRules('');
for (i = 0, l = rules.length; i < l; i++) {
rules[i](state);
}
};
// State是数据结构
// 所以链式调用Rule,修改的内容是数据结构State
Core.prototype.State = require('./rules_core/state_core');
module.exports = Core;
// 调用
var core = new Core()
let tokens = core.process(new core.State(...))
解析出Tokens数据结构类似如下:
[
{
"type": "heading_open",
"tag": "h1",
"attrs": null,
"map": [
0,
1
],
"nesting": 1,
"level": 0,
"children": null,
"content": "",
"markup": "#",
"info": "",
"meta": null,
"block": true,
"hidden": false
},
{
"type": "inline",
"tag": "",
"attrs": null,
"map": [
0,
1
],
"nesting": 0,
"level": 1,
"children": [
{
"type": "text",
"tag": "",
"attrs": null,
"map": null,
"nesting": 0,
"level": 0,
"children": null,
"content": "test",
"markup": "",
"info": "",
"meta": null,
"block": false,
"hidden": false
}
],
"content": "test",
"markup": "",
"info": "",
"meta": null,
"block": true,
"hidden": false
},
{
"type": "heading_close",
"tag": "h1",
"attrs": null,
"map": null,
"nesting": -1,
"level": 0,
"children": null,
"content": "",
"markup": "#",
"info": "",
"meta": null,
"block": true,
"hidden": false
}
]
把特定 Token 转变为特定的 HTML 的过程。
遇到匹配的 token.type,那么就会用对应的 Renderer Rule 来渲染。没有找到对应的 Renderer Rule,那么一个缺省的 render 函数会被调用。
markdown-it提供了强大的扩展机制(Plugin)。markdown-it提供了一些常用token.type对应的render规则,当你需要某些特殊的渲染效果时,可以覆写这些render rule,比如VuePress (opens new window)。另外,由于是把markdown解析成中间token数据结构,你还可以自定义插件,实现自定义parse rule以及对应的render rule,来扩展markdown-it能力,比如markdown-it-emoji (opens new window)。