chroma.go

 1package xchroma
 2
 3import (
 4	"fmt"
 5	"image/color"
 6	"io"
 7
 8	"charm.land/lipgloss/v2"
 9	"github.com/alecthomas/chroma/v2"
10)
11
12// Formatter is func that returns a custom formatter for Chroma that uses
13// Lip Gloss for foreground styling, while keeping a forced background color.
14func Formatter(bgColor color.Color, processValue func(string) string) chroma.Formatter {
15	return chroma.FormatterFunc(func(w io.Writer, style *chroma.Style, it chroma.Iterator) error {
16		for token := it(); token != chroma.EOF; token = it() {
17			value := token.Value
18			if processValue != nil {
19				value = processValue(value)
20			}
21
22			entry := style.Get(token.Type)
23			if entry.IsZero() {
24				if _, err := fmt.Fprint(w, value); err != nil {
25					return err
26				}
27				continue
28			}
29
30			s := lipgloss.NewStyle().
31				Background(bgColor)
32
33			if entry.Bold == chroma.Yes {
34				s = s.Bold(true)
35			}
36			if entry.Underline == chroma.Yes {
37				s = s.Underline(true)
38			}
39			if entry.Italic == chroma.Yes {
40				s = s.Italic(true)
41			}
42			if entry.Colour.IsSet() {
43				s = s.Foreground(lipgloss.Color(entry.Colour.String()))
44			}
45
46			if _, err := fmt.Fprint(w, s.Render(value)); err != nil {
47				return err
48			}
49		}
50		return nil
51	})
52}