HugoでMarkdownのテーブルに属性を付与する


HugoでMarkdownのテーブルに属性を付加する

Hugo、便利ですよね。当ブログはHugoを使って作成していますし、私が管理しているいくつかのサイトでも積極的にHugoを採用しています。
少なくとも管理者が一人である限り、HugoのようなStatic Site Generatorはメチャクチャ強力だと思っています1

さて、そんなHugoですが、0.60.0からCommonMarkに準拠したgoldmarkと呼ばれるMarkdownパーサー2をデフォルトで使うようになりました。
その結果、いくつかの機能が非推奨になったり変更が加えられたりしています。その影響を受けるものの一つがMarkdownのテーブルです。

雑にテーブルを書くだけなら何も問題はないのですが、例えばテーブルにclass等の属性を付与したいとき、Hugoのデフォルト記法では対応できません。
とはいえ今までは、利用するページのみMmarkというパーサーを利用することで以下のような記法で実現できていました。

---
markup: mmark
---

{#id .class data-example=10}
|example A|example B|
|---|---|
|value A|value B|
|value C|value D|
|value E|value F|

しかし、Hugo 0.60.0にてMmarkは非推奨となり、将来のバージョンで削除されることが予告されました3。Hugoの開発スピードは非常に速いため、もしかするとじきに削除されてしまうかもしれません。
したがって、Mmark以外の手法を取る必要があります。

これに対応する一番安直な方法は、HTMLをベタ書きすることです。しかしながら、これではMarkdownを使うメリットがありません。また、Hugo 0.60.0はデフォルトでHTMLを削除してしまいます4。あまり嬉しくありません。

Shortcodeを使う

こんなときはShortcodeを使えばよいのです。というわけで、ドキュメントを読みながら書いてみました。replace とか初めて使った……。

完成したものがこちら。

{{ $attrs := "" }}
{{ range $k, $v := .Params }}
  {{ $attrs = printf "%s %s=\"%v\"" $attrs $k $v }}
{{ end }}

{{ $newTable := printf "<table %s>" $attrs }}
{{ (replace (.Inner | markdownify) "<table>" $newTable) | safeHTML }}

Snippetは以下でも公開しています。

動作としては、Shortcodeの引数を全てテーブルの属性として処理するようにしました。最初はid, classくらいでいいかなと思って .Get とか使ってたんですが、後から data- とか使いたいわ、ということに気がついて今に至ります。テーブルをもっと便利に! とかではなく、あくまで従来のテーブルと同様に使えることを目指しました。

動作を試してみます。冒頭で出した以下のテーブルで確認しましょう。

|example A|example B|
|---|---|
|value A|value B|
|value C|value D|
|value E|value F|

まずは、素のテーブルです。

example Aexample B
value Avalue B
value Cvalue D
value Evalue F

使っているテーマによる影響を受けていますが、普通ですね。
ところで、弊サイトは現在時点においてBeautiful Hugoというテーマを使っており、これは内部でBootstrapを利用しています。Bootstrapはテーブルに対してclassを付与することでデザインを変えることができます5
というわけで、Shortcodeを使っていくつかクラスを付与してみましょう。以下のように使います。

{{< table class="table table-hover table-condensed" >}}
|example A|example B|
|---|---|
|value A|value B|
|value C|value D|
|value E|value F|
{{</ table >}}

結果は以下の通り。

example Aexample B
value Avalue B
value Cvalue D
value Evalue F

テーマの影響でちょっと分かりにくいですが、微妙に表示と挙動が変わっています。よいですね。後はお好みでCSSを書いてあげると幸せになれると思います。

まとめ

HugoではMarkdownを用いてテーブルを表現できます。ただし、デフォルトではテーブルに対して属性を与える記法がサポートされていません。
従来からMmarkを用いて該当のテーブルに属性を与える手法がありましたが、Hugo 0.60.0からMmarkは非推奨になりました。そこで、本記事ではShortcodeを使う方法を提案し、その使い方を示しました。この手法を用いることで、Markdownの便利さを活かしつつテーブルの細かなデザイン調整ができるようになると考えられます。


  1. 複数人(技術に明るい人以外を含む)でサイトを運営したり、サイトに動的な機能などを取り入れたい、といった要件が入ってくるとみんな大好きWordPressなども視野に入ってきますね。ただ、少なくとも個人サイトでそれを使うメリットはもうないかな、と思います。 ↩︎

  2. https://github.com/yuin/goldmark ↩︎

  3. https://github.com/gohugoio/hugo/releases/tag/v0.60.0 ↩︎

  4. 詳細は こちら 参照。 この機能がデフォルトで有効なのはセキュリティのため、と説明されています。が、Markdown自体がさほど高機能ではないため、部分的にHTMLが必要な場面はそこそこあります。それぞれにShortcodeを作れば解決はできますが、ちょっとしたspan等にまで作るのは合理的と言えません。リスクを理解した上で、configのunsafeオプションを設定することでHTMLを利用できるようになります。当ブログもunsafeオプションは有効にしていますが、その代わりにCSPを適用してあります。 ↩︎

  5. https://getbootstrap.com/docs/3.3/css/#tables ↩︎