unified(remark,rehype)を利用してMarkdownをHTMLに変換する
unifiedを使用してMarkdown形式の文章をHTMLに変換するための備忘録です。
unifiedとは
unified
は、テキストを構文木(syntax tree)として扱うためのインターフェース。unifiedで使用する構文木はunist
として仕様が決められています。
このunistを拡張し、さまざまな形式を取り扱うようにしたパッケージの一部が以下になります。
- remark : Markdownを扱うためのプロセッサで、unistを拡張した
mdast
と呼ばれる構文木を使用する - rehype : HTMLを扱うためのプロセッサで、unistを拡張した
hast
と呼ばれる構文木を使用する
この2つのパッケージのプラグインを使用することで、MarkdownからHTMLへの変換を行います。
remarkについて
remark
は、Markdownを取り扱うためのプロセッサです。remarkには以下のようなプラグインがあります。
- remark-parse : Markdownをmdastに変換するためのプラグイン
- remark-stringify : mdastをMarkdownに変換するためのプラグイン
rehypeについて
rehype
は、HTMLを取り扱うためのプロセッサです。rehypeには以下のようなプラグインがあります。
- rehype-parse : HTMLをhastに変換するためのプラグイン
- rehype-stringify : hastをMarkdownに変換するためのプラグイン
MarkdownからHTMLへ変換する
実際にMarkdownからHTMLへ変換してみます。
処理の流れは以下のようになります。
- Markdownを
mdast
に変換する mdast
をhast
に変換するhast
をHTMLに変換する
必要なプラグインをインストールします。remark-rehype
はmdastをhastに変換するためのプラグインです。
1npm i -D unified remark-parse remark-rehype rehype-stringify
プログラムは以下のようになります。
use
で使用するプラグインを順番に設定し、processSync
でMarkdownを受け取り処理を実行します。
1import unified from 'unified'; 2import remarkParse from 'remark-parse'; 3import remarkRehype from 'remark-rehype'; 4import rehypeStringify from 'rehype-stringify'; 5 6const test = () => { 7 console.log( 8 unified() 9 .use(remarkParse) 10 .use(remarkRehype) 11 .use(rehypeStringify) 12 .processSync('# Hello World') 13 .toString(), 14 ); 15};
実行した結果は以下のようになります。
1<h1>Hello World</h1>
プラグインの自作
プラグインを自作するにはunifiedのプラグインの作り方を参考にしていきます。
remarkプラグインの自作
ここでは、入力されたMarkdownの後ろにhogehoge
という文字を追加するだけのプラグインを作成します。
まずは、トランスフォーマーを宣言します。
1import { Transformer } from 'unified'; 2import { Node } from 'unist'; 3 4const remarkTest: () => Transformer = () => { 5 const transformer: Transformer = (tree: Node) => { 6 }; 7 return transformer; 8}; 9 10export default remarkTest;
次に、トランスフォーマーの中身を追加します。
treeノードをRoot
型に変換し、childrenに新しいパラグラフを追加します。値は返さなくても変更されていますが、ここでは分かりやすく変更した値を返しています。
1import { Transformer } from 'unified'; 2import { Node } from 'unist'; 3import { Root } from 'mdast'; 4 5const remarkTest: () => Transformer = () => { 6 const transformer: Transformer = (tree: Node) => { 7 const root = tree as Root; 8 root.children.push({ 9 type: 'paragraph', 10 children: [ 11 { 12 type: 'text', 13 value: 'hogehoge', 14 }, 15 ], 16 }); 17 return root; 18 }; 19 20 return transformer; 21}; 22 23export default remarkTest;
作成したremarkTest
プラグインはmdast
を変更するため、remarkParse
でmdast
に変換された後に追加します。
1const test = () => { 2 console.log( 3 unified() 4 .use(remarkParse) 5 .use(remarkTest) 6 .use(remarkRehype) 7 .use(rehypeStringify) 8 .processSync('# Hello world') 9 .toString(), 10 ); 11};
実行結果は以下のようになります。
1<h1>Hello world</h1> 2<p>hogehoge</p>
rehypeプラグインの自作
remarkと同様に作成します。違いはremarkがmdastを操作するのに対し、rehypeはhastを操作する点だけです。
おわりに
unifiedを利用し、MarkdownをHTMLに変換する方法を書きました。
unifiedのエコシステムには数多くのプラグインが存在するため、それらをうまく活用することでMarkdownやHTMLはもちろん、それ以外の文章もすばやく編集することができるようになると思います。