使用docsify并定制以使它更强大

2019-03-25

背景

经常在网上看到一些排版非常漂亮的技术手册,左边有目录栏,右边是Markdown格式的文档,整个配色都十分舒服,就像一本书一样,一看就很让人喜欢。就比如Markdown Preview Enhanced的文档.目前网上我了解的有两种工具可以实现这样的效果,一种叫做docsify,另一种叫做Gitbook。因为MPE文档用的是docsify,而且据docsify自己的宣传,说是

不同于 GitBook、Hexo 的地方是它不会生成将 .md 转成 .html 文件,所有转换工作都是在运行时进行。
这将非常实用,如果只是需要快速的搭建一个小型的文档网站,或者不想因为生成的一堆 .html 文件“污染” commit 记录,只需要创建一个 index.html 就可以开始写文档而且直接部署在 GitHub Pages。

所以我也就用它来做吧。这里先放上我的成品:https://aopstudio.github.io/docs

入门基础

具体的一些基本操作它的官方文档上面都已经写得很明白了,我就不再赘述了,官方文档地址:https://docsify.js.org/#/zh-cn/ 。它的官方文档本身就是用docsify写的,让使用者第一眼就能感受到docsify生成文档的效果。

其实我每篇博客都不会去赘述官方文档里面已经有的内容,尽管这样可以凑字数,但是没什么意义。

一些注意点

预览

安装文档里推荐安装的docisfy-cli工具,可以方便地预览文档网站。用docsify serve docs命令就可以用浏览器访问localhost:3000预览。需要注意的是serve后面的不是当前所在文件夹,而是当前目录的子文件夹,也就是说如果你在D:\\docs创建了你的项目,你就应该在D:\\执行这条命令才能成功,而不是进到D:\\docs执行。如果进入到了D:\\docs,就应当写docsify serve,这样的话预览的就是当前文件夹的内容。有意思的是,如果我把docsify的文件夹作为一个子文件夹放在我的整个网站目录中时,比如我的网站根目录是/www,docsify项目在/www/docs,如果在网站根目录执行docsify serve,预览出来的就是整个网站,而且因为docsify采用了vue.js,因此整个网站的内容都会随着文件的修改而实时更新,说实话还挺好用的。

封面

官方文档中说要给开启渲染封面功能后在文档根目录创建_coverpage.md文件,之后就能在预览页面看到封面。但是根据我自己的尝试这样其实是有问题的,在本地预览时的确可以看到封面,但一放到Github Pages里面封面就没了。我个人认为是Github Pages默认使用的Jekyll会把以下划线开头的文件忽略掉。而作者应该也想到了这个问题,所以在文档的文件夹里面放了一个文件名为.nojekyll用于阻止 GitHub Pages 会忽略掉下划线开头的文件,但不知怎么的,反正是没起到什么作用,它照样忽略了。

不过封面无法显示的问题很好解决,创建一个不以下划线开头的封面文件自定义封面路径就行。也就是把配置项中的coverpage: true改为coverpage: 自定义的封面文件路径就行。

代码高亮

默认代码高亮是只支持CSS、JavaScript 和 HTML语言的。照官方文档里的说法想要支持其他语言需要手动引入高亮插件。不过我试了试照文档里的说法手动引入高亮插件,并没有什么用。我想尽各种办法,甚至都开始对在源码级别动刀子了,还是没有用(后文会提到两个在源码级别动刀子成功的案例,但唯独这个是失败的)。吐槽一下吧,一看作者就是一个前端程序员,要是是后端程序员写的话,不可能只支持这三门语言的。

定制功能

因为整个项目本身就是以源码的形式发布的,所以给了用户较大的定制空间,特别是对于Markdown渲染器。项目自带的默认Markdown渲染器只支持基本的语法,没有目前大部分Markdown写作工具都支持的一些扩展语法,比如LaTex数学公式、流程图等等。我的笔记中对于数学公式和图用到的还是非常多的,因此我就想改进一下它的渲染器,让它能支持这两个功能。

首先感谢JavaScript这门语言,正是这门语言让我在理论上能实现这次改进。其次感谢一下BootCDN,你们提供的CDN服务使依赖文件的处理如此方便。

支持DOT语言作图

DOT语言是贝尔实验室开发的用于作图的脚本语言,最初在桌面端程序Graphviz中支持。后来有人开发了Viz.js使得浏览器端也能支持DOT语言作图的渲染。

我们的目的如下:当Markdown渲染器识别到一处语言名为dot的代码块时,就调用Viz.js渲染代码块中的语句,使它们成为DOT语言定义的矢量图。

具体操作如下:(以下所有操作都在docsify项目的index.html文件中进行)

首先,引入Viz.js文件,推荐使用BootCDN的服务,只要在head中添加一条语句就行:<script src="https://cdn.bootcss.com/viz.js/1.8.0/viz.js"></script>。这里需要提醒一句,引入的viz.js文件必须是2.0版本以下的,千万不要为图新版本而引入2.0版本之后的,2.0版本之后的支持方式发生了改变,网上相关的资料极少,我本人是没有研究出来。引入1.8.0版本是非常稳妥的。

之后的操作可以参考文档里的这部分内容:https://docsify.js.org/#/zh-cn/markdown?id=%E6%94%AF%E6%8C%81-mermaid .我本人就是参考这部分内容才实现的。不同的是,需要把

if (lang === "mermaid") {
    return (
    '<div class="mermaid">' + mermaid.render(lang, code) + "</div>"
    );
}

改成

if (lang === "dot") {
    return (
    '<div class="viz">'+ Viz(code, "SVG")+'</div>'
    );
}

这样定制之后,文档对于DOT语言的支持堪称完美。
如图:dot.JPG

支持LaTex数学公式

LaTeX是大门鼎鼎的文档排版软件,它对于数学公式的支持非常好。和DOT语言类似,一开始也是只有桌面端程序支持,但是后来同样有人开发了各种各样的.js来在浏览器端进行支持,我们这里使用的是katex.js。

首先引入katex.js,在head中添加

<link href="https://cdn.bootcss.com/KaTeX/0.10.0/katex.min.css" rel="stylesheet">
<script src="https://cdn.bootcss.com/KaTeX/0.10.0/katex.min.js"></script>

一般来说Markdown文档中数学公式会用$包围表示,但是我做不到这么细的地步,还是只能让Markdown渲染器和支持DOT语言一样,把数学公式当作一门编程语言来渲染。因此需要将公式用```tex ```进行包围,以质能转换公式为例,应当这样写:

    ```tex
        E=mc^2
    ```

这样比用$包围麻烦,但好歹能用。

同样参照上面的做法,需要把

if (lang === "mermaid") {
    return (
    '<div class="mermaid">' + mermaid.render(lang, code) + "</div>"
    );
}

改成

if (lang === "tex") {
    return (
    '<span class="tex">'+ katex.renderToString(code, {
        throwOnError: false
    })+'</span>'
    );
}

就行。

试了一下,效果还可以。
如图:latex.JPG

总结

定制docsify的Markdown渲染器是我第一次在源码级别定制软件,之前觉得这对我来说简直是不可能的事,真实尝试之后发现其实自己已经有这个能力了。当然自己离一些大牛还差得很远,特别是数学、数据结构和算法方面,自己需要弥补的东西还有很多。不要骄傲自大,也不要妄自菲薄,清楚认识自己的实力并不断增强,此乃王道也。