unified.jsはAST(抽象構文木)を使いテキストフォーマットを変換できるライブラリです。
remark(Markdown)、rehype(HTML)、retext(自然言語)といったフォーマットの実装があります。
今回はremarkとrehypeを使い、MarkdownをHTMLに変換してみます。
インストール
必要なパッケージをあらかじめインストールします。
npm i unified
npm i remark-parse
npm i remark-rehype
npm i rehype-stringify
unifiedはES Modulesとして提供されているので、Node.jsで使うにはpackage.json
に次の記載を追加する必要があるようです。
"type" : "module"
Markdownをパースする
unifiedではある形式のテキストをASTに変換する処理をParser
が担います。
今回はMarkdownをパースするのにremark-parse
を使います。
import unified from 'unified';
import remarkParse from 'remark-parse';
const parser = unified().use(remarkParse);
const mdast = parser.parse('# test');
// できたASTを出力
console.log(JSON.stringify(mdast, null, 2));
実際のmdast
の内容はこのようになっていました。heading
の下にtext
がぶら下がっていますね。
{
"type": "root",
"children": [
{
"type": "heading",
"depth": 1,
"children": [
{
"type": "text",
"value": "test",
"position": {
"start": {
"line": 1,
"column": 3,
"offset": 2
},
"end": {
"line": 1,
"column": 7,
"offset": 6
}
}
}
],
"position": {
"start": {
"line": 1,
"column": 1,
"offset": 0
},
"end": {
"line": 1,
"column": 7,
"offset": 6
}
}
}
],
"position": {
"start": {
"line": 1,
"column": 1,
"offset": 0
},
"end": {
"line": 1,
"column": 7,
"offset": 6
}
}
}
Markdown ASTからHTML ASTに変換
Markdown形式のASTからHTML形式のASTに変換をかけます。
unifiedではこれを行うのはTransformer
です。今回はremark2rehype
を使います。
...
import remark2rehype from 'remark-rehype';
...
const transformer = unified().use(remark2rehype);
const hast = transformer.runSync(mdast);
console.log(JSON.stringify(hast, null, 2));
次のようにh1
タグのelement
の子供にtext
がぶら下がりました。
{
"type": "root",
"children": [
{
"type": "element",
"tagName": "h1",
"properties": {},
"children": [
{
"type": "text",
"value": "test",
"position": {
"start": {
"line": 1,
"column": 3,
"offset": 2
},
"end": {
"line": 1,
"column": 7,
"offset": 6
}
}
}
],
"position": {
"start": {
"line": 1,
"column": 1,
"offset": 0
},
"end": {
"line": 1,
"column": 7,
"offset": 6
}
}
}
],
"position": {
"start": {
"line": 1,
"column": 1,
"offset": 0
},
"end": {
"line": 1,
"column": 7,
"offset": 6
}
}
}
HTMLに変換
最後にHTMLのASTからテキストに変換します。
unifiedではCompiler
とよばれ、今回はrehype-stringify
を使います。
...
import rehypeStringify from 'rehype-stringify';
...
const compiler = unified().use(rehypeStringify);
const html = compiler.stringify(hast);
console.log(html);
次のようにHTMLに変換されました。
<h1>test</h1>
まとめて実行
parse
,run
,stringify
はまとめてprocess
で実行できます。
3段階の処理をまとめたコードは次のようになります。
import { unified } from 'unified';
import remarkParse from 'remark-parse'
import remark2rehype from 'remark-rehype'
import rehypeStringify from 'rehype-stringify';
const processor = unified()
.use(remarkParse) // Parser
.use(remark2rehype) // Transformer
.use(rehypeStringify); // Compiler
const html = processor.processSync('# test');
console.log(html.value);