blog.azyobuzi.net を開設して1年強、メンテナンスも AsciiDoc も面倒になってきて、はてなブログに戻るのもアリだなぁという気持ちが若干発生してきていました。そもそもブログ自体書いてないじゃん。はい。すいません。
AsciiDoc というか Asciidoctor を使うことに思うところがあり、 Gatsby + Asciidoctor.js という構成をやめ、 Markdown + お手製静的サイトジェネレータ という構成に変更したというお話です。
(AsciiDoc から Markdown への移行は9月の頭には完了していましたが、記事を書く余裕がなかったので、今書いています。)
なぜ Markdown
このブログを開設して最初の記事で、なぜ AsciiDoc を選んだかを説明しました。
うんうん……。正直今ならほとんど反論できますね……。
まずは方言問題。使ってみてわかりましたが、 Asciidoctor という方言は強烈です。オリジナルの AsciiDoc に対する拡張がかなりあります。結局 Asciidoctor という方言を書くことになってしまいました。対して Markdown は CommonMark という最小かつ曖昧さのほとんどない仕様が存在します。またデファクトスタンダードである GitHub Flavored Markdown は、 CommonMark への機能追加という形で仕様が公開されています。さまざまな方言があるように見えますが、 CommonMark 以外に目を向けなければ、かなり安定した仕様と言えます。
そして次に、 AsciiDoc は機能豊富なぶん、 HTML への変換結果と、それに必要なスタイルシートがつらい
と書きましたが、これがかなりつらさにつながっていました。ブログを書いて Web に公開するとはどういうことかというと、 HTML をアウトプットするということです。セマンティックの正しい HTML を出力することについて、 AsciiDoc の機能および Asciidoctor の出力はかなりの足かせになってしまいました。私は HTML が書きたいのであって、 AsciiDoc や DocBook を書きたいわけではないのです。この点において Markdown はとても優秀なツールです。 CommonMark の機能はほぼ HTML タグと1対1対応になっており、簡単に出力される HTML を予想することができます。また CommonMark では HTML をインラインまたはブロックとして直接書くことも許されています(AsciiDoc にも Passthrough Block という機能がありますが)。つまり Markdown に不満があったら HTML を書けばいいのです。 Markdown に多くを求めなければ Markdown は HTML の糖衣構文として使うことができるのです。
このような背景で、 Markdown への移行を決めました。基本方針は GitHub Flavored Markdown にある機能だけを使い、より複雑なことがしたいならば HTML を手書きする です。追加機能が欲しい場合は、カスタム要素を使用します(カスタム要素は静的サイトジェネレータで処理されます。インタラクティブな要素が必要になったときは、そのまま出力して Web Components にしてしまおうと考えています)。 Markdown 自体は拡張しません。
静的サイトジェネレータ
Next.js や Gatsby を一度でも使ったことがあれば共感していただけると思うのですが、 JSX って HTML テンプレート言語として最強だと思うんですよ。ということで JSX を捨てたくなかったのですが、どのツールもブラウザに React をロードさせることが前提になっていました。 Gatsby の時代は過激な名前のプラグインをインストールして <script>
タグを潰していましたね。
というわけで JSX を書けて React に依存しないものを探していました。ツールは見つかりませんでしたが、いい感じのライブラリは見つけました。 hastscript。これで JSX 構文で AST を吐き出すことができます。
remark, rehype, unified
最近 JavaScript で Markdown を解析するなら remark が最有力でしょうか? remark は unified という共通 AST 処理基盤を利用する仕組みになっており、 Markdown → Markdown AST (mdast) → HTML AST (hast) → HTML といった変換工程を簡単に書くことができます。嘘です。すでに用意されてるパッケージを使うだけならうまく隠蔽されていますが、パイプラインとしてはなかなか最悪の実装になっており、それを理解してプラグインを自作することになります。
今見ているこのページの Markdown は、こんな感じのパイプラインで HTML 化されています。
できるだけシンプルにするぞと思っていたのですが、なかなか処理が多いですね。しかし Markdown 言語自体を拡張することはほとんどしておらず、処理のほとんどは HTML の AST を変形しています。このように HTML の世界に閉じ込めることで、言語を拡張するとかいう不毛なことを考えなくて済みます。
hastscript ベースのページテンプレート
素の hastscript は hast を生成するための簡単な操作しか行うことができませんが、ちょっとしたラッパーを書くことで React の関数コンポーネントの書き味を得ることができます。
このような関数を用意すると、ほぼ React の感覚で JSX を書くことができます。実際の使用例は、このブログのジェネレータのソースコード(pages ディレクトリ)を見てください。
まとめ
以上が AsciiDoc を捨てて Markdown に移行した理由と、新しい静的サイトジェネレータの実装でした。 HTML が置いてあるトラディショナル静的サイトであることをモットーにしているので、このような構成が落ち着きますね。これからは Asciidoctor のドキュメントとにらめっこせず、 HTML を書いていきます。ブログ書けよ。