需要一个小型的在线文档系统,Docsify 可以满足需求,记录一下搭建记录,主要 Docsify 官方的中文文档

本地搭建

前提:本地需要安装 nodejs 并完成相应配置。

新建 DocBase/ 文件夹,在其中本地安装 docsify-cli

1
npm i docsify-cli -g

由于 docsify-cli 不是全局安装的,存在找不到 hexo 命令的问题,对于 Windows 可以通过临时添加路径到 PATH 解决,在 DocBase 目录下执行

1
$env:Path += ";$((Get-Item -Path .\node_modules\.bin -Force).FullName)"

初始化项目

1
docsify init ./docs

初始化过程会自动新建 ./docs 子文件夹,并生成如下文件:

  • index.html:项目入口
  • README.md:内容会被渲染成项目主页
  • .nojekyll:防止 Github 忽视下划线开头文件

使用下面的命令可以在本地预览

1
2
3
cd ./docs
docsify serve
# or docsify s

这会在本地部署一个网站,通过 http://localhost:3000 访问。

自动生成的 index.html 文件默认内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!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">
</head>
<body>
<div id="app"></div>
<script>
window.$docsify = {
name: '',
repo: ''
}
</script>
<!-- Docsify v4 -->
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
</body>
</html>

可以在其中加上加载时的提示内容,例如

1
<div id="app">Loading...</div>

我们也可以绕过 npm,直接手动创建一个文件夹,其中 index.html 包括如上内容,并手动维护类似的文档结构即可。 这种方式与标准做法的差异只是没有本地预览功能而已,这里直接在本地浏览器打开 index.html 文件看起来是不行的。

下文中的主要配置都需要在 index.html 中修改 js,而且配置的修改是实时生效的,因为 docsify 总是会动态生成 html 页面。

在部署时,我们只需要将整个文件夹复制到服务器的对应位置即可,不需要在服务器上安装 nodejs 或者任何服务,也可以直接上传到 github 仓库通过 GitHub page 访问。

基本设置

多个页面

Docsify 以当前目录下的 index.htmlREADME.md 为主页,直接在目录中创建更多 md 文件(以及子目录)就会自动创建相应的子页面, 在子目录中可以加入 README.md 作为默认页面。

假设本地目录结构如下

1
2
3
4
5
6
docs
├── README.md
├── guide.md
└── zh-cn
├── README.md
└── guide.md

那么对应的访问页面将是

1
2
3
4
docs/README.md        => http://domain.com
docs/guide.md => http://domain.com/guide
docs/zh-cn/README.md => http://domain.com/zh-cn/
docs/zh-cn/guide.md => http://domain.com/zh-cn/guide

默认情况下,每一个 md 生成的页面是相互独立的,并且侧边栏会显示当前文档的目录结构,但是在文档中不支持 [toc]

侧边栏

我们可以引入 _sidebar.md 文件将各个页面组织在一起,并且在侧边栏呈现,_sidebar.md 文件的内容例如

1
2
- [首页](/)
- [快速入门](快速入门.md)

注意这里的特殊文档不能是空的,这里还可以指定页面的tab标题,例如

1
2
- [首页](/)
- [快速入门](快速入门.md "从这里开始")

需要在 index.html 中开启相应设置

1
2
3
4
5
<script>
window.$docsify = {
loadSidebar: true,
};
</script>

在进入一个目录时,我们可能希望只显示这个目录自己的侧边栏,这可以通过在每个文件夹中添加一个 _sidebar.md 文件来实现。 _sidebar.md 的加载逻辑是:从每层目录下获取文件,如果当前目录不存在该文件则回退到上一级目录。

加入侧边栏会导致不会显示文档自身的目录,可以用下面的命令开启

1
2
3
4
5
6
<script>
window.$docsify = {
loadSidebar: true,
subMaxLevel: 2,
};
</script>

这里 subMaxLevel 为导航侧边栏菜单的级数,这里设置为自动生成 2 级,可以设置更大的数字来生成更加详尽的导航目录。

我们还可以隐藏文档中的某些目录,可以在 md 文件加入如下标记

1
2
3
### 忽视标题 <!-- {docsify-ignore} -->

xxx

这个标记会使得这个目录以及它的子目录不在侧边栏显示,对应的部分在文档中仍然会显示。

导航栏

我们可以引入 _navbar.md 文件生成导航栏,_navbar.md 文件的内容例如

1
2
- [En](/)
- [简体中文](/zh-cn/)

需要在 index.html 中开启相应设置

1
2
3
4
5
<script>
window.$docsify = {
loadNavbar: true,
};
</script>

如果导航内容过多,在 _navbar.md 中可以写成嵌套的列表,会被渲染成下拉列表的形式,例如

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- 入门

- [快速开始](zh-cn/quickstart.md)
- [多页文档](zh-cn/more-pages.md)
- [定制导航栏](zh-cn/custom-navbar.md)
- [封面](zh-cn/cover.md)


- 配置
- [配置项](zh-cn/configuration.md)
- [主题](zh-cn/themes.md)
- [使用插件](zh-cn/plugins.md)
- [Markdown 配置](zh-cn/markdown.md)
- [代码高亮](zh-cn/language-highlight.md)

封面

我们可以引入 _coverpage.md 文件生成专门的封面,文档内容参考

1
2
3
4
5
6
7
8
9
10
# docsify <small>3.5</small>

> 一个神奇的文档网站生成器。

- 简单、轻便 (压缩后 ~21kB)
- 无需生成 html 文件
- 众多主题

[GitHub](https://github.com/docsifyjs/docsify/)
[Get Started](#docsify)

封面使用的样式与默认的 md 文档不同,例如这里的列表会每行居中显示,最后的两个链接会被渲染为按钮等。

需要在 index.html 中开启相应设置

1
2
3
4
5
<script>
window.$docsify = {
coverpage: true,
};
</script>

封面的默认背景是随机生成的渐变色,每次刷新都会更改,也可以自定义背景色或者背景图,这里略去。

代码块支持

包括两部分,一个是代码块的高亮显示,默认只支持包括 php 的几种语言,可以加上更多的语言,在 index.html 添加对应的 js 即可

1
2
3
4
5
6
7
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-bash.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-powershell.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-python.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-fortran.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-c.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-cpp.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-matlab.min.js"></script>

另一个是代码块的复制按钮

1
<script src="//cdn.jsdelivr.net/npm/docsify-copy-code"></script>

补充

可以给页面下面加一个 footer,示例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
window.$docsify = {
plugins: [
function(hook) {
var footer = [
'<hr/>',
'<footer>',
'<span><a href="https://example.com">cinwell</a> &copy;2017.</span>',
'<span>Proudly published with <a href="https://github.com/docsifyjs/docsify" target="_blank">docsify</a>.</span>',
'</footer>'
].join('');

hook.afterEach(function(html) {
return html + footer;
});
}
]
};
</script>

其实还缺一个本地搜索功能,但是配置看起来有点复杂,懒得测试了。

默认的 md 文档是不支持 LaTeX 的,可以加 js 实现简单的 LaTeX 支持,但是目前不需要。

记录一下目前修改后的 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
64
65
66
67
68
<!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">
</head>

<body>
<div id="app">Loading...</div>
<script>
window.$docsify = {
name: '',
repo: '',
loadSidebar: true,
subMaxLevel: 3,
plugins: [
function (hook) {
var footer = [
'<hr/>',
'<footer>',
'<span>Last modified: {docsify-updated}. Published with <a href="https://github.com/docsifyjs/docsify" target="_blank">docsify</a>.</span>',
'</footer>'
].join('');

hook.beforeEach(function (html) {
return html + footer;
});
},
],

search: {
maxAge: 1,
placeholder: 'Type to search',
noData: 'No Results!',
depth: 6,
hideOtherSidebarContent: true,
},

formatUpdated: '{YYYY}-{MM}-{DD}',

requestHeaders: {
'cache-control': 'max-age=0',
},
}
</script>
<!-- Docsify v4 -->
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>

<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-bash.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-powershell.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-python.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-fortran.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-c.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-cpp.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/prismjs@1/components/prism-matlab.min.js"></script>

<script src="//cdn.jsdelivr.net/npm/docsify-copy-code"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/search.min.js"></script>
<script src="//cdn.jsdelivr.net/npm/docsify-tabs@1"></script>
<script src="//cdn.jsdelivr.net/npm/docsify/lib/plugins/zoom-image.min.js"></script>
</body>

</html>