WordPressでソースコードをハイライトするならPrism.jsが多機能でおすすめ
ソースコードをハイライトするライブラリはいくつかありますが、全て試した中で一番使いやすかったPrism.jsについて紹介したいと思います。プラグインによって機能を拡張できたり、自分でも機能を追加することができます。
ダウンロード

ThemesはあとでCSSファイルを編集すればカスタマイズできるのでとりあえず気に入ったものを選びます。Languagesでハイライトしたいプログラミング言語を選びます。

Pluginsでは必要な機能だけ追加することができます。ここでは、よく使うと思われる行のハイライトと行番号のプラグインを追加し、説明していきます。Remove initial line feedは1行目の空行を削除してくれるので入れておきましょう。

カスタマイズが終わったら、JSファイルとCSSファイルをそれぞれダウンロードします。
基本的な使い方
読み込み
<link href="prism.css" rel="stylesheet">
<script src="prism.js"></script>
ダウンロードしたファイルを読み込みます。
HTMLはエスケープ
add_filter('the_content', function($content) {
$content = preg_replace_callback('/<pre(.*?)><code>(.+?)<\/code><\/pre>/s', function($matches) {
$matches[2] = preg_replace(['/</', '/>/'], ['<', '>'], $matches[2]);
return '<pre'.$matches[1].'><code>'.$matches[2].'</code></pre>';
}, $content);
return $content;
});
HTMLをハイライトするときは、<
や >
はそれぞれ <
>
と記述する必要がありますが、毎回手作業で置き換えるのは大変なのでPHP側で置換します。
<!-- ダメな例 -->
</code></pre>
<!-- 正しい例 -->
</code></pre>
ただし、この正規表現を使った方法だと、</code>
や </pre>
が含まれている場合、そこでタグが閉じられてしまって正しく置換されません。なので、そういう場合は手動で <
>
に置き換えます。
記法
<pre class="language-markup"><code>
ここにソースコード
</code></pre>
class="language-"
で始まるクラス名をつけます。ハイフンのあとはプログラミング言語名になりますが、Prism.jsで定義されているので以下のリンク先を確認してください。
スマホでのスクロール改善
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
-webkit-overflow-scrolling: touch;
border-radius: 0.3em;
}
スマホでスクロールを滑らかにできるように追加します。
行番号の表示
行番号を表示するにはLine Numbersプラグインが必要なので、チェックを入れてからダウンロードしてください。
記法
<pre class="language-markup line-numbers"><code>
ここにソースコード
</code></pre>
line-numbers
クラスを付けると行番号が表示されます。
開始行を指定
<pre class="language-markup line-numbers" data-start="3"><code>
ここにソースコード
</code></pre>
data-start
属性で開始行を指定できます。
行番号プラグインの問題点
CSSを見ればわかりますが、行番号の横幅が width
で設定されており、可変幅には対応していません。なので、行番号が4桁を超えると表示が崩れてしまいます。
行番号プラグインを修正
<code>
に 行番号の幅分、padding
を設定するようにします。
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
font-size: 1em;
overflow: auto;
-webkit-overflow-scrolling: touch;
border-radius: 0.3em;
}
pre[class*="language-"] > code {
display: inline-block;
padding: 1em;
}
pre.line-numbers {
position: relative;
padding-left: 3.8em;
counter-reset: linenumber;
}
.line-numbers .line-numbers-rows {
position: absolute;
pointer-events: none;
top: 0;
top: 1em; /* pre[class*="language-"] > code の padding-top */
font-size: 100%;
left: -3.8em;
left: 1em; /* pre[class*="language-"] > code の padding-bottom */
width: 3em;
letter-spacing: -1px;
border-right: 1px solid #999;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
Prism.hooks.add('complete', function(target) {
var $target = $(target.element),
$lineRows = $('.line-numbers-rows'),
padding = parseInt($target.css('padding-left')) + $lineRows.outerWidth() + parseInt($lineRows.children().eq(0).css('padding-right'));
$target.css('padding-left', padding);
});
Prism.jsにはWordPressのようにフックがあるので任意のタイミングで処理することができます。
行番号が増えても横幅が自動調整されるようになりました。
行ハイライト
行ハイライトするにはLine Highlightプラグインが必要なので、チェックを入れてからダウンロードしてください。
デフォルトだと横スクロールできるとき、背景色が途切れてしまうので少しカスタマイズします。
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
font-size: 1em;
overflow: auto;
-webkit-overflow-scrolling: touch;
border-radius: 0.3em;
}
pre[data-line] {
position: relative;
padding: 1em 0 1em 3em;
}
.line-highlight {
position: absolute;
left: 0;
left: -3em;
right: 0;
padding: inherit 0;
margin-top: 1em;
background: hsla(24, 20%, 50%,.08);
background: linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
background-color: #633b6a;
pointer-events: none;
line-height: inherit;
white-space: pre;
z-index: -1;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
pre[class*="language-"] > code {
display: inline-block;
position: relative;
min-width: 100%;
padding: 1em;
z-index: 1;
}
ソースコードブロックの余白は <code>
に設定します。
Prism.hooks.add('after-highlight', function(env) {
var lines = env.highlightedCode.split('\n');
for (var i = 0; i < lines.length - 1; ++i) {
if (lines[i] === '') {
lines[i] = '\n';
continue;
}
lines[i] = '<div>' + lines[i] + '</div>';
}
$(env.element).html(lines.join(''));
});
iOSで、横スクロール可能なとき、ハイライト部分の背景色が右端まで伸びないバグがあったので、1行ずつ div
要素で囲みます。
使い方
<pre class="language-css" data-line="2-4,8"><code>
ここにソースコード
</code></pre>
data-line
に行数を設定することでハイライトさせることができます。カンマ区切りで複数指定でき、2-4
のようにハイフンでつなぐことで2〜4行と範囲指定もできます。
行番号と行ハイライトを同時に
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
font-size: 1em;
overflow: auto;
-webkit-overflow-scrolling: touch;
border-radius: 0.3em;
}
pre[data-line] {
position: relative;
padding: 1em 0 1em 3em;
}
pre[class*="language-"] > code {
display: inline-block;
position: relative;
min-width: 100%;
padding: 1em;
z-index: 1;
}
.line-highlight {
position: absolute;
left: 0;
left: -3em;
right: 0;
padding: inherit 0;
margin-top: 1em;
background: hsla(24, 20%, 50%,.08);
background: linear-gradient(to right, hsla(24, 20%, 50%,.1) 70%, hsla(24, 20%, 50%,0));
background-color: #633b6a;
pointer-events: none;
line-height: inherit;
white-space: pre;
z-index: -1;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
pre.line-numbers {
position: relative;
padding-left: 3.8em;
counter-reset: linenumber;
}
.line-numbers .line-numbers-rows {
position: absolute;
pointer-events: none;
top: 0;
top: 1em; /* pre[class*="language-"] > code の padding-top */
font-size: 100%;
left: -3.8em;
left: 1em; /* pre[class*="language-"] > code の padding-bottom */
width: 3em;
letter-spacing: -1px;
border-right: 1px solid #999;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
Prism.hooks.add('after-highlight', function(env) {
var lines = env.highlightedCode.split('\n');
for (var i = 0; i < lines.length - 1; ++i) {
if (lines[i] === '') {
lines[i] = '\n';
continue;
}
lines[i] = '<div>' + lines[i] + '</div>';
}
$(env.element).html(lines.join(''));
});
Prism.hooks.add('complete', function(target) {
var $target = $(target.element),
$lineRows = $('.line-numbers-rows'),
padding = parseInt($target.css('padding-left')) + $lineRows.outerWidth() + parseInt($lineRows.children().eq(0).css('padding-right'));
$target.css('padding-left', padding);
$target.parent().children('.line-highlight').each(function() {
$(this).appendTo($target);
});
});
行番号と行ハイライトプラグインを同時に使用すると、ハイライトする .line-highlight
要素が <code>
ではなく、<pre>
直下に移動してしまうので、<code>
直下になるように修正します。
横幅を飛び出してしまうときの対処法
例えば、max-width: 500px
に指定していて、ソースコードの要素が overflow: auto
なのに飛び出してしまうことがあります。どのような場合にこの現象が起きるのかは分かりませんが、対処法を紹介します。
<div class="prismjs">
<pre class="language-css"><code>
ここにソースコード
</code></pre>
</div>
.prismjs {
display: table;
table-layout: fixed;
width: 100%;
}
ソースコードブロックの外側を要素で囲み、CSSを記述します。
CSS本執筆しました!!!
CSS本出します!1/29発売予定
— たかもそ@CSS本1/29発売!! (@takamosoo) 2018年12月31日
自分がCSS学びたての頃にもっとはやく知りたかったテクニックを載せています。CSSの基礎知識について解説していないので、中級者〜向けとなります。CSS入門書を読んではみたものの、思い通りに作れない人にオススメです。
よろしくお願いします。https://t.co/fkz1dM03Pj pic.twitter.com/suYyaPqwIs