先日「やっぱりシンタックス・ハイライトあった方がいいよな」と思ったこともあって、highlight.js を導入することにした。Rouge 使って Jekyll 側でやらないのは、単に宗教的な理由による。
ところで highlight.js の対応言語は現時点で 169 種類もあるのだけど、中には「どう考えても自分は一生関わらないだろコレ」っていうようなものまで揃っている。さすがにその辺は省いたものを使いたいので、次の方法のいずれかを使って必要な言語だけを集めたパッケージをビルドする必要がある。
- 公式サイトのダウンロードページでチェックボックスをポチポチして作成する
- ソースコードをダウンロードして
node tools/build.js
を実行する - Node.js 用パッケージを webpack などを使ってブラウザで動くようにする
さすがに 1. をアップデートのたびにやるのは面倒だし、せっかく npm を導入したのだから npm で管理したい。2. は package.json に GitHub リポジトリを指定すれば少なくとも npm に管理を寄せることはできなくもなさそうだが、結局アップデートのたびにビルドが必要という点では 1. と変わらないので却下。という訳で 3. の方法でやってみることにした。
まずは単純に使ってみる
サイトで使う JavaScript 用のエントリーポイント(javascripts.js)を準備して webpack.config.js の entry に追加。とりあえず require
して initHighlightingOnLoad()
するだけのスクリプトを書いて開発用サーバを起動してみる。
// project_root/assets/javascripts.js
var hljs = require('highlight.js');
hljs.initHighlightingOnLoad();
まだスタイルを当ててないので見た目は変わらないが、ブラウザの開発者ツールで確認するとちゃんとキーワードごとに span
要素になってたので、少なくとも動作はしていることが分かる。ここから必要な言語のみを選択するにはどうすればいいかを考える。
流れを確認してみる
単純に require('highlight.js')
したときに読まれる(main である)index.js を確認すると、こうなっている。
// project_root/node_modules/highlight.js/lib/index.js
var hljs = require('./highlight');
hljs.registerLanguage('1c', require('./languages/1c'));
hljs.registerLanguage('abnf', require('./languages/abnf'));
// :
// 以下、同じ調子ですべての言語定義ファイルの登録が続く
// :
hljs.registerLanguage('zephir', require('./languages/zephir'));
module.exports = hljs;
最初に素の highlight.js を require
して、それに対して各言語を登録したものを exports
しているのが分かる。という処理関係はともかく、単純にこのファイルをコピーして、不必要な言語登録処理を削除したものを require
するようにすればいけそう。
作業していく
あとあと楽なように、resolve.alias を webpack.config.js に追加しておく。
// project_root/webpack.config.js
resolve: {
alias: {
'hljs': 'highlight.js/lib'
}
},
これで node_modules/highlight.js/lib 以下のファイルが hljs/pathto/filename のような形式で require
できるようになる。そして、index.js をコピー。
$ cp node_modules/highlight.js/lib/index.js assets/javascripts/hljs.js
パスが異なるのでこのままでは当然動作しない。なので、エディタの正規表現による置換機能などを使って一気にパスを変更する。Perl 風に書くと s!\.(?=/)!hljs!g
みたいな。そして、不必要な言語登録行を削除なりコメントアウトして保存し、先の javascript.js がこちらを読むように変更する。
あとはハイライト用のスタイルを適用すればいいだけ。自分は同梱の CSS の中から Tomorrow Night Eighties を選択したが、すでに pre
や pre > code
のスタイルを定義済みだったこともあり、直接 require
はせずにコピーして少し手を加え、カラースキームだけいただいたものを require
している。
こうして作成したものが、今このサイトで動いているもの。もうちょっと工夫すればスッキリと書けそうな気もするが、どうだろうか。
全然関係ないけど、今日から「ビルド」って普通にカタカナで書くことにした。さかのぼってまでは直さない。