Add an Obsidian CSS Snippet
Tuesday, 24 January, 2023
Running Dart Code
Tuesday, 17 January, 2023

Hugo Render Hooks for Titled Code Blocks

Captions more than titles, really. No problem. We'll fix it in post.
an illustrative example
Posted
post #hugo
Got a comment? A question? More of a comment than a question? Talk to me about this page on: linkedin mastodon

I like to label my code blocks, especially when they describe the contents of a specific file.

That’s been possible with Hugo since 0.93.0, using render hooks. Render hooks let you use custom templates for all instances of certain Markdown structures such as links, headers, images, and code! I didn’t think to try them out for labeling code until just now, though. This comment from Hugo Discourse user pamubay got me started. My template builds directly on theirs.

layouts/_default/render-codeblock.html
{{- $isVerbatim := true -}}
{{- if isset .Attributes "verbatim" -}}
  {{- $isVerbatim = .Attributes.verbatim -}}
{{- end -}}
<figure class="highlight">
{{- with .Attributes.title }}
  <figcaption>
    {{- if $isVerbatim -}}
      <tt>{{ . }}</tt>
    {{- else -}}
      <span>{{ . }}</span>
    {{- end -}}
  </figcaption>
{{- end }}
{{- if transform.CanHighlight .Type }}
  <pre tabindex="0" class="chroma"
    ><code class="language-{{ .Type }}" data-lang="{{ .Type }}">
    {{- with transform.HighlightCodeBlock . -}}
      {{ .Inner }}
    {{- end -}}
  </code></pre>
{{- else }}
  <pre tabindex="0"
    ><code class="language-{{ .Type }}" data-lang="{{ .Type }}"
      >{{ .Inner }}</code></pre>
{{- end }}
</figure>

The HTML changes are personal aesthetics. I’ve been using <figure/> more and more often for illustrative examples beyond — you know — illustrations.

My render hook looks for two attributes, title and verbatim. These attributes are added after the language identifier for the fenced code block.

Titled code block
```html{title="layouts/_default/render-codeblock.html"}

title is the intended title / caption to attach. The verbatim flag indicates whether I want this in a monospaced font. Grabbed that one from the Org folks since it seems like a useful differentiator between code and not-code.

Most of the time when I label code samples, I use a filename or identifer, and I’m used to seeing those in monospace. So it makes sense to have code block captions as verbatim by default. So the verbatim flag only matters if I set it to false, such as for explanatory captions.

non-verbatim code block title
```markdown{title="Titled code block" verbatim=false}

So now I can rest happily with Hugo now that it can do almost exactly what I — ooh Pandoc 3.0 is out!