Asciidoctor.jsでプレビューしながら編集する

AsciiDoc の処理系といえば、Ruby の [Asciidoctor](https://rubygems.org/gems/asciidoctor) が有名です。しかし、JavaScript な [Asciidoctor\.js](https://asciidoctor.org/docs/asciidoctor.js/) もあります。本記事は後者を使ってみた記録です。

## 関連

- https://qiita.com/Yamane@github/items/090973185791c174532f : ブラウザで生成結果を見つつ、AsciiDoc 文書を編集できます。反映までの時間が短かく、快適に編集できます。
- https://qiita.com/dbgso/items/927c4e3d0f739855f8d6 : こちらは Ruby 版の Asciidoctor を使っています。Docker で手軽に使い始められるところが良いですね。

## バージョン

```shell-session
$ asciidoctor -v
Asciidoctor 2.0.10 [https://asciidoctor.org]
Runtime Environment (ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]) (lc:UTF-8 fs:UTF-8 in:UTF-8 ex:UTF-8)

$ npm -v
6.14.8
```

## きっかけ

注意：下記の内容はGitHubのissueにありました．将来的に本体に実装される可能性も高いでしょう[^asciidoctor-watch]．

[^asciidoctor-watch]: “Guard mode for asciidoctor command · Issue #182 · asciidoctor/asciidoctor,” GitHub. https://github.com/asciidoctor/asciidoctor/issues/182 (accessed Jan. 22, 2021).

Ruby 版の Asciidoctor には監視機能がありません。つまり、AsciiDoc ファイルに変更があった際、自動的に変換処理が行われるようにするオプションを、`asciidoctor`コマンドに指定することはできません。

```shell-session
$ asciidoctor --watch main.adoc # こうできたらいいなぁ……
```

監視機能を進めると、プレビュー機能になります。ここでのプレビュー機能とは、生成結果が変更されたタイミングでその表示に反映されることです。HTML ファイルの場合、ブラウザで再読込する手間が省けます。

今回は HTML ファイルを生成し、プレビューすることを考えます。

## Ruby 版 Asciidoctor で

[Editing AsciiDoc with Live Preview](https://asciidoctor.org/docs/editing-asciidoc-with-live-preview/) に紹介されていますが、Firefox 79.0 (64bit) では拡張機能が使えなくなっているようです。ただ、[`guard`という gem](https://github.com/guard/guard) は AsciiDoc から HTML への変換過程で使えそう。

`asciidoctor`, `guard`, `guard-shell` をインストールします。

```shell-session
$ bundle init
$ bundle add asciidoctor guard guard-shell
```

`main.adoc`という AsciiDoc ファイルを監視します。

```rb:Guardfile
require 'asciidoctor'

guard :shell do
  watch('main.adoc') { |m| Asciidoctor.convert_file m[0] }
end
```

Guard を起動します。

```shell-session
$ guard
```

AsciiDoc ファイルに変更があるたびに、HTML ファイルが更新されるようになりました。

### `live-server`登場

npm に [`live-server`](https://www.npmjs.com/package/live-server) というパッケージがあり、これでプレビューを実現できます。使い方は簡単。

```shell-session
$ live-server
```

`guard`周りでもできそうですが、これが明快かと思います。

## Asciidoctor\.js で

`live-server`で視点が変わりました。監視は [`npm-watch`](https://www.npmjs.com/package/npm-watch) に任せましょう。

```shell-session
$ npm i -D asciidoctor live-server npm-watch
```

`package.json` に [npm scripts](https://docs.npmjs.com/misc/scripts) を書きます。

```json:package.json
{
  "watch": {
    "convert": "main.adoc"
  },
  "scripts": {
    "start": "live-server",
    "watch": "npm-watch",
    "convert": "asciidoctor main.adoc"
  },
  "devDependencies": {
    "asciidoctor": "^2.2.0",
    "live-server": "^1.2.1",
    "npm-watch": "^0.7.0"
  }
}
```

注意：`$ npm run convert`で起動される Asciidoctor は Asciidoctor\.js の方です。実際、`$ npx asciidoctor --help`で Asciidoctor\.js のヘルプが表示されます。

AsciiDoc ファイルも準備しましょう。

```adoc:main.adoc
= Hello

* ワン
* ツー
* スリー
```

用意するファイルはこれだけ：

```shell-session
$ ls -1
main.adoc
package.json
```

監視、プレビュー……

```shell-session
$ npm run watch # terminal 1
$ npm run start # terminal 2
$ vim main.adoc # terminal 3
```

![before](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326541/e92b12a2-b7f1-9702-90f5-319ffda7cc98.png)

そして編集……

```adoc:main.adoc
= Hello

_Happy AsciiDocing!_
```

![after](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326541/4358772c-ce1f-cdb0-1f0b-d8d508f1807e.png)

ブラウザ上の表示が自動更新されました．

## まとめ

本記事では Asciidoctor.js を用いて，プレビューしながら AsciiDoc 文書を編集する方法を紹介しました．
この方法の良いところは，必要となる準備が Node.js のみであることです．Ruby に関係するプログラム (e.g. `asciidoctor`) の準備が要りません．

もちろん，Ruby 版 Asciidoctor を使わざるをえない場合もあります（Ruby で実装した自前のプラグインがある場合など）．途中で註記したように，こちらへの変更監視機能の追加にも期待したいところです．