自動化厨のプログラミングメモブログ │ CODE:LIFE

Python/ExcelVBA/JavaScript/Raspberry Piなどで色んなことを自動化

【2020年更新】はてなブログで書いたコードブロックに行番号を表示する方法(CSS+JavaScript)

この記事でできるようになること

  1. はてなブログのコードブロックに行番号を表示
  2. はてなブログのコードブロックの偶数行のみ背景色をつける
  3. [おまけ]はてなブログのコードブロックの左上に言語名を表示する

最初は行番号のみで考えていましたがついでに縞々もやってみました。

完成イメージは以下の状態

f:id:maru0014:20180522222246p:plain

要件

  • JavaScriptで追加する方法もあるみたいだけどCSSでやりたい
  • シンタックスハイライトははてな標準で十分
  • highlight.jsなどのライブラリは使いたくない

CSSのcontent: counterを使ってみる

body {
  counter-reset: number 0;
}
pre.code > span {
   counter-increment: linenumber;
}
pre.code > span:before {
    content: counter(linenumber);
}

しかし実際のコードブロックのHTMLは以下のように行単位で囲むタグは無く、行カウントするのは不可能。

<pre class="code lang-python" data-lang="python" data-unlink=""><span class="synComment"># -*- coding: utf-8 -*-</span>

<span class="synStatement">if</span> __name__ == <span class="synConstant">"__main__"</span>:
    <span class="synIdentifier">print</span>(<span class="synConstant">"1行目"</span>)
    <span class="synIdentifier">print</span>(<span class="synConstant">"2行目"</span>)
</pre>

これでは以下のようにspanごとに番号がカウントされてしまう。

f:id:maru0014:20180521224911p:plain

ようは行ごとにタグで囲ってそれをカウントさせればいいのだが、はてなブログにおいては出力されるHTMLの設定まではできず。

JavaScriptで行ごとにブロック化する必要がありそう。

結果CSSとJavaScriptの併用はせざるを得ない

ただし行番号までJavaScriptで追加するとコードが長くなるし複雑な(めんどくさい)ので、あくまでも行ごとにdivで囲むだけに留めてカウントはCSSに任せることにしました。

JavaScriptで行ごとにdivで囲む

2020/09/12 追記

Kaz Mu (id:fa11enprince)さんから頂いたコメントをもとに7行目を追加しました。

また、見た目上は空行があるけどコピペすると空行が無くなるという問題があったため、11行目で空行に対して改行コードを追加する処理を追記しました。

<script>
var codeBlocks = document.getElementsByClassName('code');
[].forEach.call(codeBlocks, function(e) {
  if (!/lang/.test(e.className)) {
      return;
  }
  var sourceCode = e.innerHTML.slice(-1) === '\n' ? e.innerHTML.slice(0, -1) : e.innerHTML;
  var lines = sourceCode.split(/\n/);
  var codeBlock = "";
  lines.forEach(function(line){
    line += line === '' ? '\n' : '';
    codeBlock += '<div class="code-line">' + line + '</div>'      
  })
  e.innerHTML = codeBlock;
});
</script>

上記のタグをはてなブログのデザイン設定→フッタへ追加

f:id:maru0014:20180522223725p:plain

CSSで付け足したdivごとにカウントアップ

/*code-lineクラスの数でカウント*/
.code-line {
  counter-increment: linenumber;
}

/*偶数行のみ背景色を適用*/
.code-line:nth-child(even){
  background-color: #eee;
}

/*行番号を擬似要素として表示*/
.code-line::before {
  content: counter(linenumber);
  display:inline-block;
  color: #ccc;
  text-align: right;
  width: 35px;
  padding: 0 15px 0 0;
}

同じく上記スタイルシートをはてなブログのデザイン設定→デザインCSSへ追加

f:id:maru0014:20180522223925p:plain

余白や背景色、文字色などは好みでCSSをカスタムしてみてください。

トータル40行足らずで実装できたのでまぁまぁ上出来?もっと良い書き方あったら教えてくださいな。

[おまけ]コードブロック左上に言語名を表示するCSS

/*コードブロックに言語名を表示*/
pre.code:before {
    content: attr(data-lang);
    display: inline-block;
    background: white;
    color: #666;
    padding: 3px;
    position: absolute;
    margin-left: -10px;
    margin-top: -30px;
}

pre.code {
    padding-top: 30px !important;
}

CODE:LIFEで使っているテーマ用に調整してあるので、他で使うならmarginとかの微調整は必要かもしれません。


今回の記事は以下を参考にさせていただきました

qiita.com

am1tanaka.hatenablog.com