あけましておめでとうございます。
ソフトウェアを開発し公開する場合、ドキュメント(マニュアル)を作成することが求められます。しかし、良いドキュメントを作成する方法というのはあまり知られていません。どのようにすれば良いドキュメントを作成できるのでしょうか?    
本稿では、ソフトウェアと同じくドキュメントを要素と性質に構造化することで、良いドキュメントを作成する方法を紹介します。そして、その要素と性質に対してアプローチを行っているESDoc というJavaScript(ECMAScript2015)向けのドキュメンテーションツールについても簡単に紹介します。     
対象とするドキュメント 
ドキュメントと一口にいっても仕様書、設計書、マニュアルなど様々な種類が存在します。そこで、本稿が対象とするドキュメントを「ライブラリやフレームワークなどを開発するソフトウェア開発者自身が、そのソフトウェアの使い方をエンドユーザ(そのソフトウェアを使用するほかの開発者)に向けて書くもの」とします。        
このようなドキュメントは一般的にマニュアルと呼ばれます。具体的にはREADMEやAPIリファレンス、チュートリアルなどです。ソフトウェア開発者ならば日々これらのマニュアルを読んでいることでしょう。以降、本稿でドキュメントといえばこのようなマニュアルを指すこととします。  
ドキュメントを書くための技術 
ソフトウェアの世界にはドキュメントを書くためのたくさんの技術があります。最も古くからある技術で、かつ最も有名なものの一つとしてHTMLがあります。最近ではMarkdown、reStructuredText、AsciiDoc、Re:VIEWなど、様々な記法も使われています。     
他にもPerl、Ruby、Java、Goなどの言語標準のドキュメンテーションツールとして、PerlDoc、RDoc、Javadoc、GoDocなどが存在します。言語標準以外にもYARD、JSDoc、PhpDocumentorなどがあります。これらのツールでは独自に記法を定義したり、HTMLなどの記法を組み合わせたりといった、その言語を対象にしたドキュメントを書きやすくするための工夫がなされています。           
ドキュメントを書く場所としてREADMEは以前から使われていましたが、GitHubの出現によりその重要性が格段に高くなったと言えます。また、GitHubにはGitHub PagesやWikiが標準で付属しているため、Webでドキュメントを公開して運用するコストも非常に低くなりました。最近ではRead The DocsやGitBookなどGitHubと連携してドキュメントを公開できるサービスも存在します。   
そしてドキュメントの間違いをチェックするツールとして、RedPenやtextlintなどの校正ツールも開発されています。 
ドキュメントを書くための技術とソフトウェア開発の類似性 
先ほど紹介したドキュメントを書くための技術は次のように整理できます。
言語:HTML、Markdown、reStructuredText、独自のドキュメントコメントなど    
場所:GitHub、Read The Docs、GitBookなど   
検査:RedPen、textlintなど  
 
また、ソフトウェア開発も同じように整理できます。 
言語:Ruby、Java、JavaScriptなど   
場所:GitHub、BitBucketなど  
検査:Lintツール、コーディング規約、コードフォーマッターなど   
 
このように言語、場所、検査を軸にして整理することで、ドキュメントを書く技術とソフトウェア開発は類似していることがわかります。   
しかし、ドキュメントを書く技術とソフトウェア開発では大きな違いがあります。それは、ソフトウェア開発ではソフトウェアを要素と性質に構造化するという重要な取り組みを行っている点です。この要素と性質というのは次のようなものです。  
要素:GoFのデザインパターンやMVCに代表されるようなコードそれぞれの役割 
性質:保守性、可用性、信頼性、障害耐性など    
 
ソフトウェア開発ではこれらの要素と性質に対してどのようにアプローチすれば、良い物を作れるかを考えながら開発を行っています。ではドキュメントを書くときはどうでしょうか? 要素と性質という構造に着目すると良いドキュメントを書けるのではないでしょうか? 
ドキュメントの要素と性質 
そこで筆者はドキュメントも要素と性質に構造化することを考えました。そしてその要素と性質をそれぞれ次の5つに整理しました。
要素 
導入:ソフトウェアのインストール方法、環境構築の方法など  
操作:ソフトウェアの実行方法、設定の方法、チュートリアルなど   
参照:ソフトウェアのAPIリファレンス、網羅的な設定項目など  
事例:ユースケースに応じた使い方や設定方法のサンプル、スクリーンショットやデモ動画など  
履歴:これまでの変更履歴、リリースの内容など  
  
性質 
継続性:ドキュメントが継続的に保守されているかどうか 
網羅性:ソフトウェアについて抜けも漏れなく書かれているかどうか 
正確性:ソフトウェアについて正しく書かれているかどうか 
関連性:関係するドキュメントが相互に紐付いているかどうか 
検索性:ドキュメント内を検索できるかどうか 
  
 
このように整理した要素と性質に対してアプローチすることで、良いドキュメントが書けるのではないかと考えています。 
そこで以降では筆者が開発しているESDocというJavaScript向けのドキュメンテーションツールを紹介します。ESDocはこの要素と性質に対してアプローチを行うことで良いドキュメントを書くためのツールを目指しています。
ESDoc 
ESDoc は、JavadocやJSDocなどと同じようにソースコード中の/** @foo bar */というコメントをもとにドキュメント(HTML)を生成するツールです。筆者が2015年4月から開発を行っています。   
最近ではReactiveX/RxJS  、LinkedIn/hopscotch  、Lonlyplanet/rizzo-next  などのプロダクトに採用され始めています。もちろんESDoc自身のドキュメントもESDocで作られています。
ESDoc公式サイト (GitHub )
 
  
このESDocは前述したドキュメントの要素と性質にアプローチするための様々な機能を提供しています。それらの機能について簡単に紹介します。
ドキュメントコメント 
5つの要素のうち「参照」 、つまりAPIリファレンスに対応するための機能がドキュメントコメントです。JavadocやJSDocと同じようにソースコード中に特定の書式でコメントを書くことで、そのコメントをもとにドキュメントを生成する機能です。   
 function  sum ( a ,  b )   { 
   return  a  +  b ; 
 }  
マニュアルの統合 
5つの要素のうち「導入」「 操作」「 事例」「 履歴」に対応するための機能がマニュアルの統合です。この機能はMarkdownで書かれた複数のファイルをドキュメントに組み込むことができます。これによって、インストール方法、操作方法、サンプルなどを自由に組み込めることができます。     
 
 
カバレッジ 
「継続性」を満たすためにドキュメントのカバレッジ機能を提供しています。カバレッジ機能とはテストカバレッジと同じように、ドキュメントが書かれるべきところにどれだけ書かれているかを確認する機能です。ドキュメントのカバレッジを可視化することで、継続的にドキュメントを保守するモチベーションに繋がると考えています。   
このカバレッジ機能について一つ注意してほしいことは、かならずしもカバレッジ100%を目指す必要はないということです。あくまでもドキュメントの継続性を満たすためのものであり、どの程度のカバレッジが必要かは各開発者の判断にお任せします。  
 
 
 
 
Lint 
「正確性」を満たすためにLint機能を提供しています。Lint機能とはドキュメントがコードに対して間違っていないかを検証するための機能です。あくまでもドキュメントとコードの不一致を検証するのであって、ドキュメント自体が正しいかどうかを検証できるものではありません。今のところ、このLintが対象にするのはメソッドのシグネチャとドキュメントが一致しているかどうかだけです。   
 
 
静的解析 
「網羅性」を満たすための静的解析機能を提供しています。静的解析機能とはドキュメントコメントが書かれていないコードからも、そのコードからわかる情報を使ってなるべくドキュメントを生成するというものです。  
例えば次のようにドキュメントが一切書いていないソースコードの場合でも「Class構文によるクラスと継承」「 デフォルト引数による仮引数の型」「 return文による戻り値の存在」「 テンプレートリテラルによる文字列型」を解析することで、ある程度ドキュメントを作成することができます。   
export   default   class   Foo   extends   Bar   { 
  baz ( p  =   'Alice' )   { 
     return   `hello ${p}` ; 
   } 
 }  
テストコードの統合 
「関連性」を満たすためにテストコードの統合機能を提供しています。テストコードの統合機能とはテストコード自体も有益なドキュメントと考え、テストコードとテスト対象を関連付けてドキュメントを生成するというものです。  
テストコードとテスト対象を次のように関連付けると、生成されたFooクラスのドキュメントにはテストコードへのリンクが、テストコードの一覧にはテスト対象へのリンクが自動的に追加されます。  
describe ( 'Foo is useful class' ,   ()=>{ 
   
  it ( 'is useful method' ,   ()=>{ 
     const  foo  =   new   Foo (); 
     assert ( typeof  foo . bar ,   'function' ); 
   }); 
 });  
 
 
 
 
組み込み検索 
「検索性」を満たすために組み込み検索機能を提供しています。組み込み検索機能とはその名前のとおり、ドキュメント内を検索できる機能です。この組み込み検索機能はJavaScriptだけで実装されているため、サーバ側の実装は一切不要です。静的ファイルとしてWebサーバで配信する、もしくはローカルのファイルをブラウザで直接開いて検索できます。    
 
 
ホスティング 
ドキュメントを作成したあと、どこかで公開して誰でも閲覧できるようにする必要があります。そこで手軽にドキュメントを公開できる仕組みとして、ESDoc専用のホスティングサービス を提供しています。このホスティングサービスはESDocを使用しているGitHubのリポジトリURLを登録するだけで利用できます。  
 
 
 
 
まとめ 
ドキュメントを要素と性質に構造化することで、良いドキュメントを書けるのではないかという考えを述べました。そしてその考えをもとに筆者が開発しているESDocというドキュメンテーションツールとその機能を紹介しました。このように、ドキュメントを書く技術に関してはまだまだ発展の余地があります。みなさんもより良いドキュメントを書くためにドキュメントについて考察してみるのはいかがでしょうか。より良いドキュメントはより良いソフトウェアを作ります。  
なお、本稿ではドキュメントの構造を中心にお話しましたが、「 ドキュメントとはそもそもどういうものなのか?」「 何故ドキュメントを書くのか?」「 良いドキュメントとは?」などの話については 『 The Web Explorer 』にて掲載しています。この書籍は多数の著者による共著になっており、ESDoc以外にもWebの最先端の話が収録された書籍になりますので、興味のある方は是非ご覧ください。