最开始使用 GitBook 撰写电子书是从去年开始维护的 billryan/algorithm-exercise 算法文档开始的,因为这个项目我已经造了不少轮子,给 GitBook 添加类似博客中的 category/tag 功能的插件在下班后的周末抽空写了写,趁这个中秋小长假美化了 CSS, 修了修 bug. 下文先介绍如何使用 gitbook-plugin-tags 插件,随后介绍自己实现这个插件的全过程。

使用

预览网站 ==> https://yuanbin.gitbooks.io/test/content/

根目录下手动新建tags.md

由于 GitBook 在 2.0.0 之后就将 summary 的 hook 移除了,所以目前需要先在根目录下新建 tags.md 文档并将其置于 SUMMARY.md 的最末尾。以某文件夹为例:

1
2
3
4
5
6
7
8
en
├── README.md
├── SUMMARY.md
├── faq
│   ├── README.md
│   ├── contributors.md
│   └── guidelines_for_contributing.md
└── tags.md

其中 SUMMARY.md 的内容如下:

1
2
3
4
5
6
7
# Summary
* [Preface](README.md)
* [FAQ](faq/README.md)
* [Guidelines for Contributing](faq/guidelines_for_contributing.md)
* [Contributors](faq/contributors.md)
* [Tags](tags.md)

切记* [Tags](tags.md)务必位于 SUMMARY.md 的末尾,因为 GitBook 是按顺序解析渲染的。

tags.md 中的内容自定,比如可以只包含一行 # Tags 作为标题。

新增 tags

tags 标记可以使用 YAML 在 markdown 源文件的前导处加入,如

1
2
3
4
5
---
tags: ['tag1', 'tag2', 'tag3 is here']
---
# FAQ - Frequently Asked Question
...

也可在正文中以单独一行表示,tag 之间以逗号分隔,tags 一定要在一行的开头,否则不予解析。

1
2
3
# FAQ - Frequently Asked Question
tags: tag1, tag2, tag3 is here

在正文中出现的 tag 格式要求相对较为随意,最关键的是一行开头要有 tags:, 不同 tag 以逗号分隔。

book.json 中新增 tags 插件

plugins 内增加 tags 即可,无需其他配置。

1
2
3
4
5
6
{
"plugins": [
"...",
"tags"
]
}

实现

功能设计

受 Hexo 博客引擎启发,tags 应该单独有一页面,该页面包含各 tag 所在的原网页链接,原网页链接则包含指向 tags.html 的链接,页面内容较多时需要使用定位符直接跳转到指定位置。简化起见,这里不为每个 tag 生成新页面,而是所有 tag 在一个 tags.html 页面中显示,利用 # 定位不同标签名。综合下来有两大基本需求:

  1. 源文档中的 tags: 处应能指向 tags.html 的链接,并根据不同 tag 以 # 加速定位
  2. tags.html 中应能包含不同 tag 所指向的原网页链接。

除了以上两个基本需求外,此插件最好能支持多国语言,同时用户设置 tag 信息时应比较人性化,显示 tag 最好能美观大方一些,而不是纯文字链接,俗话来说就是要讲究用户体验。

生成 tags.html

由于 GitBook 是从 SUMMARY.md 中提取 markdown 进行解析渲染的,所以在没找到直接调用解析生成 tags.html 的方法之前还是需要用户在根目录下新建 tags.md 并将其置于 SUMMARY.md 末尾,这样我们就能充分利用 GitBook 解析生成 tags.html 了。如果不在 SUMMARY.md 中添加 tags.md, 那么我们要么能在 GitBook 读取 summary 之前用程序加进去,要么能直接渲染生成 tags.html 静态文件。summary 的 hook 在 2.0.0 之后便被移除,直接渲染的方法一时也没有看到,所以折中下来暂时只能先麻烦下用户了。

CSS 美化

自己不是专业的设计师,所以参考了 https://hexo.io 和自己博客的主题,结合了 fontawesome 字体,取消了逗号分隔,为每个 tag 加了边框等等细节,看起来总算是舒服了一点点。由于在 markdown 中添加 div 标签等信息不太方便,这里我用了预加入 <!-- tags --> 信息以方便后期 HTML 中添加 tags 等 id 和 class.

多国语言

与 sitemap 插件不同,该插件多国语言的支持在于巧妙利用了浏览器和 markdown 解析器的寻址方式,用户浏览时会自动补全前面的网址等信息。

定位符直接定位

借助 github-slugid, 我们可以很方便的在 GitBook 中根据不同 header 生成相应的定位符。

正则匹配

之前正则匹配用的不熟,这次发现 JavaScript 中字符串的操作用正则实现十分便利,尤其是 /im 的引入可使得每一行单独处理而不是一次处理整个 page.content.

如果你喜欢我这个插件,不妨给这个项目 billryan/gitbook-plugin-tags 加一颗星吧 :)