Rehype Pretty Code を使って、美しきシンタックスハイライトを手に入れる

Created on

技術系ブログを書くならシンタックスハイライトは必須ですよね。

というわけで、今回はシンタックスハイライトの導入を行っていきます。

パッケージとしては、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 プラグインです。

今回は詳しく書きませんが、特定の行のハイライトや行番号・ファイル名の表示なども行うことができます。例えば次のように表示させることができます。

add.js
const add = (a, b) => a + b;
 
add(2, 3); // 5

行のハイライトや行番号・ファイル名の表示については、 Rehype Pretty Code で、コードブロックに行番号を付け、特定の行をハイライトする をご参照ください。

Rehype プラグインを使うための準備

このブログは、記事作成時点では Next.js の公式チュートリアルをもとに作っていて、マークダウンを HTML に変換するために remarkremark-html を使用しています。

remark-html は、 .use(remarkRehype).use(rehypeStringify) のショートカットにあたるプラグインですが、 rehype プラグインを使うためには remark-rehyperemark-stringify を別々で使用する必要があります。

なので、 remark-html を取り除き、

Terminal
pnpm rm remark-html

remark-rehyperehype-stringify をインストールしましょう。

Terminal
pnpm add remark-rehype rehype-stringify

そしてそれらを使用するために lib/posts.js で、それらをインポートし、remark-html は削除します。

lib/posts.js
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 を変更します。

lib/posts.js
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 のセットアップを行っていきましょう。

まずは 公式ドキュメントに沿って、必要なパッケージをインストールします。

Terminal
pnpm add rehype-pretty-code shiki

次に lib/posts.jsrehype-pretty-code をインポートします。

lib/posts.js
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) を追加します。

lib/posts.js
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 で、コードブロックに行番号を付け、特定の行をハイライトする


参考