Syntax Highlighting Code with Goldmark
How to style code blocks in Go using the Goldmark library and its Goldmark Highlighting extension.
1 min read
Goldmark is a powerful markdown processor, which is used on this very site. You can easily add syntax highlighting using the Goldmark-highlighting extension. Simply create a custom markdown processor to get started.
import (
"github.com/yuin/goldmark"
highlighting "github.com/yuin/goldmark-highlighting/v2"
)
var Markdown = goldmark.New(
goldmark.WithExtensions(
extension.GFM,
highlighting.NewHighlighting(
highlighting.WithStyle("dracula"),
),
),
)
Once you've set up the custom processor, you can choose from any of the supported themes, which can be found on the extension's repository. However, one feature that I wanted was to add the language of the code block as a data attribute to the generated markup. This would allow me to create a simple header for each code block.
After browsing through the Goldmark documentation and Github repository, I discovered the WithWrapperRenderer
method that runs a function for every code block. This was exactly what I needed! Here's how I got it working:
import (
"github.com/yuin/goldmark"
highlighting "github.com/yuin/goldmark-highlighting/v2"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/util"
)
func wrapperRenderer(w util.BufWriter, ctx highlighting.CodeBlockContext, entering bool) {
language, ok := ctx.Language()
lang := string(language)
// code block with a language
if ok && lang != "" {
if entering {
w.WriteString("<div data-lang=" + lang + ">")
} else {
w.WriteString(`</div>`)
}
return
}
// code block with no language specified
if language == nil {
if entering {
w.WriteString("<pre><code>")
} else {
w.WriteString(`</code></pre>`)
}
}
}
var Markdown = goldmark.New(
goldmark.WithExtensions(
extension.GFM,
highlighting.NewHighlighting(
highlighting.WithStyle("dracula"),
highlighting.WithWrapperRenderer(wrapperRenderer), // updated code here
),
),
)
Now all code blocks will be wrapped with a div
that contains a data-lang
attribute specifying the language. This allows you to use this value on your frontend as you see fit!