JeffreyFrancesco.org 公開日 タグ Tag Permalink 現在地 Facebook page Twitter RSS feed

先日「やっぱりシンタックス・ハイライトあった方がいいよな」と思ったこともあって、highlight.js を導入することにした。Rouge 使って Jekyll 側でやらないのは、単に宗教的な理由による。

ところで highlight.js の対応言語は現時点で 169 種類もあるのだけど、中には「どう考えても自分は一生関わらないだろコレ」っていうようなものまで揃っている。さすがにその辺は省いたものを使いたいので、次の方法のいずれかを使って必要な言語だけを集めたパッケージをビルドする必要がある。

  1. 公式サイトのダウンロードページでチェックボックスをポチポチして作成する
  2. ソースコードをダウンロードして node tools/build.js を実行する
  3. 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 を選択したが、すでに prepre > code のスタイルを定義済みだったこともあり、直接 require はせずにコピーして少し手を加え、カラースキームだけいただいたものを require している。


こうして作成したものが、今このサイトで動いているもの。もうちょっと工夫すればスッキリと書けそうな気もするが、どうだろうか。

全然関係ないけど、今日から「ビルド」って普通にカタカナで書くことにした。さかのぼってまでは直さない。