D言語のドキュメント生成(gendoc)のお話

#概要
- [gendoc](https://code.dlang.org/packages/gendoc)はD言語標準の方法でドキュメント生成するためのヘルパツールです
- dubプロジェクトのフォルダで `dub run gendoc` すればインストール不要で誰でも簡単に使えます
- [dlang-jp](https://github.com/dlang-jp)の[Cookbook](https://dlang-jp.github.io/Cookbook/)で使うために作りました！


#D言語のドキュメント生成事情
[2018年にまとめたのでご参照](https://qiita.com/mono_shoo/items/012acab29cd9cd990d4c)
2018年に標準の方法について「訓練されていなければ困難」と書きました。
この理由たらしめている課題は、「[標準の方法の使用方法](https://qiita.com/mono_shoo/items/012acab29cd9cd990d4c#%E6%A8%99%E6%BA%96%E3%81%AE%E6%96%B9%E6%B3%95%E3%81%AE%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95)」でしれっと端折っている、1つのソースコードから1つのHTMLしか吐けない点と、デフォルトのスタイルが貧弱という点、dubを使っている場合に`-I`で指定しなきゃいけないインポートディレクトリを探すのが大変な点などです。
このため、ほかの多くのツールが作られました。
しかしながら、それら多くのツールは、D言語のコンパイラでドキュメントを生成させるのではなく、どうせやるなら自分でドキュメントの抽出やパースをしてしまおうという思想のものがほとんどでした。

さて、[dlang-jp](https://github.com/dlang-jp)というコミュニティがあります。[D言語もくもく会](https://dlang-mokumoku.connpass.com/)というイベントの参加メンバーが懇親会の場で思いついて今年夏ごろに始まったコミュニティです。
その場で「いろいろドキュメント生成見てみたけど、なんだかんだ[公式](https://dlang.org/phobos/index.html)のがほかの言語のドキュメント含め一番見やすくて強いよね」という話が挙がりました。
[公式のドキュメント](https://dlang.org/phobos/index.html)は、D言語コンパイラで生成したHTMLファイルによってできています。しかしながらこれを自分で作るプロジェクトでやろうとしたときの問題点は先述のとおりです。
[Cookbookみたいな、コードサンプル集](https://dlang-jp.github.io/Cookbook/)ほしいよねという話もあり、先述の課題を何とかしようという流れになったので、そういうヘルパツールを[作りました](https://code.dlang.org/packages/gendoc)。

#[gendoc](https://code.dlang.org/packages/gendoc)

ダウンロード・インストールは不要です。

使い方は、以下のようにあなたの持っているdubプロジェクトでコマンドを実行するだけです。

```sh
dub run gendoc
```

これでdubがgendocをダウンロード・ビルド・実行してくれます。

## カスタマイズ

生成されるHTMLの外観や動作を変えたい場合は、以下のようにコマンドを実行することで、デフォルトのテンプレがdubプロジェクトのファイルに追加されます。

```sh
dub build gendoc -c=init
```

追加された、`(dub project)/ddoc`や`(dub project)/source_docs`の`*.ddoc`や`*.dd`, `*.css`, `*.js`などを編集することで、生成されるページを任意にカスタマイズできます。

## ツールがやってくれること

このツールがやってくれることは、以下の通り。

1. dubプロジェクトから依存関係を調べて、dmdやldc2でコンパイルするために`-I`で指定するべきインポートディレクトリを探します。
2. dubプロジェクトで管理されているソースファイルの一覧を使って、モジュールリストを作ります。(メニューとかに使う)
3. `*.mustache`なファイルを使って内部情報を埋め込みます。(バージョン情報とか)
4. `*.ddoc`のように一緒にコンパイルするファイルを探します。(デフォルトでは`ddoc`から)
5. `*.css`, `*.js`など、装飾になど他に使用するファイルを探してコピーします。(デフォルトでは`source_docs`から)
6. `*.d`や`*.dd`ファイルに対してdmdかldc2コンパイラを呼び出してHTMLを生成します

## ダウンロード・インストール不要の理由

dubパッケージとして登録しているため、`dub run gendoc`とすると、dubがオンラインから勝手に探してダウンロード・ビルド・実行してくれます。
また、装飾用のファイルはデフォルトでは現在のディレクトリを起点に探しますが、それが見つからなければバイナリファイルのある所(つまりdubがビルドした場所)を起点に探し、使ってくれるという寸法です。

ただし、注意点があって、これを一回やると、バージョンがその時のものに固定されてしまう場合があるようで、gendocのバージョンが更新されても勝手に追従してくれません。([dubのバグ](https://github.com/dlang/dub/issues/1751))
`dub remove gendoc`とか、パッケージのキャッシュを保存しておく場所にあるgendoc用のフォルダを直接消し去るとかすると新しいバージョンに追従できると思います。

# 隘路事項
dubプロジェクトの情報を使うので、dubをライブラリとして使用しています。ライブラリとしての使用方法は、「ソース読め」だったのでその点苦労しました。
dubの中身は難解だともっぱらのうわさです。
しかもバグバグしい挙動をいくつか見つけてしまい、それを回避するのも苦労しました。

また、コンパイラは、通常のアプリケーションやライブラリをビルドする場合であればいっぺんにソースファイルを渡してあげればすべて一緒にコンパイル・リンクしてくれるのですが、[HTMLファイルはファイル名がかぶるファイルがあるといっぺんに指定することができません。](https://issues.dlang.org/show_bug.cgi?id=18062) ※ちなみにこれ、解決すると[$50もらえますよ](https://www.flipcause.com/secure/cause_pdetails/NjU3MTU=)
そのため、できる場合はいっぺんにコンパイルして時短。できない場合はファイルを一つずつコンパイルするみたいなことをやってます。

# サンプルページ

- [dlang-jp/Cookbook](https://dlang-jp.github.io/Cookbook/)
- [gendoc](https://shoo.github.io/gendoc/)

# 開発に貢献
- https://github.com/shoo/gendoc
- [バグ報告はこちら](https://github.com/shoo/gendoc/issues)
- [プルリクエスト](https://github.com/shoo/gendoc/pulls)歓迎します！
- [Cookbook](https://github.com/dlang-jp/Cookbook)のレイアウト上の問題や要望も、最終的にはこのツールに取り込まれることが多いです。
- 使ってくれるたびに[dubパッケージ](https://code.dlang.org/packages/gendoc)のダウンロード数がカウントされるので、作者のやる気がでます！