Giraffy [Lab]

Hugo の自動サマリーでの日本語の扱い

Hugo では記事をリスト表示する際、 サマリー(summary) 機能を使用します。

サマリーとして使用されるのは、手動で <!–more–> と設定している手前までか、 front matter (ページ毎のメタデータ)で summary に指定されているテキストか、 あるいはいずれでもないときに自動サマリーとして summaryLength で設定されているワード数分のテキストです。

このうち、自動サマリーの挙動が、久しぶりに更新したら以前のバージョンと変わってしまっていて 困っている、という人がいたので、どうなっているのだろうか、という話です。

仕様としては、自動サマリーはページが CJK (中国語、日本語、韓国語) 系の言語で書かれている 場合には、通常のワード(スペースで区切られた単語)のカウントではなく、CJK 用の カウントを使用する、ということになっています。

CJK ページであるかは、個別のページの front matter に isCJKLanguage が true または false として設定されていればそれに従い、 そうでない場合にサイト設定で hasCJKLanguage が true に設定されていればページが CJK であるかを自動判定します。

自動判定を行う際は、ページ内に漢字、ハングル、ひらがな、かたかなが含まれているかという正規表現 \p{Han}|\p{Hangul}|\p{Hiragana}|\p{Katakana} でチェックしているようです。 (ぱっと見てもぴんとこない「Han」は「漢」のことで、\p{Han} で漢字にマッチします。)

CJK 用の処理の実体としては、通常ワード数のカウントで自動サマリーとしての使用範囲を決めるところを、 文字数(Go での「ルーン」数)のカウントで置き換えているようです。

ワード数と文字数では全然違うのでそもそも無理があるわけですが、それでも以前は ひとまずそれでだいたい意図通りになっていたのが、現在ではこの設定をしても長々と文章が 表示されてしまうし、サマリーに HTML が効いているようだし、どうなってしまっているのだろう、 とのことです。

最初は hasCJKLanguage が効かなくなってしまっているのかとも思ったのですが、手元で動作させた 限りでは設定自体は有効に働いている様子です。

個別ページでの isCJKLanguage を true に設定すると CJK 用処理が使用されている様子ですし、 isCJKLanguage しないで hugo.toml で hasCJKLanguage を true にしただけでも、日本語ページは しっかり CJK 用処理されるようです。

しかし表示される文字数はたしかにまちまちで、聞いていた話とは違います。

Hugo のソースのコミット履歴から探してみると、どうやらサマリーの表示方法自体が、 この鬼コミットによって変わっているようです。

https://github.com/gohugoio/hugo/commit/37609262dcddac6d3358412b10214111b4d4dc3d

(この変更の含まれた v0.134.0 のリリースノート )

この変更で、以前は自動サマリーの場合にはプレーンテキストが返ってきていたところが、 手動・自動ともに HTML で返ってくるようになっている、とのことです。

また、従来から非CJKの自動サマリーでは上限のワード数に達したときにもその段落までは 全体が返されるようになっていたようなのですが、CJK 時にもそれに準じた動作となり、 上限のワード数(ルーン数)になっても途中ではカットされず段落全体が表示されるように なっているようです。

従来のように、HTML なしのプレーンなテキストが欲しいときには {{ .Summary | plainify }} を使うように、とのことです。

また、段落ではなく文字数でカットしたい場合には、 {{ .Summary | strings.Truncate 30 }} のようにすれば、タグを除いた 30 文字(30 ルーン)に納まるようにカットしてくれます。 (英単語などが含まれる場合は単語が途中でカットされないように配慮されますし、閉じタグも 補われます。)

これを組み合わせて {{ .Summary | plainify | strings.Truncate 30 }} のように書くことも可能です。

ところで、

これとは別に hugo server で public の内容が書き変わるようになってしまった、という話もあって、 それはおそらく v0.123.0 に含まれている https://github.com/gohugoio/hugo/issues/11987 によるものです。server 時にもディスクへの書き出しがデフォルトになったので、これを以前のデフォルト 動作のようにメモリーへの書き出しとするには hugo server --renderToMemory と指定します。