- 先日、Obsidianでcitationを扱う方法を考えたので、Hugoでもどこまでできそうか考えたい
- Hugoはスクリプトである程度自由にできてしまうので、問題なくできそうではある
- ページ内の
[[@citekey]]を集めてfootnote1のように最下部に一覧表示するとか、[@citekey]を指定のスタイルで置き換えるとか @citekeyページを作っておけば、そのfrontmatterからメタ情報を取得できるはず?
- ページ内の
- Obsidianとの相互運用性を考慮して、
@citekeyで文献ノートを作り、wikilink形式でリンクを張るとする - とりあえず、前回作った
post_content.htmlを以下のように、処理中に情報をstoreに集められるように修正した
{{- /* コードブロックの外だけで置換処理を適用するpartial */ -}}
{{- $store := newScratch -}}
{{- $result := "" -}}
{{- /* codeタグで分割する */ -}}
{{- $s1 := split .Content "<code" -}}
{{- /* 先頭は必ずコード外として処理する */ -}}
{{- $content := index $s1 0 -}}
{{- $content = partial "replace-japanese-novel-ruby.html" (dict "Content" $content "Store" $store) -}}
{{- $content = partial "replace-wikilinks.html" (dict "Content" $content "Store" $store) -}}
{{- $result = print $result $content -}}
{{- /* 残りはコード内と外のペアとして処理する */ -}}
{{- range after 1 $s1 -}}
{{- /* codeタグで分割する */ -}}
{{- $s2 := split . "</code>" -}}
{{- /* 先方はコード内 */ -}}
{{- $result = print $result "<code" (index $s2 0) "</code>" -}}
{{- /* 後方はコード外 */ -}}
{{- $content := (index $s2 1) -}}
{{- $content = partial "replace-japanese-novel-ruby.html" (dict "Content" $content "Store" $store) -}}
{{- $content = partial "replace-wikilinks.html" (dict "Content" $content "Store" $store) -}}
{{- $result = print $result $content -}}
{{- end -}}
{{- $result | safeHTML -}}
{{- partial "references.html" $store -}}replace-wikilinks.htmlを以下のように修正する- 頭に
@を持つリンクは、そのaタグにid属性を個別に付ける - どの
@citekeyがどれだけあるかを.Storeに記録する - 一応、
@citekeyに関係なく連続するインデックスでもIDを割り当てている
- 頭に
{{- $content := .Content -}}
{{- range (findRESubmatch `\[\[(((@?)[^#\|\]\n]*)(?:#([^\|\]\n]*))?)(?:\|([^\]\n]*))?\]\]` $content) -}}
{{- $matched := index . 0 -}}
{{- $full_name := index . 1 -}}
{{- $file_name := index . 2 -}}
{{- $at := index . 3 -}}
{{- $heading_name := index . 4 -}}
{{- $title := index . 5 -}}
{{- /* リンク先をURLに変換する */ -}}
{{- $url := "" -}}
{{- if $file_name -}}
{{- /* エラー隠蔽のためにtryを使いたかったが、上手くいかなかった(v0.148.1) */ -}}
{{- $path := relref page $file_name -}}
{{- if eq $path "" -}}
{{- /* リンク先が存在しなければ、リンクを置き換えない */ -}}
{{- continue -}}
{{- end -}}
{{- $url = print $path -}}
{{- end -}}
{{- if $heading_name -}}
{{- $url = print $url "#" (anchorize $heading_name) -}}
{{- end -}}
{{- /* @citekey形式はaタグにidを付ける */ -}}
{{- $global_id := "" -}}
{{- $local_id := "" -}}
{{- if $at -}}
{{- /* @citekeyの出現順を含めたidを作る */ -}}
{{- $global_count_k := "references::global_count" -}}
{{- $global_count_v := add (or ($.Store.Get $global_count_k) 0) 1 -}}
{{- $global_id = print "citation-" $global_count_v -}}
{{- $local_count_k := print "references::" $file_name ".count" -}}
{{- $local_count_v := add (or ($.Store.Get $local_count_k) 0) 1 -}}
{{- $local_id = print "citation-" $file_name "-" $local_count_v -}}
{{- /* 同名の@citekeyで情報を共有するために保存しておく */ -}}
{{- $.Store.Set $global_count_k $global_count_v -}}
{{- $.Store.Set $local_count_k $local_count_v -}}
{{- $.Store.Add "references::citekeys" (slice $file_name) -}}
{{- end -}}
{{- /* wikilink形式をHTMLに置き換える */ -}}
{{- $c_attr := "" -}}
{{- with $global_id -}}
{{- $c_attr = print $c_attr " id=\"" . "\"" -}}
{{- end -}}
{{- $a_attr := "" -}}
{{- with $local_id -}}
{{- $a_attr = print $a_attr " id=\"" . "\"" -}}
{{- end -}}
{{- with $url -}}
{{- $a_attr = print $a_attr " href=\"" . "\"" -}}
{{- end -}}
{{- $content = replace $content $matched (print "<span id=\"" $c_attr "\"><a" $a_attr ">" (or $title $full_name) "</a></span>") 1 -}}
{{- end -}}
{{- $content | safeHTML -}}references.htmlを以下の内容で作る.Storeに格納された@citekeyリストを使って一覧を表示する- とりあえず、footnoteの書き方をそのまま利用している
- その文献の情報はその文献ノートのfrontmatterから取得する
{{- with .Get "references::citekeys" | uniq | sort -}}
<div class="footnotes" role="doc-endnotes">
<hr>
<h6>References</h6>
<ul>
{{- range . -}}
{{- $citekey := . -}}
{{- $url := relref page $citekey -}}
{{- $page := site.GetPage $url -}}
<li>
<p><a href="{{$url}}">[{{substr $citekey 1}}] {{print (or $page.Params.authors "[AUTHORS]") ", \"" (or $page.Title "[TITLE]") ",\" " (or $page.Params.year "[YEAR]") "."}}</a> 
{{- range $.Get (print "references::" $citekey ".count") -}}
{{- /* whitespace */}} <a href="#citation-{{$citekey}}-{{add . 1}}" class="footnote-backref"
role="doc-backlink">↩︎</a>
{{- end -}}
</p>
</li>
{{- end -}}
</ul>
</div>
{{- end -}}- これで、頭に
@のついた生きたリンクがあれば、footnoteの下に参考文献として表示されるようになったはず- [[ Last 2025Last, F. 2025. Example.]]
- ここまでやってみて、ビルドがどれだけ重くなったかは検証していない
おまけ#
.Pageや.Siteに関連した.Storeもあるのでグローバル変数のような感覚で使える- ただし、ライブリロードではリセットされないので、ちょっと使いづらい
- frontmatterにあるユーザー定義の値は
.Page.Paramsから取得できるらしい- 詳しくは不明だが、実際そのように見える
参考文献#
Footnotes#
-
こういうやつ ↩