HUGO の Code Block Render Hooks を使って、コードブロックにファイル名を表示する
Markdown のコードブロックに記述したコードを、「foo.js」のようにファイル名をつけて表示できるようにします。
この記事では、v0.93.0 で追加された Code Block Render Hooks を使います。
Code Block Render Hooks が追加されるまでは、下記のページで紹介されているように、ショートコードを実装する必要がありました。
ソースコードをハイライト表示する (highlight)
Code Block Render Hooks を使うと、Markdown Syntax のコードブロックのまま、ファイル名を表示できるようになります。
この場合、ショートコードを使うときとは異なり、JavaScript のコードであれば eslint-plugin-markdown を使って ESLint を適用できます。
動作を確認した環境
HUGO v0.93.0
Code Block Render Hooks とは
コードブロック用の Render Hooks は、layouts > _default > _markup
の下に、render-codeblock.html
を作成します。
参考. 公式ドキュメント
layouts
└── _default
└── _markup
└── render-codeblock.html
└── render-codeblock-bash.html
表示する言語ごとに、Code Block Render Hooks テンプレートを出し分けることもできます。render-codeblock-
のプレフィックスと言語の識別子をファイルの名前につけます。
言語の識別子とは、````js` のようにバッククォート 3 つの後に付ける言語名のことです。
HUGO のドキュメントには、mermaid を使って図を表示する例が紹介されています。
ファイル名を表示する Code Block Render Hooks を実装する
コンテンツのファイルに、次のようにコードブロックを記述することを考えます。
表示するファイル名は、言語の識別子の後に {name="ファイル名"}
のように記載します。
```js {name="foo.js"}
(() => {
'use strict';
console.log("Hello World!");
})();
```
Code Block Render Hooks として、render-codeblock.html
に次の内容を記載します。
<div>
{{- $name := .Attributes.name -}}
{{ with $name }}<div class="codeblock--name">{{ . }}</div>{{ end }}
<div class="codeblock--content">
{{- highlight (.Inner | safeHTML) .Type .Options }}
</div>
</div>
{}
内で渡したファイル名は、.Attributes
で受け取ります。
コードブロック内の内容は .Inner
で受け取ることができるため、highlight 関数でハイライト表示します。
HUGO でハイライト表示するときに {}
内へ指定できる、行番号の開始数などのオプションは、.Options
に格納されます。
highlight 関数の第 3 引数として .Options
を渡すと、同じように行番号の開始数などを指定できます。
行番号の開始数などのオプションの詳細は、Highlighting in Code Fences を参照してください。
例えば、次のように行番号を変更したり、行をハイライト表示するオプションを指定して Markdown を書いたとします。
```js {linenos=table,hl_lines=["2-3"],linenostart=199,name="foo.js"}
(() => {
'use strict';
console.log("Hello");
})();
```
前述のrender-codeblock.html
では highlight 関数に
.Options` を渡しているため、指定したオプションが反映されています。
ちなみに、今回のファイル名の表示部分には、次のような css を適用しています。
.codeblock--name {
width: fit-content;
margin: 1rem 0 0;
padding: 0.4rem;
font-size: 0.9rem;
color: rgb(255, 255, 255);
background-color: #05acc1;
}
.codeblock--name + .codeblock--content {
margin-top: 0;
}