📖

GitBookによるドキュメント作成

2021/02/22に公開

GitBook は Markdown形式のファイルからドキュメントを作成するツールです.HTML形式,PDF形式,EPUB形式,MOBI形式を作成することができます.
本記事での動作環境は Windows とします.

過去に以下の記事を書きました.

それぞれメリット・デメリットがあります.今回の GitBook は最終的に PDF 出力が出来て,そこそこ体裁が整っているのが最大の魅力だと思います.

📌 gitbook-cli

GitBook はクラウドサービスですが,GitBookの機能をコマンドラインから操作できるツール gitbook-cli があります.これを使用してオフラインでも GitBook を使ってドキュメントを作成します.

📌 環境構築

Miniconda (Anaconda) を使って環境を構築します.
まずは gitbook という仮想環境を作成します.

conda create -n gitbook
conda activate gitbook

gitbook-cli (gitbook) を動作させるために,Nodejs をインストールします.

conda install nodejs

次に npm を使って gitbook-cli をインストールします.

$ npm install gitbook-cli -g
$ gitbook --version
CLI version: 2.3.2
GitBook version: 3.2.3

📌 プロジェクトの作成

init コマンドで空のプロジェクトを作成できます.試しに example というプロジェクトを作成します.

$ mkdir example
$ cd example
$ gitbook init
warn: no summary file in this book
info: create README.md
info: create SUMMARY.md
info: initialization is finished

README.mdSUMMARY.md ファイルが作成されます.README.md はトップページになります.

// README.md

# Introduction

SUMMARY.md には文書の構成を記述します.これはサイドバーに表示される構造になります.

// SUMMARY.md

# Summary

* [Introduction](README.md)

📌 ビルド

HTML形式で出力するには build コマンドを使います.

$ gitbook build
info: 7 plugins are installed                       
info: 6 explicitly listed                           
info: loading plugin "highlight"... OK              
info: loading plugin "search"... OK                 
info: loading plugin "lunr"... OK                   
info: loading plugin "sharing"... OK                
info: loading plugin "fontsettings"... OK           
info: loading plugin "theme-default"... OK          
info: found 1 pages                                 
info: found 0 asset files                           
info: >> generation finished with success in 0.6s ! 

ビルドしたデータは _book フォルダに作成されます.このフォルダの中をデプロイすることで公開することができます.

また,serve コマンドを使うことで,ローカルでサーバーを起動して表示確認することができます.

$ gitbook serve
Live reload server started on port: 35729
Press CTRL+C to quit ...

info: 7 plugins are installed
info: loading plugin "livereload"... OK
info: loading plugin "highlight"... OK
info: loading plugin "search"... OK
info: loading plugin "lunr"... OK
info: loading plugin "sharing"... OK
info: loading plugin "fontsettings"... OK
info: loading plugin "theme-default"... OK
info: found 1 pages
info: found 0 asset files
info: >> generation finished with success in 0.6s !

Starting server ...
Serving book on http://localhost:4000

ブラウザで http://localhost:4000 を開いて確認します.

1575570306863

Error: ENOENT: no such file or directory, stat '***'

gitbook のコマンドを実行したときに,

Error: ENOENT: no such file or directory, stat '***'

というエラーが表示された場合は C:\Users\<user>\.gitbook\versions\3.2.3\lib\output\website\copyPluginAssets.js を開いて copyAssets(output, plugin), copyResources(output,plugin) という関数にある

confirm: true

confirm: false

に変更します.

参考:GitBook で 'no such file or directory' というエラーが表示される

📌 カスタマイズ

各種設定は book.json ファイルで指定します.次は日本語設定したシンプルな設定です.

{
    "language": "ja"
}

1575570269318

タイトルや概要は title, description で指定します.

{
    "title": "GitBook Tutorial",
    "description": "This is a gitbook example"
}

指定しなければ,README.md の最初のヘッダ,パラグラフが使われます.
root でドキュメントの検索フォルダを変更することができます.

{
    "root": "src"
}

styles で拡張スタイルシートを指定することができます.

{
    "styles": {
        "website": "styles/website.css",
        "ebook": "styles/ebook.css",
        "pdf": "styles/pdf.css",
        "mobi": "styles/mobi.css",
        "epub": "styles/epub.css"
    }
}

例えば website.css を次のようにして,H1 を装飾します.

h1 {
    border-bottom: 1px solid #000;
}

1575571859576

📌 プラグイン

GitBook はプラグインを導入してカスタマイズすることができます.空のプロジェクトを作成した時点でいくつかのプラグインが自動で有効になります.

  • livereload
  • highlight
  • search
  • lunr
  • sharing
  • fontsettings
  • theme-default

プラグインの追加は plugins で設定します.

{
    "plugins": [...]
}

また,プラグインの設定は pluginsConfig で設定します.

{
    "plugins": [...],
    "pluginsConfig": {...}
}

plugins に追加したプラグインは gitbook install でインストールします.

gitbook install

様々なプラグインがありますので,個人的にオススメなものをピックアップしていきます.

テーマ

デフォルトのテーマは theme-default です.他には theme-api, theme-official がいい感じです.テーマはそのテーマのプラグインを有効にすることで反映されます.まずは,デフォルトのテーマは次のようなものです.

1575573086442

上部にあるアイコンから,フォントの大きさやフォントのセリフ・サンセリフ,そして,テーマカラーの切り替えが出来ます.

1575603981

Sepia

1575604054

Night

1575604070

次に theme-api です.

{
    "plugins": ["theme-api"]
}

1575573100647

theme-api は上の画像だと違いがわかりづらいですが,特徴的な機能として2列レイアウトがあります.

1575573793167

また,赤丸で囲んだアイコンをクリックすると通常表示と2列表示を切り替えることができます.このサンプルは以下のようになっています.

    {% method %}
    ## 環境構築 {#env}

    Miniconda (Anaconda) を使って環境を構築します.
    まずは `GitBook` という仮想環境を作成します.

    {% sample lang="shell" %}
    ```
    conda create -n gitbook
    conda activate gitbook
    ```

    {% endmethod %}

    {% method %}
    ## Node.js のインストール {#nodejs}
    GitBook-cli は Nodejs アプリなので,Nodejs をインストールします.

    {% sample lang="shell" %}
    ```
    conda install nodejs
    ```

    {% endmethod %}

    {% method %}
    ## gitbook-cli のインストール {#gitbookcli}

    npm を使って GitBook-cli をインストールします.

    {% sample lang="shell" %}
    ```
    $ npm install gitbook-cli -g
    $ gitbook --version
    CLI version: 2.3.2
    GitBook version: 3.2.3
    ```

    {% endmethod %}

この theme-api にはダークモードがあります.これはプラグインの設定で指定します.

{
    "plugins": ["theme-api"],
    "pluginsConfig": {
        "theme-api": {
            "theme": "dark"
        }
    }
}

1575574076702

theme-default ではコンテンツの幅が標準で 800px になっていますが,theme-api の場合,ウィンドウの幅に合わせて伸縮します.

次のテーマは,theme-official です.

{
    "plugins": ["theme-official"]
}

1575574347823

フォント

CSS で指定します.初期状態では次のようになっています.

1575604602

例えば,本文に Noto Serif JP, Noto Sans JP, 見出しに Roboto Slab,pre, code には Roboto Mono を指定した website.css は次のようになります.

@import url(https://fonts.googleapis.com/css?family=Noto+Sans+JP|Noto+Serif+JP|Roboto+Mono|Roboto+Slab&display=swap&subset=japanese);

.book.font-family-0 {
  font-family: "Noto Serif JP", "メイリオ", serif;
}

.book.font-family-1 {
  font-family: "Noto Sans JP", "メイリオ", sans-serif;
}

.markdown-section h1, 
.markdown-section h2, 
.markdown-section h3, 
.markdown-section h4, 
.markdown-section h5 {
  font-family: "Roboto Slab", "Noto Sans JP", sans-serif;
}

.markdown-section pre,
.markdown-section code {
  font-family: "Roboto Mono", Consolas, "Courier New", courier, monospace;
}

.book.font-family-0 はセリフ系フォントを指定します.

1575604849

.book.font-family-1 はサンセリフ系を設定します.

1575604873

見出しの装飾を次のように指定すると

@import url(https://fonts.googleapis.com/css?family=Noto+Sans+JP|Noto+Serif+JP|Roboto+Mono|Roboto+Slab&display=swap&subset=japanese);

.book.font-family-0 {
  font-family: "Noto Serif JP", "メイリオ", serif;
}

.book.font-family-1 {
  font-family: "Noto Sans JP", "メイリオ", sans-serif;
}

.markdown-section h1, 
.markdown-section h2, 
.markdown-section h3, 
.markdown-section h4, 
.markdown-section h5 {
  font-family: "Roboto Slab", "Noto Sans JP", sans-serif;
  font-weight: bold;
  color: rgb(0,113,188);
}

.markdown-section h1 { 
  border-bottom: 1px solid #000; 
}

.markdown-section h2 {
  border-bottom: 1px dotted #888;
}

.markdown-section pre,
.markdown-section code {
  font-family: "Roboto Mono", Consolas, "Courier New", courier, monospace;
}

1575605143

SNSボタン

右上に表示される SNSボタンは sharing プラグインです.これは標準で有効になっています.

1575612027

非表示にしたい場合はプラグインを無効にします.

{
    "plugins": ["-sharing"]
}

また,個別に指定したい場合は次のようになります.

{
    "pluginsConfig": {
        "sharing": [
        "facebook": true,
        "twitter": true,
        "google": false,
        "weibo": false,
        "instapaper": false,
        "vk": false,
        "all": [
            "facebook", "google", "twitter", "weibo", "instapaper"
        ]
    }
}

コードハイライト

コードのハイライト機能は標準で hilight が有効になっています.

#include <iostream>
int main() {
    std::cout << "Hello World!" << std::endl;
    return 0;
}
console.log('Hello World!');

prism

ハイライトのプラグインは他に prism があります.有効にする時は標準のハイライトプラグインを無効にしておきます.

{
    "plugins": ["prism", "-highlight"]
}

1575613032

prism には以下のテーマが用意されています.

  • Okaidia (prismjs/themes/prism-okaidia.css)
  • Solarized Light (prismjs/themes/prism-solarizedlight.css)
  • Tomorrow (prismjs/themes/prism-tomorrow.css)
  • Dark (prismjs/themes/prism-dark.css)
  • Coy (prismjs/themes/prism-coy.css)
  • Funky (prismjs/themes/prism-funky.css)
  • Twilight (prismjs/themes/prism-twilight.css)

テーマを指定するには次のようにします.

{
    "pluginsConfig": {
        "prism": {
            "css": [
                "prismjs/themes/prism-solarizedlight.css"
            ]
        }
    }
}

1575613495

sunlight-highlighter

他のコードハイライトプラグインとして sunlight-highlighter がオススメです.これは行番号を表示することができます.

{
    "plugins": ["sunlight-highlighter", "-highlight"],
    "pluginsConfig": {
        "sunlightHighlighter": {
            "theme": "gitbook",
            "lineNumbers": true
        }
    }
}

1575614908

テーマとして標準の gitbook の他に light, dark が用意されています.

1575614955

1575614968

コードのコピーボタン

コードをクリップボードにコピーするボタンを表示する copy-code-button プラグインがあります.

{
    "plugins": ["copy-code-button"]
}

1575615785

残念ながら,コードハイライトプラグイン sunlight-highlighter を合わせて使うと表示が崩れてしまいます.

ソースコードの挿入

ソースコードのファイルを挿入してシンタックスハイライトを適用する include-codeblock プラグインがあります.

{
    "plugins": ["include-codeblock"]
}

例えば次のような src/main.cpp ファイルがあります.

#include <iostream>
int main() {
    std::cout << "Hello World!" << std::endl;
    return 0;
}

これをドキュメントに挿入する場合は次のようになります.

[include](src/main.cpp)

または

[import](src/main.cpp);

コードハイライト prism と合わせて使用する場合,例えばc++のソースコードを挿入すると言語は c_cpp となりますが,prism にはその言語に対応していません.
そこで,エイリアスを設定することで対応することができます.

{
    "pluginsConfig": {
        "prism": {
            "lang": {
                "c_cpp": "cpp"
            }
        }
    }
}

include-codeblock ではテンプレートに ace を設定することができます.ace はエディタープラグインです.これを使って monokai テーマを適用してみます.

{
    "plugins": ["include-codeblock", "ace"],
    "pluginsConfig": {
        "include-codeblock": {
            "template": "ace",
            "theme": "monokai"
        }
    }
}

1575619890

ただし,テンプレートを ace にした場合は copy-code-button プラグインの対象にならないようです.

include-codeblock には様々な機能があります.興味のある人は以下を参照してください.

「GitBookで公開」の削除

サイドバーにある GitBookで公開 (Published with GitBook) を削除するには hide-published-with プラグインを使います.

{
    "plugins": ["hide-published-with"]
}

1575621401

これがこうなります.

1575621430

アンカー

anchors を使うと各見出しにアンカーを自動で付けてくれます.

{
    "plugins": ["anchors"]
}

1575622222

目次の追加

いくつかプラグインがあります.

右上に目次(折りたたみ可能),右下にトップに戻るボタンが追加されます.

{
    "plugins": ["navigator"]
}

1575622762

1575622801

page-treeview

ページの上部に目次をツリー形式で追加されます.

{
    "plugins": ["page-treeview"]
}

1575622941

右下にコピーライト表記が追加されます.これは設定で消すことができます.また,目次に追加する見出しの調整も出来ます.

{
    "pluginsConfig": {
        "page-treeview": {
            "copyright": "",
            "minHeaderCount": "2",
            "minHeaderDeep": "2"
        }
    }
}

atoc

page-treeview で著作権表記を消すと上部に隙間が空いてしまいます.代わりに atoc プラグインを使えば,この隙間がなくなりスッキリします.

{
    "plugins": ["atoc"]
}

ただし,atoc の場合は各ページに <!-- toc --> を追加しなければなりません.

intopic-toc

右上に目次を表示します.標準では見出しレベル2のものが表示されます.

{
    "plugins": ["intopic-toc"]
}

1575626294

後述する back-to-top-button プラグインと組み合わせるといい感じです.

ページのトップに戻るボタン

navigator プラグインでも追加することは出来ますが,外観がよい back-to-top-button プラグインもオススメです.このプラグインはデフォルトテーマの各テーマカラーに対応しています.

{
    "plugins": ["back-to-top-button"]
}

1575624177-tile

見出しに番号をつける

numbered-headings-for-web-and-books を使います.

{
    "plugins": ["numbered-headings"]
}

1575625949

スタイルシートで外観の調整ができます.

h1:before, h2:before, h3:before, h4:before, h5:before {
  color: #aaa;
  width: 40px;
}

サイドメニューの折りたたみ

SUMMARY.md に書かれているSUMMARYのツリーを折りたたみできるようにするプラグインがあります.

expand-active-chapter

まずは expand-active-chapter プラグインです.これはアクティブなツリーのみ展開します.

{
    "plugins": ["expand-active-chapter"]
}

1575627423

collapsible-chapters

collapsible-chapters は折りたたみ可能なノードの先頭にアイコンが付き,わかりやすくなります.

{
    "plugins": ["collapsible-chapters"]
}

1575627454

警告などのメッセージ

hints プラグインを使います.

{
    "plugins": ["hints"]
}

info, tip, danger, working の4種類があります.使い方は次のようになります.

{% hint style='info' %}
info: this is a information
{% endhint %}

{% hint style='tip' %}
tip: this is a tip
{% endhint %}

{% hint style='danger' %}
danger: this is a danger message
{% endhint %}

{% hint style='working' %}
working: this is working
{% endhint %}

1575651034774

絵文字

advanced-emoji プラグインを使います.

{
    "plugins": ["advanced-emoji"]
}

次のように使います.

:smile:, :heart_eyes:, :blush:

1575659267158

絵文字は以下を参照したり検索エンジンで検索してみてください.

TODOリスト

todo プラグインを使います.

{
    "plugins": ["todo"]
}

次のように使います.

- [x] apple
- [x] orange
- [ ] cherry
- [ ] strawberry

1575659656770

UML

uml プラグインを使います.

{
    "plugins": "uml"
}

次のように使います.

@startuml

	Class Stage
	Class Timeout {
		+constructor:function(cfg)
		+timeout:function(ctx)
		+overdue:function(ctx)
		+stage: Stage
	}
 	Stage <|-- Timeout

@enduml

1575660339859

Mermaid

Mermaid は様々な図を作成できるJavascriptライブラリです.これをGitbookで使うプラグインはいくつもありますが,試したところ mermaid-gb3 が良さそうです.

{
    "plugins": ["mermaid-gb3"]
}

使い方は次のようになります.

```mermaid
graph TD
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
```

1575697271102

```mermaid
sequenceDiagram
Alice->>John: Hello John, how are you?
loop Healthcheck
    John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
```

1575697352543

```mermaid
gantt
section Section
Completed :done,    des1, 2014-01-06,2014-01-08
Active        :active,  des2, 2014-01-07, 3d
Parallel 1   :         des3, after des1, 1d
Parallel 2   :         des4, after des1, 1d
Parallel 3   :         des5, after des3, 1d
Parallel 4   :         des6, after des4, 1d
```

1575697384916

フォントを標準から変更したところ,フローチャートでは表示が一部切れてしまっていました.

1575697452275

根本的な解決方法はわかっていないのですが,例えばスタイルシートを次のように調整すると

g.label foreignObject {
  width: 100px;
  text-align: center;
}

g.label foreignObject span.edgeLabel {
  margin-left: -70px;
}

1575697707674

いい感じに見えますが,固定幅になっていますので図によって再調整しなければなりません.

グラフ

graph プラグインを使います.

{
    "plugins": ["graph"]
}

次のように使います.

{% graph %}
    {
        "title":"cos(2*PI*x/2)*(1+0.5cos(2*PI*x/100))",     
        "grid":true,
        "xAxis": {
            "label":"Sample",
            "domain": [0,300]
        },
        "yAxis": {
            "label":"Amplitude",
            "domain": [-1.5,1.5]
        },
        "data": [
            { "fn": "cos(2*PI*x/2)*(1+0.5cos(2*PI*x/100))"},         
            { "fn": "(1+0.5cos(2*PI*x/100))"}
        ]
    }
{% endgraph %}

1575698226008

数式

数式を表示するには mathjaxkatex プラグインを使います.
Mathjax は数式を表示するための Javascriptライブラリです.Katex は Mathjax より高速に処理しますが,表現できる数式に制限があります.まずは mathjax プラグインを使う場合は次のようになります.

{
    "plugins": ["mathjax"],
    "pluginsConfig": {
        "mathjax": {
            "forceSVG": true,
            "version":  "2.7.6"
        }
    }
}

SVG形式で出力します.また,Mathjaxのバージョンがメジャーアップしているので,一応バージョンを指定しています.
次に katex の場合は次のようになります.

{
    "plugins": ["katex"]
}

使い方は両方とも同じです.

When {% math %}a \ne 0{% endmath %},
there are two solutions to {% math %}(ax^2 + bx + c = 0){% endmath %}
and they are {% math %}x = {-b \pm \sqrt{b^2-4ac} \over 2a}.{% endmath %}

When $$a \ne 0$$,
there are two solutions to $$(ax^2 + bx + c = 0)$$
and they are $$x = {-b \pm \sqrt{b^2-4ac} \over 2a}.$$

1575700736673

mathjax プラグインを使用している場合,次のようなエラーが出る場合があります.

Error: TypeError: speech.processExpression is not a function

この場合は node_modules/mathjax_node/mj-single.jsGetSpeech 関数にある speech.processExpression(result.mml)speech.toSpeech(result.mml) に書き換えます.

画像の表題

image-captions プラグインを使うと,画像のタイトルを追加することが出来ます.

{
    "plugins": ["image-captions"]
}

1575911517997

標準では画像の右下の位置に,接頭辞 Figurealt 内容に追加したものが出力されるようです.
これはプラグイン設定で変更することができます.例えば,次のように設定すると

{
    "pluginsConfig": {
        "image-captions": {
            "caption": "Fig. _BOOK_IMAGE_NUMBER_ _CAPTION_",
            "align": "left"
        }
    }
}

1575911907263

のようになります.細かく調整できますので,詳細は以下を参照してください.

📌 Tips

コンテンツの幅を調整

スタイルシートで調整します.

.container {
    max-width: 1200px;
}

タグを無視

gitbook は {%%} で囲んだ文字をタグと認識します.ですが,場合によっては無視したいこともあります.
その場合は raw, endraw タグで囲みます.ただし,上手くいかないこともあります.

📌 PDF

gitbook は Calibre というアプリケーションを使って電子文書形式を作成することができます.
そのため,まずは Calibre を準備する必要があります.

Windows版のインストーラをダウンロードしてインストールします.ポータブル版でも構いません.
ここでは C:\Calibre にインストールしたとします.

gitbook が Calibre を使用することができるようにパスを通す必要があります.
環境変数 PATHC:\Calibre\Calibre を追加します.

これで各電子文書を作成することができます.PDFを作成する場合は次のコマンドを実行します.

gitbook pdf

上手く動作しない場合はPCを再起動してみましょう.環境変数が反映されていないかもしれません.

Anaconda用の設定

個人的にシステム環境変数やユーザー環境変数のPATHに追加することはあまり好きではありません.なるべく,PATHの設定は最小限にしたいと思っていたりします.

今回は Anaconda を使っていて,gitbook という仮想環境を構築しています.
そこで,gitbook の仮想環境のときに,Calibre のパスが通るようにします.

gitbook が有効の状態にします.

$ conda activate gitbook

仮想環境のフォルダを取得します.

$ (gitbook) set CONDA_PREFIX
CONDA_PREFIX=C:\Miniconda3\envs\gitbook

C:\Miniconda3\envs\gitbook\etc\conda\activate.d というフォルダを作成し,そのフォルダ内に env_vars.bat というファイルを作成します.env_vars.bat の中身は次のようにします.

set PATH=C:\Calibre\Calibre;%PATH:C:\Calibre\Calibre;=%

このバッチファイルは activate したときに呼ばれるバッチファイルです.これで activate したときに PATH に Calibre が追加されます.

また,同様に C:\Miniconda3\envs\gitbook\etc\conda\deactivate.d というフォルダを作成し,env_vars.bat を作成すれば,deactivate されたときに呼ばれます.

Mathjax

Mathjax で SVG 形式で出力設定をしている場合,PDF出力時に以下のエラーが出ます.

Error: Error with command "svgexport"

そこで svgexport をインストールします.

npm install -y svgexport -g

Mermaid

どうやら pdf では図は出力されないようです.
このような場合はあらかじめ画像で出力しておいて表示するといった対応が必要になります.

出力設定

book.jsonpdf で設定できます.例えば,本文書では次のような設定になっています.

{
    "pdf": {
        "pageNumbers": true,
        "fontFamily": "VL Gothic",
        "fontSize": 10,
        "paperSize": "a4",
        "margin": {
            "right": 0,
            "left": 0,
            "top": 0,
            "bottom": 0
        }
    }
}

PDF 出力時のスタイルシートは

{
    "styles": {
        "pdf": "styles/pdf.css"
    }
}

とすれば,pdf.css で編集できます.

カバー

1800x2360 の大きさで cover.jpg というファイル名で book.json と同じ場所に置いておくと,PDF作成時に表紙として使用されます.

📌 参考

📌 サンプル

gitbook を使ったサンプルを以下に公開してあります.

また,PDF出力したものを公開しました.

📌 最後に

gitbook-cli は現在はメンテナンスされていないようです.各プラグインも更新がされていませんが,現状のものでもある程度のドキュメントは作成できる機能があると思います.他にも様々なプラグインがありますので,興味がある人は試してみてください.

Discussion