Replace chroma with go-highlite

This commit is contained in:
2025-06-19 14:18:55 -04:00
parent c271197076
commit f4718e24c8
12 changed files with 318 additions and 1117 deletions
+8 -109
View File
@@ -2,64 +2,17 @@ package ansi
import (
"io"
"sync"
"github.com/alecthomas/chroma/v2"
"github.com/alecthomas/chroma/v2/quick"
"github.com/alecthomas/chroma/v2/styles"
"github.com/muesli/reflow/indent"
"github.com/muesli/termenv"
rwansi "github.com/rwinkhart/go-highlite/ansi"
)
const (
// The chroma style theme name used for rendering.
chromaStyleTheme = "charm"
)
// mutex for synchronizing access to the chroma style registry.
// Related https://github.com/alecthomas/chroma/pull/650
var mutex = sync.Mutex{}
// A CodeBlockElement is used to render code blocks.
type CodeBlockElement struct {
Code string
Language string
}
func chromaStyle(style StylePrimitive) string {
var s string
if style.Color != nil {
s = *style.Color
}
if style.BackgroundColor != nil {
if s != "" {
s += " "
}
s += "bg:" + *style.BackgroundColor
}
if style.Italic != nil && *style.Italic {
if s != "" {
s += " "
}
s += "italic"
}
if style.Bold != nil && *style.Bold {
if s != "" {
s += " "
}
s += "bold"
}
if style.Underline != nil && *style.Underline {
if s != "" {
s += " "
}
s += "underline"
}
return s
}
func (e *CodeBlockElement) Render(w io.Writer, ctx RenderContext) error {
bs := ctx.blockStack
@@ -72,71 +25,17 @@ func (e *CodeBlockElement) Render(w io.Writer, ctx RenderContext) error {
if rules.Margin != nil {
margin = *rules.Margin
}
theme := rules.Theme
if rules.Chroma != nil && ctx.options.ColorProfile != termenv.Ascii {
theme = chromaStyleTheme
mutex.Lock()
// Don't register the style if it's already registered.
_, ok := styles.Registry[theme]
if !ok {
styles.Register(chroma.MustNewStyle(theme,
chroma.StyleEntries{
chroma.Text: chromaStyle(rules.Chroma.Text),
chroma.Error: chromaStyle(rules.Chroma.Error),
chroma.Comment: chromaStyle(rules.Chroma.Comment),
chroma.CommentPreproc: chromaStyle(rules.Chroma.CommentPreproc),
chroma.Keyword: chromaStyle(rules.Chroma.Keyword),
chroma.KeywordReserved: chromaStyle(rules.Chroma.KeywordReserved),
chroma.KeywordNamespace: chromaStyle(rules.Chroma.KeywordNamespace),
chroma.KeywordType: chromaStyle(rules.Chroma.KeywordType),
chroma.Operator: chromaStyle(rules.Chroma.Operator),
chroma.Punctuation: chromaStyle(rules.Chroma.Punctuation),
chroma.Name: chromaStyle(rules.Chroma.Name),
chroma.NameBuiltin: chromaStyle(rules.Chroma.NameBuiltin),
chroma.NameTag: chromaStyle(rules.Chroma.NameTag),
chroma.NameAttribute: chromaStyle(rules.Chroma.NameAttribute),
chroma.NameClass: chromaStyle(rules.Chroma.NameClass),
chroma.NameConstant: chromaStyle(rules.Chroma.NameConstant),
chroma.NameDecorator: chromaStyle(rules.Chroma.NameDecorator),
chroma.NameException: chromaStyle(rules.Chroma.NameException),
chroma.NameFunction: chromaStyle(rules.Chroma.NameFunction),
chroma.NameOther: chromaStyle(rules.Chroma.NameOther),
chroma.Literal: chromaStyle(rules.Chroma.Literal),
chroma.LiteralNumber: chromaStyle(rules.Chroma.LiteralNumber),
chroma.LiteralDate: chromaStyle(rules.Chroma.LiteralDate),
chroma.LiteralString: chromaStyle(rules.Chroma.LiteralString),
chroma.LiteralStringEscape: chromaStyle(rules.Chroma.LiteralStringEscape),
chroma.GenericDeleted: chromaStyle(rules.Chroma.GenericDeleted),
chroma.GenericEmph: chromaStyle(rules.Chroma.GenericEmph),
chroma.GenericInserted: chromaStyle(rules.Chroma.GenericInserted),
chroma.GenericStrong: chromaStyle(rules.Chroma.GenericStrong),
chroma.GenericSubheading: chromaStyle(rules.Chroma.GenericSubheading),
chroma.Background: chromaStyle(rules.Chroma.Background),
}))
}
mutex.Unlock()
}
iw := indent.NewWriterPipe(w, indentation+margin, func(wr io.Writer) {
renderText(w, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, " ")
})
if len(theme) > 0 {
renderText(iw, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, rules.BlockPrefix)
err := quick.Highlight(iw, e.Code, e.Language, "terminal256", theme)
if err != nil {
return err
}
renderText(iw, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, rules.BlockSuffix)
return nil
renderText(iw, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, rules.BlockPrefix)
highightedCode, err := rwansi.Colorize(e.Code, e.Language, 171)
if err != nil {
return err
}
// fallback rendering
el := &BaseElement{
Token: e.Code,
Style: rules.StylePrimitive,
}
return el.Render(iw, ctx)
iw.Write([]byte(highightedCode))
renderText(iw, ctx.options.ColorProfile, bs.Current().Style.StylePrimitive, rules.BlockSuffix)
return nil
}
-37
View File
@@ -1,40 +1,5 @@
package ansi
// Chroma holds all the chroma settings.
type Chroma struct {
Text StylePrimitive `json:"text,omitempty"`
Error StylePrimitive `json:"error,omitempty"`
Comment StylePrimitive `json:"comment,omitempty"`
CommentPreproc StylePrimitive `json:"comment_preproc,omitempty"`
Keyword StylePrimitive `json:"keyword,omitempty"`
KeywordReserved StylePrimitive `json:"keyword_reserved,omitempty"`
KeywordNamespace StylePrimitive `json:"keyword_namespace,omitempty"`
KeywordType StylePrimitive `json:"keyword_type,omitempty"`
Operator StylePrimitive `json:"operator,omitempty"`
Punctuation StylePrimitive `json:"punctuation,omitempty"`
Name StylePrimitive `json:"name,omitempty"`
NameBuiltin StylePrimitive `json:"name_builtin,omitempty"`
NameTag StylePrimitive `json:"name_tag,omitempty"`
NameAttribute StylePrimitive `json:"name_attribute,omitempty"`
NameClass StylePrimitive `json:"name_class,omitempty"`
NameConstant StylePrimitive `json:"name_constant,omitempty"`
NameDecorator StylePrimitive `json:"name_decorator,omitempty"`
NameException StylePrimitive `json:"name_exception,omitempty"`
NameFunction StylePrimitive `json:"name_function,omitempty"`
NameOther StylePrimitive `json:"name_other,omitempty"`
Literal StylePrimitive `json:"literal,omitempty"`
LiteralNumber StylePrimitive `json:"literal_number,omitempty"`
LiteralDate StylePrimitive `json:"literal_date,omitempty"`
LiteralString StylePrimitive `json:"literal_string,omitempty"`
LiteralStringEscape StylePrimitive `json:"literal_string_escape,omitempty"`
GenericDeleted StylePrimitive `json:"generic_deleted,omitempty"`
GenericEmph StylePrimitive `json:"generic_emph,omitempty"`
GenericInserted StylePrimitive `json:"generic_inserted,omitempty"`
GenericStrong StylePrimitive `json:"generic_strong,omitempty"`
GenericSubheading StylePrimitive `json:"generic_subheading,omitempty"`
Background StylePrimitive `json:"background,omitempty"`
}
// StylePrimitive holds all the basic style settings.
type StylePrimitive struct {
BlockPrefix string `json:"block_prefix,omitempty"`
@@ -76,8 +41,6 @@ type StyleBlock struct {
// StyleCodeBlock holds the style settings for a code block.
type StyleCodeBlock struct {
StyleBlock
Theme string `json:"theme,omitempty"`
Chroma *Chroma `json:"chroma,omitempty"`
}
// StyleList holds the style settings for a list.