← history for repobrowser/internal/rendering/highlight.go
dd6c7f93repobrowser/internal/rendering/highlight.go67 lines⬡ raw↓ download
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/**
 * AltGit - altgit
 *
 * This file is licensed under the Affero General Public License version 3 or
 * later. See the COPYING file.
 *
 * @author Paolo Lulli <kevwe.com>
 * @copyright Paolo Lulli 2026
 */

package rendering

import (
    "bytes"
    "html/template"

    chromalib "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"
)

func HighlightCode(content, filename string) (string, string) {
    lexer := lexers.Match(filename)
    if lexer == nil {
        lexer = lexers.Analyse(content)
    }
    if lexer == nil {
        lexer = lexers.Fallback
    }
    lexer = chromalib.Coalesce(lexer)

    style := styles.Get("onedark")
    if style == nil {
        style = styles.Fallback
    }

    formatter := chromahtml.New(
        chromahtml.WithClasses(true),
        chromahtml.TabWidth(4),
        chromahtml.WithLineNumbers(true),
        chromahtml.LineNumbersInTable(true),
    )

    var cssBuf bytes.Buffer
    if err := formatter.WriteCSS(&cssBuf, style); err != nil {
        return plainFallback(content), ""
    }
    chromaCSS := cssBuf.String()

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

    var hlBuf bytes.Buffer
    if err := formatter.Format(&hlBuf, style, iterator); err != nil {
        return plainFallback(content), chromaCSS
    }

    return hlBuf.String(), chromaCSS
}

func plainFallback(content string) string {
    return `<pre style="padding:1rem;overflow:auto;font-size:0.82rem;line-height:1.65">` +
        template.HTMLEscapeString(content) + `</pre>`
}