unifiedを使ってMarkdownの記事データをHTMLに変換してNext.jsで表示させる
このブログでContentfulからマークダウンで書いた記事をHtmlに変換してシンタックスハイライトもつけて表示させていますが、unifiedを使ってやってみたのでその備忘録です。
unifiedとは
githubの最初の紹介文には以下のように書かれています。
unified is an interface for processing text using syntax trees. It’s what powers remark (Markdown), retext (natural language), and rehype (HTML), and allows for processing between formats.
unifiedは、構文木を使用してテキストを処理するためのインターフェースです。これは、remark(Markdown)、retext(自然言語)、およびrehype(HTML)を強化し、フォーマット間の処理を可能にするものです。
unified自体は、テキストデータを異なるフォーマットへ変換するための一連の処理(パース、変換、コンパイル)におけるインターフェースを提供していて、そのインターフェースに対応したライブラリを組み合わせて自由に操作ができるようになっているようです。各フェーズの処理にはそれ用のライブラリがいろいろと用意されています。例えばマークダウンをパースする場合はremarkがありますし、HTMLをパースしたい場合はrehypeがあります。 一応学習用のサイト(Learn - unified)も用意されていました。
サンプル
実際にマークダウンを変換する部分だけのサンプルをcodesandboxで作ってみました。
変換する部分のコードは以下になります。各工程で何をやってるかがわかるようにコメントを付けてます。
// mdToHtml.js
import { unified } from "unified";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import rehypeRaw from "rehype-raw";
import rehypeFormat from "rehype-format";
import rehypePrismPlus from "rehype-prism-plus";
import remarkGfm from "remark-gfm";
import rehypeStringify from "rehype-stringify";
const mdToHtml = async (markdown) => {
const result = await unified()
.use(remarkParse) // マークダウンのパーサー
.use(remarkGfm) // Autolink literals、Strikethrough、Table、Tasklist、に対応するためのremarkのプラグイン。
.use(remarkRehype, { allowDangerousHtml: true }) // マークダウンをhtmlに変換するremarkのプラグイン
.use(rehypePrismPlus) // PrismでHTMLのコードブロックを強調表示するrehypeプラグイン(rehypeRawの前にやらないと、.line-number、.highlight-line、line属性が削られてしまう)
.use(rehypeRaw) // HTMLで記述されている部分(iframeなど)をパースするためのプラグイン
.use(rehypeFormat) // htmlをきれいに整形するrehypeプラグイン
.use(rehypeStringify) // htmlをシリアライズするunified用のコンパイラ
.process(markdown);
return String(result);
};
export default mdToHtml;