Files
2026-08-20 18:47:29 -04:00

67 lines
1.8 KiB
Go

package highlight
import (
"bytes"
"github.com/AvengeMedia/DankMaterialShell/core/internal/highlight/lexers"
"github.com/alecthomas/chroma/v2"
"github.com/alecthomas/chroma/v2/formatters/html"
"github.com/yuin/goldmark"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/renderer"
ghtml "github.com/yuin/goldmark/renderer/html"
"github.com/yuin/goldmark/util"
)
// Markdown is a goldmark extension that highlights fenced code blocks with a
// known language; other blocks render as plain <pre><code>.
type Markdown struct {
Style *chroma.Style
Formatter *html.Formatter
}
func (m Markdown) Extend(md goldmark.Markdown) {
md.Renderer().AddOptions(renderer.WithNodeRenderers(util.Prioritized(m, 200)))
}
func (m Markdown) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) {
reg.Register(ast.KindFencedCodeBlock, m.renderFencedCodeBlock)
}
func (m Markdown) renderFencedCodeBlock(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) {
if !entering {
return ast.WalkContinue, nil
}
n := node.(*ast.FencedCodeBlock)
language := n.Language(source)
var code bytes.Buffer
for i := range n.Lines().Len() {
line := n.Lines().At(i)
code.Write(line.Value(source))
}
var lexer chroma.Lexer
if language != nil {
lexer = lexers.Get(string(language))
}
if lexer == nil {
_, _ = w.WriteString("<pre><code")
if language != nil {
_, _ = w.WriteString(` class="language-`)
ghtml.DefaultWriter.Write(w, language)
_, _ = w.WriteString(`"`)
}
_ = w.WriteByte('>')
ghtml.DefaultWriter.RawWrite(w, code.Bytes())
_, _ = w.WriteString("</code></pre>\n")
return ast.WalkContinue, nil
}
iterator, err := chroma.Coalesce(lexer).Tokenise(nil, code.String())
if err != nil {
return ast.WalkStop, err
}
return ast.WalkContinue, m.Formatter.Format(w, m.Style, iterator)
}