package main
import (
"bytes"
"fmt"
"html/template"
"path/filepath"
"strings"
"github.com/alecthomas/chroma/v2"
"github.com/alecthomas/chroma/v2/formatters/html"
"github.com/alecthomas/chroma/v2/lexers"
"github.com/alecthomas/chroma/v2/styles"
)
var formatter = html.New(
html.WithClasses(true),
html.WithLineNumbers(true),
html.LineNumbersInTable(true),
html.WithLinkableLineNumbers(true, "L"),
html.TabWidth(4),
)
var highlightStyle = styles.Get("pygments")
func highlightLimited(name string, content []byte) (template.HTML, bool) {
if len(content) > maxHighlight {
return "", false
}
return highlight(name, content)
}
func highlight(name string, content []byte) (template.HTML, bool) {
lexer := lexers.Match(filepath.Base(name))
if lexer == nil {
lexer = lexers.Analyse(string(content))
}
if lexer == nil {
return "", false
}
lexer = chroma.Coalesce(lexer)
iterator, err := lexer.Tokenise(nil, string(content))
if err != nil {
return "", false
}
var buf bytes.Buffer
if err := formatter.Format(&buf, highlightStyle, iterator); err != nil {
return "", false
}
return template.HTML(buf.String()), true
}
func scoped(rules []string, scope string) string {
var b strings.Builder
for _, r := range rules {
b.WriteString(scope + r + "\n")
}
return b.String()
}
func highlightCSS() []byte {
var buf, dark bytes.Buffer
formatter.WriteCSS(&buf, highlightStyle)
formatter.WriteCSS(&dark, styles.Get("github-dark"))
var rules []string
for line := range strings.Lines(dark.String()) {
_, rule, ok := strings.Cut(line, "*/ ")
if !ok || !strings.HasPrefix(rule, ".chroma .") || strings.Contains(rule, "background-color") {
continue
}
rules = append(rules, strings.TrimSpace(rule))
}
fmt.Fprintf(&buf, "%s\n@media (prefers-color-scheme:dark){\n%s}\n", scoped(rules, ":root[data-theme=dark] "), scoped(rules, ":root:not([data-theme=light]) "))
return buf.Bytes()
}