はてなブログ: コードブロックに行番号を振る簡単な方法
本記事では、はてなブログでpreタグを使ってコード表記をする際に、行ごとに連番を付ける簡単な方法を紹介します。javaScriptとCSSスタイリングの組み合わせで、読みやすく整形されたコード表示が可能となります。
デモページ
コードブロックの表記方法
以下のように記述することによってpreタグが生成され、シンタックスハイライトも自動で付与されます。
Markdown
```ファイルタイプ(htmlなど) ここにコードの中身を書く ```
はてな記法(スーパーpre記法)
>|ファイルタイプ| ここにコードの中身を書く ||<
生成されるHTML要素
"code"、"lang"クラスを持つpreタグを生成します。ちなみにdata-unlink=""
は、URLに対する自動リンク化(はてなブログの独自機能)を、preタグ内で無効にするためのコードです。
<pre class="code lang-hatena" data-lang="hatena" data-unlink=""> コードの中身 </pre>
連番を振るソースコード
大まかなコードの構成・仕組みとしては、
- JavaScriptでコードブロック内の行ごとに動的にHTML要素を追加し、
- 追加された要素には、あらかじめ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; } });
コードの解説
解説が開きます
var codeBlocks = document.getElementsByClassName("code")
」
codeBlocks
変数に格納[].forEach.call(codeBlocks, function(element) { ... })
」
codeBlocks
内の各要素に対し、forEach
メソッドを使ってループ処理を行うif (/lang/.test(element.className)) { ... }
」
{ ... }
内の処理を行うvar lines = element.innerHTML.split(/\n/);
」
\n
)で分割し、各行をlines
変数に格納var formattedCode = ""
」
formattedCode
を初期化lines.forEach(function(line) { ... })
」
if (line !== "") { ... }
」
{ ... }
内の処理を行うformattedCode += '\n<span class="code-line">' + line + "</span>"
」
line
の冒頭に改行を付け、spanタブで囲い、code-lineクラスを付与element.innerHTML = formattedCode
」
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; }
コードの解説
「code-line::before」(before要素) 「.code-line:nth-child(even)」
解説が開きます
counter-increment: linenumber
:
各コード行に適用されているこのクラスに対し、counter-increment
プロパティにて行番号をインクリメントする *1
before要素を利用し、各コード行の前に行番号を表示し、表示のスタイルを指定
content: counter(linenumber)
: 「1.」のcounter-increment: linenumber
で取得された行番号を、カウンター(counter
)から取得してcontent
として表示display: inline-block
: 要素を行内ブロック要素として表示 *2
偶数行に対してスタイルを適用
アレンジ
背景色をテキストの幅に揃える
.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"を持ち、指定された横幅、高さ、背景色、余白のスタイルが適用されます。この要素は行内ブロックとして振る舞い、横方向に並び、指定されたスタイルに基づいて表示されます。