markdown-it 是前端的一个 markdown 解析库, 将 markdown 解析成 Token 流
网上都有很多详细的 token 流解析过程,请先简单看一遍
markdown-it解析 - 简书 https://www.jianshu.com/p/39ed59f610d4
看完的小伙伴应该一头雾水,下面我们来实践一下
首先,如果你需要解析流呢,就要往他的规则里面添加新的规则
// 添加规则
md.core.ruler.push('规则名', (state)=> {
// code here
return true;
});
// 渲染
md.render(`# hello word`)
上面的代码在 md 的规则里面添加了一个新的规则 show-line-rule
state
则是一个对象,其中有一个最重要的属性 tokens
,里面包括了解析完成的所有 token 流
例如一行 hello word
就会被解析成 3 个 token 。
xxx_open
: 开始 tokeninline
: 内容 tokenxxx_close
: 结束 token每个 token 都会被渲染成 html 标签
xxx_open
: <p>inline
: <p>xxx</p>xxx_close
: </p>渲染结果为 :
<p>
<p>xxx</p>
</p>
那么我们下面开始添加新的规则,渲染后给每一行加上行数
这里说明一下 token.attrs 的类型为
Array<[string,string]>
第一个string
是元素的属性名
第二个string
是元素的属性值
// 添加规则
md.core.ruler.push('show-line', (state)=> {
// forEach 遍历 tokens
state.tokens.forEach(token => {
// token.map 即所在的行数
if (token.map) {
// 起始行
const start = ["data-line-start", token.map[0].toString()]
// 结束行
const end = ["data-line-end", token.map[1].toString()]
// 初始化属性
token.attrs = token.attrs || []
// 添加属性
token.attrs.push(start,end)
}
})
return true;
});
渲染如下内容
# hello word
# hello word2
渲染结果
<h1 data-line-start="0" data-line-end="1"><a href="#hello-word">#</a> hello word</h1>
<h1 data-line-start="2" data-line-end="3"><a href="#hello-word2">#</a> hello word2</h1>
如果你要修改里面的内容呢就会相对复杂,因为每个 token 还可能会有 子token,所以这里就不仔细分析了。