コードブロックに行番号を実装する

ブログやサイトなどでのコードブロック(ソースコード表示)に、highlight.js や Google Code Prettify、Prism などのシンタックスハイライターを用いたり、pre 要素と code 要素をそのまま使っている方は多いと思います。

そのようなコードブロックに行番号が付いていると、コードの各行を参照しやすくなり、解説やデバッグの際にも役立ちます。

そこで今回は、JavaScript と CSS で手軽にソースコードに行番号を実装する方法をご紹介します。

アイキャッチ
この記事の目次

JavaScript で行番号表示部分を作成

こちらの JavaScript のコードを </body> の上あたり(できれば直前) に設置すると、pre 要素と code 要素を用いた2行以上のコードブロックの HTML を行番号仕様に書き換えることができます。コードが1行のときは何も変化しません。

<script>(function(){  const code = document.querySelectorAll('pre code');  if(code.length == 0) return;  for(let i = 0; i < code.length; i++){    if(!/\n/.test(code[i].innerHTML)) continue;    code[i].innerHTML = code[i].innerHTML.split('\n').map(line => {      return `<span class="line-wrap"><span class="line-number"></span><span class="line-code">${line}</span></span>`;    }).join('');  }})();</script>

Blogger で使う場合は、コードの <script><script>//<![CDATA[ に、</script>//]]></script> にそれぞれ置き換えてください。

備忘録がてらコードの解説をしてみます。

例えばこんな感じのコードブロックがあるとします。変化がわかりやすいように1行目に色を付けています。

const x = 5;const y = 10;console.log(x + y)

まず、このコードブロックに対して split('\n') を用いて code 要素内の内部テキストを改行毎に分割し、配列にします。

['const x = 5;', 'const y = 10;', 'console.log(x + y);']

次に、map() で配列の各要素に対して行番号表示の HTML タグを追加し、新しい配列を作成します。

['<span class="line-wrap"><span class="line-number"></span><span class="line-code">const x = 5;</span></span>', '<span class="line-wrap"><span class="line-number"></span><span class="line-code">const y = 10;</span></span>', '<span class="line-wrap"><span class="line-number"></span><span class="line-code">console.log(x + y);</span></span>']

ソースコードを 1 行ごとに span.line-wrap で囲み、その中に行番号を表示させるための span.line-number と、もともとのソースコードを表示させるための span.line-code を追加しています。

最後に、join('') で上で作成した新しい配列の要素を再び結合し、一つの文字列にして code 内を書き換えます。

<span class="line-wrap"><span class="line-number"></span><span class="line-code">const x = 5;</span></span><span class="line-wrap"><span class="line-number"></span><span class="line-code">const y = 10;</span></span><span class="line-wrap"><span class="line-number"></span><span class="line-code">console.log(x + y);</span></span></code></pre>

こうして行番号を表示するための HTML 要素を追加することができました。

CSS カウンターで行番号を付与

前項で作成した行番号表示用の HTML に行番号を振っていきます。

番号を付与する処理は innerText やら textContent なりを使えば JavaScript でも行えますが、precode の中身をコピーするボタンを使うと行番号までコピーされてしまうためベストな方法ではありません。

CSS カウンターという、この用途にうってつけのものが存在しますので、これを .line-number の疑似要素 ::before に使っていきます。

::before , ::aftercontent に指定された文字列は DOM に存在しないため、直接的にはコピーできません。詳しい解説は以下のリンク先を御覧ください。

以下がコードブロック全体の CSS のサンプルです。環境によっては表示が崩れる場合もあるので、適宜変更してください。

pre{  display: block;  line-height: 1.6;  margin: 32px 0;  font-size: 14px;  background: #333;  color: #fff;  white-space: pre-wrap;  overflow-wrap: anywhere;}pre code{  counter-reset: line; /* カウンター line を 0 に初期化 */  display: block;  margin: 0;  padding: 32px 16px 16px;  max-height: 320px;  overflow: auto;}.line-wrap{  display: flex;  margin: 0;  padding: 0;}.line-number{  flex-shrink:0;  flex-basis: 40px;  padding: 0 8px 0 0;  height: auto;  font-size: 12px;  text-align: right;  border-right: 1px solid var(--text);}.line-number::before{  counter-increment: line; /* カウンター line を 1 増加 */  content: counter(line); /* カウンターの値を表示 */}.line-code{  flex: 1;  margin: 0;  padding:0 0 0 16px;}

CSS カウンターに関わる部分はコードにコメントを入れてあります。個別のプロパティについて詳しく知りたい方はこちらの MDN の記事を参照してください。

使っている CSS は上記のものと若干違いますが、本記事で実際に行番号スクリプトを導入しています。見え方を確認していただけたら幸いです。

編集
ホーム