This repository has been archived on 2022-05-06. You can view files and clone it, but cannot push or open issues/pull-requests.
chromajson/chromajson.go

80 lines
1.8 KiB
Go

package chromajson
import (
"encoding/json"
"fmt"
"io"
"strings"
"github.com/alecthomas/chroma/v2"
"github.com/alecthomas/chroma/v2/styles"
)
// Style is a chroma style
type Style struct {
Name string `json:"name"`
Entries map[string]StyleEntry `json:"style"`
}
// StyleEntry is a mapping for a chroma style
type StyleEntry struct {
Color string `json:"color"`
Background string `json:"background"`
Border string `json:"border"`
Accents []string `json:"accent"`
}
// String returns a chroma-representable style entry
func (s StyleEntry) String() string {
normalise := func(c string) string {
return "#" + strings.TrimLeft(c, "#")
}
parts := make([]string, 0, 4)
if len(s.Accents) > 0 {
parts = append(parts, strings.Join(s.Accents, " "))
}
if s.Background != "" {
parts = append(parts, fmt.Sprintf("bg:%s", normalise(s.Background)))
}
if s.Border != "" {
parts = append(parts, fmt.Sprintf("border:%s", normalise(s.Border)))
}
if s.Color != "" {
parts = append(parts, normalise(s.Color))
}
return strings.Join(parts, " ")
}
// Chroma converts a Style to a chroma.Style
func (s *Style) Chroma() (*chroma.Style, error) {
style := chroma.NewStyleBuilder(s.Name)
for name, entry := range s.Entries {
if token, ok := tokenToType[name]; ok {
style.Add(token, entry.String())
}
}
return style.Build()
}
// Register registers the Style directly to chroma
func (s *Style) Register() error {
style, err := s.Chroma()
if err != nil {
return err
}
styles.Register(style)
return nil
}
// LoadStyle loads a Style from an io.Reader
func LoadStyle(r io.Reader) (*Style, error) {
var s Style
d := json.NewDecoder(r)
d.DisallowUnknownFields()
if err := d.Decode(&s); err != nil {
return nil, err
}
return &s, nil
}