GitHub Pagesでコードブロックにファイル名を表示する
- jekyll 3.7.4
- highlight.js v9.13.1
GitHub PagesとJekyllを使っているという前提ですが、QiitaのようにMarkdownのコードブロックでファイル名を表示できるようにします。

JavaScriptとCSSでファイル名を表示
JavaScript
以下のようにmyscript.jsというファイルを作成してみましょう。ここではassets/jsフォルダに置いています。
document.addEventListener('DOMContentLoaded', () => {
const code = document.getElementsByTagName('code');
Array.from(code).forEach(el => {
if (el.className) {
const s = el.className.split(':');
const highlightLang = s[0];
const filename = s[1];
if (filename) {
el.classList.remove(el.className);
el.classList.add(highlightLang);
el.parentElement.setAttribute('data-lang', filename);
el.parentElement.classList.add('code-block-header');
}
}
});
});
簡単に説明すると
DOMContentLoadedをしてHTMLの読み込みが完了したら、<code>タグを持つ要素を取得します。結果はHTMLCollectionとして返ります。-
そのHTMLCollectionを
forEachで回して、それぞれの要素がclass名を持っていればそのclass名を:文字で分割します。 -
もし
:文字がない場合は分割できないのでhighlightLangにはそのままclass名が入り、filenameはundefinedになります。 -
if (filename)の中では一旦もとのclass名を削除して:hoge.rbを除いたclass名を再度追加しています。 - それから
<code>タグの親要素である<pre>タグにdata-lang="hoge.rb"とcode-block-headerというclassを追加します。class名は任意です。
CSS
.code-block-headerの中身は以下のようにします。適当なsassファイルに追加して下さい。
.code-block-header {
position: relative;
padding-top: 32px;
&::before {
content: attr(data-lang);
background: darken(#f6f8fa, 8%);
color: darken(#f6f8fa, 50%);
display: block;
font-size: 13px;
font-weight: 700;
padding: 1px 10px;
position: absolute;
top: 0;
left: 0;
z-index: 10;
}
}
data-属性とCSSの::beforeを使っています。
JavaScriptを読み込む
最後に作成したmyscript.jsを読み込みましょう。
HTMLの<head>タグの中に追加します。
<script src="/assets/js/myscript.js"></script>
これで一応コードブロックにファイル名を表示することができました。

しかしシンタックスハイライトが効いていません。
何故ならGitHub Pagesがデフォルトで使うRougeは、例えばruby:hoge.rbならlanguage-ruby:hoge.rbというclass名を使うことになるからです。
Rougeの代わりにhighlight.jsを使う
DOMが構築された後にJavaScriptでいろいろな操作をしているので、RougeよりもJavaScriptのライブラリのほうが都合が良いです。ここではhighlight.jsを使います。
Rougeを無効にする
詳しくはこちらを参照してください。
markdown: kramdown
kramdown:
syntax_highlighter_opts:
disable: true
highlight.jsをダウンロード
公式サイトからhighlight.pack.jsと好きなテーマのCSSファイルをダウンロードして読み込みます。ここではgithub-gistというテーマを選びました。
<link rel="stylesheet" href="/assets/css/github-gist.css">
<script src="/assets/js/highlight.pack.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<pre>タグと<code>タグのbackground-colorが違う場合は修正しましょう。
以上で完了です。
補足
myscript.jsのコードは改良の余地があります。というのも生成されたHTMLを見てみると<code>タグには言語毎のclassの他にhljsというclassが追加されています。classが2つ以上あると上記のコードではたぶんうまく動かないと思います。
なぜちゃんと動いているかというと、DOMContentLoadedの中ではまだhljsclassは追加されていなくて、その挙動に依存しているからです。