JSDoc/Doxygen/Docstring タグ 対応一覧

## 背景

ドキュメントジェネレータとは、Markdown ソースや、指定の文法で記述されたコメントアウトなどから、プログラムのドキュメントを生成してくれるものです。

:::note
出力ドキュメントフォーマットは Web (HTML) だったり TeX だったり PDF だったり、ものによって対応は様々。(だいたい HTML はきちんと対応している印象)
:::

ここでは後者「コメントアウトから、プログラムのドキュメント」について扱います。

| 言語 | ジェネレータ |
| --- | --- |
| C/C++ など | [Doxygen](http://www.doxygen.jp) |
| JavaScript | [JSDoc](https://jsdoc.app) |
| Python | [Sphinx \(Docstring\)](https://www.sphinx-doc.org) |

:::note
ちなみに Markdown → Web のジェネレーターは GitBook や Docsify などがある。
:::

特に Doxygen と JSDoc については、`@...` というコマンドを書く特徴がよく似ています。ただ、コマンドが全く同じではないため、「どっちが何だっけ･･･」と混合してしまうことがしばしば。

というわけで、引数や返り値など、主なコマンドの対応一覧を作成することにしました。

:::note
Docstring は [Google スタイル](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html)を考えます。
:::

(ちなみに、これらの言語は自分がよく使うというだけの選びです。)

## 一覧

次のように表記します。

* 変数名を書く箇所: `name`
* 型名を書く箇所: `type`
* スペース: `_`

| 内容 | Doxygen | JSDoc | Sphinx (Docstring) |
| --- | --- | --- | --- |
| 簡易説明 | `@brief` | `@summary`<br>(タグ省略可) | 最初の `"""` の行 |
| 詳細説明 | `@details` | `@description`<br>(タグ省略可) | 最初の `"""` に 1行空けた次 |
| ノート | `@note` | *規定なし* | `Note:` |
| 引数 | `@args[in] name`<br>`@args[out] name` | `@param {type} name` | `Args:`<br>`__name (type):` |
| 返り値 | `@return` | `@returns {type}` | `Returns:`<br>`__type:` |
| メンバ変数 | *詳細後述* | *詳細後述* | `Attributes:`<br>`__name (type):`<br>(Args と同じ文法) |
| コード例 | *詳細後述* | `@example` | `Example:` |
| 作者 | `@author` | `@author` | *規定なし* |

※ 表記方法が複数ある場合もありますが、1つのみ掲載

### Doxygen のコード例記述について

`@example` というタグがありますが、JSDoc、Sphinx と違い、ここにはコード例の書かれたソースファイル名を指定します。(`@example func_sample.c` というように。)

コードブロック上に直接コード例を書きたいときは、代わりに `@code` が使えます。(記述例を参照)

### メンバ変数の記述について

Doxygen、JSDoc では、いずれもメンバの宣言の上にドキュメントを記せばタグ不要です。

```cpp
class AnyClass {
  private:
  /**
   * @brief Member description
   */
  int member;
};
```

```js
class AnyClass {
  /**
   * @summary Member description
   */
  #member;
}
```

:::note
Doxygen における `@fn` (関数説明)、`@var` (変数説明) も同様で、関数定義の真上に書けばタグ不要です (下の記述例のように)。

`@fn` については、**必須なときだけ**使ってほしいと[公式ドキュメント](http://www.doxygen.jp/commands.html#cmdfn)にあります。
:::

:::note warn
プライベートメンバ・メソッドは、デフォルトでドキュメント出力されません。出力させるには、設定の変更またはビルド時にオプションが必要です。
:::

JSDoc では、スタティックメンバには `@memberof ClassName` を追加で書きます。そうすると、ドキュメントに static として表示してくれます。(JSDoc 4.0.2 で動作確認)

```js
class AnyClass {
  /**
   * @summary Member description
   *
   * @memberof AnyClass
   */
  static member = 2;
}
```

なお、スタティックメソッドは追加の記述無しでも static として表示してくれます。(何で･･･？)

## 記述例

### Doxygen (C/C++)

```c
/**
 * @file func.c
 * ↑これ無しだとデフォルトでドキュメント化されない
 *
 * @brief Source file description
 *
 * @details
 * Source file detail description
 *
 * @author aKuad
 */

/**
 * @brief Function description
 *
 * @details
 * Function detail description
 * 
 * Example:
 *
 * @code
 * int res = func(3);
 * // 3
 * @endcode
 *
 * @note
 * Note of function
 *
 * @param[in] arg Argument description
 * @return Return description
 */
int func(int arg) {
  return arg;
}
```

ドキュメント表示例:

https://akuad.github.io/docs-gen-samples/doxygen/index.html

<details>
<summary>スクリーンショット</summary>

![sample-doxygen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/da7fcdb8-cb61-2d00-0290-fd4ef1aa76ae.png)

</details>

### JSDoc

```js
/**
 * @file Source file description
 * ↑トップページへの表示に必要
 *
 * @description
 * Source file detail description
 *
 * @author aKuad
 */

/**
 * @summary Function description
 *
 * @description
 * Function detail description
 *
 * @example
 * res = func(3);
 * // 3
 *
 * @param {number} arg Argument description
 * @returns Return description
 */
function func(arg) {
  return arg;
}
```

ドキュメント表示例:

https://akuad.github.io/docs-gen-samples/jsdoc/index.html

<details>
<summary>スクリーンショット</summary>

![sample-jsdoc-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/d7951745-5818-09a7-9707-d22e8410213f.png)

`@file` 横の概要記述 (または `@summary`) と `@description` を同時に記述すると、`@description` しか反映されないようです。(JSDoc 4.0.2 で動作確認)

![sample-jsdoc-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/6b96f07d-2bc7-9151-1645-afb37aa921bd.png)

`@summary` と `@description` の表示の違いは特に見られないようです。

</details>

### docstring

```py
"""Source file description

Source file detail description

"""

def func(arg: int):
  """Function description

  Function detail description

  Example:
    Examples here::

      ret = func(3)

  Note:
    Note of function

  Args:
    arg(int): Argument description
  
  Return:
    int: Return description

  """
  return arg

```

ドキュメント表示例:

https://akuad.github.io/docs-gen-samples/sphinx/index.html

<details>
<summary>スクリーンショット</summary>

![sample-sphinx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540894/c9d12a9f-833b-73a5-851e-8647829c4623.png)

</details>

## 付録 - 全タグ一覧

Doxygen タグ一覧

http://www.doxygen.jp/commands.html

JSDoc タグ一覧 (トップページ)

https://jsdoc.app

Docstring セクション一覧

https://www.sphinx-doc.org/ja/master/usage/extensions/napoleon.html#docstring-sections

## 付録 - ビルドコマンド例

### Doxygen

```sh
sudo apt install doxygen
```

```sh
ls
# func.cpp

doxygen -g
ls
# Doxyfile  func.c

vim Doxyfile
# 任意のエディタで各種設定をする
# 出力先の指定は
#   OUTPUT_DIRECTORY       = ./docs
# クラスのプライベートメンバも出力するには
#   EXTRACT_PRIVATE        = YES

doxygen
ls
# Doxyfile  func.c  docs
# ./docs/html に HTML ページが生成される
```

### JSDoc

```sh
npm install -g jsdoc
```

```sh
ls
# func.js

jsdoc -d docs *
# クラスのプライベートメンバも出力するには -p を付与
#   jsdoc -p -d docs *

ls
# func.js  docs
# ./docs/html に HTML ページが生成される
```

### Sphinx

```sh
pip install sphinx
```

```sh
ls
# func.py

sphinx-quickstart docs
# 表示に従って各設定を入力
# ここではビルドディレクトリは分けない設定で

ls
# func.py  docs

vim docs/conf.py
# 任意のエディタで各種設定をする, 以下は最低限でも必須
# パス追加
#   import os, sys
#   sys.path.insert(0, os.path.dirname('../'))
# 拡張の追加
#   extensions = ['sphinx.ext.autodoc', 'sphinx.ext.napoleon']

cd docs
sphinx-apidoc -f -o ./ ../
# クラスのプライベートメンバも出力するには -P を付与
#   sphinx-apidoc -f -P -o ./ ../
sphinx-build ./ ./_build/

# ./docs/_build に HTML ページが生成される
```