Markdownでリッチなコードブロックを実現する「Expressive Code」
投稿日:
更新日:
QiitaなどのサイトではMarkdown構文が独自に拡張されており、たとえばコードブロックにファイル名を表示したりできます。しかし、通常のMarkdownでは、そのようなことはできません。
Expressive Codeを使うと、ファイル名を表示したり、特定の行を強調表示したりなど、MarkdownまたはMDXを使ってWebでリッチなコードブロックを表現できます。
実際にこのブログではExpressive Codeを使っており、次のコードブロックのように美しく機能的な表現ができます。
この記事では、そんなExpressive Codeの使い方を説明します。
Expressive Codeとは
Expressive Codeは、Webでソースコードを美しく表示するためのエンジンです。VS Codeと同じ正確なエンジンでシンタックスハイライトを処理しており、またテキストマーカーや差分表示、フレームなどの機能を備えています。
クライアントサイドのフレームワークに依存せず、高パフォーマンスで軽量なことが特徴です。
また、コードブロックの右上にはコピーボタンが表示され、クリックするとコードをクリップボードにコピーできます。
前提条件
Expressive Codeは、Markdownパーサーのremarkと、静的サイトジェネレーターのAstroに対応しています。
コア部分のパッケージは独立して提供されており、自分で他のフレームワークに対応させることもできます。しかし、通常はremarkかAstroを使うことになるでしょう。
インストール方法
remarkで使う場合とAstroで使う場合に分けて説明します。
Expressive Codeをremarkで使う場合は、プラグインとしてインストールします。
他のプラグインと同じように利用できます。第2引数としてオプションを指定できます。詳細は公式リポジトリーを確認してください。
※コード例は公式リポジトリーより
Astroの場合
Astroの場合は、インテグレーションが用意されています。次のコマンドを実行するだけで、自動的に使えるようになります。
設定
Expressive Codeでは、コードブロックの配色(テーマ)などをカスタマイズできます。また、閲覧しているユーザーの環境がライトモードかダークモードかに応じた自動切り替えもできます。
詳細は公式ドキュメントを確認してください。
使い方
Expressive Codeは、通常のMarkdownのコードブロック構文に加え、いくつかの独自の構文をサポートしています。
タイトル
コードブロックにタイトルを表示するには、次のように書きます。
すると、次のように表示されます。
行の強調
コードの特定の行を強調表示するには、mark={}
で行番号を指定します。
たとえば、2〜3行目を強調表示したい場合は、mark={2-3}
とします。
複数の行を強調表示したい場合は、mark={1,4}
のようにカンマ区切りで指定します。
行の挿入
コードの特定の行を挿入したような差分表示をするには、ins={}
で行番号を指定します。
複数行にまたがって挿入したい場合や、複数箇所に挿入したい場合の指定方法は、行の強調と同じです。
行の削除
コードの特定の行を削除したような差分表示をするには、del={}
で行番号を指定します。
複数行にまたがって削除したい場合や、複数箇所に削除したい場合の指定方法は、行の強調や行の挿入と同じです。
ラベル付きマーカー
コードの特定の行を強調表示し、そこにラベルを付与するにはmark={"ラベル":行番号}
で行番号を指定します。また、del
やins
でも同様にできます。
テキストマーカー
コード中の特定の文字列を強調表示するには、"テキスト"
のようにダブルクォーテーションで囲みます。
また、正規表現も利用できます。正規表現ではキャプチャーされた範囲のみが強調表示されるので、キャプチャーしたくない場合は(?:)
でグループ化します。
フレームの変更
デフォルトではエディター風のフレームが表示されます。
コードの言語として次のいずれかを指定すると、ターミナルウィンドウ風のフレームが表示されます。
bash
shellscript
shell
sh
zsh
フレームの設定を上書きしたい場合は、frame=
で指定します。frame
オプションにはcode
、terminal
、none
、auto
のいずれかを指定できます。デフォルトではauto
です。
ワードラップ(行の折り返し)
行を折り返すには、wrap
にtrue
を指定します。false
を指定すると折り返しを無効にできます。true
やfalse
を省略した場合はtrue
とみなされます。
折り返したときに折り返し部分のインデントを無効化するには、preserveIndent
にfalse
を指定します。true
やfalse
を省略した場合はtrue
とみなされます。
行番号の表示
Expressive Codeで行番号を表示するには、次のようにプラグインをインストールします。
Astroの場合は、プラグインとしてpluginLineNumbers()
を追加します。
コードブロックごとに個別に行番号のオン・オフを切り替えたい場合は、showLineNumbers
にtrue
またはfalse
を指定します。true
やfalse
を省略した場合はtrue
とみなされます。
また、行番号の開始番号を変更したい場合は、startLineNumber=
に開始番号を指定します。
特定の言語の場合にのみ行番号を表示したい場合や、逆に特定の言語の場合にのみ行番号を非表示にしたい場合は、設定で挙動を変更できます。たとえば、コンソール系の言語では行番号を表示しない場合は、次のようにします。
古い内容(一応残しているだけなので無視して大丈夫)
Expressive Codeには、記事執筆時点では行番号を表示するオプションが存在しません。Issueは上がっていますが、現時点では実装方法を検討中のようです。
そこで、Expressive Codeが内部で使用しているShikiに上がっていたIssueを参考に、次のようなCSSを追加すると、行番号を表示できます。
ただし、行の強調表示(差分表示を含む)との非互換性があるため、オススメしません。
Tips
ターミナルウィンドウをmacOS風にする
Expressive Codeのターミナルウィンドウ風フレームの左上には、3つのボタンのような飾りがついています。これらのボタンは、デフォルトでは灰色です。
これをmacOSのウィンドウ風の配色にするには、次のようなCSSを追加します。
コピーボタンのテキストを変更する
Expressive Codeのコピーボタンのテキストは、デフォルトでは英語表記になっています。Astroでこれを日本語にしたい場合は、次のようにします。
まとめ
MarkdownやMDXを使って、Webでリッチなコードブロックを表現できるExpressive Codeを紹介しました。
Expressive Codeは、Astroの公式ドキュメント(が使っているStarlight)でも利用されているようです。
通常のMarkdownではできない、高度で美しいコードブロックを表現できるので、ぜひ使ってみてください。