这两天在从零开始手写新博客,在收尾阶段处理了下markdown的解析,用到的是markdown-it库。
用法很简单,直接v-html="markdownIt.render(markdown内容)"
就行了
但因为特殊需求,比如给tabel
标签外套一层div,用来做水平溢出滚动效果,需要更改下输出配置,这可就犯难了
上网到处找,但相关内容太少,官方文档也过于简单,直到看到这个大佬的文章:
文章中提到了markdown-it
是借用Token
序列渲染导出配置的,而对应渲染规则的方法则在markdownIt.renderer.rules
内,每个html元素都对应两个渲染方法[DOM_NAME]_open
和[DOM_NAME]_close
,如a
标签的规则名字就是link_open
但问题来了,这个DOM_NAME
怎么获得呢?文章中给出了通过打印参数Token
来获取,但我尝试了,未果,随意写一个dom_name的话得到的token为null
;即使手动重写了已知的link_open
,其参数token也仅仅包含文章中的a标签,并不包括其他标签。网上也找不到相关文章,这就把我难住了
既然拿到了规则,那么可以很容易的开始着手于修改渲染结果了
新建markdown/index.js
文件,填入以下基本内容
import Vue from 'vue'
// 引入 markdownIt
import MarkdownIt from 'markdown-it'
const md = new MarkdownIt({
html: true,
linkify: true,
typographer: true
})
// 这里为渲染规则修改部分配置
...
// 写入Vue全局方便调用
Vue.prototype.$markdownIt = md
我希望渲染的table标签被包裹在自带类名table-responsive和box-shadow-wrap-lg的div中,根据前文源码得知,table起始和结束的标签规则名为table_open
与table_close
,则配置代码如下
md.renderer.rules.table_open = (tokens, idx, options, env, self) => {
return '<div class="table-responsive box-shadow-wrap-lg"><table>'
}
md.renderer.rules.table_close = (tokens, idx, options, env, self) => {
return '</table></div>'
}
规则渲染方法几个形参作用解释:
通过这几个形参,可以获得每个渲染标签的详细内容,如
// 获取当前渲染标签的属性数组
tokens[idx].attrs
// 获取标签内容
tokens[idx].content
既然这样,那就可以来点更深层次的修改了。
我希望能让每一个image标签被渲染为如下几个特点
md.renderer.rules.image = (tokens, idx, options, env, self) => {
const srcItem = tokens[idx].attrs.find(item => {
return item[0] === 'src'
})
const src = srcItem[1]
const alt = tokens[idx].content
return `<p>
<div class="light-link" data-fancybox="gallery" no-pjax="" data-type="image" data-caption="${alt}">
<img src="${src}" alt="${alt}" />
<span class="post-img-desc">${alt}</span>
</div>
</p>`
}
有的时候可能只是想给原规则渲染结果添加一个属性(如class类名),并不需要其他大幅修改
渲染对象提供了attrSet
方法来实现添加属性这一操作,添加后直接将规则原路返回即可实现规则渲染修改
例如,我希望给删除线的渲染结果添加一个title属性,代码处理如下
// 复写删除线
md.renderer.rules.s_open = (tokens, idx, options, env, self) => {
tokens[idx].attrSet('title', '你知道的太多了')
return md.renderer.renderToken(tokens, idx, options, env, self)
}
因篇幅问题不能全部显示,请点此查看更多更全内容