導入
皆さんの好きなマークアップ言語は何ですか?
私はAsciiDocが好きなのですが、普段はMarkdown対応したwikiサービスを使っています。特に不便は感じていませんが、やはり AsciiDoc の表現力を知っていると、時々物足りなさを感じる場面もあります。特に Markdown、CommonMarkにおいて、数式を想定した仕様がまとめられていない点は気になってしまいます。このような理由から、AsciiDoc に対応した wiki サービスの台頭を望む声も少なくないはずです。(当社調べ)
今回はAsciiDoc好きのための静的サイトジェネレータであるAntoraについて、ドキュメントを一読したので要約をまとめます。最初に注意点として、私はAntoraの開発に関与していない全くの素人なので、雰囲気を知る程度に読んでいただければ幸いです。
記事の目的
この記事は私自身の知識整理のために作成するとともに、AsciiDoc 好きな方々へ Antora を布教することを目的としています。Antora の導入は多少ハードルがある、と個人的に感じました。少なくとも docs を流し読みしただけで期待した動作を得ることは難しいと思います。「使いたいけど docs をガッツリ読んで architecture を把握する時間がない」という方を念頭に記事を作成しています。
したがってこの記事では、AsciiDoc の記法であったり、AsciiDoc と Markdown の違いであったり、npm 環境についてであったりは記述しません。また文章量の問題から、Antora におけるバージョン/navigation file の扱い、UI についても記載しません。
Antoraの特徴
公式サイトにも記載されるように Antora は、AsciiDoc 好きのための静的サイトジェネレータです。"for tech writers"とあるように、ライブラリの docs ページによくある、バージョン毎に記事を管理する、といった高級な事もできるとのこと(私は確認してない)です。もちろん、個人ページの運用にも利用できます。私が特に好ましく思っているのは次の点です。
- No flavor lock-in
例えばMarkdownにおける数式記述の構文がよい例かと思います。Markdownではその仕様が定まっていないため、サービスによって記法が若干異なったりします。互換性を意識した設計思想は心強いのではないでしょうか。
Antora の簡単な例
環境設定
mkdir test_page
cd test_page
git init
npm init
npm install @antora/cli@2.2 @antora/site-generator-default@2.2 # 2020/02/04時点の最新です。公式サイトから最新版を確認ください。
次に touch antora-playbook.yml
して内容を次のようにします。
site:
title: てすとページ
url: http://localhost/
start_page: home::index.adoc
content:
sources:
- url: .
start_path: docs
ui:
bundle:
url: https://gitlab.com/antora/antora-ui-default/-/jobs/artifacts/master/raw/build/ui-bundle.zip?job=bundle-stable
output:
dir: ./public
上記において site>title
と site>url
、 output>dir
は変更しても問題ありません。しかし site>content>sources>url
や site>content>sources>start_path
などは、architecture を把握してからいじることを奨めます。
touch .gitignore
で以下を記述しておきましょう。
public/
node_modules/
記事追加
mkdir -p docs/modules/ROOT/pages; touch docs/modules/ROOT/pages/index.adoc
して動作確認のための記事を書きましょう。
= Top Page
== 見出し
ほげほげ。
[source,shell]
----
echo "hoge"
----
後述の Architecture で触れますが、 antora.yml
という重要な役割を有するファイルを作成します。
touch docs/antora.yml
の中身を次のように編集します。
name: home
version: master
ここまでで次のようなディレクトリ構成となっています。
.
|-- antora-playbook.yml
|-- docs
| |-- antora.yml
| `-- modules
| `-- ROOT
| `-- pages
| `-- index.adoc
|-- package-lock.json
`-- package.json
サイト生成
以上で最低限必要なファイルの準備が終わりました。次のコマンドを実行して public/
以下に先程の index.adoc
に対応した html ファイルを生成します。
git add .
git commit -m "updated" # 更新をcommitしないとantoraにファイルの存在が認識されないようです。詳しい仕様は把握していないです。
./node_modules/.bin/antora antora-playbook.yml
これでpublic/home/index.html
が生成されていれば成功です。ブラウザで確認してみてください。
Antora の Architecture
先程の簡易例には、いくつかの YAML ファイルや意味深なディレクトリ名がありました。ここではこれらの役割を説明することで、サイト構成の理解を促します。主に次の用語の役割が明確になることを意識して説明を進めます。
- component descriptor
- documentation component
- module
- family
- page identifier
- playbook
Module: 共通のテーマを有する記事や資料のまとまり
wiki のようなものを構成する際、似た内容の記事は一箇所に集めて管理する、というのは一般的と思います。そして記事を作成する場合、現代ではテキストのみとは限らず、画像・音声・動画を埋め込むこともあるかと思います。テーマを共有する複数の記事、そして記事作成に必要な各種資料の集まりのことを Module と呼びます。先程の簡易例において、 ROOT
ディレクトリはこの Module の一種です。
Module 内において、音声・画像・動画・テキストデータを同一ディレクトリに保存するのは好ましくありません。音声データだけのディレクトリ、テキストデータだけのディレクトリ、といった具合に分けて管理するのが自然でしょう。Module における同一種類データを内包するディレクトリのことを、 Family と呼びます。簡易例における pages
ディレクトリはこの Family の一種で、adoc ファイルをまとめる場所として扱われます。簡易例ではテキストファイルしか使わなかったため pages しか現れませんでしたが他にも、画像を格納する images
、 zip ファイルや pdf ファイルのような添付ファイルを保存する attachments
などもFamily subdirectory として扱われます。
ここまでで Module という用語の導入を行い、これが共通のテーマを有する記事のまとまりであることを説明しました。であればディレクトリ名を見ただけで、そのディレクトリ以下にどのようなテーマの記事が格納されているのかわかるほうがありがたいです。ROOT 以外のディレクトリ名を与えられた、ROOT ディレクトリと同階層にあるディレクトリを named module と呼びます。つまり、Module は 2 種類に大別することができ、ROOT module と、それ以外の named module があります。ROOT module と named module の使い分けについては documentation component と絡むので後述します。
以下の例において、 ThemeA
が named module に相当します。
.
|-- ROOT
| |-- attachments
| |-- images
| | `-- fig.svg
| `-- pages
| `-- index.adoc
`-- ThemeA
|-- images
`-- pages
|-- article1.adoc
`-- index.adoc
Documentation Component: メタ情報を共有する module のまとまり
Documentation Component とは、端的に言えば module のまとまりを指します。まとめられた module においては記事の version、まとまりの名前(name)などのメタ情報を共有しています。以降では単に Component と呼ぶこともあります。具体的にどのような単位で module を分けるか、component を分けるべきかは公式 docs にも記載ありませんが、例として、1 つの商品のドキュメントを 1 つの documentation component として表すと記述されています。
compA
|-- antora.yml
`-- modules
|-- ROOT
| |-- attachments
| |-- images
| | `-- fig.svg
| `-- pages
| `-- index.adoc
`-- ThemeA
|-- images
`-- pages
|-- article1.adoc
`-- index.adoc
上記のディレクトリ構造において、antora.yml
と modules
を含むディレクトリが Documentation Component となります。後述しますが、 compAというディレクトリ名は重要ではありません。 antora.ymlの name key に設定された値が、この Documentation Component の名前になります。 Documentation Component を構成する必須条件は以下の4つです。
- component descriptor file (antora.yml) を含む
- modules directory を含む
- modules directory に少なくとも 1 つの module を含む
- module に少なくとも 1 つの Family を含む
Component Descriptor file: Documentation Component の存在を Antora へ伝えるファイル
-
antora.yml
と名付けられた、 - YAML で記述され、
- 少なくとも
name, version
key とその値が設定されており、 - modules directory と同階層に配置されるファイル
の事を Component Descriptor file と呼びます。この記事では簡単のために、Component Descriptor file のことを antora.yml と呼んだりします。antora.yml
の役割は 2 つ、(i) Antora へ Component の存在を伝えること、(ii) Component の名前やバージョン、navigation file の存在といった情報を保持することです。
name: home
version: v1.0
nav:
- modules/ROOT/nav.adoc
上記は antora.yml の一例です。この antora.yml 以下のディレクトリで構成される Component について、(i) その名前が home
であること、(ii) バージョンが v1.0
であること、(iii) navigation file が modules/ROOT/nav.adoc
に存在すること、がわかります。nav.adoc やバージョンの詳細について本記事では解説しません。
Page Identifier: ユニークに記事を特定するための ID
記事を構成するどの資料も、何らかの Family に属し、その Family はいずれかの Module 内に配置され、Module は Documentation Component で束ねられていることをここまでで説明しました。したがってすべての adoc ファイルはこれらによって一意に決定されます。これを Page Identifier (PageID) と呼びます。この PageID は、ある adoc ファイルにおいて別の adoc ファイルへのリンクを作成する時などに利用されます。PageID は次の書式に従います。
version@component:module:path/to/adocfile
ここで path/to/adocfile
の部分には該当 module 内の pages ディレクトリからのパスを記載します。
compA
|-- antora.yml
`-- modules
`-- ROOT
`-- pages
|-- index.adoc
`-- topic1
`-- article1.adoc
上記の例において、antora.yml に記載された comp name を home
、version を v1.0
とした場合、index.adoc
の PageID は v1.0@home:ROOT:index.adoc
となり、 article1.adoc
の PageID は v1.0@home:ROOT:topic1/article1.adoc
となります。ある adoc ファイル内で別の adoc ファイルへのリンクを張る際は
xref:version@component:module:path/to/adocfile[リンクテキスト]
という形で記述します。しかし毎回このような ID を記述するのは煩雑であるため、 同一 module の記事へアクセスする際の簡略記法 が用意されており、以下の形で記述できます。
xref:path/to/adocfile[リンクテキスト]
Playbook: サイトの構成を記述する設定ファイル
前述までの内容は、Antora では記事をどのように格納し、ユニークに特定するかを記述していました。ここでは最後に、サイト全体の構成情報を扱う設定ファイルについて記述します。
Antora はサイトジェネレータですから、最終的には HTML への出力を想定します。したがって、(i) base URL は何なのか、(ii) サイトのタイトルは何か、(iii) UI は何を用いるか、(iv) そもそも documentation component はどこにあるのか、などの情報を Antora へ伝える必要があります。
上記のようなサイト全体の情報や、サイト構成に必要な情報をまとめた設定ファイルを Playbook と呼びます。前述の簡易例における antora-playbook.yml
がこれにあたります。様々な情報を扱うことができキリがないため、ここでは簡易例における content>sources>{url,start_path}
に触れます。
content>sources>url
: Document Component (Git) Repository の場所の明記
content>sources>{url, start_path}
key で Documentation Component を含むリポジトリの場所を明記します。公式 docs に記載されておらず、ソースコードも読んでいない私の意見ですが、ここでいう Repository は Git Repository を指すと思われます。というのも、単に Documentation Component の要件を満たすディレクトリを指定しても、エラーが生じて処理が進まなかったためです。上記簡易例のようにローカル環境のパスでリポジトリを指定することも、公式 docs のように URL でリポジトリを指定することも可能です。
start_path
key ではそのリポジトリにおける、Documentation Component のディレクトリパスを指定します。このような仕様になっているのは、例えばあるライブラリのソースコードを含むリポジトリの一部として、Component が含まれるような管理状況を想定しているためと思われます。前述の簡易例の場合、Component の要件を満たすのは docs
ディレクトリであるため、antora-playbook.yml から docs への相対パス が記述されています。
まとめ
Architecture 理解に必要な要素を詰め込んだ結果、わかりにくい記事になってしまいました。布教の目的もあるので、今後ブラッシュアップしていく予定です。この記事を読んで AsciiDoc や Antora に触れる人が 1 人でも増えればうれしい限りです。
本記事で触れることができなかったUI関連について知りたい方は、Antora Default UIあたりの資料を読むことをお薦めします。
追記: 2023/03/16
上記に記載の内容は,追記時点でも有用だと確認しました.またホームページ全体の構成については,まとめに若干触れたとおり,Antora Default UIをforkし修正することで変えることができます.公式でもページのPlaybookではurl部分に,CIによるartifactのURLを指定していますが,作成過程ではローカルパスを渡しても機能しますので,そういった利便性は確保されています.