モダンFortran向けドキュメント自動生成ツールFORDの使い方

# 概要
FORDはFORtran Documenterの略で，モダンFortranプログラム向けのドキュメント自動生成ツールです．Fortranプログラムのドキュメント生成において，Doxygenでは不十分であり，かつ代替ツールが無いことが，FORD開発のきっかけだったようです．

FORDは，ソースコードから変数，派生型定義，手続き（関数およびサブルーチン），モジュールの情報を抽出し，ドキュメントを生成します．それらの情報に，コメントで追加の情報を付加することができます．コメントには，MarkdownやLaTeX記法を利用できます．また，関数の呼出し関係やモジュールの参照関係，派生型の継承関係を図示することができます．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/2808d215-41bb-e097-db12-e0471af12cb8.png)

FORDは多機能ですが，わかりにくい部分や落とし穴もあります．

- FORDがドキュメントと称しているのは，プログラミングインタフェース情報です．
    - プログラミング言語におけるリファレンスに相当
- インストール方法や背景理論，サンプルなど，いわゆるアプリケーションにおけるドキュメントは，ページと呼ばれています．
- ドキュメントの出力ディレクトリの中身は，FORDでドキュメントを生成する際に何の断りもなく削除されます．

本記事では，FORDの用語に沿って，FORDが生成するプログラミングインタフェース情報をドキュメント，それ以外をページと称します．

# 環境
## Windows
- Windows 10 Pro 20H2
- Python 3.8.5 (Anaconda Individual Edition 4.10.1)
- FORD 6.0.0
- python-graphviz 0.16
- graphviz 2.38.0

## Linux
- Ubuntu 18.04 (on WSL)
- Python 3.6.9
- FORD 6.0.0
- graphviz 2.40.1

# FORDのインストール

## FORD本体のインストール
### condaを用いたインストール
（2022年11月6日追記）

FORDのインストールに`conda`が利用できるようになりました．
`conda-forge`をチャンネルに登録し，`conda`を使ってインストールできます．

Windowsの場合は，Anaconda Promptを管理者権限で起動して，

```console
conda config --add channels conda-forge
conda config --set channel_priority strict
```

```console
conda install ford
```

を実行します．

日本語を含むファイルを処理する場合，日本語のエンコードに起因してFORDがエラーになる場合があります．**Windowsで日本語エンコードにUTF-8を用いる場合，環境変数`PYTHONUTF8`の値を`1`に設定してください**．

### pipを用いたインストール

Windowsの場合は，Anaconda Promptを管理者権限で起動して，

```console
pip install FORD
```

を実行します．

Ubuntuの場合は，`sudo`を付けて実行します．

```console
sudo pip install FORD
```

日本語を含むファイルを処理する場合，日本語のエンコードに起因してFORDがエラーになる場合があります．**Windowsで日本語エンコードにUTF-8を用いる場合，環境変数`PYTHONUTF8`の値を`1`に設定してください**．

## graphvizのインストール（Windowsのみ）
FORDは，関数の呼出し関係やモジュールの参照関係，派生型の継承関係の関係図の生成にgraphvizを利用します．`pip`でFORDをインストールすると，graphviz[^python_graphviz]もまとめてインストールしてくれるのですが，Windowsの場合は，Windows上で動くgraphvizのバイナリもインストールする必要があります．

[^python_graphviz]: conda上では，python-graphvizと表示されます．

Windowsの場合，2通りの方法でバイナリをインストールできます．

- 正式なWindows版

[公式ページ](http://www.graphviz.org)からインストーラをダウンロードしてインストールした後，環境変数PATHにインストールディレクトリを追加します．

- `conda`

**`conda`を利用してFORDをインストールした場合，graphvizのバイナリも併せてインストールされます．graphvizのインストールに関しては何もする必要はありません．** （2022年11月9日追記）

`conda`を利用してインストールします．この方法は，`pip`と`conda`を混ぜることになるので，仮想環境を作って実行してください．

```console
conda install graphviz
```

### 動作確認
graphvizをインストールした後，graphvizのバイナリがインストールされたディレクトリをパスに追加します．
著者の場合は，Anacondaを全ユーザが利用できる設定でインストールしているので，Anacondaは`C:\ProgramData\Anaconda3`にインストールされています．`conda`でインストールしたgraphvizは，Anacondaのインストールディレクトリ以下の`Library\bin\graphviz`にインストールされるので，`C:\ProgramData\Anaconda3\Library\bin\graphviz`を環境変数PATHに追加します．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/22c8f8a3-7ba9-bbdc-0ce4-929bf1f91c8a.png)

その後，コマンドプロンプトを起動して，`dot -V`を実行します．

```console
>dot -V
dot - graphviz version 2.38.0 (20140413.2041)
```

などといった表示が現れれば，インストールは成功です．

# FORDによるドキュメント生成
## サンプルソースファイル
サンプルとして，エラトステネスのふるいのソースを用います．

<details><summary>main.f90</summary><div>

```Fortran:main.f90
program main
    use, intrinsic :: iso_fortran_env
    implicit none

    integer(int32), allocatable :: primes(:)

    call generate_primes_up_to(100, result=primes)
    print *, "number of primes", size(primes)
    print *, "generated primes", primes(:)

contains
    subroutine generate_primes_up_to(num, result)
        use, intrinsic :: iso_fortran_env
        implicit none
        integer(int32), intent(in) :: num
        integer(int32), allocatable, intent(inout) :: result(:)

        integer(int32), allocatable :: number(:)

        if (num >= 2) then
            call initialize(number, num)

            call sieve(number)

            call extract_primes(number, result)

            deallocate (number)
        else
            allocate (primes(0))
        end if
    end subroutine generate_primes_up_to

    subroutine initialize(number, num)
        use, intrinsic :: iso_fortran_env
        implicit none
        integer(int32), allocatable, intent(inout) :: number(:)
        integer(int32), intent(in) :: num

        integer(int32) :: i

        allocate (number(2:num), source=[(i, i=2, num)])
    end subroutine initialize

    subroutine sieve(number)
        use, intrinsic :: iso_fortran_env
        implicit none
        integer(int32), intent(inout) :: number(2:)

        integer(int32) :: i, num

        num = maxval(number)

        do i = 2, int(num**0.5)
            if (number(i) /= 0) then
                number(i+i::i) = 0 !&
            end if
        end do
    end subroutine sieve

    subroutine extract_primes(number, result)
        use, intrinsic :: iso_fortran_env
        implicit none
        integer(int32), intent(in) :: number(2:)
        integer(int32), allocatable, intent(inout) :: result(:)

        result = pack(array=number, mask=(number /= 0))
    end subroutine extract_primes
end program main
```

</div></details>


## FORDの実行

FORDを用いてドキュメントを生成するには，FORD用の設定ファイルを作成し，それをコマンドライン引数としてFORDを実行します．

```
ford 設定ファイル.md
```

設定ファイルは生成されるドキュメントのトップページも兼ねるので，設定ファイルには2種類の情報を書く必要があります．

1. FORDの設定
1. トップページに書くべき内容

### FORDの設定
設定ファイルに記述できる内容は非常に多いので，詳細は[公式ページ](https://github.com/Fortran-FOSS-Programmers/ford/wiki/Project-File-Options)に任せて，必須と思われる内容を挙げていきます．

設定は全て `設定名: 値`で指定します．
なお，FORDは設定の途中に空行など設定以外の情報が入っていると，その時点で設定の読み込みを止める（以降はトップページの内容として扱う）ので，**絶対に空行など設定以外の情報を入れないでください**．

#### プロジェクト情報
- `project` プロジェクトの名前．
- `summary` プロジェクトの概要．
- `license` ドキュメントのライセンス．以下から選択
    - `by`, `by-nd`, `by-sa`, `by-nc`, `by-nc-nd`, `by-nc-sa`, `gfdl`, `opl`, `pdl`, `bsd`

その他，必要があれば，githubやbitbucket, sourceforgeなどのURL，プロジェクトのWebサイトやロゴ（アイコン）などを指定できます．

#### 著者情報
- `author` 著者名

その他，著者の簡単な紹介，e-mailアドレスや各種SNSアカウントを指定できます．

#### ディレクトリ情報
- `src_dir` ソースファイルのディレクトリ（標準は設定ファイルのあるディレクトリをカレントとして`./src`）
- `output_dir` 生成されたドキュメントの出力ディレクトリ（標準は設定ファイルのあるディレクトリをカレントとして`./doc`）

ディレクトリの指定には注意が必要です．
概要でも述べたとおり，FORDが生成するドキュメントは，プログラミングインタフェース情報です．インストール方法や背景理論，サンプルなど，いわゆるアプリケーションにおけるドキュメントを`./doc`に置くことが多いでしょうが，**`output_dir`を指定しないと，`./doc`に置かれているファイルが全て消去されてしまいます**．

いくつかのプロジェクトでは，いわゆるアプリケーションにおけるドキュメントを`./doc`に置き，FORDが生成するドキュメントを`./api-doc`など`./doc`とは異なるディレクトリに出力し，FORDが生成するドキュメントはリポジトリに登録しないようにしています．

本記事もこれにならい，FORDが生成するドキュメントは`./api-doc`に出力することにします．

#### 設定ファイルの例
上記で挙げた設定を記述して，Fordでドキュメントを生成してみます．設定ファイル名は`api-doc-ford-settings.md`としました．

```Markdown:api-doc-ford-settings.md
src_dir: ./src
output_dir: ./api-doc
project: エラトステネスのふるい
summary: エラトステネスのふるいを用いて素数を生成する
author: implicit none
license: by-nc
```

ファイルの配置は下記のようになっています．

```
.
├── src
│   └── main.f90
└── api-doc-ford-settings.md
```

FORDの設定ファイルがあるディレクトリで，FORDを実行します．

```console
>ford api-doc-ford-settings.md
Reading file src\main.f90

Processing documentation comments...
Correlating information from different parts of your project...

Creating HTML documentation...
Creating search index...
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 6/6 [00:00<00:00, 22.70/s]

Writing resulting documentation.
```

カレントディレクトリに`api-doc`フォルダが出力されます．
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/8d7e05e2-0836-3a3c-a532-8e9562cc8610.png)


`api-doc\index.html`を開くと，下図のようなドキュメントが生成されたことが確認できます．
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/ad4bb2ad-e6a9-a1f4-376c-4fc6669078f1.png)

Source Filesはソースファイルの一覧，Proceduresには手続き（関数およびサブルーチン）の一覧が現れています．

Source Filesにあるmain.f90のリンクをクリックすると，シンタックスハイライト付きでソースファイルを確認できます．
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/04b68440-6f4b-802e-a351-2fe945ea67f8.png)

Proceduresのリンク，例えば`generate_primes_up_to`をクリックすると，インタフェース情報を確認できます．
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/d9b74b10-29c3-07eb-8a9d-55731a6e076e.png)

設定ファイルに`graph: true`を追加して再度FORDでドキュメントを生成すると，他のモジュールや関数との関係が図示されます．何度も書きますが，設定を書く際は空行などを入れないようにしてください．
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/b51a79fd-8bff-5cb1-cf10-0d2ee189481e.png)

## 注釈による情報の追加
FORDでは，ソースファイルに注釈を付けることで，生成するドキュメントに情報を追加することができます．Documentation Markerとよばれる記号をコメントに続けて付けることで，注釈を記述できます．

FORDでは，4種類のDocumentation Markerを定めています．

|FORDの設定名|Documentation Marker（標準，変更可能）|
|:--|:--|
|`docmark`|`!`|
|`docmark_alt`|`*`|
|`predocmark`|`>`|
|`predocmark_alt`|&#124;[^vbar]|
[^vbar]: 縦棒がMarkdownだと表の区切りと重なるので，`&#124;`を使って記述しています．

Documentation Markerは設定で変更可能ですが，`#`は注釈にMarkdownを使うときに混乱しますし，`@`は後述するFORDの拡張機能と重複します．`$`はOpenMPのディレクティブやディレクティブセンチネル`!$`と衝突します．ソースをfprettifyで整形する場合は，`&`が衝突します．そのため，代替記号の選択肢はあまりないように思います．

### 変数，手続きに対する注釈
`docmark`は，コメント記号に続けてDocumentation Markerを書くことで，以降のコメントが上の行に書かれた項目の注釈であることを意味します．コメントのインデントは必須ではありません．読みやすさのためにインデントしています．

```Fortran
integer(int32), intent(in) :: num
    !! 素数の上限値
```

と書くと，`素数の上限値`が`num`の注釈として扱われます．この状態でFORDによって処理すると，ドキュメントの引数に注釈が追加されます．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/4ca354a4-3567-de89-6012-b02618752fec.png)

`docmark`によって注釈の対象となるのは1行のみです．複数行にわたる注釈を記述したい場合は，複数行にわたって`docmark`を付ける必要があります．

```Fortran
integer(int32), intent(in) :: num
    !! 素数の上限値<br>
    !! 0以上の整数．負の数は受け付けない
```

![docmark_multline.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/da0cdbdc-28d2-9bfc-42a0-0fb7c2ac11da.png)

行数が長くなると，`docmark`を付けるのも大変になるので，複数行にわたる注釈を付けやすくするために`docmark_alt`を利用します．

```Fortran
integer(int32), allocatable, intent(inout) :: result(:)
    !* 生成された素数<br>
    !  要素数は素数の個数に等しく，小さい素数から順番に格納される
```

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/26ff7e29-420e-5f26-0746-b3680f2ac888.png)

`docmark`や`docmark_alt`とは逆に，注釈を付けたい項目の上に注釈を書きたい場合もあります．その場合は，`predocmark`か`predocmark_alt`を用います．

```Fortran
!> 素数の上限値<br>
!> 0以上の整数．負の数は受け付けない
integer(int32), intent(in) :: num

!| 生成された素数<br>
! 要素数は素数の個数に等しく，小さい素数から順番に格納される
integer(int32), allocatable, intent(inout) :: result(:)
```

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/03250a79-9c5a-08f5-3af6-2f0c3b4c0bd3.png)

### それ以外の注釈
変数や手続きのように，注釈を付ける項目がある場合は，`docmark`や`predocmark`の挙動の違いは重要です．TODOや既知のバグ，あるいは関数の使用例を書く場合は，どれを使っても問題ありません．

下の例では，`predocmark_alt`を利用しています．関数の中ほどに書いた注釈には，近くに関連付ける項目（関数や手続き）がありません．これらは，ドキュメント中に本文として表示されます．`@todo`は，FORDの機能です．詳しくは後述します．

```Fortran
!|第1引数で指定された数を上限として，その数までの素数を生成する．
! 第2引数は，生成された素数を格納する．
! 素数生成のアルゴリズムにはエラトステネスのふるいを用いる．
subroutine generate_primes_up_to(num, result)
    use, intrinsic :: iso_fortran_env
    implicit none
    integer(int32), intent(in) :: num
        !! 素数の上限値        <br>
        !! 0以上の整数．負の数は受け付けない
    integer(int32), allocatable, intent(inout) :: result(:)
        !! 生成された素数<br>
        !! 要素数は素数の個数に等しく，小さい素数から順番に格納される

    integer(int32), allocatable :: number(:) ! 2からnumまでの数表

    !|##例
    !```Fortran
    !program main
    !   integer(int32),allocatable :: primes(:)
    !   call generate_primes_up_to(num=10, result=primes)
    !   ! primes = [2, 3, 5, 7]
    !end program main
    !```

    if (num >= 2) then
        call initialize(number, num)

        call sieve(number)

        call extract_primes(number, result)

        deallocate (number)
    else
        ! numが1以下であれば，素数は0個
        !!@todo `num<0`の場合に警告を出す
        allocate (primes(0))
    end if
end subroutine generate_primes_up_to
```

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/20c7f0ae-a71b-76aa-2f5b-60e63bd4a3d9.png)

## FORDで利用できる記法
FORDで注釈を付ける際，Markdown，LaTeXおよびFORD独自の拡張記法が利用できます．

LaTeX記法を用いる場合，`$...$`は対応しておらず，`\(...\)`を利用するように指示されています．

FORD独自の拡張記法には，`@note`, `@warning`, `@todo`, `@bug`環境があります．これらの使い方は全て同じで，この環境を用いると，FORDで処理された際に，強調表示されます．

`@todo num<0の場合に警告を出す`のように1行で書くこともできます．複数行にわたって記述したい場合は`@環境名~@end環境名`で囲みます．FORDの注釈の処理が甘いので，1行であっても複数行用の記述を用いた方が，想定通りの結果を得られます．

```
@todo

- リファクタリング
- コマンドライン引数への対応

@endtodo
```

その他，ドキュメント内の要素にリンクを張るための[`[[]]`という記法](#ドキュメント内リンク)も利用できます．それ以外にも多くの記法・機能があるので，詳しくは[公式ページ](https://github.com/Fortran-FOSS-Programmers/ford/wiki/Writing-Documentation)を確認してください．

### トップページの作成
さて，FORDの設定ファイルはトップページを兼ねていることを既に説明しました．トップページに何も情報がないのも見栄えが悪いので，FORDの記法を利用してトップページに情報を追記してみます．

```Markdown:api-doc-ford-settings.md
src_dir: ./src
output_dir: ./api-doc
project: エラトステネスのふるい
summary: エラトステネスのふるいを用いて素数を生成する
author: implicit none
license: by-nc
graph: true

エラトステネスのふるいを用いて素数を生成する．

@warning
Work in progress
@endwarning

## 素数生成の手順
エラトステネスのふるいでは，ある数\(n\)が与えられた時に，\(2\)から\(n\)までの数表を用意し，まず\(2\)の倍数を数表から取り除く．
この作業をふるい落としと呼ぶ．数字を\(3, 4, 5...\lfloor\sqrt{n}\rfloor\)と順次変えて，
その数の倍数を数表からふるい落とし，最後までふるい落とされなかった数を素数として扱う．

@note
このプロジェクトでは，

- 数表を用意することを初期化（対応する手続きは[[initialize(procedure)]]）
- 倍数を数表から取り除くことをふるい落とし（対応する手続きは[[sieve(procedure)]]）
- ふるい落とされなかった数を取り出すことを素数の抽出（対応する手続きは[[extract_primes(procedure)]]）

と呼ぶ．
@endnote

@todo

- リファクタリング
- コマンドライン引数への対応
- 他

@endtodo

@bug
現在の所バグは見つかっていない．
@endbug
```

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/ab41a191-33d5-f793-a7b4-bc20961369d0.png)

`[[initialize(procedure)]]`はFORDの独自拡張記述で，ドキュメント内の`intialize`という名前の手続きのページにリンクを張ります．

個人的には，ドキュメント生成ツールの設定とトップページの内容を一つのファイルに書くのは，あまりよくないと感じています．FORDの仕様上，設定とトップページを分けることはできませんが，FORDの拡張機能の一つであるMarkdown-include拡張を利用すると，擬似的に設定とトップページを分けることができます．

Markdown-include拡張では，`{!ファイル名.md!}`とすることで，指定したファイルの中身で当該行を置き換える事ができます．つまり，トップページの内容は，`api-doc-index.md`等設定とは別のMarkdownファイルに作成し，設定ファイル内に`{!api-doc-index.md!}`と書いておくことで，FORDが処理する際に設定ファイル内にトップページの内容が展開されるようになります．

```Markdown:api-doc-ford-settings.md
src_dir: ./src
output_dir: ./api-doc
project: エラトステネスのふるい
summary: エラトステネスのふるいを用いて素数を生成する
author: implicit none
license: by-nc
graph: true

{!api-doc-index.md!}
```

```Markdown:api-doc-index.md
エラトステネスのふるいを用いて素数を生成する．

@warning
Work in progress
@endwarning

## 素数生成の手順
エラトステネスのふるいでは，ある数\(n\)が与えられた時に，\(2\)から\(n\)までの数表を用意し，まず\(2\)の倍数を数表から取り除く．
この作業をふるい落としと呼ぶ．数字を\(3, 4, 5...\lfloor\sqrt{n}\rfloor\)と順次変えて，
その数の倍数を数表からふるい落とし，最後までふるい落とされなかった数を素数として扱う．

@note
このプロジェクトでは，

- 数表を用意することを初期化（対応する手続きは[[initialize(procedure)]]）
- 倍数を数表から取り除くことをふるい落とし（対応する手続きは[[sieve(procedure)]]）
- ふるい落とされなかった数を取り出すことを素数の抽出（対応する手続きは[[extract_primes(procedure)]]）

と呼ぶ．
@endnote

@todo

- リファクタリング
- コマンドライン引数への対応
- 他

@endtodo

@bug
現在の所バグは見つかっていない．
@endbug
```

Markdown-include拡張でincludeされるファイルは，標準で設定ファイルと同じディレクトリから探されます．ディレクトリを変えたい場合は，`md_base_dir:`で設定ファイルからの相対パスを指定することができます．

## ページの生成
FORDがドキュメントと称しているのはプログラミングインタフェース情報で，インストール方法や背景理論，サンプルなど，いわゆるアプリケーションにおけるドキュメントは，ページと呼ばれているのでした．

FORDでは，ページも生成できます．ページを生成するには，設定で`page_dir`を指定し，`page_dir`にMarkdown（およびFORDがサポートする記法）で内容を記述します．

ページの生成では制約が二つあります．

1. ページの基となる`.md`ファイルには，メタデータを記述する必要がある．
1. `page_dir`およびサブディレクトリには，`index.md`という名前のファイルが必要

メタデータは3種類あります．
- `title:` ページタイトル（必須）
- `author:` ページの生成者（オプション）
- `date:` ページの生成日（オプション）

`page_dir`およびサブディレクトリには，`index.md`という名前のファイルが必要ですが，その`title:`はファイル名と一致させる必要はありません．

リポジトリのREADME.mdやLICENSEをページに含める場合，FORDのMarkdown-include拡張を用いると，同じ内容を2カ所に記述する必要がなくなります．

下記のように，LICENSEとREADME.mdを追加し，docにページの基となるファイルを用意しました．

```
.
├── src
│   └── main.f90
├── doc
│   ├── index.md
│   └── license.md
├── api-doc-ford-settings.md
├── api-doc-index.md
├── LICENSE
└── README.md
```

```Markdown:README.md
# Sieve of Eratosthenes

## Goals and Motivations

## Scope

## Install

## Usage

## Contributions

## Links
```

```:LICENSE
Copyright (c) 2021 implicit_none

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```

```Markdown:./doc/index.md
---
title: Read Me
---

{!README.md!}
```

```Markdown:./doc/license.md
---
title: license
---

{!LICENSE!}
```

設定の部分に，`page_dir: ./doc`を追記してFORDでドキュメントを生成してみると，ページ上部のメニューにRead Meが追加されていることが確認できます．
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/acc5e2c4-b75b-092b-56d8-232d97fee37a.png)

Read Meのリンクをクリックすると，ページのトップ（index.mdから生成された`api-doc/page/index.html`）に移動します．README.mdの内容が挿入されていることが確認できます．

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/97ec206b-4908-6cd5-2762-9b085aad9c3e.png)

licenseのリンクをクリックした移動先ページでも同様に，LICENSEの内容が挿入されています．
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224040/08f5cacf-6ab3-3813-e3c7-5ee68770f1c3.png)

# ドキュメント内リンク
FORDには，ドキュメント内のモジュールや手続，変数へのリンクを簡単に記述できる独自拡張`[[]]`が用意されています．このドキュメント内リンクの一般的な書式は下記のようになっています．

```markdown
[[リンクを張りたい項目を含む単位の名前（単位の種類）:リンクを張りたい項目(項目の種類)]]
```

最も単純な書き方は`[[リンクを張りたい項目]]`です．例えば`[[initialize]]`などと書きます．しかしこの書き方では，同じ名前で異なる種類の項目があったときに問題が生じます．ユーザ定義派生型にリンクを張りたいのか，built-inコンストラクタをオーバーロードしたコンストラクタにリンクを張りたいのかが自明ではありません．そこで，`(項目の種類)`を指定することで，何にリンクを張りたいのかを明らかにします．

項目の種類として，下記が指定できます．

- `variable`: 変数
- `type`: ユーザ定義派生型
- `constructor`: コンストラクタ
- `interface`: インタフェース
- `absinterface`: 抽象インタフェース (abstract interface)
- `subroutine`: サブルーチン
- `function`: 関数
- `final`: 後始末手続 (finalization procedure)
- `bound`: 型束縛手続 (type-bound procedure)
- `modproc`: モジュール手続，総称名(generic interface block)
- `common`: common block

同様に，異なるプログラム単位に同じ名前の項目があった場合にも，問題が生じます．例えば，異なるモジュールに同じ名前の手続が定義されている場合です．その場合には，`リンクを張りたい項目を含む単位の名前:`を追加で指定することにより，どの項目を指しているのかを明確にします．

リンクを張りたい項目を含む単位の種類も指定できます．サブルーチンと関数の厳密な区別は行われず，`procedure`, `subroutine`, `function`, `proc`はどれを用いても問題ありません．`interface`は抽象インタフェースも指すことができます．

- `procedure`: サブルーチンおよび関数
- `subroutine`: サブルーチン
- `function`: 関数
- `proc` サブルーチンおよび手続
- `interface`: インタフェース
- `absinterface`: 抽象インタフェース(both of which are for abstract interfaces)
- `block`: FORTRAN77のblock data
- `type`: ユーザ定義派生型
- `file`: ファイル
- `module`: モジュール
- `program`: メインルーチン

## 例
`module A`と`module B`に同じ名前のサブルーチン`exec`が定義されており，ドキュメント内で`module B`の`exec`の箇所にリンクを張りたい場合は，`[[B:exec]]`と書きます．より正確に書くと，`[[B(module):exec(subroutine)]]`です．

ユーザ定義派生型`T`の成分として，ユーザ定義派生型`U_t`の変数`u`が宣言されており，その`u`の箇所にリンクを張りたい場合，`u`の名前がプログラム全体を通して唯一の名前であれば，`[[u]]`と書けます．他にも同じ名前がある場合には，区別するためにユーザ定義派生型の名前を付けて`[[T:u]]`とします．このとき，それぞれの項目を書くと`[[T(type):u(variable)]]`となります．

# VSCodeのTask
コマンドをいちいち入力するのも億劫なので，VSCodeの`tasks.json`にタスクとして登録します．FORDの実行ファイルと設定ファイルの名前があればよいので，設定自体は非常に簡単です．`"command"`の部分は著者の環境です．

```json
        {
            "label": "generate document",
            "type": "shell",
            "options": {
                "cwd": "${workspaceRoot}"
            },
            "command": "C:\\ProgramData\\Anaconda3\\Scripts\\ford.exe",
            "args": [
                "api-doc-ford-settings.md"
            ],
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": true,
                "panel": "shared",
                "showReuseMessage": true,
                "clear": false
            },
            "problemMatcher": [],
        }
```

このようにタスクとして登録するのであれば，FORDの設定ファイルは名前を固定するようにルールを定めた方がよいでしょう．

# おわりに
FORDの使い方を，一通り簡単に紹介しました．これだけでもFORDを使ってドキュメントを生成できますが，FORDは他にも多くの機能を持っています．色々と試して，FORDのベストプラクティスを見つけたいと思います．

## FORDの注意点まとめ

- FORDの生成するドキュメントは，プログラミングインタフェース情報である
- アプリケーションのドキュメントは，FORDではページとよばれる
- 標準の出力ディレクトリは`./doc`であり，生成のタイミングで中身を全て消す
    - アプリケーションのドキュメントを`./doc`に作成している場合は，設定ファイルで出力ディレクトリを指定する
- FORDの設定ファイルは，設定と生成されるドキュメントのトップページを兼ねる
- 設定を記述する部分で，途中に空行などの設定以外の情報が入っていると，その時点で設定の読み込みを止めるので，**絶対に空行など設定以外の情報を入れない**
- ソースファイルに日本語が含まれる場合は，OS標準の日本語エンコーディングとファイルの日本語エンコーディングの違いに注意し，必要があればPythonの環境変数を設定する
- FORDの設定ファイル名は，`出力ディレクトリ名-ford-settings.md`など名前を固定すると楽