AngularJSアプリケーションのドキュメントをdgeniで自動生成しよう

**注意 これは自動生成をしようとして諦めた記事です**

---

皆さんはAngularJSアプリケーションでのドキュメントの生成をどうしていますか？

AngularJSではngdoc形式のコメントを使っており、Javascriptの定番の[JSDoc](http://usejsdoc.org/)とはまた違う形式のドックコメントになっています。
もし、フレームワークに合わせようと思うとngdocに対応したドキュメント生成器を使う必要があります。
メジャーなところで言えば対応しているドキュメント生成器は3つになります。

* [grunt-ngdoc](https://www.npmjs.org/package/grunt-ngdoc)
* [grunt-ngdocs](https://www.npmjs.org/package/grunt-ngdocs)
* [docular](http://grunt-docular.com/)

個人的にこの中で一番使いやすかったのはdocularです。
詳しくは手前味噌になりますが、こちらの紹介記事をどうぞ。

[AngularJS API documentation generator “Docular”.](http://blog.kinzal.net/post/67656572065/angularjs-api-documentation-generator-docular)

しかし、これらのツールはAngularJSで使われている````@ngdoc````の指定ができなかったり、微妙に構文が違ってたりします。
特にAngularJSにはない````@ngdoc````の指定で、アプリケーション開発では必ず使う````@ngdoc controller````のサポート状況もツールによってまちまちです。

ここはAngularJSでも使われている[dgeni](https://github.com/angular/dgeni)を使うのが一番差が出なくて済みそうです。

# dgeni？
dgeniはAngularJSで使っているドキュメント生成器です。
AngularJS以外でも使われているプロジェクトがいくつかあります。

* [protractor](https://github.com/angular/protractor/tree/master/docs)
* [ionic](https://github.com/driftyco/ionic)
* [famous-angular](https://github.com/Famous/famous-angular)

dgeniは他のドキュメント生成器と違い、[middleman](http://middlemanapp.com/)や[Phest](https://github.com/chatwork/Phest)のような静的サイトジェネレーターに近い特色を持っています。
````@name````に対応したテンプレートファイルを作成し、ドックコメントをパースした結果をパラメーターとしてテンプレートに当てはめた結果をドキュメントとして出力します。（未検証ですがフォーマットはテンプレートに依存するのでmdの生成もできそうです）
そのため、チーム用にドキュメントを作るというより、フレームワークなどの公開用のドキュメントを作るのに向いています。

また、dgeniは公開されてから1年も経っていない若いツールのため日本語、英語問わず情報は全然ありません。
今のところ使い方として一番わかりやすかった下記を参考にするか、上で紹介した実際に使われているプロジェクトを参考にしてください。

* [dgeni-example](https://github.com/petebacondarwin/dgeni-example)

注意点としてはdgeni-exampleでは0.4.0-beta系で、実際に使われているプロジェクトでは0.3.0系になります。
gruntからの呼び出し方や設定の書き方が違うので気をつけてください。

# インストール

dgeniをnpmでインストールします。
0.3.x系の方が参考になる情報が多いため、今回は0.3.0を使います。

    npm install --save-dev dgeni@0.3.0
    npm install --save-dev dgeni-packages@0.3.0
    npm install --save-dev lodash

※ 自分の環境ではlodashをインストールしないと実行することができませんでした

# grunt

dgeniはgrunt、gulpどちらでも呼び出すことが出来ます。
自分はgrunt派なのでgruntでの使い方を説明します。（glup派はgrunt-exampleを見てください）

```js:Gruntfile.js
grunt.registerTask('dgeni', [], function() {
  var dgeni = require('dgeni');
  var done = this.async();
  var dgeniGenerator = dgeni.generator('docs/dgeni.config.js');
  dgeniGenerator().then(done);
});
````

もう少し仕様が固まったらプラグイン化すると良さそうです。

# コンフィグファイル

次にdgeni用のコンフィグファイルを作成します。

```js:docs/dgeni.config.js
module.exports = function(config) {
  // パッケージの読み込み
  config = require('dgeni-packages/jsdoc')(config);
  config = require('dgeni-packages/ngdoc')(config);
  config = require('dgeni-packages/examples')(config);
  // テンプレートディレクトリの指定
  config.prepend('rendering.templateFolders', [
    path.resolve(__dirname, 'templates')
  ]);
  // 読み込むスクリプトの指定
  config.set('source.projectPath', path.resolve(basePath, '../app/'));
  config.set('source.files', [
    { pattern: 'scripts/**/*.js', basePath: path.resolve(basePath,'../app/') },
  ]);
  // 出力先ディレクトリの指定
  config.set('rendering.outputFolder', '../build/docs');
  config.set('rendering.contentsFolder', 'partials'); // 
  // ログレベルの指定
  config.set('logging.level', 'info');
  // 
  config.merge('deployment', {
    environments: [{
      name: 'app',
      scripts: [], // ページで読み込むスクリプト？
      stylesheets: [] // ページで読み込むスタイルシート？
    }]
  });

  return config;
};
````

これが出力に必要な最低限の設定になります。
ただ、自分としても若干設定としてよく分からない箇所があるため、詳しくは各プロジェクトのコンフィグファイルを解読することをオススメします。

# テンプレートの作成

ここまでの設定で````grunt dgeni````を実行するとドキュメントの生成をすることができます。
しかし、````@ngdoc controller````を使っている場合は対応するテンプレートがないためドキュメントを生成に失敗します。
（ngdocとしてはcontrollerの指定に対応していません）
そこで、controller用のテンプレートファイルを作成します。

    curl https://raw.githubusercontent.com/angular/dgeni-packages/master/ngdoc/templates/api/object.template.html > docs/templates/controller.template.html 

一から作るのは面倒臭いので、ngdocで近そうなテンプレートをdgeni-packagesから取得します。
これで````grunt dgeni````を実行するとAngularJSアプリケーションのドキュメントを生成することができます。

# プロセッサの作成

生成したドキュメントを見るとHTMLの一部が出力されていることがわかります。
これはdgeni-packagesのngdocテンプレートはAngularJSを使用してビューとして読み込むことを前提なっているためです。

これに対応するには

1. テンプレートを単独で動かせるように作り直す
2. 事前に読み込むためのindex.htmlを作成する
3. dgeniの機能のプロセッサを使ってindex.htmlを生成する

のいずれかの方法を取る必要があります。
実際に使っている各プロジェクトでは3のプロセッサの機能での生成されているので、これが定番的な手法になるようです。

それでは実際にプロセッサを作成します。

<br/><br/><br/><br/><br/><br/>

...と思ったのですがここで力尽きました。
自分はngdoc形式でコメントを書いて、それが正しく書けているのか確認するためにドキュメントを生成したかっただけなので、こんなに苦労したくねーよーという状態になりました。

もし、プロセッサを作るという人がいたら各プロジェクトの````docs/config/processors/index-page.js````を参考にすると良いと思います。

# まとめ

尻つぼみになってしまいましたが、いかがだったでしょうか。
これは個人的な印象ですが、AngularJSアプリケーションにdgeniを使うという選択肢はかなり有りです。
が、dgeniでは手軽に試せるテンプレートがまだなく、情報も全然ないため今使うには少し難しいです。

せめて手軽に試せるテンプレートが出たらAngularJS使いに一気に広まりそうなだけにおしいですね。

---

今度、日本語のAngularJS本が出るようなので、このあたりのドックコメントについても言及されていると嬉しいですね！！
実際に業務で使っているという話は良く聞くようになってきましたが、ドックコメントはこう書いてますという話を全く聞かないので皆さんどうしているのか気になります。