Add custom div to `pre.chroma` syntax-highlighted sections

On my site, I currently use client-side JavaScript that checks for the existence of chroma-highlighted code, grabs the data-lang attribute, and creates a custom <div> above the code block that contains the name of the code language. I call these <div>s “codeblock headers” because they tell readers the language of the code they’re reading. It looks like this:

language

Keep in mind that I did not put anything in my markdown that created this little grey “javascript” label. It would be really annoying to have to put <div class="codeblock-header">language here</div> before every block of code in my markdown. Besides, I already put the name of the language in the opening code fence, so I should be able to make use of that.

In fact, I actually wrote a whole article about how I did it here. However, it’s entirely unnecessary for this to be done using client-side JavaScript: these headers are the same for every reader, so they ideally would be server-side rendered. Ideally, I would be able to customize the generation of the pre.chroma element and its children, so that when i run hugo, these “codeblock headers” are generated automatically, without the need for client-side JavaScript.

As a workaround, I wrote some NodeJS code to run through my articles and run the JavaScript on them to create the codeblock headers. It works, but this makes it really difficult to do local development using hugo serve, because hugo serve doesn’t act nicely when you modify the HTML it spits out, and I have to have a separate script watching for hugo serve to spit out HTML so I can modify it using my NodeJS script.

Is there a way for me to customize the way Hugo creates these syntax-highlighted portions, so that these headers are created automatically?

if this is for visual only, not for accessibility or any SEO-related things. you can use CSS pseudo-element content to achieve that look.

as hugo generated this <code> wrap:

<code class="language-toml" data-lang="toml">

we can grab that data-lang attribute via css pseudo-element content

an example a codeblock from this website:

alternative method: using replaceRE to modify .Content

1 Like

Both of those solutions (or possibly a combination) should work perfectly, thank you! I had not even considered using replaceRE.

@pamubay Thanks! That was very helpful.

Basically I could do something like this and then customize the styling further:

    pre code:before {
      display: block;
      content: attr(data-lang);
    }

One has to do some margin and padding adjustments if you want it to look pretty. It has its drawbacks but saves many lines of JS :slight_smile:

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.