【HUGO】Render Hooks for Code Blocks を使ってコードブロックにファイル名を表示する

コードブロックにファイル名を表示したい

HUGOの v0.93.0 で追加された Render Hooks for Code Blocks を使うことで簡単に実装できます。

Render Hooks for Code Blocks | HUGO

実装例

layouts/_default/_markup/render-codeblock.html
1<div class="Code {{ if .Attributes.name }} Code--attr {{ end }}">
2    {{ with .Attributes.name }}
3        <div class="Code__name">{{ . }}</div>
4    {{ end }}
5
6    <div class="Code__inner">
7        {{ highlight (.Inner | safeHTML) .Type .Options }}
8    </div>
9</div>
記事Markdown内でのコードブロックの記載例
1```js {name="main.js"}
2document.addEventListner('DOMContentLoaded', () => {
3    console.log('Hello, World.');
4});
5```
SCSSの例
 1pre {
 2    line-height: 1.25;
 3    border-radius: 7px;
 4    overflow-x: auto;
 5    padding: 12px 16px 16px;
 6    display: block;
 7    & > code {
 8        display: inline-block;
 9    }
10}
11
12.Code {
13    margin: 16px 0;
14    position: relative;
15    &--attr {
16        pre {
17            border-top-left-radius: 0;
18        }
19    }
20    &__header {
21        display: inline-block;
22        padding: 5px 14px;
23        background: #333331;
24        color: #decbcb;
25        font-size: 85%;
26        font-family: 'SFMono-Regular', Menlo, Consolas, 'PT Mono', 'Liberation Mono', Courier, monospace;
27        border-top-left-radius: 7px;
28        border-top-right-radius: 7px;
29    }
30}

解説

layouts/_default/_markup/render-{kind}.html の名称を持つテンプレートを作成することで、マークダウンから HTML への変換処理をカスタマイズすることができます。

現在 hugo v0.102.3 時点でサポートされているフックの種類は次の通りです。

  • 画像
  • リンク
  • 見出し
  • コードブロック

例えば、a タグに target="_blank" を仕込んだりといった加工処理もフックを利用して実現が可能です。

マークダウン

記事Markdown内でのコードブロックの記載例
1```js {name="main.js"}
2document.addEventListner('DOMContentLoaded', () => {
3    console.log('Hello, World.');
4});
5```

1行目で {name="main.js"} のように {} を使ってファイル名を宣言しています。ここのプロパティ名は必ずしも name である必要はなく、任意の名称で、任意の個数を設定することが可能です。

テンプレートファイル

layouts/_default/_markup/render-codeblock.html
1<div class="Code {{ if .Attributes.name }} Code--attr {{ end }}">
2    {{ with .Attributes.name }}
3        <div class="Code__name">{{ . }}</div>
4    {{ end }}
5
6    <div class="Code__inner">
7        {{ highlight (.Inner | safeHTML) .Type .Options }}
8    </div>
9</div>

1行目では .Attributes.name が設定されていたらクラス名を追加しています。

2-4行目では .Attributes.name が設定されていた場合にファイル名を描画する HTML 要素を生成しています。

7行目では highlight 関数にコード・ファイルタイプ・オプションを渡してコードにシンタックスハイライトを付与しています。