Jupyter Notebook(.ipynb)から出版品質の本やドキュメントを作成できる「Jupyter Book」の使い方

# Jupyter Bookとは？

タイトルの通り、Jupyter Notebookファイル(.ipynb)やMarkdownファイル(.md)から、美しい出版品質の本やドキュメント(HTMLやPDFなど)を作成できるのが[「Jupyter Book」](https://jupyterbook.org/intro.html)です。URL先の公式リファレンスも、「Jupyter Book」を使って作成されています。他にも、東京大学素粒子物理国際研究センター（ICEPP）の、量子コンピューティングを手を動かして学びたい人向けの入門教材、[「量子コンピューティング・ワークブック」](https://utokyo-icepp.github.io/qc-workbook/)もJupyterBookが使用されているようです。

名前がJupyter Notebookと似ていますが**別のもの**で、[「Project Jupyter」](https://jupyter.org/)や[「The Executable Book Project」](https://executablebooks.org/en/latest/)のプロジェクトの1つです。[Read the Docs](https://docs.readthedocs.io/en/stable/tutorial/)のPython版とも解釈できます。自分が探した限りでは日本語のリファレンスがなかったので、Jupyter Bookについて簡単な紹介をしていこうと思います。執筆時点でのバージョンは0.9です。


# インストール方法

pipを使って簡単にインストールすることができます。自分はpipとJupyter Lab環境でのインストールとなります。Jupyter Labのインストール方法は[こちらの記事](https://qiita.com/kirikei/items/a1639954ce5ccaf7ac3c)がおすすめです。

<!--
![スクリーンショット 2021-01-14 22.26.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/28c7e6ab-f4c8-522d-9f2c-1ebd9b879fa6.png)
--->

`pip`コマンドでインストールします。

```zsh
% python3 -m pip install jupyter-book
```

<!--
![スクリーンショット 2021-01-14 22.29.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/4e437eda-5fee-67fc-18fb-3ac40ddfb9dd.png)
--->

Ubuntuでインストールを試したところ、`/home/ユーザ名/.local/bin`へPATHを通す必要がありました。`~/.bashrc`などに以下を追加してください。

```bash:~/.bashrc
export PATH="$PATH:/home/$(whoami)/.local/bin"
```

# 基本的なコマンド
インストール後、適当なディレクトリに移動してJupyter Bookプロジェクトを作成してみましょう。Jupyter Bookは、`jupyter-book`または`jb`コマンドを使用します。どちらも違いはありませんので、以降は短い`jb`を使用します。

## jb create

`jb create`で「test_book」という名前のJupyter Bookプロジェクトを作成します。プロジェクト名は変更して構いません。ここでは使用していませんが、`create`では`--cookiecutter`オプションを付加することもできます。

```zsh
% jb create test_book
```

test_book/にテンプレートのJupyter Bookが作成されました。
![スクリーンショット 2021-01-14 22.33.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/b32fef9d-c438-19f6-d01d-e1a50a9ea7d8.png)

## jb build
`jb build`でJupyter Bookをビルドすることができます。

```zsh
% cd test_book
% jb build .
```

ログが表示された後、ビルドが完了すると、以下のように表示されます。
![スクリーンショット 2021-01-14 22.35.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/d1027883-1e89-1cba-57c5-86a1a77a4e91.png)
`test_book/_build/html`にHTMLファイルが作成されています。Chromeなどのブラウザで表示させてみましょう。ブラウザにHTMLファイルのパスを入れると、次のように表示されるはずです。簡単にドキュメントを作成することができました。
![スクリーンショット 2021-01-13 21.09.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/12786ff6-a963-9b9c-d9a6-04c3cb73c7e6.png)

# 公式デモブック
公式デモブックも用意されています。ビルド時にエラーが発生することがあるので、ビルド時の実行をしないオプションを個人的に推奨します。

```zsh
% git clone https://github.com/executablebooks/quantecon-mini-example
% cd quantecon-mini-example/mini_book
% cat _config.yml
```

ここで_config.ymlの`execute_notebooks`を`"off"`に書き換えます。
![スクリーンショット 2021-01-14 22.40.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/b7969a28-ad7d-f007-5c66-3b48c8a702ee.png)
ビルドしてブラウザで表示させてみましょう。

```zsh
% jb build .
% open /Applications/Google\ Chrome.app _build/html/index.html
```

![スクリーンショット 2021-01-14 3.01.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/947d5298-9285-42fb-aa4c-13d1db860a17.png)

# PDFを作成する

HTMLと同様に、PDFの作成も簡単にすることができます。2通りの方法があり、少し違いがあります。

## ① ブラウザから作成する方法

ブラウザでHTMLを表示すると、右上にダウンロードボタンがあります。クリックすると、ダウンロードする形式を指定できます。.pdfをクリックするとPDFファイルを保存することができます。これで完了です。
![スクリーンショット 2021-01-14 16.44.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/56ef7853-6957-0642-63bf-44a35396a5e9.png)

## ② ビルドして作成する方法

こちらの方法にはpyppeteerが必要なので、インストールします。

```zsh
% pip install pyppeteer
```

Jupyter Bookでは、1ページ単位でビルドすることもできます。先ほど作った`test_book`の中の`notebook.ipynb`をPDFにしてみましょう。`build`のときに`--builder pdfhtml`を指定します。

```zsh
% cd test_book
% jb build notebooks.ipynb --builder pdfhtml
```

以下のように表示されたら、PDFの完成です。
![スクリーンショット 2021-01-14 22.43.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/e1f1e9c7-483c-9e82-e573-4a5fb077b852.png)
こちらの方法では、①で右側に表示されていたバーが表示されていませんでした。
![スクリーンショット 2021-01-14 16.51.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/385d7d38-d85e-d74a-ce2b-7f70bb5aac85.png)
この他にも、「.tex」ファイルを作成したり、 $\LaTeX$ を使用してPDFを作成することもできます。詳しくは[公式リファレンスのPDFページ](https://jupyterbook.org/advanced/pdf.html)をご覧ください。

# Jupyter Bookのカスタマイズ

ここまでで「.ipynbや.md」→「HTMLやPDF」という変換をする方法を紹介しました。ここでは、Jupyter Bookのページ内容や構成を変更する方法を取り上げます。ここでのコードは、後ほど取り上げる通り[GitHub](https://github.com/magolors/test_book_online)で公開していますので、コピーなどしたい場合はそちらからご参照ください。

## ページの追加

ページを追加するには、ディレクトリに「.ipynb」か「.md」を追加します。ここでは「test_page.ipynb」を作成します。例えば次のような内容で作成します。
![スクリーンショット 2021-01-15 23.32.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/ee763ba9-e59e-42e6-1a49-b27d32d5d3dd.png)



### _config.yml
`_config.yml`を編集します。このファイルは、Jupyter Bookの設定を記述するものです。詳しくは[公式リファレンスのconfigページ](https://jupyterbook.org/customize/config.html)をご覧ください。ここでは`title`と`author`、`execute_notebooks`を編集しました。ついでに、数式を使えるように1番下に追記しました。
![スクリーンショット 2021-01-16 15.38.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/4ee715b2-8f3b-8192-b622-b6c5f243c998.png)


### _toc.yml
`_toc.yml`を編集します。このファイルは、Jupyter Bookの構造を記述するものです。詳しくは[公式リファレンスのtocページ](https://jupyterbook.org/customize/toc.html)をご覧ください。ここでは、以下のようなページ構造にしました。
![スクリーンショット 2021-01-14 23.12.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/61df1f0a-4cb0-14c6-47fd-695087ccc1bb.png)

### ビルド
追加したページを含めたJupyterBook全体をビルドしましょう。通常のビルドでは、ページのキャッシュが残っており、変更・追加したページしか更新されないため、更新していないページから追加したページへのリンクが表示されません。それを防ぐため、`--all`オプションを付加してJupyterBook全体を再構成するようにします。

```zsh
% cd test_book
% jb build --all .
```

この内容でビルドすると、以下のように表示されます(ここでは次の章で取り扱う1.4も表示されています)。ページの追加と、目次の構成を変えることができました。
![スクリーンショット 2021-01-15 23.36.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/06675192-fb09-ec6b-c011-c594746df8d6.png)



## MyST Markdown

Jupyter Bookでは、MyST Markdownという拡張されたMarkdownを使用することができます。ここでは個人的に使用頻度が高いDirectivesとRolesについて説明します。

通常のMarkdownについては、Qiita公式の[Markdownの書き方](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)をご覧ください。MyST Markdownにも[公式リファレンス](https://myst-parser.readthedocs.io/en/latest/using/syntax.html)と[チートシート](https://jupyterbook.org/reference/cheatsheet.html)があるので、ぜひそちらもご覧ください。

### Directives
Directivesは、先ほどの「test page」の1番下にあったようなコンテンツブロックを作成することができる機能です。書式はこの通りです。
![スクリーンショット 2021-01-16 13.55.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/e19096e7-78d3-f7d2-8599-dc5ee285e16f.png)
directives.mdというファイルを作成して種類と書式を紹介します。以下のように書くと、コンテンツブロックを作成できます。

`admonition`は特殊な書式で、自由にタイトルとクラスを設定することができます。この例では`:class: tip`で`tip`のコンテンツブロックを指定しています。

`code-block`と言語を指定すると、それぞれの言語にそって表示してくれます。

![スクリーンショット 2021-01-15 0.32.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/f1833df6-049d-0577-6eba-1ad120b7ed04.png)
![スクリーンショット 2021-01-16 14.06.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/82d3d8a1-c2a3-4187-e106-4af9a11425dd.png)
コンテンツブロックはこのように表示されます。ここではコンテンツブロックのなかに、`{}`内に書くべきワードを書いています。内容がないと、エラーが出てしまうので注意してください。
![スクリーンショット 2021-01-15 0.33.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/5c2d4aa9-c873-5b1a-7436-ad8c79073551.png)
![スクリーンショット 2021-01-15 0.37.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/72b4b39c-7047-9243-21b3-491f1941e447.png)
`{code-block}`ではなく`{code-cell}`を指定して、.mdファイルの1番最初に`JupytText`というものを記述すると、コードを表示するだけでなく実行結果を表示させることもできます。また、ネストすることも可能です。
![スクリーンショット 2021-01-16 14.02.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/d5ebdf3d-b992-944f-8f64-ed0753a8c18b.png)
![スクリーンショット 2021-01-16 15.40.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/d0d7584c-c416-faef-71e4-7e5b206c360a.png)
![スクリーンショット 2021-01-16 15.41.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/68e02893-12d9-f1ea-8112-6732b3148f44.png)

`toggle`を使うと、ボタンで開閉できるスペースを作ることができます。
![スクリーンショット 2021-01-29 18.13.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/bf5ab4f4-055a-8e11-6bc8-9a036767679d.png)
![スクリーンショット 2021-01-29 18.13.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/a9a983d5-5af4-0073-4c68-e09ec198ac4b.png)
![スクリーンショット 2021-01-29 18.14.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/9f46b554-d068-17ac-89ef-611efedfcd74.png)



この他にも多くの書式がありますので、[Jupyter BookのMyST Markdownページ](https://jupyterbook.org/content/myst.html)や、[MySTのDirectivesページ](https://myst-parser.readthedocs.io/en/latest/using/syntax.html#directives-a-block-level-extension-point)や、[SphinxのDirectivesページ](https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html)をご覧ください。

### Roles

RolesはDerectivesと違って、1行でこのように書きます。
![スクリーンショット 2021-01-16 14.01.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/2f641ddf-0c8b-2ffa-6778-080642d299d6.png)
例えば以下のように書くと、チェックマークを表示させることができます。
![スクリーンショット 2021-01-16 14.17.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/f720a1b6-fe77-b02b-4909-8fac161cb22d.png)
![スクリーンショット 2021-01-16 14.18.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/323b8a6e-2f80-1e4f-5ebd-5bf32a860305.png)
この他にも多くの書式がありますので、[MySTのRolesページ](https://myst-parser.readthedocs.io/en/latest/using/syntax.html#roles-an-in-line-extension-point)をご覧ください。


# Jupyter Bookの公開

Jupyter BookはHTMLを生成するので、静的Webサイトを構成することができます。ここでは、GitHub Pagesを使ってJupyter Bookを公開してみましょう。

## リポジトリの初期設定

GitHubでJupyter Bookのための新しいリポジトリを作ります。以下のページにアクセスしてください。

https://github.com/new

今回は、`test_book_online`という名前のリポジトリを作りました。Jupyter Bookでリポジトリへのリンクを変更するため、`_config.yml`の`repository`部を編集します。
![スクリーンショット 2021-01-16 15.39.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/546645/82e8480a-f837-2585-b7bb-91ac60898966.png)
ここからリポジトリを設定します。まず`master`ブランチの設定を以下のコマンドで行います。ユーザ名やリポジトリ名は自分のものに置き換えてください。

```zsh
% cd test_book
% git init
% git add .
% git commit -m "adding my first book"
% git remote add origin https://github.com/<ユーザ名>/<リポジトリ名>.git
% git push origin master
```


これでリポジトリの設定をすることが出来ました。次はPythonの`ghp-import`というパッケージを使ってGitHub Pagesの設定をします。`ghp-import`が`gh-pages`ブランチを自動で作ってくれるので、`git branch gh-pages`などを実行する必要は**ありません**。

```zsh
% pip install ghp-import
% ghp-import -n -p -f _build/html
```


少し待ったあと、`https://<ユーザ名>.github.io/<リポジトリ名>` にアクセスすると、`test_book`の内容が表示されていると思います。自分の場合は、https://magolors.github.io/test_book_online と置き換えます。

これで公開することが出来ました。

## リポジトリの更新

Jupyter Bookのソースコードを更新したいときは、以下のように実行してください。

```zsh
% cd test_book
% jb build --all .
% git checkout master
% git add .
% git commit -m "comment"
% git push origin master
```

GitHub Pagesを更新したいときは、以下のように実行してください。`git checkout gh-pages`を実行する必要はありません。

```zsh
% cd test_book
% jb build --all .
% git checkout master
% ghp-import -n -p -f _build/html
```

この方法の他に、[GitHub Actionsを利用してJupyter Bookが更新されると自動でGitHub Pagesも更新する](https://jupyterbook.org/publish/gh-pages.html#automatically-host-your-book-with-github-actions)という方法もあります。

# 最後に

ここまでJupyter Bookの簡単な紹介をしてきました。ここで取り上げたもの以外にも、非常に多くの機能があるので、ぜひ[公式リファレンス](https://jupyterbook.org/index.html)をご参照ください。また、他にDirectivesの種類があったり、何か間違いなどありましたらコメントにて連絡をお願いします。

ここまで読んでいただきありがとうございました。 面白いと思った方はLGTMを押していただけると励みになります:smile: