# JupyterとSphinxで本書いた
SphinxCon JP 2019
2019-11-25@株式会社インターネットイニシアティブ
driller@patraqushe
---
## 誰?
- どりらん
- [@patraqushe](https://twitter.com/patraqushe) ![](https://i.imgur.com/u7l3rnc.png)
- フラフラしてます
- 最近よく歩いてます<a href="https://www.dragonquest.jp/walk/"><img src="https://pbs.twimg.com/profile_images/1169446429720363008/EAQDTMsd.png" width=35 height=35></a>
----
## SphinxCon JP 2017でやったLTの続きです
<iframe width="640" height="480" allowfullscreen frameborder=0 src="https://slideship.com/embed/presentations/GX5q8tJTPHuctnT1LeAZZd/"></iframe>
----
### 木星から帰ってきました
[![](https://lohas.nicoseiga.jp/thumb/2486299i)](https://dic.nicovideo.jp/a/ジュピトリス)
---
## さいしょに書いた本
[![](https://gihyo.jp/assets/images/cover/2017/thumb/TH160_9784774192239.jpg)](https://gihyo.jp/book/2017/978-4-7741-9223-9)
----
## どうやって書いたか
原稿はAsciiDoc
- Jupyterのコードを貼り付け
- Jupyterの実行結果を貼り付け
----
## 課題
- コードと結果の移植がちょーめんどくさい
- 転記漏れで出力と結果が異なる事件が発生
- レビュー時に発覚して事なきを得た
- 変更するときも大変
----
## どうするべきだったか?
執筆者内の反省会にて
**全部Jupyterで書けばよかった**
----
## Jupyterでドキュメントを書く利点
解説、コード、実行結果が一元化できる
----
### 一元化すると...
コードや結果を転記する必要がなくなる
----
### 転記する必要がなくなると...
- 転記漏れ・ミスがなくなる
- テストやチェックがドキュメント上(Jupyter)から行える
----
こういうのを防げる
![](https://pbs.twimg.com/media/EA7jtfYVUAAe6Mb.jpg:small)
---
## どうやって書くのか
- Jupyter上に全部書く
- 解説部分はMarkdownやreSTで書く
- コードはJupyter上で実行する
- ドキュメントビルダでHTML化やPDF化
- Jupyterに対応したドキュメントビルダ
----
### Jupyterで書いた雑誌
[![](https://gihyo.jp/assets/images/cover/2018/thumb/TH160_641802.jpg)](https://gihyo.jp/magazine/SD/archive/2018/201802) [![](https://gihyo.jp/assets/images/cover/2019/thumb/TH160_9784297103965.jpg)](https://gihyo.jp/book/2019/978-4-297-10396-5)
----
### Jupyterで書いた書籍
2冊を執筆中 :books:
![](https://2.bp.blogspot.com/-mlIud9tJ37E/WJmxGNUEbrI/AAAAAAABBks/zqWU-GZC_8MavsTtbThNGoJag00nsO35gCLcB/s180-c/slump_bad_man_write.png)
----
## Jupyterをビルドできるライブラリ
- Sphinx
- nbsphinx
- jupyter-sphinx
- jupyter-book
- Nikola
- Miyadaiku
---
### [nbsphinx](https://nbsphinx.readthedocs.io/)
- Sphinxのextension
- HTMLやLaTeXに変換できる
- 基本的な使い方はSphinxと同じ
----
### nbsphinxでドキュメントを作る手順
----
#### インストール
```bash
pip install jupyter nbsphinx
```
----
#### プロジェクトを作成
```bash
sphinx-quickstart -q -p nbsample -a nbauther -l ja --sep
```
----
##### source/conf.py
下記を追記
```python
extensions = [
'nbsphinx',
'sphinx.ext.mathjax',
]
exclude_patterns = ['_build', '**.ipynb_checkpoints']
```
----
#### Jupyter原稿を書く
`source/sample.ipynb`
![](https://i.imgur.com/YFQMKv9.png)
----
##### Jupyter NotebookでreSTセルにする方法
![](https://i.imgur.com/4nsJnRG.png)
----
##### JupyterLabでreSTセルにする方法
![](https://i.imgur.com/qFTUkWy.png)
----
#### toctreeにNotebookを追加
拡張子は含めない
`source/index.rst`
```rst
.. toctree::
:maxdepth: 2
:caption: Contents:
sample
```
----
#### ビルド
```bash
make html
```
![](https://i.imgur.com/ogn8m2W.png)
----
サンプルプロジェクト
https://github.com/drillan/SphinxConJP2019
---
## はまったり工夫したこと
Jupyterに関連したTipsなど
----
### 実行結果がJavaScriptだとレンダリングされない
- Bokeh
- Plotly
- etc
[Jupyter Sphinx](https://jupyter-sphinx.readthedocs.io/en/latest/)(後述)を入れたら解決した
なぜかは不明
----
#### 特定のセルをドキュメントの対象外としたい
コード実行時に生成されてしまうファイルを削除する処理など
```bash
!rm tempfile
```
セルのmetadataに下記を入れておくとビルドの対象外にできる
```json
"nbsphinx": "hidden"
```
Hidden Cells: https://nbsphinx.readthedocs.io/en/0.5.0/hidden-cells.html
----
### コーディングスタイルを統一したい
Jupyter Notebook
- [jupyter-black](https://github.com/drillan/jupyter-black)
JupyterLab
- [jupyterlab_code_formatter](https://github.com/ryantam626/jupyterlab_code_formatter)
----
### 日本語のチェックをしたい :crossed_flags:
- [textlint](https://textlint.github.io)
- [textlint-plugin-rst](https://github.com/jimo1001/textlint-plugin-rst)
- reStructuredText
- [textlint-rule-preset-ja-technical-writing](https://github.com/textlint-ja/textlint-rule-preset-ja-technical-writing)
- 技術文書向けのtextlintルールプリセット
- [preset-jtf-style](https://github.com/textlint-ja/textlint-rule-preset-JTF-style)
- JTF日本語標準スタイルガイドのtextlint版
- [textlint-rule-prh](https://github.com/textlint-rule/textlint-rule-prh)
- 表記ゆれ校正
- [WEB+DB_PRESS.yml](https://github.com/prh/rules/blob/master/media/WEB%2BDB_PRESS.yml)
- WEB+DB PRESSのルール
----
#### どうやってJupyterのファイルをtextlintにかけるか
- [nbconvert](https://nbconvert.readthedocs.io/en/latest/)を使う
- MarkdownやreSTのセルだけ抜き出せる
ipynbファイルをtextlintにするための魔法のコマンド
```bash
jupyter nbconvert xxx.ipynb \
--to rst --stdout \
--TemplateExporter.exclude_code_cell=True | \
textlint --stdin
```
----
#### nbformat
[nbformat](https://nbformat.readthedocs.io/en/latest/)を使うと色々できる
<iframe width="460" height="284" allowfullscreen frameborder=0 src="https://slideship.com/embed/presentations/QqQrVw7nF6Vfwh9ivh2RJX/"></iframe>
----
### Notebookのdiffをしたい
[nbdime](https://nbdime.readthedocs.io/en/latest/)が超便利
![](https://nbdime.readthedocs.io/en/latest/_images/nbdiff-web.png)
----
#### [Notebook Extensions](https://nbdime.readthedocs.io/en/latest/extensions.html)
ボタン一発でdiffができる
![](https://nbdime.readthedocs.io/en/latest/_images/nbext-preview.png)
---
## はまったり工夫したこと
Jupyter関係なくSphinxに関連したこと
----
### 黒丸数字がlatexでビルドできない
[#6841](https://github.com/sphinx-doc/sphinx/pull/6841)で解決
![](https://i.imgur.com/SRVPinl.png)
----
### Font Awesomeを使いたい
<i class="fa-step-forward fa"></i> のようなアイコンをだしたい
----
##### [sphinx fontawesome](https://github.com/fraoustin/sphinx_fontawesome)
ディレクティブとロールを使って書ける
ディレクティブ
```rst
.. fa:: check
```
ロール
```rst
:fa:`check`
:fa:`check lg`
:fa:`square-o`
```
----
### SVGの画像を表に埋め込みたい
![](https://i.imgur.com/XgnudO3.png)
----
#### replaceが便利
参考: [replaceを使ってテーブルに画像を貼る](https://sphinx-users.jp/reverse-dict/table/replace-table.html)
```rst
.. |Zoom| raw:: html
<svg viewBox="0 0 1000 1000" class="icon" height="1em" width="1em"><path d="m1000-25l-250 251c40 63 63 138 63 218 0 224-182 406-407 406-224 0-406-182-406-406s183-406 407-406c80 0 155 22 218 62l250-250 125 125z m-812 250l0 438 437 0 0-438-437 0z m62 375l313 0 0-312-313 0 0 312z" transform="matrix(1 0 0 -1 0 850)"></path></svg>
.. list-table:: モードバーの機能
:widths: 10 25 65
:header-rows: 1
:name: mode_bar_list
* - アイコン
- ボタン名
- 機能
* - |Zoom|
- Zoom
- マウスドラッグでグラフ領域を拡大します。元のビューに戻るには、プロット上の任意の場所をダブルクリックします。
```
----
#### ビルド環境を共有したい :whale:
[Docker Image](https://hub.docker.com/repository/docker/driller/nbsphinx-build)を作った
HTMLでビルド
```bash
docker run --rm -v <project_dir>:/build driller/nbsphinx-build make html
```
latexでビルド
```bash
docker run --rm -v <project_dir>:/build driller/nbsphinx-build make latexpdf
```
Imageを`driller/nbsphinx-build:requirements`にすると`requirements.txt`のパッケージをインストールしてからビルド
---
## 課題
- JavaScriptの出力がlatexに変換できない
![](https://i.imgur.com/I44p4Fz.png)
- CIでビルド
- GitHub Actionsを使ってやりたかった
- [ためしてみたい](https://github.com/ammaraskar/sphinx-action)
---
## オマケ: [Jupyter Sphinx](https://jupyter-sphinx.readthedocs.io/en/latest/)
- reST上に書いたコードをJupyterのカーネルで実行できる
- nbsphinxはipynbで記述するのに対してJupyter SphinxはreSTで記述
- コードと実行結果がドキュメント化できる
- [ThebeLab](https://thebelab.readthedocs.io/en/latest/)に対応
----
### Jupyter Sphinxの書き方
コードブロックを`jupyter-execute`ディレクティブにするとJupyterで実行される
```rst
.. jupyter-execute::
name = 'world'
print('hello ' + name + '!')
```
---
## 謝辞
- Sphinxメンテナの皆様
- Sphinx users jpの皆様
- Python ドキュメント日本語訳プロジェクトの皆様
{"metaMigratedAt":"2023-06-15T01:33:55.067Z","metaMigratedFrom":"YAML","title":"JupyterとSphinxで本書いた","breaks":true,"description":"SphinxCon JP 2019","lang":"ja-jp","slideOptions":"{\"allottedMinutes\":20,\"parallaxBackgroundImage\":\"https://www.sphinx-doc.org/ja/master/_static/headerbg.png\"}","contributors":"[{\"id\":\"c8293db1-2634-4fca-a1fe-de631ba868a8\",\"add\":10351,\"del\":2672}]"}