giraphme/blog

Markdown を型付きオレオレ AST に変換する

本ブログでは Markdown を良い感じの AST に変換するため unifiedremark を使用しています。

2020年ごろに Remark のパーサー(micromark)が仕様変更したことによって一部のプラグインが使用できなくなり、新旧入り乱れた情報が見つかるので、 2023年時点でどのように使ったかを記録しておきます。

##TL;DR;

##基本の使い方

unified は何らかのテキスト(HTML, Markdown, Plain Text など)をシンタックスツリーに変換し、そのシンタックスツリーを別の形式にコンパイルするインターフェイスです。

Markdown をパースして AST に変換するだけであれば、以下のように書くことができます。

unified の use にプラグインを渡すことでパース・変換・フォーマットを行います。

上記は Markdown のパースを行う remark-parse をプラグインとして渡しているだけです。

mdast は Markdown をパースした結果の AST です。

remark の README などでは .process(markdown) を使われていますが、今回は AST を得ることが目的なので .parse(markdown) を使用しています。

若干強引なやり方であれば、この AST を操作すれば期待する結果を得られますが、折角なので unified のインターフェイスで操作してみましょう。

##Plugin を自作する

unified.Plugin 型を返す関数を use に渡すことで自作プラグインを使用することができます。

最小ではこれだけです。

注意点として、 Plugin 型はデフォルトで Node<Data> 型のシンタックスツリー期待しているので、 mdast の Rootを generics で渡す必要があります。(void[]use のオプションです。)

##Root の型を拡張して Image にサイズ情報を持たせる

Markdown を HTML に変換するとき、 width, height 属性を指定したいケースが良くあるかと思います。

簡易的なサンプルとして、 Image にメタ情報を持たせてみましょう。

サイズ取得は私が良く使っていて慣れているため sharp を使用します。

###mdast の型を拡張する

適当な場所に型定義ファイルを配置します。

###プラグインを作成する

##上手いやり方が見つかっていない

###unified の parse, run, stringify, process

unified の Plugin には parser, transformer, compiler の3種類が存在します。

データをパースする場合は parse(), AST を操作する場合は run(), フォーマットする場合は stringify(), 全て実行する場合は process()を呼び出します。

サンプルなどを見ていると、 parse のメソッドチェインに transformer を渡しても実行されているようですが、自作の Plugin では上手く実行されません。

そのため、下記のように 2段階に分けて呼び出す必要があります。

Plugin が parser か transformer か compiler かを見分ける方法をいまいち見つけられていないので、何か分かったら追記します。

© giraph.me