GitHubレポジトリのREADMEをAsciidocで書きたい、しかしGFAがinclude文をサポートしない、なんとかしたい



## 解決したい問題

GitHubリポジトリに`README.adoc`という名前のファイルを作って、[Asciidoc](https://asciidoc-py.github.io/index.html)の構文で文書を書くことができる。するとGitHubはAsciidocをHTMLに変換して応答するので、Markdownで書いたREADMEと同じようにきれいに整ったドキュメントをブラウザ上で見ることができる。
一例を挙げよう。

- [article.adoc](https://github.com/kazurayam/IncludeIsNotSupportedInGithubFlavoredAsciidoc-a_workaround/blob/master/article.adoc)

ところが困ったことがひとつある。GitHubのAsciidoc処理系(GFA, GitHub Flavored Asciidoc)が [`include`](https://docs.asciidoctor.org/asciidoc/latest/directives/include/) 文をサポートしていないのだ。例の[article.adoc](https://github.com/kazurayam/IncludeIsNotSupportedInGithubFlavoredAsciidoc-a_workaround/blob/master/article.adoc)の最後のあたりに Include directive という見出しがあるのだが、そこをみてほしい。Asciidocのソースコード上はこう書いてある。

```
== Include directive

Here we include the source code of the file `src/main/java/my/Hello.java`.

[source,java]
----
include::src/main/java/my/Hello.java[]
----
```


GitHubが応答した画面上ではこういうふうに表示されている。

![Include directive not working](https://github.com/kazurayam/IncludeIsNotSupportedInGithubFlavoredAsciidoc-a_workaround/raw/master/docs/images/Include_directive_not_working.png)

こうじゃないんだ、僕がほしいのは。プログラムのコードがドキュメントの中に埋め込まれた形になってほしい。つまりこうだ。

![Include directive as expected](https://github.com/kazurayam/IncludeIsNotSupportedInGithubFlavoredAsciidoc-a_workaround/raw/master/docs/images/Include_directive_as_expected.png)

僕はGitHubレポジトリのREADMEドキュメントをAsciidocで書きたいと思っている。なぜかと言えばAsciidocなら`include`文が使えるはずだから。外部ファイルからプログラムのソースコードを採ってきてREADMEに埋め込みたい。これができればドキュメントを執筆する手間がおおいに省ける。いっぽうMarkdownではコードの埋め込みができない。だから僕はAsciidocでREADMEを書きたいのだ。

なぜGitHubはAsciidocをサポートしつつinclude文だけはサポートしないのだろうか？この問題は4年前から議論になっていて、いまだにopenのままだ。

- [Asciidoctor: support include directives for other asciidoc files #1095](https://github.com/github/markup/issues/1095)

これによればGitHubがinclude文をサポートする見込みは無さそうだ。でも僕はいますぐなんとかしたい。

## 解決方法

前述の[Issue #1095](https://github.com/github/markup/issues/1095)のスレッドのなかで9th June 2021に @chevdoor がなんとかする方法を提案していた。参照の便宜のため、彼の投稿をそのまま引用しておこう。

>This is by far my favorite workaround although it requires a little setup and tooling. Install pandoc and asciidoctor, you can then create a new (executable) .gti/hooks/pre-commit file with the following content:

```
#!/usr/bin/env bash

# convert all the files in the root
find . -iname "*.adoc" -type f -maxdepth 1 -not -name "_*.adoc" | while read fname; do
  target=${fname//adoc/md}
  xml=${fname//adoc/xml}
  echo "converting $fname into $target"

  asciidoctor -b docbook -a leveloffset=+1 -o - "$fname" | pandoc  --markdown-headings=atx --wrap=preserve -t markdown_strict -f docbook - > "$target"
  echo deleting $xml
  rm -f "$xml"
done

# if we find a readme*.md, we rename to README.md
find . -iname "readme*.md" -not -name "README.md" -type f -maxdepth 1 | while read fname; do
  echo Renaming $fname to README.md
  mv $fname README.md
done
```

>The script will look for all the adoc files in the root of your project (except those starting with _) and convert them. Since github picks the asciidoc by default when you have both a README.adoc and a README.md 🤦 , I have to further get my README.adoc out of the way renaming to README_src.adoc) and add extra renaming to the script.
>
>To cheer us up, this option comes with a small benefit: your asciidoc is now linted before you ever commit, so you will spot wrong includes paths before your commit makes it in.

つまりAsciidocで書かれたファイルをHTMLに変換する処理をGitHubに依存するのを止める。ローカルでpandocとasciidocを使いREADME*.adocからREADME.mdに変換しよう。できたREADME.mdをレポジトリにcommitする。GitHub上のサイトを閲覧する人にはREADME.mdを見せればいい。

![sequence](https://github.com/kazurayam/IncludeIsNotSupportedInGithubFlavoredAsciidoc-a_workaround/raw/master/docs/images/sequence.png)

僕はこの回避策を試した。うまくいった。よし、これで行こう。

## 説明

### 僕の環境

- マシン: Mac Book Air
- OS: macOS Monterey v12.0.1
- シェル: Bash

### 依存するソフトウェア

#### pandoc

"[pandoc](https://pandoc.org/), a universal document converter" をHomebrewでMacにインストールした。

```
$ brew install pandoc
```

#### asciidoctor

"[asciidoctor](https://asciidoctor.org/), A fast text processor & publishing toolchain for converting AsciiDoc to HTML5, DocBook & more" をHomebrewでMacにインストールした。

```
$ brew install asciidoctor
```

### プロジェクトに追加したコード

#### シェルスクリプト readmeconv.sh

自分のプロジェクトのルートディレクトリにシェルスクリプトを書いた。名前はなんでもいいのだが [`readmeconv.sh`](https://github.com/kazurayam/IncludeIsNotSupportedInGithubFlavoredAsciidoc-a_workaround/blob/master/readmeconv.sh) とした。 中身は @chevdoor が示してくれたbashスクリプトをコピペしただけ。

このシェルファイルを実行可能にしておく必要がある。

```
$ chmod +x ./readmeconv.sh
```

このシェルをコマンドラインで直に実行することができる。こんなふうに。

```
$ ./readmeconv.sh
converting ./README_.adoc into ./README_.md
deleting ./README_.xml
converting ./article.adoc into ./article.md
deleting ./article.xml
Renaming ./README_.md to README.md
```

これで `README_.adoc` ファイルから `README.md` ファイルが生成された。

もしもAsciidocファイルに記述ミスがあれば`readmeconv.sh`を実行したときにエラーが発生するだろう。エラーを手早く見つけるのに役立つ。

#### Gitフック

gitに[pre-commitフック](https://git-scm.com/book/ja/v2/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%83%95%E3%83%83%E3%82%AF)を設定した。`.adoc`ファイルをエディタで編集した後で`git commit`コマンドを投入した時、commitが実行される直前に `readmeconv.sh` を自動的に実行して`README.md`ファイルを更新するようにした。`<projectDir>/.git/hooks/pre-commit`ファイルにこう書いた。

```
#!/usr/bin/env bash
git secrets --pre_commit_hook -- "$@"

# convert README_.adoc to README.md
./readmeconv.sh
``` 

### ファイル名をどうするか?

`README_.adoc`とするのが良い。`README.adoc`ではダメだった。

GitHubの公式ドキュメント[About READMEs](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-readmes)にこう書いてある。

>If you put your README file in your repository's root, docs, or hidden .github directory, GitHub will recognise and automatically surface your README to repository visitors.

あなたのプロジェクトのレポジトリのルートディレクトリに `README.adoc` と `README.md` と二つのファイルがあったとしよう。ブラウザでそのレポジトリのトップページを開いた時にどっちのREADMEが表示されるだろうか？実際やってみると`README.md`ではなく、`README.adoc`が表示された。`README.adoc`ファイルを作り`readmeconv.sh`シェルで変換して`README.md`ファイルを生成することは問題なくできる。しかしそれだと生成された`README.md`をGitHubが選んでくれないので意味がない。どうすればいいか？

`readmeconv.sh`のbashスクリプトのコードの細部を読んでほしいのだが、このシェルは`README_.adoc`のように余計な文字をくっつけた名前のAsciidocファイル許容し、生成したコードを`README.md`に出力する。GitHubは `README_.adoc`をREADMEドキュメントしては認識しない。GitHubは`README.md`を見つけてそれをレポジトリの表紙として応答するだろう。これでファイル名の問題は解決した。

## 結論

Asciidocの`include`文が使えればソフトウエアプロジェクトのドキュメントを書くのが楽しくなる。`include`文が使えれば、プログラムのコードをREADMEに手作業でコピペする手間が省けるし、プログラムを書きかえたのにREADMEの方を直すのを忘れるおそれも無くなる。GFAがinclude文をサポートしないという問題を回避するために@chevdoorが提案した策は有効だ。これで僕はGitHubプロジェクトのREADMEをAsciidocで書くことができる。良かった、よかった。

## 補足

この記事は[Include directive is not supported in Github-flavored Asciidoc ---- a workaround proposed](https://github.com/kazurayam/IncludeIsNotSupportedInGithubFlavoredAsciidoc-a_workaround)を日本語になおしたものです。

僕はMacでだけ試した。Windowsではどうなんだろうか？bashもpandocもasciidoctorもWindows版がある。それらをWindowsマシンにインストールして適切に設定すれば問題なく動くだろうと思うが、試してはいない。どなたか、やってみて報告いただければありがたいです。