Markdownでマニュアル作成環境を整える（Sphinx+ sphinx_rtd_theme+recommonmark編）

## Sphinxとは
- ドキュメントの整形を支援する強力なツール。
- reStructuredTextや**Markdown**で文書を書く。
- HTML、PDF、ePubなどに出力できる。

百聞は一見に如かず。一例として、以下のようなイメージでマニュアルサイトを作る事ができます。広く使われているツールなので似たイメージを見た事があるのではないでしょうか？。

![part00-index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/6e54269d-0e18-4a4f-215f-01a90d90d0a5.png)


この記事では、以下のサンプルマークダウンをビルドしてHTMLに変換する方法を掲載します。
https://github.com/ka2taka/lab_202009_sphinx/tree/master/source

ビルドして出力したHTMLは以下のようになります。
https://ka2taka.github.io/lab_202009_sphinx/part01/index.html


## この記事で前提とする作業環境
- 環境
    - Windows 10 Pro
    - Python v3.8.3(Anaconda3)
    - Sphinx v3.2.1
    - recommonmark v0.6.0 
    - sphinx-rtd-theme v0.5.0(Read the Docs Sphinx Theme)
- 作業フォルダ
    - C:&yen;work&yen;manual



## Pythonの仮想環境を作成する（virtual env）
```shell-session
(base) C:\work>mkdir manual
(base) C:\work\manual>cd manual
(base) C:\work\manual>python -m venv venv
(base) C:\work\manual>venv\Scripts\activate.bat
```

インストールされているパッケージを確認。

```shell-session
(venv) (base) C:\work\manual>pip list
Package    Version
---------- -------
pip        19.2.3
setuptools 41.2.0
WARNING: You are using pip version 19.2.3, however version 20.2.3 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
```

警告が出たのでPIPをアップグレード

```
(venv) (base) C:\work\manual>python -m pip install --upgrade pip
...途中省略...
Successfully installed pip-20.2.3
```

- 参考
  - [Creating a virtual environment](https://packaging.python.org/guides/installing-using-pip-and-virtual-environments/#creating-a-virtual-environment)

## Pythonのパッケージを導入する。

```
(venv) (base) C:\work\manual>pip install sphinx
(venv) (base) C:\work\manual>pip install recommonmark
(venv) (base) C:\work\manual>pip install sphinx-markdown-tables
(venv) (base) C:\work\manual>pip install sphinx_rtd_theme
(venv) (base) C:\work\manual>pip install sphinxcontrib-blockdiag
(venv) (base) C:\work\manual>pip install sphinxcontrib-actdiag
```


## Sphinxのセットアップ
```
(venv) (base) C:\work\manual>sphinx-quickstart  
...途中省略...
> Separate source and build directories (y/n) [n]: y
...途中省略...
> Project name: manual
> Author name(s): ka2taka
> Project release []: 2020-12-31
...途中省略...
> Project language [en]: ja
...途中省略...
```

以下のフォルダとファイルが作成される。

```
(venv) (base) C:\work\manual>tree /F
C:.(manualの場所)
│make.bat
│Makefile
│
├─build　・・・変換後の文書の出力先。
└─source　・・・作成する原文の場所。
    │conf.py　・・・各種設定。
    │index.rst　・・・ルートになるドキュメント。
    │
    ├─_static
    └─_templates

※venvフォルダ等は記載省略
```

## 拡張機能を有効にする

以下の機能を有効にします。


- markdownから変換出来るようにする。
- markdownのテーブルを使えるようにする。
- [Read the doc](https://sphinx-rtd-theme.readthedocs.io/en/stable/)のテーマを有効にする。
- UMLの作図をテストするので、blockdiagとactdiagを有効にする。

source/conf.pyの編集

```python
extensions = [
    'recommonmark',
    'sphinx_markdown_tables'
    'sphinxcontrib.blockdiag',
    'sphinxcontrib.actdiag',
]
source_suffix = {
    '.rst': 'restructuredtext',
    '.txt': 'markdown',
    '.md': 'markdown',
}

from recommonmark.transform import AutoStructify
# github_doc_root = 'https://github.com/rtfd/recommonmark/tree/master/doc/'
def setup(app):
    app.add_config_value('recommonmark_config', {
            # 'url_resolver': lambda url: github_doc_root + url,
            'auto_toc_tree_section': 'Contents',
            }, True)
    app.add_transform(AutoStructify)
```
```python
html_theme = 'sphinx_rtd_theme'
```
- url_resolverは試してないのでコメントアウト
- 参考
  - markdownサポートについては以下に記述がある。
      - https://www.sphinx-doc.org/ja/1.6/markdown.html#markdown
      - https://recommonmark.readthedocs.io/en/latest/auto_structify.html
  - テーマオプションについては以下に記載がある。
      - https://www.sphinx-doc.org/ja/master/usage/theming.html  
      - https://planset-study-sphinx.readthedocs.io/ja/latest/06.html
  - conf.pyの書き方  
      - https://www.sphinx-doc.org/ja/1.6/config.html



## 今回の検証用に作成する文書構造
以下の構造で文書を作ろうと思います。

```
1. 第1部
  1.1 第1章
    1.1.1 第1節
      1.1.1.1 第1小節
```

上記の第1部と同様に、第2部と第3部も作ります。
後述する試験用のサンプルドキュメントは以下のような英語表現になってます。
英語にする理由は特にありません。最初になんとなく作ったサンプルがそうなってただけです。

```
1. Part-01
  1.1. Chapter-01
    1.1.1. Section-001
      1.1.1.1. Sub Section-001
```

## 今回の検証用に作成するフォルダ構造
複数人で共同作業する場合、ファイルを複数に分割したいですよね？
ファイルの分割の粒度を変えながら3パターンのフォルダ構成を作ってみます。

イメージは以下の通りです。

![slide1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/ea7738a3-7c8e-1bcb-5fb6-28868febb4e6.png)



## 文書ファイルの作成。
構造構造の定義はreStructuredTextで記述します。
文章本体はMarkdownで記述します。

### 文書構造の記述
index.rstに定義します。
「toctree」の下に目次化する深さや、ドキュメントへのリンクを書きます。

```
.. toctree::
   :maxdepth: 3
   :caption: Contents:
   :numbered:

   part01/index ・・・第1部(Part-01)の文書の場所を指定。
   part02/index ・・・第2部(Part-02)の文書の場所を指定。
   part03/index ・・・第3部(Part-03)の文書の場所を指定。
```

### 文章本体の記述
本文はMarkdownで記述します。
例えばpart01/index.mdが該当します。普通のマークダウンです。

```
# Part-01
Above line is writed by using headers #.

## Chapter-01
Above line is writed by using headers ##.
```

ここからビルド方法を説明します。
まずはサンプルファイルを使ってビルドしてみてください。
サンプルは以下にありますのでsource配下に保存します。
https://github.com/ka2taka/lab_202009_sphinx

## 文書ファイルの変換
「make html」で文書が変換されます。
「source」配下のドキュメントが「build」配下に変換されます。

```
(venv) (base) C:\work\manual>make html
Running Sphinx v3.2.1
...（途中省略）...
writing output... [100%] part03/index
C:\work\manual\source\appendix.md:27: WARNING: Pygments lexer name 'markdown' is not known
...（途中省略）...
The HTML pages are in build\html.
```

コードブロックに記述したキーワード「markdown」は解釈できないようで、WARNINGが出ています。キーワード「python」は解釈できるようでした。
↓WARNINGになったMarkdownのコードブロックの記述例

<pre>
```markdown
|a|b|c|
|-----|-----|-----|
|1|2|3|
|a|b|c|
|あ|い|う|
```
</pre>


## 文書ファイルの作成方法の解説
前述では、文書ファイルの作成につて
### 第1部(Prat-01)の解説
#### 文書構造の定義
manual&yen;source&yen;index.rst
今回の例ではindex.rstで配下の構造を定義します。
ルートフォルダにあるindex.rstから第1部（Part-01）の場所を指定する記述は以下の通りです。
maxdepthは目次化する深さを示します。

```
sphinx sample document　・・・　ドキュメント全体のタイトル
======================================

.. toctree::
   :maxdepth: 3
   :caption: Contents:
   :numbered:

   part01/index ・・・第1部(Part-01)の文書の場所を指定。
   part02/index
   part03/index
```

ファイルの関係をビジュアルに見せると以下の通りです。
![slide2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/1b6bdf87-8fba-acaf-808a-db116a1f34dc.png)

#### 文書の中身
manual&yen;source&yen;part01&yen;index.md
index.mdの中身は普通のマークダウンです。

- レベル１の見出し「#」が部(Part)のタイトルになります。
- レベル２の見出し「##」が章(Chapter)のタイトルになります。

```
# Part-01
Above line is writed by using headers #.

## Chapter-01
Above line is writed by using headers ##.

### Section-001
Above line is writed by using headers ###.

#### Sub-Section-001
Above line is writed by using headers ####.
```

#### 出来上がった文書イメージ

![part01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/ca3f6bfe-bc62-aa44-c69a-260c0652b8c5.png)

第1部(Part-01)は、index.mdの1ファイルで文書全体を作成しました。
この場合、パンくずリスト（breadcrumb list）は、1階層で表現されるようです。
画面中央上部の「🏠 >> 1.Part-01」の事です。

### 第2部(Prat-02)の解説
#### 文書構造の定義
ルートフォルダにあるindex.rstから第2部（Part-02）の場所を指定する記述は以下の通りです。
manual&yen;source&yen;index.rst

```
sphinx sample document　・・・　ドキュメント全体のタイトル
======================================

.. toctree::
   :maxdepth: 3
   :caption: Contents:
   :numbered:

   part01/index
   part02/index ・・・第2部(Part-02)の文書の場所を指定。
   part03/index
```

更にmanual&yen;source&yen;part02&yen;index.rstで配下の構造を定義します。

```
Part-02　・・・　第2部のタイトル。
=============================================

.. toctree::
   :maxdepth: 2
   :caption: Contents:

   chapter01　・・・　第2部 第1章のファイル
   chapter02　・・・　第2部 第2章のファイル
```

ファイルの関係をビジュアルに見せると以下の通りです。
![slide3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/b23ac2e9-c95b-79cc-2ac2-f47c7d5c4bfd.png)


#### 文書の中身
manual&yen;source&yen;part02&yen;chapter01.md
chapter01.mdの中身は普通のマークダウンです。

- レベル１の見出し「#」が章(Chapter)のタイトルになります。
- レベル２の見出し「##」が節(Section)のタイトルになります。

```
# Chapter-01
Above line is writed by using headers #.

## Section-001
Above line is writed by using headers ##.

### Sub-Section-001
 Above line is writed by using headers ###.
```

第1部(Part-01)ではレベル1の見出し「#」が部(Part)でした。
第2部(Part-02)ではレベル1の見出し「#」が章(Chapter)になります。
Sphinxが文書の階層に応じて見出しを解釈してくれます。

#### 出来上がった文書イメージ

![part02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/98c13194-fe15-54e8-4d6d-9d04ae86a66e.png)
![part02-chapter01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/f5026db1-4678-3913-8cc8-cd0ccdd2adcb.png)


第2部(Part-02)は、章(Chapter)別にファイルを作成しました。
この場合、パンくずリスト（breadcrumb list）は、2階層で表現されるようです。
画面中央上部の「🏠 >> 2.Part-02 >> 2.1.Chapter-01」の事です。
これは第1部(Part-01)とは異なる振る舞いです。

## 変換がうまく出来なかったもの
appendix.mdでmarkdownの変換テストをしています。
うまく変換出来ないものがいくつかありました。原因は調べ中です。

### 取り消し線
<pre>
~~打消し~~
</pre>

### タスクリスト（チェックボックス）
<pre>
- [x] a
- [ ] b
- [ ] c
</pre>

## Markdownで表現できないもの
blockdiagなどの拡張機能はmarkdownで扱えないため、markdownファイルの中にreStructuredTextを埋め込みます。

<pre>
```eval_rst
.. blockdiag::
   :desctable:

   blockdiag {
      A -> B -> C;
   }
```
</pre>

変換されたイメージは以下です。
![blockdiag.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324770/5c1ecabb-ab08-062e-4324-e5afcd1a8999.png)


Sphinxの拡張機能は、以下の文書を参考にしました。
https://recommonmark.readthedocs.io/en/latest/auto_structify.html#embed-restructuredtext


## GitHub-Pagesにアップする時の注意点（_から始まるフォルダが無視される）
### .nojekyllを作成する必要がある
作成したHTMLをGitHub-Pagesにアップする場合、注意点があります。
Sphinxは、CSS等の静的ファイルを「_ static」に出力します。
GitHub-Pagesは、通常「_」で開始するファイルを無視します。

これを問題は、GitHub-Pagesのトップフォルダに「.nojekyll」を置くことで回避できます。
ファイルの中身は空で大丈夫です。

GitHub-Pagesにアップする際の問題解決は、以下の記事を参考にしました。
https://github.blog/2009-12-29-bypassing-jekyll-on-github-pages/
https://github.com/sphinx-doc/sphinx/issues/2202

### _から始まるフォルダ名を変える方法は無さそう。
Sphinxが出力するフォルダの名前を変更できないか？を調べたものの、手段が提供されていないようでした。
ビルド設定ファイル（conf.py）のhtml_static_pathオプションを試したのですが、インプットフォルダの名称を変える事はできたものの、出力先のフォルダ名称は変わらないようでした。

### Sphinx側での回避方法（sphinx.ext.githubpages）
extensionsに、sphinx.ext.githubpagesを加える事で、「.nojekyll」が自動で作られるようです。

以下に記載がありました。
https://www.sphinx-doc.org/ja/master/usage/extensions/githubpages.html


## 参考文献
1. https://www.sphinx-doc.org/ja/master/