前段階#
- 先日、Hugoでwikilink形式のcitationを扱えるようにしたが、wikilink形式は普通のリンクであったほうが嬉しい気がしてきた
- citekeyなのに脚注に飛ばないのは不親切な気がしてきた
- Pandoc Reference Listの挙動に合わせるほうが良いかも
@citekeyは著者姓 [年]
[@citekey]は[著者姓 年]
[[@citekey]]は[著者姓 年]で文献ノートにリンクする
- 問題は、
@citekeyの区切りをどうやって識別するか
- Pandoc Reference Listもそこまで細かくは対応していないみたい
- 欧文だと、
,.!?;()あたりで区切れたり、文字が続くと区切れなかったりする
- 和文だと、
、。・()「」とかで句切れたりする
- 誤作動を防ぐため、基本的には後にスペースを入れる運用になりそう
- 表示スタイルは様々あるそうなので、そこまで厳密にやらなくても良いと思う
- 著者が2人だと
andでつなぐとか、3人以上だとet al.で略されるとか
- First nameをイニシャルにするとか、
Last, Fist表記にするとか
- そもそも、人の名前はどう扱えば良いのだろう?
姓 名の順の文化圏の人はどうするとか
- last nameがどこまでなのかとか
- Pandoc Reference Listはどこまで整形してくれるのかとか
作業中#
- とりあえず、
replace-wikilinks.htmlからcitation周りを取り除いて、代わりにreplace-citations.htmlを以下の内容で作った
[[@citekey]]形式は明示的に除外している
- 単純にするため、citekeyは
\w+でマッチさせる
- 文中引用に
id="cite-@citekey:N"、参考文献のバックリンクにid="@citekey:N"がついていることを想定している
{{- /* @citekeyを脚注へのリンクに置き換える */ -}}
{{- $content := .Content -}}
{{- /* @citekeyと[@citekey]のみ扱う。[[@citekey]]は通常のリンクとする。 */ -}}
{{- range (findRESubmatch `(\[?\[?)(@\w+(?:;\s*@\w+)*)(\]?\]?)` $content) -}}
{{- /* 括弧の数が揃っていなければ、書き間違いと思われるので、置き換えない */ -}}
{{- $left_brackets := index . 1 -}}
{{- $right_brackets := index . 3 -}}
{{- if ne (len $left_brackets) (len $right_brackets) -}}
{{- continue -}}
{{- end -}}
{{- /* [[@citekey]]は通常のリンクとして扱うので、ここでは置き換えない */ -}}
{{- $type := len $left_brackets -}}
{{- if ge $type 2 -}}
{{- continue -}}
{{- end -}}
{{- /* 括弧の中身を処理する */ -}}
{{- $matched := index . 0 -}}
{{- $citekeys := index . 2 -}}
{{- $result := "" -}}
{{- range (findRESubmatch `(;?\s*)(@\w+)` $citekeys) -}}
{{- $spacing := index . 1 -}}
{{- $citekey := index . 2 -}}
{{- /* 文献ノートがあれば、それをもとに引用表示リンクを作る */ -}}
{{- $url := relref page $citekey -}}
{{- if $url -}}
{{- /* citekeyを一覧に追加する */ -}}
{{- $count_k := print "references::" $citekey ".count" -}}
{{- $count_v := add (or ($.Store.Get $count_k) 0) 1 -}}
{{- $.Store.Set $count_k $count_v -}}
{{- $.Store.Add "references::citekeys" (slice $citekey) -}}
{{- /* 文献ノートからメタ情報を取得する */ -}}
{{- $page := site.GetPage $url -}}
{{- $authors := "" -}}
{{- with $page.Params.authors -}}
{{- /* findRESubmatch => [["First Last", "Last"]] */ -}}
{{- $authors = index (index (findRESubmatch `.* (.+)` (index . 0) 1) 0) 1 -}}
{{- if eq (len .) 2 -}}
{{- $authors = print $authors " and " (index (index (findRESubmatch `.* (.+)` (index . 1) 1) 0) 1) -}}
{{- else if gt (len .) 2 -}}
{{- $authors = print $authors " et al." -}}
{{- end -}}
{{- end -}}
{{- $year := $page.Params.year -}}
{{- if eq $type 0 -}}
{{- $year = print "[" $year "]" -}}
{{- end -}}
{{- /* HTMLに変換する */ -}}
{{- $result = print $result $spacing "<a id=\"cite-" $citekey ":" $count_v "\" href=\"#" $citekey ":" $count_v "\">" (delimit (slice $authors $year) " ") "</a>" -}}
{{- else -}}
{{- /* 文献ノートがなければ、そのままにする */ -}}
{{- $result = print $result (index . 0) -}}
{{- end -}}
{{- end -}}
{{- /* 内容を置き換える */ -}}
{{- if eq $type 0 -}}
{{- $content = replace $content $matched $result 1 -}}
{{- else -}}
{{- $content = replace $content $matched (print "[" $result "]") 1 -}}
{{- end -}}
{{- end -}}
{{- $content | safeHTML -}}
- 合わせて
references.htmlを修正した
- 表示内容とid名を微調整して、文献ノートへのリンクを付けた
{{- /* ページ内citekeyリストから参考文献一覧を作る */ -}}
{{- with .Get "references::citekeys" | uniq | sort -}}
<div class="footnotes" role="doc-endnotes"><hr><h6>References</h6><ul>
{{- range . -}}
{{- /* 文献ノートがあれば、そのメタ情報を使って参考文献表示を作る */ -}}
{{- $citekey := . -}}
{{- $url := relref page $citekey -}}
{{- if $url -}}
{{- $page := site.GetPage $url -}}
{{- /* 文献ノートからメタ情報を取り出す */ -}}
{{- $body := slice -}}
{{- with $page.Params.authors -}}
{{- $body = $body | append (slice (print (delimit . ", " " and ") ".")) -}}
{{- end -}}
{{- with $page.Params.year -}}
{{- $body = $body | append (slice (print . ".")) -}}
{{- end -}}
{{- with $page.Title -}}
{{- $body = $body | append (slice (print . ".")) -}}
{{- end -}}
{{- /* HTMLを作る */ -}}
<li id="{{.}}"><p>[{{substr $citekey 1}}] {{/**/ -}}
{{delimit $body " "}}
{{- range $.Get (print "references::" $citekey ".count") -}}
{{- /**/}} <a href="#cite-{{$citekey}}:{{add . 1}}" id="{{$citekey}}:{{add . 1}}" class="footnote-backref" role="doc-backlink">↩︎</a>
{{- end -}}
{{- /**/}} <a href="{{$url}}">🗅</a></p></li>
{{- end -}}
{{- end -}}
</ul></div>
{{- end -}}
post_content.htmlにその他と同じような呼び出しを追加しておしまい
- 担当範囲が被らないようになっているので、順番はどうでも大丈夫
@Example2025や[@Example2025]と書くと、Last [2025Last, F. 2025. Example.]や[Last 2025Last, F. 2025. Example.]となり、最下段に参考文献一覧が追加されるようになる
- これで置換対象が増えたので、そこまで頻発しないとは思うけど、少し注意が必要になった
- これまでの通り、エスケープしても置換時に判別できない
- 生の
@を文中に使いたい場合は、同名の文献ノートと被らないようにする
- 代わりに、全角@を使うとか、コードブロックにするとかで回避する
[@citekey]はreference型のリンクと記法を共有するので被らないようにする
おまけ#
- delimitは最後の区切りを別の文字にすることができる
- 文章のように、コンマで並べて最後だけandにする、といったことができる