今までコードのハイライトライブラリはhighlight.jsを使っていましたが、使っていくうちに細かいところが気になるようになり、Prism.jsに乗り換えたいなぁと思うようになりました。
ただ普通に乗り換えるとなると<code>
タグに入れるクラスなど、過去記事を全部Prism.js向けに直さないといけなくなり非常に面倒です。でもやっぱりPrism.jsに乗り換えたいし、なんとかならないかなぁ…。
ということで、今回はhighlight.jsからPrism.jsに乗り換える方法を解説していきます。過去記事を全部Prism.js向けに修正するのはさすがに面倒なのでjsでうまいことやります。解説記事が皆無だったので自己流ですが悪しからず。
Prism.jsの使い方がわからない人は以下の記事で解説しているので参考にしつつ進めてください。
>>Prism.jsの使い方!シンタックスハイライトにおすすめ
highlight.jsとPrism.jsの違いを把握しておく
highlight.jsとPrism.jsではハイライトの仕方が違うので、まずはここを把握しておきましょう。
なお、共通点としてはどちらも<pre><code> ~ </code></pre>
の中で動作します。<pre>
だけや<code>
だけでは発動しません。
highlight.js
<code class="言語名 hljs">
でハイライト。「言語名」の部分でハイライトする言語が決まり、「hljs」は自動で入る。- 言語名の指定がない場合はhighlight.jsが自動で判定して「言語名 hljs」クラスを入れる(精度は微妙)
Prism.js
<code class="language-言語名">
でハイライト。自分で入力する。- 言語の自動判定なし。
- 「language-**」というクラスがあれば一応黒い画面に白い文字で表示できる(ハイライトはなし)
- プラグイン追加可能。
つまり、超簡単に言えばhighlight.jsを使っているときに指定していた「言語名」のクラスを「language-言語名」というクラスに置換してやればいいわけです。
それと、僕はhighlight.jsの使い方がよくわからないまま使ってた時期があったので、過去記事によって<code>
に言語名の指定があったりなかったりとまちまちです。この辺の違いも吸収してやる必要がありますね。
やることを整理する
乗り換えるにあたってPrism.jsの便利なプラグインも一緒に入れちゃいます。今回は「Line Numbers」と「Line Highlight」の2つを入れます。
- Line Numbers:行数を表示する。
<pre class="line-numbers">
で表示(クラスを入れるのは<code>
じゃないので注意) - Line Highlight:任意の行の背景をハイライトする。
<pre data-line="2, 5-8">
(=2行目と5〜8行目をハイライト)みたいに指定(これも<code>
じゃないので注意)
他にもいろいろプラグインがあります。この辺は実際見た方が早いと思うので公式サイト見てください。
>>https://prismjs.com/#plugins
highlight.jsからPrism.jsへ乗り換えるためにやることをまとめるとこんな感じ。
<code class="言語名">
の場合→<code class="language-言語名 line-numbers">
に置換する。<code>
の場合(言語名が入っていない場合。主に過去記事)→<code class="language-undefined line-numbers">
を新しく追加する(別にundefinedじゃなくてもいいんだけど、黒い画面と白文字で表示したいので指定なしって意味でとりあえずundefinedとしておく)- 念のため自分で
<code class="language-言語名">
と指定してしまった(「language-」の部分を自分で入れてしまった)場合でも正しくハイライトできるようにする(というかこれが本来のPrism.jsの指定なので一応) <pre class="line-numbers">
をjsで入れてLine Numbersを自動で有効にする。- 行数を表示したくない場合は自分で
<pre class="no-line-numbers">
を指定して行数を非表示にする。
Line Numbersは毎回指定するのが面倒なのでjsで自動で入れちゃいます。行数を表示したくない時だけ<pre class="no-line-numbers">
を自分で指定して行数を非表示にします(Line Numbersは「no-line-numbers」クラスを入れると行数を非表示にできます)
なんだかごちゃごちゃしてますが、要するにパターンとしては
<code class="言語名">
→<code class="language-言語名 line-numbers">
<code>
→<code class="language-undefined line-numbers">
<code class="language-言語名">
→<code class="language-言語名">
(変更なし)
という感じにしたいわけです。
で、乗り換える手順はこんな感じで行きます。
- Prism.jsをダウンロード+読み込み(highlight.jsを使っている状態でPrism.jsを読み込んでokです。highlight.jsは
<pre><code>
に勝手に反応しますが、Prism.jsは<code>
に「language-**」というクラスを入れない限り何も反応しません) - 上で書いたやることを実現するスクリプトを書く。クラスの詳細度の関係でhighlight.jsよりもPrism.jsの方がスタイルが強いので、highlight.jsを有効にしたままPrism.jsでハイライトを上書きできます。
- スクリプトがちゃんと動いているのを確認したら最後にhighlight.jsを削除します。
説明ばかりだと飽きちゃうので、早速highlight.jsからPrism.jsへ乗り換えていきましょう。
補足:本番環境をいじるのが怖いなら開発環境を用意しよう
「本番環境をいじって変なことになったら怖い…」という人はローカルに開発環境を作ってそこで試しながらやるのがおすすめです。まあほとんどPHPも触らないので余程のことがない限り大丈夫だとは思いますが…。
WordPressの開発環境はLocalというフリーソフトとAll-in-One WP Migrationというプラグインで超簡単に作れます。
以下の記事で解説しているので不安な人はやってみてください。
>>【超簡単】本番のWordPressをローカル環境に移行する最も簡単な方法
highlight.jsからPrism.jsへ乗り換える
1.Prism.jsをダウンロード+読み込み
公式サイトからPrism.jsをダウンロードしましょう。
必要な言語とプラグインにチェックを入れてダウンロードします。
>>https://prismjs.com/download.html
Prism.jsはCDNよりダウンロードして読み込んだ方がいいです。
CDNだと言語ごとに1つずつスクリプトを読み込まないといけないので大変なことになります。ダウンロード版は自分がハイライトしたい言語を選択して1つのファイルにまとめられるので軽いですね。
それと、面倒だからといって言語を全部選択してダウンロードするのはやめましょう。せっかくの軽量ライブラリなのに意味ないです。
ダウンロードしたらFTPソフトなどを使ってサーバーにcssとjsをアップします。
子テーマを使っている人は子テーマ内にアップすればokです。僕はcssとjsディレクトリを作ってそこに入れました。
そうしたらheader.phpで読み込みましょう。これも子テーマ内で読み込めばok。
<link rel="stylesheet" href="<?php echo get_stylesheet_directory_uri(); ?>/css/prism.css">
<script src="<?php echo get_stylesheet_directory_uri(); ?>/js/prism.js"></script>
これでPrism.jsの読み込みはokです。まだ何も起きてないですが、<pre><code class="language-言語名">
と指定すればPrism.jsのハイライトが有効になると思います。
2.highlight.jsからPrism.jsへ乗り換えるスクリプトを書く
さっきまとめた「highlight.jsからPrism.jsへ乗り換えるためにやること」を実現するスクリプトを書きます。
これはもうコードを見てもらうのが早いですね。以下のコードをPrism.jsのcssとjsを読み込んだ下に<script>
とかで囲って入れます。jQueryが競合してしまう場合は$
をjQuery
に置き換えてください。
$(function() {
$('pre').each(function() {
var $pre = $(this);
var $code = $pre.find('code');
var codeClassName = $code.attr('class');
// codeがクラスなしなら.language-undefined
if(!$code.attr('class')) {
$code.addClass('line-numbers language-undefined');
} else if(codeClassName.indexOf('language-') == 0) {
// 間違えて自分でlanguage-と指定してしまったらlanguage-はつけない
//preにno-line-numbers指定で行数を非表示
if($pre.hasClass('no-line-numbers')) {
return;
} else {
//通常は自動でline-numbersを追加
$pre.addClass('line-numbers');
}
} else {
// codeに言語名ありパターン。codeにlanguage-とpreにline-numbersをつける
// preにno-line-numbers指定で行数を非表示
if($pre.hasClass('no-line-numbers')) {
$code.removeClass(codeClassName).addClass('language-' + codeClassName);
} else {
//通常は自動でline-numbersを追加
$code.removeClass(codeClassName).addClass('language-' + codeClassName);
$pre.addClass('line-numbers');
}
}
});
});
ざっくりとコメントにも書きましたが、順番に解説します。
$('pre').each(function() {
var $pre = $(this);
var $code = $pre.find('code');
var codeClassName = $code.attr('class');
ページ内の<pre>
全部に処理をかけます。変数は見たままですね。
$pre = $(this);
は各々の<pre>
という意味です。
// codeがクラスなしなら.language-undefined
if(!$code.attr('class')) {
$code.addClass('line-numbers language-undefined');
<code>
に言語名がないパターンですね。過去記事対策です。
この場合はとりあえず黒い画面に白い文字で表示させたいので「language-undefined」クラスを入れます。あと行数を表示したいので「line-numbers」クラスも入れます。
言語のハイライトはできないですが、これだけでもそれっぽく見えるのでよし。
} else if(codeClassName.indexOf('language-') == 0) {
// 間違えて自分でlanguage-と指定してしまったらlanguage-はつけない
//preにno-line-numbers指定で行数を非表示
if($pre.hasClass('no-line-numbers')) {
return;
} else {
//通常は自動でline-numbersを追加
$pre.addClass('line-numbers');
}
うっかり「language-」の部分を自分で指定しちゃったパターンです。判定方法はindexOf()
を使って「language-」から始まるクラス名があるかどうかで判定します。
さらに分岐で、<pre class="no-line-numbers">
が指定されていたらそのまま抜けます(=行数は表示しない)。それ以外なら<pre class="line-numbers">
として自動で行数を表示します。
} else {
// codeに言語名ありパターン。codeにlanguage-とpreにline-numbersをつける
// preにno-line-numbers指定で行数を非表示
if($pre.hasClass('no-line-numbers')) {
$code.removeClass(codeClassName).addClass('language-' + codeClassName);
} else {
//通常は自動でline-numbersを追加
$code.removeClass(codeClassName).addClass('language-' + codeClassName);
$pre.addClass('line-numbers');
}
}
最後に<code class="言語名">
のパターンです。
これも<pre class="no-line-numbers">
が指定されていたら<code>
のクラスを置換するだけにします(=行数は表示しない)。指定されていないなら<pre class="line-numbers">
として自動で行数を表示します。
<code>
のクラスを置換する方法としては、元々入っていたクラスを変数に保存した後、一度クラスを削除して「language-言語名」というクラスを再度追加するという感じです。
スクリプトはこんな感じです。これで保存するとPrism.jsが動作してコードがハイライトされるはずです。
本来Prism.jsは<code class="language-言語名">
という指定がないとハイライトできませんが、上記のスクリプトはlanguage-
の部分を自動で入れてくれるので、自分が記事を書く場合は<code class="言語名">
と書けば大丈夫です。
記述が短い分ちょっとラクですね。もちろん<code class="language-言語名">
と自分で指定してもok。
3.highlight.jsを削除する
上記のコードをコピペしてPrism.jsのハイライトが動作していれば乗り換えができているのでhighlight.jsは削除して構いません。
highlight.js関連でオリジナルのスタイルを書いている場合はPrism.js向けに書き直しておきましょう。もしくはいらないならこれも削除してしまうとか。
まとめ
コードをハイライトするプラグインとかライブラリってたくさんあるんですが、途中で乗り換えるとなると全記事を修正しないといけなくなるのが本当に面倒なんですよね。
今回自分がhighlight.jsからPrism.jsの乗り換えるにあたって「全記事修正はさすがにめんどくさい…できるならjsでゴリ押ししたい」と思っていたのでやってみました。
個人的にはハイライトライブラリはhighlight.jsよりもPrism.jsかなと思っているので、同じように乗り換えたいと思っている人がいたら参考にしてみてください。