Hugoのシンタックスハイライトを設定する

2019年12月30日 Yasu

hugo.png

ブログ記事内のソースコードをカラフルに表示する際に、一般的にWordPressのような動的なCMSではJavaScriptで書かれたプラグインなどを使用します。これらはレンダリング時に書き換えを行うため、ソースコードの量が多くなるとどうしても重くなりがちです。一方、このサイトではHugoという静的サイトジェネレーターを使っています。シンタックスハイライトの機能が含まれているため、サイトの生成時にソースコードの部分を装飾したHTMLに変換して出力してくれます。このためサイトを閲覧する際の高速化に一役買ってくれています。使い方や気づいた点をメモしておきます。

環境

  • Hugo 0.62.0

カスタマイズ内容をconfig.tomlに設定

最近のバージョン(0.60.0)から特に何も設定しなくても、マークダウンのコードブロック部分のシンタックスハイライトが有効になっており、下記がデフォルトの設定にとなります。

[markup]
  [markup.highlight]
    codeFences = true
    guessSyntax = false
    hl_Lines = ""
    lineNoStart = 1
    lineNos = false
    lineNumbersInTable = true
    noClasses = true
    style = "monokai"
    tabWidth = 4

スタイル

デフォルトのスタイルとしてmonokaiが適用されることがわかります。その他にも多くのスタイルが用意されているので、好きなスタイルを選んでstyleに設定します。

行番号

行番号表示の設定は2箇所に別れていて、lineNos = trueとすると全てのコードブロックで行番号が表示されるようになります。また、lineNumbersInTable = trueとなっているので、ソースコードの選択がしやすいように行番号とソースコード部分に分割されて表示します。行番号もインラインで表示したい場合は、lineNumbersInTable = falseとします。

ブログ記事の中でカスタマイズ

ソースコードの種類によって行番号の表示方法を変えたい場合に、ブログ記事のマークダウンの中でデフォルトの設定を上書きすする方法が用意されています。

ショートコードを使う

highlightというショートコードが用意されていてます。ここで注意が必要なのが先程の設定ファイルとは指定の方法が異なることです…

{{< highlight go "linenos=true" >}}
// ... code
{{< / highlight >}}

linenosというパラメータ一つによって制御し、各ブロックごとに表示方法を設定することができます。

linenos=true

# または

lineos=inline

とすると行番号をインラインで表示します。

linenos=table

とすると行番号とソースコードを分割して表示します。また、

linenos=false

とすると行番号を非表示にできます。

linenos=truelinenos=inlineの違いは出力されたHTMLを見る限りでは違いがわかりませんでした。

※タイポがあっても特にエラーは出力されずにlinenos=trueとした結果が表示されるので注意が必要です

マークダウンでの指定

0.62.0から以下のようにマークダウン記法のコードブロックでも指定ができるようになりました。

```go {linenos=true}
// ... code
```

ここでパラメータにダブルクオート(")をつけると反映されません。またlineNosと設定ファイルに合わせて一部大文字にすると反映されません…

その他のオプション

hi_linesというオプションを指定すると、任意の行をハイライト表示できます。また、行番号を表示する際に先頭になる番号を指定するlinenostartというオプションも用意されています。それぞれ以下のように指定します。

ショートコードhighlightを使う場合

{{< highlight elm "linenos=table,hl_lines=8 20-22,linenostart=10" >}}
# ... code
{{< / highlight >}}

マークダウンのコードブロックを使う場合

```elm {linenos=table,hl_lines=[8, "20-22"],linenostart=10}
# ... code
```

※ショートコードとマークダウンでオプションの指定方法が微妙に異なるので要注意です

ここでは8行目および20-22行目をハイライト表示するように指定しています。また行番号の先頭を10に設定しています。結果はこちらになります。

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)

main =
  Browser.sandbox { init = 0, update = update, view = view }

type Msg = Increment | Decrement

update msg model =
  case msg of
    Increment ->
      model + 1

    Decrement ->
      model - 1

view model =
  div []
    [ button [ onClick Decrement ] [ text "-" ]
    , div [] [ text (String.fromInt model) ]
    , button [ onClick Increment ] [ text "+" ]
    ]
```

```elm {linenos=table,hl_lines=[8, "20-22"]}
import Browser
import Html exposing (Html, button, div, text)
import Html.Events exposing (onClick)

main =
  Browser.sandbox { init = 0, update = update, view = view }

type Msg = Increment | Decrement

update msg model =
  case msg of
    Increment ->
      model + 1

    Decrement ->
      model - 1

view model =
  div []
    [ button [ onClick Decrement ] [ text "-" ]
    , div [] [ text (String.fromInt model) ]
    , button [ onClick Increment ] [ text "+" ]
    ]

スタイルの適用

デフォルトの状態ですとシンタックスハイライトされた部分全体に対する余白が狭かったり、横に長いコードが画面からはみだしてしまいます。

<pre>
  <code>
    ... code
  </code>
</pre>

このようなHTMLとして表示されますので、この辺は別途適当なCSSでの設定が必要です。

pre {
  padding: 0.5rem;
  overflow-x: scroll;
}

インラインコードのスタイル

ひとつ困ったことがありました。コードをインライン表示で書くとcodeタグとして表示されますが、このタグに任意のCSSを当てていると、先のコードにも反映されてしまい、シンタックスハイライト表示が崩れてしまいます。とりあえず動作する解決方法が下記になります。

:not(pre) > code {
  background-color: #111;
  color: #999;
  padding: 0.1rem;
}

直接の親にpreを持たないcodeタグ全てにこのスタイルを適用しています。

終わりに

GoHugoという名のとおりGo言語で書かれているためGoの特徴(癖?)を多く引き継いでいるのかなという印象です。以前にGo言語を少し勉強して挫折😢したことがあるのでなんとか使えています😅。

Tags: Hugo
相場のお問い合わせはお電話・メール・LINEにてお気軽にどうぞ!
 tel:0120-41-1578
 email:info@officeiko.co.jp
 LINE ID:@oue6072d