/ #hugo #CSS

Hugo のコードの色付けを CSS クラスにする(highlight.js をやめた)

JavaScript はいらなかった

旧サイトのテーマでは highlight.js を読み込んで、ブラウザ側でコードに色を付けていました。 作り直すにあたって調べたところ、Hugo には Chroma というハイライターが入っていて、 ビルドのときに色付けまで済ませてくれます。 JavaScript を読み込む必要がなくなるので、こちらに乗り換えました。

何もしなくても色は付く

Markdown にふつうにコードブロックを書くだけで、Chroma が色を付けてくれます:

```ruby
def hello
  puts "hi"
end
```

ただし、初期設定ではこんな HTML になります:

<pre tabindex="0" style="color:#f8f8f2;background-color:#272822;...">
  <code class="language-ruby" data-lang="ruby">
    <span style="display:flex;"><span><span style="color:#66d9ef">def</span> ...

色が style 属性で直接埋め込まれています。 これだと、

  • 色を変えたくなったら、全ページをビルドし直すしかない
  • CSS から上書きしにくい
  • コードが長いほど、同じ style が何度も繰り返されて HTML が重くなる

ので、色は CSS に任せることにします。

CSS クラスで出力する

hugo.yaml に次の設定を追加します:

markup:
  highlight:
    noClasses: false

すると、style の代わりにクラス名が付くようになります:

<pre tabindex="0" class="chroma">
  <code class="language-ruby" data-lang="ruby">
    <span class="line"><span class="cl"><span class="k">def</span> <span class="nf">hello</span>

k はキーワード、nf は関数名、といった具合です。

色の CSS は Hugo が作ってくれる

クラスに色を付ける CSS は、自分で書く必要はありません。 好きなスタイル名を指定して、Hugo に生成してもらいます:

$ hugo gen chromastyles --style=github-dark > assets/css/syntax.css

このサイトでは github-dark を使っています。 使えるスタイルの一覧と見た目は、hugo gen chromastyles --help に載っている URL から確認できます。

あとは、できた CSS をほかの CSS と一緒に読み込むだけです:

{{- $css := slice (resources.Get "css/casper.css") (resources.Get "css/syntax.css") (resources.Get "css/nantokapress.css") | resources.Concat "css/bundle.css" | minify | fingerprint }}
<link rel="stylesheet" href="{{ $css.RelPermalink }}" integrity="{{ $css.Data.Integrity }}">

色を変えたくなったら、コマンドをもう一度実行して syntax.css を差し替えれば済みます。

おまけ: 行番号と行の強調

コードブロックの言語名の後ろにオプションを書くと、行番号を付けたり、特定の行を目立たせたりできます:

```ruby {linenos=inline, hl_lines=[2]}
def hello
  puts "hi"
end
```
1def hello
2  puts "hi"
3end

強調した行には hl クラスが付くので、色は生成した CSS の .chroma .hl で変えられます。

読み込む JavaScript が 1 本減って、すっきりしました。 ぜひ。