diff --git a/assets/css/extended/custom.css b/assets/css/extended/custom.css index 2d3bbca..c105fc0 100644 --- a/assets/css/extended/custom.css +++ b/assets/css/extended/custom.css @@ -37,6 +37,46 @@ body { font-size: .7em; } + +.toc { + padding: 14px; + border: solid 1px lightgray; + font-size: 12px; +} + + +@media (min-width: 1280px) { + .toc { + position: sticky; + float: left; + --toc-left: calc(100vw / 50); + left: var(--toc-left); /* _minimum_ distance from left screen border */ + top: 100px; + margin-left: -1000px; /* overruled by left */ + + width: calc((100vw - var(--main-width) - 2 * var(--gap)) / 2 - 2 * var(--toc-left)); + padding: 14px; + border: solid 1px lightgray; + font-size: 12px; + } + + .toc .inner { + padding: 0; + } + + .toc details summary { + margin-inline-start: 0; + margin-bottom: 10px; + } + +} + + + +summary { + cursor: pointer !important; +} + :root { --gap: 24px; --content-gap: 20px; diff --git a/layouts/partials/toc.html b/layouts/partials/toc.html new file mode 100644 index 0000000..4d6748d --- /dev/null +++ b/layouts/partials/toc.html @@ -0,0 +1,93 @@ +
+
+ +
{{ .Title }}
+
+
+{{- $headers := findRE "(.|\n])+?" .Content -}} +{{- $has_headers := ge (len $headers) 1 -}} +{{- if $has_headers -}} + +{{- $largest := 6 -}} +{{- range $headers -}} +{{- $headerLevel := index (findRE "[1-6]" . 1) 0 -}} +{{- $headerLevel := len (seq $headerLevel) -}} +{{- if lt $headerLevel $largest -}} +{{- $largest = $headerLevel -}} +{{- end -}} +{{- end -}} + +{{- $firstHeaderLevel := len (seq (index (findRE "[1-6]" (index $headers 0) 1) 0)) -}} + +{{- $.Scratch.Set "bareul" slice -}} +
    + {{- range seq (sub $firstHeaderLevel $largest) -}} +
      + {{- $.Scratch.Add "bareul" (sub (add $largest .) 1) -}} + {{- end -}} + {{- range $i, $header := $headers -}} + {{- $headerLevel := index (findRE "[1-6]" . 1) 0 -}} + {{- $headerLevel := len (seq $headerLevel) -}} + + {{/* get id="xyz" */}} + {{- $id := index (findRE "(id=\"(.*?)\")" $header 9) 0 }} + + {{- /* strip id="" to leave xyz, no way to get regex capturing groups in hugo */ -}} + {{- $cleanedID := replace (replace $id "id=\"" "") "\"" "" }} + {{- $header := replaceRE "((.|\n])+?)" "$1" $header -}} + + {{- if ne $i 0 -}} + {{- $prevHeaderLevel := index (findRE "[1-6]" (index $headers (sub $i 1)) 1) 0 -}} + {{- $prevHeaderLevel := len (seq $prevHeaderLevel) -}} + {{- if gt $headerLevel $prevHeaderLevel -}} + {{- range seq $prevHeaderLevel (sub $headerLevel 1) -}} +
        + {{/* the first should not be recorded */}} + {{- if ne $prevHeaderLevel . -}} + {{- $.Scratch.Add "bareul" . -}} + {{- end -}} + {{- end -}} + {{- else -}} + + {{- if lt $headerLevel $prevHeaderLevel -}} + {{- range seq (sub $prevHeaderLevel 1) -1 $headerLevel -}} + {{- if in ($.Scratch.Get "bareul") . -}} +
      + {{/* manually do pop item */}} + {{- $tmp := $.Scratch.Get "bareul" -}} + {{- $.Scratch.Delete "bareul" -}} + {{- $.Scratch.Set "bareul" slice}} + {{- range seq (sub (len $tmp) 1) -}} + {{- $.Scratch.Add "bareul" (index $tmp (sub . 1)) -}} + {{- end -}} + {{- else -}} +
    + + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} +
  • + {{- $header | safeHTML -}} + {{- else -}} +
  • + {{- $header | safeHTML -}} + {{- end -}} + {{- end -}} + + {{- $firstHeaderLevel := $largest }} + {{- $lastHeaderLevel := len (seq (index (findRE "[1-6]" (index $headers (sub (len $headers) 1)) 1) 0)) -}} +
  • + {{- range seq (sub $lastHeaderLevel $firstHeaderLevel) -}} + {{- if in ($.Scratch.Get "bareul") (add . $firstHeaderLevel) -}} +
+{{- else -}} + + +{{- end -}} +{{- end -}} + +{{- end -}} +
+
+
\ No newline at end of file