Rehype Pretty Code を使って、美しきシンタックスハイライトを手に入れる
技術系ブログを書くならシンタックスハイライトは必須ですよね。
というわけで、今回はシンタックスハイライトの導入を行っていきます。
パッケージとしては、Rehype Pretty Code という rehype プラグインを使います。このパッケージは、 Shiki を使ってシンタックスハイライトを行います。
シンタックスハイライトといえば Prism が有名ですが、今回は Shiki を使用したパッケージを採用しました。
Prism よりも Shiki の方が精度が高い
他の導入事例を見たところ、 Prism はハイライトの精度が完全でなく、崩れることもあるようでした。→ syntax highlighter を shiki に切り替えた | blog.ojisan.io 参照。
その点、Shiki は VS Code と同じシンタックスハイライトのエンジンを使っているようなので安心です。
ちなみに、Astro でも、 Shiki がデフォルトのシンタックスハイライトとして使われているようです。→ Markdown & MDX 🚀 Astro Documentation 参照。
そんなわけで、 Shiki を使うのがよかろうと結論しました。
で、 Shiki を使うために色々と調べているときに出会ったのが Rehype Pretty Code (rehype-pretty-code
) という rehype プラグインです。
ちなみにこのプラグインは、 Next.jsでブログをつくった | 神話募集中 という記事を見て知りました。筆者の方に感謝です。
Rehype Pretty Code とは?
Rehype Pretty Code は、MD/MDX ドキュメントに美しいコードブロックを提供する rehype プラグインです。
今回は詳しく書きませんが、特定の行のハイライトや行番号・ファイル名の表示なども行うことができます。例えば次のように表示させることができます。
const add = (a, b) => a + b;
add(2, 3); // 5
行のハイライトや行番号・ファイル名の表示については、 Rehype Pretty Code で、コードブロックに行番号を付け、特定の行をハイライトする をご参照ください。
Rehype プラグインを使うための準備
このブログは、記事作成時点では Next.js の公式チュートリアルをもとに作っていて、マークダウンを HTML に変換するために remark
と remark-html
を使用しています。
remark-html
は、 .use(remarkRehype).use(rehypeStringify)
のショートカットにあたるプラグインですが、 rehype プラグインを使うためには remark-rehype
と remark-stringify
を別々で使用する必要があります。
なので、 remark-html
を取り除き、
pnpm rm remark-html
remark-rehype
と rehype-stringify
をインストールしましょう。
pnpm add remark-rehype rehype-stringify
そしてそれらを使用するために lib/posts.js
で、それらをインポートし、remark-html
は削除します。
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { remark } from 'remark';
import html from 'remark-html';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
次に、それらを使用している getPostData
を変更します。
export const getPostData = async (id) => {
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, 'utf8');
const matterResult = matter(fileContents);
const processedContent = await remark()
.use(html)
.use(remarkRehype)
.use(rehypeStringify)
.process(matterResult.content);
const contentHtml = processedContent.toString();
return {
id,
contentHtml,
...matterResult.data,
};
};
今回追加した .use(remarkRehype)
と .use(rehypeStringify)
の間に記述することで rehype プラグインが使用できるようになるので、ここに rehype-pretty-code
を追加していきます。
Rehype Pretty Code の導入
Rehype プラグインを使用する準備ができたので、 rehype-pretty-code
のセットアップを行っていきましょう。
まずは 公式ドキュメントに沿って、必要なパッケージをインストールします。
pnpm add rehype-pretty-code shiki
次に lib/posts.js
で rehype-pretty-code
をインポートします。
import fs from "fs";
import path from "path";
import matter from "gray-matter";
import rehypePrettyCode from "rehype-pretty-code";
import rehypeStringify from "rehype-stringify";
import remarkRehype from "remark-rehype";
そして、それを使用するために getPostData
を変更します。 次のように .use(rehypePrettyCode)
を追加します。
export const getPostData = async (id) => {
const fullPath = path.join(postsDirectory, `${id}.md`);
const fileContents = fs.readFileSync(fullPath, "utf8");
const matterResult = matter(fileContents);
const processedContent = await remark()
.use(remarkRehype)
.use(rehypePrettyCode)
.use(rehypeStringify)
.process(matterResult.content);
const contentHtml = processedContent.toString();
return {
id,
contentHtml,
...matterResult.data,
};
};
これでシンタックスハイライトが効くようになります。
テーマを変更してみる
シンタックスハイライトのテーマは、個人的に One Dark Pro が好みなので、それに変更してみます。
テーマの変更は簡単で、プラグイン使用時にオプションとして指定するだけです。 Shiki に含まれるテーマであれば文字列を渡すだけで OK です。
次のコード例のように theme: 'one-dark-pro'
を追加します。
併せて追記している keepBackground: true
というのは、テーマに設定されている背景色を使うための指定です。自身で設定した背景色を使いたい場合は false
にしてください。
const processedContent = await remark()
.use(remarkRehype)
.use(rehypePrettyCode, {
theme: "one-dark-pro",
keepBackground: true,
})
.use(rehypeStringify)
.process(matterResult.content);
ちなみに Shiki に含まれるテーマは Themes | Shiki から確認できます。
Shiki に含まれていないテーマでも、 JSON があればそれを読み込んで使用することもできます。詳しくはドキュメントをご参照あれ。
さいごに
これで、ようやくこのブログにもシンタックスハイライトが適用されました。
Rehype Pretty Code には、他にも便利な機能があり、特定の行のハイライトや行番号を行うことも可能です。
この辺については、後日改めて記事を公開する予定ですのでお楽しみに! → 公開しました 👉🏼 Rehype Pretty Code で、コードブロックに行番号を付け、特定の行をハイライトする
参考