blue271828's misc :-)

Hugo+MmarkでTOCを表示する

環境

背景

Hugo で Mmark ファイルをビルドする場合、TOC (table of contents) が仕様上表示されない。

対策

{{ .TableOfContents }} の代わりに、カスタムテンプレートを作成する。

HTML

{{ $headers := findRE "<h[2-4].*?>(.|\n])+?</h[2-4]>" .Content }}
{{ $numHeaders := len $headers }}
{{ $hasHeaders := ge $numHeaders 1 }}
{{ if $hasHeaders }}
<nav id="TableOfContents">
  <ul>
    {{ range $i, $header := $headers }}
    {{ $anchorId := (replaceRE  "[ ]" "-" ($header | htmlUnescape | plainify | htmlEscape)) }}
    {{ $listItemTitle := $header | htmlUnescape | plainify | htmlEscape }}
    {{ $listItemOpen := safeHTML (printf "<li><a href='#%s'>%s</a></li>" $anchorId $listItemTitle) }}

    {{ $currentHeaderLevelString := index (findRE "[2-4]" $header 1) 0 }}
    {{ $currentHeaderLevel := len (seq $currentHeaderLevelString) }}
    {{ if lt $i 1 }}
    {{ $.Scratch.Set "previous" 2 }}
    {{ else }}
    {{ $previousHeader := index $headers (sub $i 1) }}
    {{ $previousHeaderLevelString := index (findRE "[2-4]" $previousHeader 1) 0 }}
    {{ $previousHeaderLevel := len (seq $previousHeaderLevelString) }}
    {{ $.Scratch.Set "previous" $previousHeaderLevel }}
    {{ end }}
    {{ $previousHeaderLevel := ($.Scratch.Get "previous") }}

    {{ range $j := seq (sub $currentHeaderLevel $previousHeaderLevel) }}
    {{ if gt $j 0 }}<ul>{{ else }}</ul>{{ end }}
    {{ end }}
    {{ $listItemOpen }}
    {{ end }}    
  </ul>
</nav>
{{ end }}

参考文献

Tags

#Ansible (3) #Bash (1) #Docker (1) #Git (2) #Hugo (2) #Molecule (1) #Python (1) #WSLtty (1) #アルゴリズム (4) #ビジネス用語 (1) #プログラミング (1) #位相空間論 (8) #初等数学 (20) #初等関数 (1) #実解析 (1) #幾何学 (3) #微分積分学 (18) #情報理論 (4) #抽象代数学 (14) #数理モデル (2) #数理論理学 (21) #機械学習 (3) #正規表現 (1) #測度論 (3) #特殊関数 (4) #確率論 (18) #組合せ論 (5) #統計学 (12) #線型代数学 (18) #複素解析学 (4) #解析学 (15) #論理学 (6) #順序集合論 (9)