bin/utils/highlight_text.go

71 lines
1.3 KiB
Go
Raw Normal View History

2023-09-13 20:03:34 +02:00
package utils
import (
"bytes"
"context"
"fmt"
"io"
"github.com/alecthomas/chroma/formatters/html"
"github.com/alecthomas/chroma/lexers"
"github.com/alecthomas/chroma/styles"
"github.com/sirupsen/logrus"
)
type HighlightedText struct {
text string
}
func (ht HighlightedText) Render(ctx context.Context, w io.Writer) error {
_, err := w.Write([]byte(ht.text))
return err
}
func NewPreText(text string) HighlightedText {
return HighlightedText{
text: fmt.Sprintf("<pre>%s</pre>", text),
}
}
func HighlightText(text, lang, style_name string) HighlightedText {
if style_name == "" {
style_name = "solarized-light"
}
style := styles.Get(style_name)
if style == nil {
logrus.WithField("style", style_name).Warnln("Cannot find style")
return NewPreText(text)
}
lexer := lexers.Get(lang)
if lexer == nil {
return NewPreText(text)
}
formatter := html.New(html.WithLineNumbers(true))
if formatter == nil {
return NewPreText(text)
}
tokens, err := lexer.Tokenise(nil, text)
if err != nil {
return NewPreText(text)
}
buf := new(bytes.Buffer)
err = formatter.Format(buf, style, tokens)
if err != nil {
return NewPreText(text)
}
b, err := io.ReadAll(buf)
if err != nil {
return NewPreText(text)
}
return HighlightedText{
2023-09-13 20:39:24 +02:00
text: "<style>pre { width: fit-content; }</style>\n" + string(b),
2023-09-13 20:03:34 +02:00
}
}