ikurotime / gitgud

public
main / internal/interface/web/presenter/render.go
1.3 KB · Go Raw
 1package presenter
 2
 3import (
 4	"bytes"
 5
 6	chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
 7	"github.com/alecthomas/chroma/v2/lexers"
 8	"github.com/alecthomas/chroma/v2/styles"
 9	"github.com/yuin/goldmark"
10	"github.com/yuin/goldmark/extension"
11)
12
13var md = goldmark.New(goldmark.WithExtensions(extension.GFM))
14
15// RenderMarkdown converts markdown to HTML. Raw HTML in the source is escaped
16// (goldmark's default, no WithUnsafe), which keeps user content safe.
17func RenderMarkdown(src []byte) string {
18	var buf bytes.Buffer
19	if err := md.Convert(src, &buf); err != nil {
20		return "<pre>" + string(src) + "</pre>"
21	}
22	return buf.String()
23}
24
25var (
26	highlightStyle     = styles.Get("github-dark")
27	highlightFormatter = chromahtml.New(chromahtml.WithClasses(false), chromahtml.WithLineNumbers(true))
28)
29
30// Highlight renders source code as highlighted HTML, choosing a lexer by filename.
31func Highlight(code, filename string) string {
32	lexer := lexers.Match(filename)
33	if lexer == nil {
34		lexer = lexers.Analyse(code)
35	}
36	if lexer == nil {
37		lexer = lexers.Fallback
38	}
39
40	iterator, err := lexer.Tokenise(nil, code)
41	if err != nil {
42		return "<pre>" + code + "</pre>"
43	}
44
45	var buf bytes.Buffer
46	if err := highlightFormatter.Format(&buf, highlightStyle, iterator); err != nil {
47		return "<pre>" + code + "</pre>"
48	}
49	return buf.String()
50}