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}