はてなブログ: コードブロックに行番号を振る簡単な方法

本記事では、はてなブログでpreタグを使ってコード表記をする際に、行ごとに連番を付ける簡単な方法を紹介します。javaScriptとCSSスタイリングの組み合わせで、読みやすく整形されたコード表示が可能となります。

https://pixabay.com/photos/track-and-field-athletic-field-1867053/

デモページ

デモページを見る

コードブロックの表記方法

以下のように記述することによってpreタグが生成され、シンタックスハイライトも自動で付与されます。

Markdown

 ```ファイルタイプ(htmlなど)
 ここにコードの中身を書く
 ```

はてな記法(スーパーpre記法)

 >|ファイルタイプ|
 ここにコードの中身を書く
 ||<

生成されるHTML要素

"code"、"lang"クラスを持つpreタグを生成します。ちなみにdata-unlink=""は、URLに対する自動リンク化(はてなブログの独自機能)を、preタグ内で無効にするためのコードです。

<pre class="code lang-hatena" data-lang="hatena" data-unlink="">
 コードの中身
</pre>

連番を振るソースコード

大まかなコードの構成・仕組みとしては、

  1. JavaScriptでコードブロック内の行ごとに動的にHTML要素を追加し、
  2. 追加された要素には、あらかじめCSSで連番を振るスタイリングを施しておきます。

JavaScript

このコードは、"code"クラスを持つHTML要素の中で、さらにクラス名に"lang"が含まれている要素(つまり、コードブロック表記で生成されるHTML要素)に対し、コードの行ごとにスタイルを適用するための処理を行っています。

/** コードブロックに連番を振る */
var codeBlocks = document.getElementsByClassName("code");
[].forEach.call(codeBlocks, function(element) {
  if (/lang/.test(element.className)) {
    var lines = element.innerHTML.split(/\n/);
    var formattedCode = "";
    lines.forEach(function(line) {
      if (line !== "") {
        formattedCode += '\n<span class="code-line">' + line + "</span>";
      }
    });
    element.innerHTML = formattedCode;
  }
});

コードの解説

解説が開きます

  1. var codeBlocks = document.getElementsByClassName("code")
    • HTML内の"code"クラスを持つ要素をすべて取得し、それらの要素をcodeBlocks変数に格納
  2. [].forEach.call(codeBlocks, function(element) { ... })
    • 取得したcodeBlocks内の各要素に対し、forEachメソッドを使ってループ処理を行う
  3. if (/lang/.test(element.className)) { ... }
    • クラス名に"lang"が含まれている場合、{ ... }内の処理を行う
  4. var lines = element.innerHTML.split(/\n/);
    • 要素内のコードを改行(\n)で分割し、各行をlines変数に格納
  5. var formattedCode = ""
    • 新しいコードを格納するための変数formattedCodeを初期化
  6. lines.forEach(function(line) { ... })
    • 各行に対し、ループ処理を行う
  7. if (line !== "") { ... }
    • 空でない行の場合、{ ... }内の処理を行う
  8. formattedCode += '\n<span class="code-line">' + line + "</span>"
    • 取得した各行の変数lineの冒頭に改行を付け、spanタブで囲い、code-lineクラスを付与
  9. element.innerHTML = formattedCode
    • 元の要素(innerHTMLプロパティ)を処理されたコード(変数formattedCode)で更新

CSSでスタイリング

このCSSコードは、行番号を表示するためのスタイルをコード行に適用しています。 具体的には、上記したJavaScriptコードで生成された「code-lineクラス」に対し、CSSにてスタイリングを施し、また偶数行には背景色を付けるスタイルも定義しています。

.code-line {
  counter-increment: linenumber
}

.code-line::before {
  content: counter(linenumber);
  display: inline-block;
  color: #ccc;
  text-align: left;
  width: 30px;
  padding: 0 5px 0 0
}

.code-line:nth-child(even) {
  background-color: #E8E9F2;
  width: 100%;
  display: inline-block;
}

コードの解説

解説が開きます

  1. .code-line
    • counter-increment: linenumber:
      各コード行に適用されているこのクラスに対し、counter-incrementプロパティにて行番号をインクリメントする *1
  2. code-line::before」(before要素)
    before要素を利用し、各コード行の前に行番号を表示し、表示のスタイルを指定

    • content: counter(linenumber): 「1.」のcounter-increment: linenumberで取得された行番号を、カウンター(counter)から取得してcontentとして表示
    • display: inline-block: 要素を行内ブロック要素として表示 *2
  3. .code-line:nth-child(even)
    偶数行に対してスタイルを適用

アレンジ

背景色をテキストの幅に揃える

.code-line:nth-child(even)要素でwidthの指定をautoに変える(もしくはwidth自体を削除)すると、偶数行に付与した背景色の幅がテキストの長さと同じになります。

出力見本

.code-line {
/* 中略 */
}

.code-line::before {
/* 中略 */
}

.code-line:nth-child(even) {
  background-color: #E8E9F2;
  /* width: 100%; */
  display: inline-block;
}

おわりに

はてなブログの記事内にコードブロックを設置した時、各コード行に序数を割り当てる方法について解説しました。

素敵なコーディング環境作りの一助になれば幸いです♬

脚注

*1:「インクリメント」とは、プログラミングや数学の文脈でよく使われる用語で、特定の値を1だけ増やす操作を指します。CSSの"counter-increment"プロパティも同様に、特定のカウンターを1だけ増加させるもので、ここでは"linenumber"というカウンターがインクリメントされています。これにより、各".code-line"要素が表示されるたび、"linenumber"の値が1ずつ増加します。

*2:"display: inline-block"は、CSSで要素の表示方法を指定するプロパティであり、要素を行内ブロック要素として表示します。このプロパティは、通常のインライン要素(行内要素)とブロック要素の中間に位置するため、行内ブロック要素と呼ばれます。

「インラインブロック要素の特徴」

①行内ブロックのように振る舞う: "inline-block"要素は、通常のインライン要素のように、他の要素と同じ行に表示されます。しかし、同時にブロック要素のように、横幅や高さの調整が可能です。
②横並びの要素として配置: "inline-block"要素は横方向に並び、隣接する要素と同じ行に表示されます。これにより、横方向に並ぶ要素を制御しながら、高さや余白などの調整が可能です。
③高さ・幅の指定が可能: 通常のインライン要素は高さや幅を指定することができませんが、"inline-block"要素は指定することができます。これにより、テキストや画像などを横に並べつつ、それぞれの要素に独自の高さや幅を設定できます。
④ボックスモデルを持つ: "inline-block"要素はブロック要素と同様に、ボックスモデル(content、padding、border、margin)を持ちます。したがって、これらのプロパティを調整して要素をスタイリングできます。

「cssコードの例」

 .inline-block-example {
   display: inline-block;
   width: 100px; / 幅の指定 /
   height: 50px; / 高さの指定 /
   background-color: #ffcc00; / 背景色の指定 /
   margin-right: 10px; / 右の余白の指定 /
 }

上記の例では、".inline-block-example"クラスが"display: inline-block"を持ち、指定された横幅、高さ、背景色、余白のスタイルが適用されます。この要素は行内ブロックとして振る舞い、横方向に並び、指定されたスタイルに基づいて表示されます。