Gitfed
bastien-mrq/gitfed / cmd / gitfed-web / highlight.go
package main

import (
	"bytes"
	"html/template"

	"github.com/alecthomas/chroma/v2"
	chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
	"github.com/alecthomas/chroma/v2/lexers"
	"github.com/alecthomas/chroma/v2/styles"
)

// chromaFormatter emits inline per-token styles rather than CSS classes
// (chromahtml.WithClasses(false), the default) — no separate stylesheet or
// CSP change needed, since style-src already allows 'unsafe-inline' for the
// inline style="" attributes the rest of the app already relies on (see
// security_headers.go). PreventSurroundingPre(true) drops chroma's own
// <pre> wrapper so highlightCode can reuse gitfed's existing, already-
// themed "pre, code" rule (shellHeadSrc) instead of nesting two of them.
var chromaFormatter = chromahtml.New(chromahtml.PreventSurroundingPre(true), chromahtml.WithClasses(false))

// chromaStyle is a fixed built-in theme (Nord) rather than something
// derived from gitfed's own CSS tokens — matching them exactly would mean
// hand-authoring a chroma style for every token type, well past what a
// "small win" like server-side highlighting needs; Nord's cool dark
// blue-grey palette already sits close to gitfed's own.
var chromaStyle = styles.Get("nord")

// highlightCode renders content as syntax-highlighted HTML for filename's
// detected language, wrapped in a plain <pre><code> so it inherits the
// same global styling as the unhighlighted fallback. ok is false (with a
// nil error) when no lexer matches the filename — the caller falls back to
// plain preformatted text in that case, same as before this existed.
func highlightCode(filename, content string) (html template.HTML, ok bool, err error) {
	lexer := lexers.Match(filename)
	if lexer == nil {
		return "", false, nil
	}
	lexer = chroma.Coalesce(lexer)

	iterator, err := lexer.Tokenise(nil, content)
	if err != nil {
		return "", false, err
	}

	var buf bytes.Buffer
	buf.WriteString("<pre><code>")
	if err := chromaFormatter.Format(&buf, chromaStyle, iterator); err != nil {
		return "", false, err
	}
	buf.WriteString("</code></pre>")
	return template.HTML(buf.String()), true, nil
}