记录下如何给docsify添加多语言的代码高亮支持,以及在代码高亮的同时能显示行号,便利使用。

环境准备

需要预先安装nodejs,之后在终端执行下述命令

1
2
3
npm i docsify-cli -g
docsify init ./docs
docsify serve ./docs

之后可通过http://localhost:3000来访问默认的模板,给默认生成的README.md文件分别添加javascriptjavagolang代码块后显示结果类似如下

docsify默认的代码高亮显示效果

从上图中可发现如下几个问题:

  1. javascript代码有高亮显示,而javagolang代码没有高亮显示
  2. javascript代码虽然支持高亮显示,但是没有显示行号
  3. 代码块与真正的代码内容之间的间距过大,占用过多空间也不便于阅读

代码高亮

Language highlighting中有如下说明

docsify代码高亮说明

可知其默认支持的代码高亮语言有限,其它的需要手工添加,在prismjs CDN files可查看全部支持的语言列表,在其生成的index.html文件中添加相关的高亮文件

1
2
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-go.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-java.min.js"></script>

保存配置后,可发现浏览器中的页面已经修改,javagolang已经添加了高亮支持

docsify添加代码高亮

前述第1个问题解决,余下的2个仍未解决。

样式改进

index.html中添加如下css代码

1
2
3
.markdown-section pre > code {
    padding: 5px;
}

此时可发现代码块的间距已经显著减少,问题2解决。

docsify代码高亮样式改进

显示行号

显示行号是代码高亮的一个刚需功能,不太明白为啥docsify的开发者一直没有整合这个功能。

简单搜素下就发现有人已经提过此类问题**Prismjs supports line numbers and sepcific line highlight **根据该链接的回复对index.js做一些修改。

将默认的渲染行为修改如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
window.$docsify = {
    name: '',
    repo: '',
    markdown: {
        renderer:{
            code: function(code, lang) {
                if(lang =='html'){
                    code = code.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
                }
                return ('<pre data-lang="'+lang+'"><code class="line-numbers language-'+lang+'">'+code+'</code></pre>')
            }
        }	  
    },
    plugins: [
        function (hook, vm) {
            hook.doneEach(function (html) {                
                Prism.highlightAll();
            })
        }
    ]

}

添加如下css样式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
.markdown-section pre[data-lang] {
    overflow: auto !important;
}

.markdown-section pre[data-lang] code {
    overflow: visible;
}

.line-numbers .line-numbers-rows {
    border-right : 0px solid white;
    /* Fix paddings to align with code.*/
    padding: 5px; /* Same as code block */
}

分别引入相关的cssjs文件

1
2
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/line-numbers/prism-line-numbers.min.css">
<script src="//cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/line-numbers/prism-line-numbers.min.js"></script>

之后查看docsify页面,效果如下,至此问题3也解决,顺利达成目的!

docsify代码高亮且有行号

后记

框架切换

由于docsify是将所有的markdown文件全部加载并渲染成单个html文件,导致其在初次打开时很卡顿,渲染完成后就很流畅。但每次打开浏览器访问docsify时都需要花时间进行初次渲染,尤其是随着markdown文件越来越多,渲染耗时也越来越多,严重影响体验。

后续处于便于使用以及便于扩展、维护的角度考虑,最终将docsify替换为了GitBook,详情参见GitBook插件中实现从多个不同的文件夹下加载css和js文件

参考代码

完整的index.html代码如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  <meta name="description" content="Description">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
  <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify@4/lib/themes/vue.css">
  <link rel="stylesheet" href="//cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/line-numbers/prism-line-numbers.min.css">
  <style type="text/css">	
	.markdown-section pre[data-lang] {
		overflow: auto !important;
	}
	
	.markdown-section pre[data-lang] code {
		overflow: visible;
	}

	.line-numbers .line-numbers-rows {
		border-right : 0px solid white;
		/* Fix paddings to align with code.*/
		padding: 5px; /* Same as code block */
	}
	
	.markdown-section pre > code {
		padding: 5px;
	}
  </style>
</head>
<body>
  <div id="app"></div>
  <script>
    window.$docsify = {
      name: '',
      repo: '',
	  markdown: {
            renderer:{
				code: function(code, lang) {
				    if(lang =='html'){
					  code = code.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
					}
					return ('<pre data-lang="'+lang+'"><code class="line-numbers language-'+lang+'">'+code+'</code></pre>')
				}
			}	  
	 },
	 plugins: [
		  function (hook, vm) {
			  hook.doneEach(function (html) {                
				Prism.highlightAll();
			  })
		  }
	  ]

    }
  </script>
  <!-- Docsify v4 -->
  <script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
  <script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-go.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-java.min.js"></script>
  <script src="//cdn.jsdelivr.net/npm/prismjs@1.29.0/plugins/line-numbers/prism-line-numbers.min.js"></script>
</body>
</html>