在用GitBook整理笔记的过程中,因GitBook年久失修,碰到了很多问题。
安装 gitbook-cli
Link to heading
使用GitBook需要先安装 node.js
,之后安装 gitbook-cli
:
$ npm install -g gitbook-cli
$ npm list -g
...
└── gitbook-cli@2.3.2
目录结构及测试文件内容如下:
$ ls -1
book.json
README.md
SUMMARY.md
$ cat book.json
{
"gitbook": "3.x.x",
"title": "测试",
"author": "fkon",
"description": "测试",
"language": "zh-hans"
}
$ cat README.md
# README
Hello!
$ cat SUMMARY.md
# Summary
* [README](README.md)
使用 gitbook serve
在本地测试书籍,结果报错:
$ gitbook serve
Live reload server started on port: 35729
Press CTRL+C to quit ...
C:\Users\user\AppData\Roaming\npm\node_modules\gitbook-cli\node_modules\npm\node_modules\graceful-fs\polyfills.js:287
if (cb) cb.apply(this, arguments)
^
TypeError: cb.apply is not a function
at C:\Users\user\AppData\Roaming\npm\node_modules\gitbook-cli\node_modules\npm\node_modules\graceful-fs\polyfills.js:287:18
at FSReqCallback.oncomplete (fs.js:169:5)
原因是 gitbook-cli
依赖旧版本的 graceful-fs
,其中含有bug。解决办法是找到上述 gitbook-cli
的安装路径,升级 graceful-fs
至 4.2.0
。重新运行 gitbook serve
,在浏览器中打开 localhost:4000
,GitBook已成功运行:
$ cd C:\\Users\\user\\AppData\\Roaming\\npm\\node_modules\\gitbook-cli\\node_modules\\npm\\node_modules
$ npm install graceful-fs@4.2.0 --save
$ cd -
$ gitbook serve
Starting server ...
Serving book on http://localhost:4000
使用MathJax数学插件 Link to heading
MathJax和Katex是两个Latex数学公式渲染引擎,差异主要有:
- MathJax支持的Latex符号更多,渲染速度慢,用于生成pdf时清晰度不够;
- Katex支持的Latex符号不如MathJax多,渲染速度快,生成pdf时清晰度很高;
因此,在GitBook中应首先尝试Katex,其次MathJax。
作为示例,修改 README.md
内容如下:
# README
Batch Normalization output $y_i$:
$$
\mu_B \leftarrow \frac{1}{m}\sum_{i = 1}^{m}x_i \newline
\sigma_B^2 \leftarrow \frac{1}{m} \sum_{i=1}^{m}(x_i - \mu_B)^2 \newline
\hat{x_i} \leftarrow \frac{x_i - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}} \newline
y_i \leftarrow \gamma \hat{x_i} + \beta \equiv \text{BN}_{\gamma,\beta}(x_i) \newline
$$
同时把 "plugins": ["mathjax"]
添加到 book.json
中,随后使用 gitbook install
安装插件。遇到安装错误,改用 npm
安装插件,运行 gitbook serve
,再次报错:
$ gitbook install
info: install plugin "mathjax" (*) from NPM with version 1.1.2
C:\Users\user\.gitbook\versions\3.2.3\node_modules\npm\node_modules\aproba\index.js:25
if (args[ii] == null) throw missingRequiredArg(ii)
^
$ npm install gitbook-plugin-mathjax
$ gitbook serve
info: loading plugin "mathjax"... ERROR
PluginError: Error with plugin "mathjax": Unexpected token '<<'
查看 mathjax
插件源码发现竟然存在未解决的冲突,先手动解决冲突:
--- node_modules/gitbook-plugin-mathjax/index.js 2021-09-19 19:09:11.486548700 +0800
+++ node_modules/gitbook-plugin-mathjax/index.js 2021-09-19 19:09:22.438413500 +0800
@@ -1,10 +1,3 @@
-<<<<<<< HEAD
-var Promise = require('q');
-var crc = require('crc');
-var mjAPI = require('mathjax-node/lib/mj-single.js');
-
-var started = false;
-=======
var Q = require('q');
var fs = require('fs');
var path = require('path');
@@ -13,7 +6,6 @@
var mjAPI = require('mathjax-node/lib/mj-single.js');
var started = false;
->>>>>>> master
var countMath = 0;
var cache = {};
再次尝试 gitbook serve
, 继续报错:
$ gitbook serve
info: loading plugin "mathjax"... ERROR
PluginError: Error with plugin "mathjax": Cannot find module 'mathjax/unpacked/MathJax'
查看MathJax版本,发现是 3.2.0
,降级到 2.7.7
后上面错误消失,新的错误出现:
$ npm install mathjax@2.7.7
$ gitbook serve
info: loading plugin "mathjax"... ERROR
Error: GitBook doesn't satisfy the requirements of this plugin: >=4.0.0-alpha
GitBook的MathJax插件中要求GitBook的engine版本高于 4.0.0-alpha
,先尝试降低要求到 3.0.0
:
--- node_modules/gitbook-plugin-mathjax/package.json 2021-09-19 19:25:28.224953200 +0800
+++ node_modules/gitbook-plugin-mathjax/package.json 2021-09-19 19:25:46.678249600 +0800
@@ -6,7 +6,7 @@
"icon": "./icon.png",
"version": "2.0.0",
"engines": {
- "gitbook": ">=4.0.0-alpha"
+ "gitbook": ">=3.0.0"
},
"dependencies": {
"crc": "^3.2.1",
再次报错:
$ gitbook serve
error: error while generating page "README.md":
Template render error: (C:\Users\user\Desktop\exp\README.md)
TypeError: Cannot read property '0' of undefined
好吧,错误没完没了。官方的MathJax插件已经失修太久,改为第三方插件,比如 mathjax-pro
。在 book.json
中修改插件为 "plugins": ["mathjax-pro"]
,然后安装插件:
$ gitbook install
$ gitbook serve
终于成功运行,然而打开网页一看,示例中的两个公式都没有成功渲染。
前一个是行内公式,查看MathJax插件源代码 plugin-mathjax/blob/master/index.js#L134,发现是 inline/display math,分界符都是双 $$
。因此,使用此插件时需要注意任何公式都要用 $$
作为公式分界符,单纯修改插件代码添加单个 $
作为inline math的解决方案存在bug。
第二个公式是display math,原来MathJax对多行公式要求严格,需要放在 aligned
环境中,而Katex则不需要,修改后的 README.md
内容:
# README
Batch Normalization output $$y_i$$:
$$
\begin{aligned}
\mu_B \leftarrow \frac{1}{m}\sum_{i = 1}^{m}x_i \newline
\sigma_B^2 \leftarrow \frac{1}{m} \sum_{i=1}^{m}(x_i - \mu_B)^2 \newline
\hat{x_i} \leftarrow \frac{x_i - \mu_B}{\sqrt{\sigma_B^2 + \epsilon}} \newline
y_i \leftarrow \gamma \hat{x_i} + \beta \equiv \text{BN}_{\gamma,\beta}(x_i) \newline
\end{aligned}
$$
此时两个公式都可以正常显示,但第二个公式却是左对齐,通常情况下display math都是居中显示,因此还存在bug。查看插件源代码,发现判断是否是inline的逻辑是 var isInline = !(tex[0] == "\n");
,display math是以换行符开头的,但在Windows上换行符是 \r\n
,所以这个判断逻辑对以 \r\n
换行的Markdown文件失效。一个临时的修复方法是判断公式文本中是否包含 \n
,对于绝大多数情况下这样做没有问题:
--- node_modules/gitbook-plugin-mathjax-pro/index.js 2021-09-19 20:06:15.709172100 +0800
+++ node_modules/gitbook-plugin-mathjax-pro/index.js 2021-09-19 20:06:43.695891500 +0800
@@ -72,7 +72,7 @@
function processBlock(blk) {
var book = this;
var tex = blk.body;
- var isInline = !(tex[0] == "\n");
+ var isInline = !tex.includes("\n");
// For website return as script
var config = book.config.get('pluginsConfig.mathjax-pro', {});
至此,GitBook终于能够用MathJax渲染数学公式了。
使用Katex数学插件 Link to heading
虽然MathJax功能强大,但是出于渲染速度和生成pdf文档时清晰度的考虑,还是希望用Katex。在 book.json
中把插件改为 katex
,即 "plugins": ["katex"]
,然后安装Katex插件:
$ gitbook install
$ gitbook serve
error: error while generating page "README.md":
Template render error: (C:\Users\user\Desktop\exp\README.md)
ParseError: KaTeX parse error: Expected & or \\ or \end at position 68: …{i = 1}^{m}x_i \̲n̲e̲w̲l̲i̲n̲e̲
\sigma_B^2 \l…
查看Katex版本,发现是 0.7.1
,非常古老。第三方插件 katex-pp
已经修复了这个问题,修改 book.json
后安装插件:
$ gitbook install
$ gitbook serve
运行成功,但是4行道公式挤在了1行。使用Katex时以上公式并不需要 alinged
环境,移除后即可。重新运行后display公式也是左对齐,这个MathJax的问题一样,插件没有正确区分inline/display公式,主要原因是换行符所致,按下面的path修改插件源代码后,Katex正常渲染数学公式。
--- node_modules/gitbook-plugin-katex-pp/index.js 2021-09-19 20:50:13.948081800 +0800
+++ node_modules/gitbook-plugin-katex-pp/index.js 2021-09-19 20:51:10.518884100 +0800
@@ -23,9 +23,9 @@
},
process: function(blk) {
var tex = blk.body;
- var isInline = !(tex[0] == "\n");
+ var isDisplay = tex.includes("\n");
var output = katex.renderToString(tex, {
- displayMode: !isInline,
+ displayMode: isDisplay,
leqno: false,
output: "htmlAndMathml"
});
生成pdf文档 Link to heading
gitbook-cli
的一个很重要的功能是生成pdf格式电子书,生成pdf时需要安装 svgexport
和 ebook-convert
:
$ npm install -g svgexport ebook-convert
$ npm list -g
...
├── ebook-convert@2.0.1
├── gitbook-cli@2.3.2
└── svgexport@0.4.2
除此之外,需要在配置生成pdf时的属性,将如下内容添加到 book.json
中:
"pdf": {
"pageNumbers": true,
"fontFamily": "Arial",
"fontSize": 12,
"paperSize": "a4",
"margin": {
"right": 31,
"left": 31,
"top": 28,
"bottom": 28
}
}
生成pdf使用 gitbook pdf
,中途报错:
$ gitbook pdf
error: error while generating page "README.md":
Error: Error converting C:\Users\user\AppData\Local\Temp\tmp-3416kGYRf4rnonJy\de680f32.svg into C:\Users\user\AppData\Local\Temp\tmp-3416kGYRf4rnonJy\94bab1f.png
手动调用 svgexport
把SVG转为PNG格式也报错,打开上述SVG文件,发现它并不是一个有效的SVG文件,主要是缺少了 xmlns
属性。作为测试,打开SVG文件并把 <svg ...>
标签改为 <svg xmlns="http://www.w3.org/2000/svg" ...>
,再次手动转PNG,成功。
$ gitbook pdf
error: error while generating page "README.md":
Error: Error converting C:\Users\user\AppData\Local\Temp\tmp-3416kGYRf4rnonJy\de680f32.svg into C:\Users\user\AppData\Local\Temp\tmp-3416kGYRf4rnonJy\94bab1f.png
$ svgexport 'C:\Users\user\AppData\Local\Temp\tmp-3416kGYRf4rnonJy\de680f32.svg' 'tmp.png'
Error: Evaluation failed: TypeError: el.getBBox is not a function
at __puppeteer_evaluation_script__:26:22
$ vim C:/Users/user/AppData/Local/Temp/tmp-3416kGYRf4rnonJy/de680f32.svg
# change <svg ...> to <svg xmlns="http://www.w3.org/2000/svg" ...>
$ svgexport 'C:\Users\user\AppData\Local\Temp\tmp-3416kGYRf4rnonJy\de680f32.svg' 'tmp.png'
... png 100% 1x 0:0:6400:20.47 6400:20.47
可见,问题并不发生在 svgexport
,而是因为GitBook在把Katex的输出渲染为DOM时丢失了必要的 xmlns
属性,如 lib/output/modifiers/svgToImg.js#L34。找到GitBook的安装位置,在Windows上通常在 C:\Users\user\.gitbook\versions\3.2.3
,修改源代码,为每个SVG文件添加 xmlns
属性:
--- lib/output/modifiers/svgToImg.js 2021-09-19 21:19:43.428873100 +0800
+++ lib/output/modifiers/svgToImg.js 2021-09-19 21:20:05.747750000 +0800
@@ -32,6 +32,10 @@
var currentDirectory = path.dirname(currentFile);
return editHTMLElement($, 'svg', function($svg) {
+ for (let i = 0; i < $svg.length; i++) {
+ $svg[i].attribs.xmlns = "http://www.w3.org/2000/svg";
+ }
+
var content = '<?xml version="1.0" encoding="UTF-8"?>' +
renderDOM($, $svg);
重新运行 gitbook serve
,成功生成pdf文档。
总结 Link to heading
GitBook是一个用Markdown写书的工具,但是由于项目多年没更新,官方用于支持MathJax和Katex的插件都已无法运行,需要使用第三方插件或者自己修正问题。