mirror of
https://github.com/alecthomas/chroma.git
synced 2025-03-27 21:49:13 +02:00
Move style and formatter API into chroma package.
This commit is contained in:
parent
ef4a53333b
commit
d852022f8d
8
README.md
Normal file
8
README.md
Normal file
@ -0,0 +1,8 @@
|
||||
# Chroma - A general purpose syntax highlighter for Go
|
||||
|
||||
Chroma is inspired by [Pygments](http://pygments.org/).
|
||||
|
||||
|
||||
## Unsupported Pygments features
|
||||
|
||||
- Autodetection from content.
|
@ -1,4 +1,4 @@
|
||||
package styles
|
||||
package chroma
|
||||
|
||||
import (
|
||||
"fmt"
|
@ -1,4 +1,4 @@
|
||||
package styles
|
||||
package chroma
|
||||
|
||||
import (
|
||||
"testing"
|
18
formatter.go
Normal file
18
formatter.go
Normal file
@ -0,0 +1,18 @@
|
||||
package chroma
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
// A Formatter for Chroma lexers.
|
||||
type Formatter interface {
|
||||
// Format returns a formatting function for tokens.
|
||||
Format(w io.Writer, style *Style) (func(*Token), error)
|
||||
}
|
||||
|
||||
// A FormatterFunc is a Formatter implemented as a function.
|
||||
type FormatterFunc func(io.Writer, *Style) (func(*Token), error)
|
||||
|
||||
func (f FormatterFunc) Format(w io.Writer, s *Style) (func(*Token), error) {
|
||||
return f(w, s)
|
||||
}
|
@ -4,35 +4,23 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/alecthomas/chroma"
|
||||
"github.com/alecthomas/chroma/styles"
|
||||
)
|
||||
|
||||
// A Formatter for Chroma lexers.
|
||||
type Formatter interface {
|
||||
// Format returns a formatting function for tokens.
|
||||
Format(w io.Writer, style *styles.Style) (func(*chroma.Token), error)
|
||||
}
|
||||
|
||||
type FormatterFunc func(io.Writer, *styles.Style) (func(*chroma.Token), error)
|
||||
|
||||
func (f FormatterFunc) Format(w io.Writer, s *styles.Style) (func(*chroma.Token), error) {
|
||||
return f(w, s)
|
||||
}
|
||||
|
||||
var noop = Register("noop", FormatterFunc(func(w io.Writer, s *styles.Style) (func(*chroma.Token), error) {
|
||||
// NoOp formatter.
|
||||
var NoOp = Register("noop", chroma.FormatterFunc(func(w io.Writer, s *chroma.Style) (func(*chroma.Token), error) {
|
||||
return func(t *chroma.Token) { io.WriteString(w, t.Value) }, nil
|
||||
}))
|
||||
|
||||
// Fallback formatter.
|
||||
var Fallback = noop
|
||||
var Fallback = NoOp
|
||||
|
||||
// Registry of Formatters.
|
||||
var Registry = map[string]Formatter{}
|
||||
var Registry = map[string]chroma.Formatter{}
|
||||
|
||||
// Get formatter by name.
|
||||
//
|
||||
// If the given formatter is not found, the Fallback formatter will be returned.
|
||||
func Get(name string) Formatter {
|
||||
func Get(name string) chroma.Formatter {
|
||||
if f, ok := Registry[name]; ok {
|
||||
return f
|
||||
}
|
||||
@ -40,7 +28,7 @@ func Get(name string) Formatter {
|
||||
}
|
||||
|
||||
// Register a named formatter.
|
||||
func Register(name string, formatter Formatter) Formatter {
|
||||
func Register(name string, formatter chroma.Formatter) chroma.Formatter {
|
||||
Registry[name] = formatter
|
||||
return formatter
|
||||
}
|
||||
|
@ -5,11 +5,10 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/alecthomas/chroma"
|
||||
"github.com/alecthomas/chroma/styles"
|
||||
)
|
||||
|
||||
// Tokens formatter outputs the raw token structures.
|
||||
var Tokens = Register("tokens", FormatterFunc(func(w io.Writer, s *styles.Style) (func(*chroma.Token), error) {
|
||||
var Tokens = Register("tokens", chroma.FormatterFunc(func(w io.Writer, s *chroma.Style) (func(*chroma.Token), error) {
|
||||
return func(token *chroma.Token) {
|
||||
fmt.Fprintln(w, token.GoString())
|
||||
}, nil
|
||||
|
@ -5,26 +5,25 @@ import (
|
||||
"io"
|
||||
"math"
|
||||
|
||||
"github.com/alecthomas/chroma" // nolint
|
||||
"github.com/alecthomas/chroma/styles"
|
||||
"github.com/alecthomas/chroma"
|
||||
)
|
||||
|
||||
type ttyTable struct {
|
||||
foreground map[styles.Colour]string
|
||||
background map[styles.Colour]string
|
||||
foreground map[chroma.Colour]string
|
||||
background map[chroma.Colour]string
|
||||
}
|
||||
|
||||
var c = styles.ParseColour
|
||||
var c = chroma.ParseColour
|
||||
|
||||
var ttyTables = map[int]*ttyTable{
|
||||
8: &ttyTable{
|
||||
foreground: map[styles.Colour]string{
|
||||
foreground: map[chroma.Colour]string{
|
||||
c("#000000"): "\033[30m", c("#7f0000"): "\033[31m", c("#007f00"): "\033[32m", c("#7f7fe0"): "\033[33m",
|
||||
c("#00007f"): "\033[34m", c("#7f007f"): "\033[35m", c("#007f7f"): "\033[36m", c("#e5e5e5"): "\033[37m",
|
||||
c("#555555"): "\033[90m", c("#ff0000"): "\033[91m", c("#00ff00"): "\033[92m", c("#ffff00"): "\033[93m",
|
||||
c("#0000ff"): "\033[94m", c("#ff00ff"): "\033[95m", c("#00ffff"): "\033[96m", c("#ffffff"): "\033[97m",
|
||||
},
|
||||
background: map[styles.Colour]string{
|
||||
background: map[chroma.Colour]string{
|
||||
c("#000000"): "\033[40m", c("#7f0000"): "\033[41m", c("#007f00"): "\033[42m", c("#7f7fe0"): "\033[43m",
|
||||
c("#00007f"): "\033[44m", c("#7f007f"): "\033[45m", c("#007f7f"): "\033[46m", c("#e5e5e5"): "\033[47m",
|
||||
c("#555555"): "\033[100m", c("#ff0000"): "\033[101m", c("#00ff00"): "\033[102m", c("#ffff00"): "\033[103m",
|
||||
@ -32,7 +31,7 @@ var ttyTables = map[int]*ttyTable{
|
||||
},
|
||||
},
|
||||
256: &ttyTable{
|
||||
foreground: map[styles.Colour]string{
|
||||
foreground: map[chroma.Colour]string{
|
||||
c("#000000"): "\033[38;5;0m", c("#800000"): "\033[38;5;1m", c("#008000"): "\033[38;5;2m", c("#808000"): "\033[38;5;3m",
|
||||
c("#000080"): "\033[38;5;4m", c("#800080"): "\033[38;5;5m", c("#008080"): "\033[38;5;6m", c("#c0c0c0"): "\033[38;5;7m",
|
||||
c("#808080"): "\033[38;5;8m", c("#ff0000"): "\033[38;5;9m", c("#00ff00"): "\033[38;5;10m", c("#ffff00"): "\033[38;5;11m",
|
||||
@ -98,7 +97,7 @@ var ttyTables = map[int]*ttyTable{
|
||||
c("#a8a8a8"): "\033[38;5;248m", c("#b2b2b2"): "\033[38;5;249m", c("#bcbcbc"): "\033[38;5;250m", c("#c6c6c6"): "\033[38;5;251m",
|
||||
c("#d0d0d0"): "\033[38;5;252m", c("#dadada"): "\033[38;5;253m", c("#e4e4e4"): "\033[38;5;254m", c("#eeeeee"): "\033[38;5;255m",
|
||||
},
|
||||
background: map[styles.Colour]string{
|
||||
background: map[chroma.Colour]string{
|
||||
c("#000000"): "\033[48;5;0m", c("#800000"): "\033[48;5;1m", c("#008000"): "\033[48;5;2m", c("#808000"): "\033[48;5;3m",
|
||||
c("#000080"): "\033[48;5;4m", c("#800080"): "\033[48;5;5m", c("#008080"): "\033[48;5;6m", c("#c0c0c0"): "\033[48;5;7m",
|
||||
c("#808080"): "\033[48;5;8m", c("#ff0000"): "\033[48;5;9m", c("#00ff00"): "\033[48;5;10m", c("#ffff00"): "\033[48;5;11m",
|
||||
@ -167,7 +166,7 @@ var ttyTables = map[int]*ttyTable{
|
||||
},
|
||||
}
|
||||
|
||||
func entryToEscapeSequence(table *ttyTable, entry *styles.Entry) string {
|
||||
func entryToEscapeSequence(table *ttyTable, entry *chroma.StyleEntry) string {
|
||||
out := ""
|
||||
if entry.Bold {
|
||||
out += "\033[1m"
|
||||
@ -184,8 +183,8 @@ func entryToEscapeSequence(table *ttyTable, entry *styles.Entry) string {
|
||||
return out
|
||||
}
|
||||
|
||||
func findClosest(table *ttyTable, colour styles.Colour) styles.Colour {
|
||||
closestColour := styles.Colour(0)
|
||||
func findClosest(table *ttyTable, colour chroma.Colour) chroma.Colour {
|
||||
closestColour := chroma.Colour(0)
|
||||
closest := math.MaxInt32
|
||||
for styleColour := range table.foreground {
|
||||
distance := styleColour.Distance(colour)
|
||||
@ -197,7 +196,7 @@ func findClosest(table *ttyTable, colour styles.Colour) styles.Colour {
|
||||
return closestColour
|
||||
}
|
||||
|
||||
func styleToEscapeSequence(table *ttyTable, style *styles.Style) map[chroma.TokenType]string {
|
||||
func styleToEscapeSequence(table *ttyTable, style *chroma.Style) map[chroma.TokenType]string {
|
||||
out := map[chroma.TokenType]string{}
|
||||
for ttype, entry := range style.Entries {
|
||||
out[ttype] = entryToEscapeSequence(table, entry)
|
||||
@ -209,7 +208,7 @@ type indexedTTYFormatter struct {
|
||||
table *ttyTable
|
||||
}
|
||||
|
||||
func (c *indexedTTYFormatter) Format(w io.Writer, style *styles.Style) (func(*chroma.Token), error) {
|
||||
func (c *indexedTTYFormatter) Format(w io.Writer, style *chroma.Style) (func(*chroma.Token), error) {
|
||||
theme := styleToEscapeSequence(c.table, style)
|
||||
return func(token *chroma.Token) {
|
||||
// TODO: Cache token lookups?
|
||||
@ -219,7 +218,7 @@ func (c *indexedTTYFormatter) Format(w io.Writer, style *styles.Style) (func(*ch
|
||||
if !ok {
|
||||
clr, ok = theme[token.Type.Category()]
|
||||
if !ok {
|
||||
clr = theme[styles.Inherit]
|
||||
clr = theme[chroma.InheritStyle]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,13 +5,12 @@ import (
|
||||
"io"
|
||||
|
||||
"github.com/alecthomas/chroma"
|
||||
"github.com/alecthomas/chroma/styles"
|
||||
)
|
||||
|
||||
// TTY16m is a true-colour terminal formatter.
|
||||
var TTY16m = Register("terminal16m", FormatterFunc(trueColourFormatter))
|
||||
var TTY16m = Register("terminal16m", chroma.FormatterFunc(trueColourFormatter))
|
||||
|
||||
func trueColourFormatter(w io.Writer, style *styles.Style) (func(*chroma.Token), error) {
|
||||
func trueColourFormatter(w io.Writer, style *chroma.Style) (func(*chroma.Token), error) {
|
||||
return func(token *chroma.Token) {
|
||||
entry := style.Get(token.Type)
|
||||
if !entry.IsZero() {
|
||||
|
149
style.go
Normal file
149
style.go
Normal file
@ -0,0 +1,149 @@
|
||||
package chroma
|
||||
|
||||
import "strings"
|
||||
|
||||
// InheritStyle from entry with this key.
|
||||
const InheritStyle TokenType = -1
|
||||
|
||||
// A StyleEntry in the Style map.
|
||||
type StyleEntry struct {
|
||||
// Hex colours.
|
||||
Colour Colour
|
||||
Background Colour
|
||||
Border Colour
|
||||
|
||||
Bold bool
|
||||
Italic bool
|
||||
Underline bool
|
||||
}
|
||||
|
||||
func (e *StyleEntry) String() string {
|
||||
out := []string{}
|
||||
if e.Bold {
|
||||
out = append(out, "bold")
|
||||
}
|
||||
if e.Italic {
|
||||
out = append(out, "italic")
|
||||
}
|
||||
if e.Underline {
|
||||
out = append(out, "underline")
|
||||
}
|
||||
if e.Colour.IsSet() {
|
||||
out = append(out, e.Colour.String())
|
||||
}
|
||||
if e.Background.IsSet() {
|
||||
out = append(out, "bg:"+e.Background.String())
|
||||
}
|
||||
if e.Border.IsSet() {
|
||||
out = append(out, "border:"+e.Border.String())
|
||||
}
|
||||
return strings.Join(out, " ")
|
||||
}
|
||||
|
||||
func (e *StyleEntry) IsZero() bool {
|
||||
return e.Colour == 0 && e.Background == 0 && e.Border == 0 && !e.Bold && !e.Italic && !e.Underline
|
||||
}
|
||||
|
||||
// StyleEntries mapping TokenType to colour definition.
|
||||
type StyleEntries map[TokenType]string
|
||||
|
||||
// NewStyle creates a new style definition.
|
||||
func NewStyle(name string, entries StyleEntries) *Style {
|
||||
s := &Style{
|
||||
Name: name,
|
||||
Entries: map[TokenType]*StyleEntry{
|
||||
InheritStyle: &StyleEntry{},
|
||||
},
|
||||
}
|
||||
for tt, entry := range entries {
|
||||
s.Add(tt, entry)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// A Style definition.
|
||||
//
|
||||
// See http://pygments.org/docs/styles/ for details. Semantics are intended to be identical.
|
||||
type Style struct {
|
||||
Name string
|
||||
Entries map[TokenType]*StyleEntry
|
||||
}
|
||||
|
||||
// Get a style entry. Will try sub-category or category if an exact match is not found, and
|
||||
// finally return the entry mapped to `InheritStyle`.
|
||||
func (s *Style) Get(ttype TokenType) *StyleEntry {
|
||||
out := s.Entries[ttype]
|
||||
if out == nil {
|
||||
out = s.Entries[ttype.SubCategory()]
|
||||
if out == nil {
|
||||
out = s.Entries[ttype.Category()]
|
||||
if out == nil {
|
||||
out = s.Entries[InheritStyle]
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Add an StyleEntry to the Style map.
|
||||
//
|
||||
// See http://pygments.org/docs/styles/#style-rules for details.
|
||||
func (s *Style) Add(ttype TokenType, entry string) *Style { // nolint: gocyclo
|
||||
out := &StyleEntry{}
|
||||
dupl := s.Entries[ttype.SubCategory()]
|
||||
if dupl == nil {
|
||||
dupl = s.Entries[ttype.Category()]
|
||||
if dupl == nil {
|
||||
dupl = s.Entries[InheritStyle]
|
||||
}
|
||||
}
|
||||
parent := &StyleEntry{}
|
||||
// Duplicate ancestor node.
|
||||
*parent = *dupl
|
||||
for _, part := range strings.Fields(entry) {
|
||||
switch {
|
||||
case part == "italic":
|
||||
out.Italic = true
|
||||
case part == "noitalic":
|
||||
out.Italic = false
|
||||
case part == "bold":
|
||||
out.Bold = true
|
||||
case part == "nobold":
|
||||
out.Bold = false
|
||||
case part == "underline":
|
||||
out.Underline = true
|
||||
case part == "nounderline":
|
||||
out.Underline = false
|
||||
case part == "noinherit":
|
||||
parent = &StyleEntry{}
|
||||
case strings.HasPrefix(part, "bg:#"):
|
||||
out.Background = ParseColour(part[3:])
|
||||
case strings.HasPrefix(part, "border:#"):
|
||||
out.Border = ParseColour(part[7:])
|
||||
case strings.HasPrefix(part, "#"):
|
||||
out.Colour = ParseColour(part)
|
||||
default:
|
||||
panic("unsupported style entry " + part)
|
||||
}
|
||||
}
|
||||
if parent.Colour != 0 && out.Colour == 0 {
|
||||
out.Colour = parent.Colour
|
||||
}
|
||||
if parent.Background != 0 && out.Background == 0 {
|
||||
out.Background = parent.Background
|
||||
}
|
||||
if parent.Border != 0 && out.Border == 0 {
|
||||
out.Border = parent.Border
|
||||
}
|
||||
if parent.Bold && !out.Bold {
|
||||
out.Bold = true
|
||||
}
|
||||
if parent.Italic && !out.Italic {
|
||||
out.Italic = true
|
||||
}
|
||||
if parent.Underline && !out.Underline {
|
||||
out.Underline = true
|
||||
}
|
||||
s.Entries[ttype] = out
|
||||
return s
|
||||
}
|
30
style_test.go
Normal file
30
style_test.go
Normal file
@ -0,0 +1,30 @@
|
||||
package chroma
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestStyleAddNoInherit(t *testing.T) {
|
||||
s := NewStyle("test", StyleEntries{
|
||||
Name: "bold #f00",
|
||||
NameVariable: "noinherit #fff",
|
||||
})
|
||||
require.Equal(t, &StyleEntry{Colour: 0x1000000}, s.Get(NameVariable))
|
||||
}
|
||||
|
||||
func TestStyleInherit(t *testing.T) {
|
||||
s := NewStyle("test", StyleEntries{
|
||||
Name: "bold #f00",
|
||||
NameVariable: "#fff",
|
||||
})
|
||||
require.Equal(t, &StyleEntry{Colour: 0x1000000, Bold: true}, s.Get(NameVariable))
|
||||
}
|
||||
|
||||
func TestColours(t *testing.T) {
|
||||
s := NewStyle("test", StyleEntries{
|
||||
Name: "#f00 bg:#001 border:#ansiblue",
|
||||
})
|
||||
require.Equal(t, &StyleEntry{Colour: 0xff0001, Background: 0x000012, Border: 0x000100}, s.Get(Name))
|
||||
}
|
160
styles/api.go
160
styles/api.go
@ -1,173 +1,23 @@
|
||||
package styles
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/alecthomas/chroma"
|
||||
)
|
||||
import "github.com/alecthomas/chroma"
|
||||
|
||||
// Registry of Styles.
|
||||
var Registry = map[string]*Style{}
|
||||
var Registry = map[string]*chroma.Style{}
|
||||
|
||||
// Fallback style. Reassign to change the default fallback style.
|
||||
var Fallback = SwapOff
|
||||
|
||||
// Register a Style.
|
||||
func Register(style *Style) *Style {
|
||||
// Register a chroma.Style.
|
||||
func Register(style *chroma.Style) *chroma.Style {
|
||||
Registry[style.Name] = style
|
||||
return style
|
||||
}
|
||||
|
||||
// Get named style, or Fallback.
|
||||
func Get(name string) *Style {
|
||||
func Get(name string) *chroma.Style {
|
||||
if style, ok := Registry[name]; ok {
|
||||
return style
|
||||
}
|
||||
return Fallback
|
||||
}
|
||||
|
||||
// Inherit from entry with this key.
|
||||
const Inherit chroma.TokenType = -1
|
||||
|
||||
// An Entry in the Style map.
|
||||
type Entry struct {
|
||||
// Hex colours.
|
||||
Colour Colour
|
||||
Background Colour
|
||||
Border Colour
|
||||
|
||||
Bold bool
|
||||
Italic bool
|
||||
Underline bool
|
||||
}
|
||||
|
||||
func (e *Entry) String() string {
|
||||
out := []string{}
|
||||
if e.Bold {
|
||||
out = append(out, "bold")
|
||||
}
|
||||
if e.Italic {
|
||||
out = append(out, "italic")
|
||||
}
|
||||
if e.Underline {
|
||||
out = append(out, "underline")
|
||||
}
|
||||
if e.Colour.IsSet() {
|
||||
out = append(out, e.Colour.String())
|
||||
}
|
||||
if e.Background.IsSet() {
|
||||
out = append(out, "bg:"+e.Background.String())
|
||||
}
|
||||
if e.Border.IsSet() {
|
||||
out = append(out, "border:"+e.Border.String())
|
||||
}
|
||||
return strings.Join(out, " ")
|
||||
}
|
||||
|
||||
// Entries mapping TokenType to colour definition.
|
||||
type Entries map[chroma.TokenType]string
|
||||
|
||||
func (e *Entry) IsZero() bool {
|
||||
return e.Colour == 0 && e.Background == 0 && e.Border == 0 && !e.Bold && !e.Italic && !e.Underline
|
||||
}
|
||||
|
||||
// New creates a new style definition.
|
||||
func New(name string, entries Entries) *Style {
|
||||
s := &Style{
|
||||
Name: name,
|
||||
Entries: map[chroma.TokenType]*Entry{
|
||||
Inherit: &Entry{},
|
||||
},
|
||||
}
|
||||
for tt, entry := range entries {
|
||||
s.Add(tt, entry)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// A Style definition.
|
||||
//
|
||||
// See http://pygments.org/docs/styles/ for details. Semantics are intended to be identical.
|
||||
type Style struct {
|
||||
Name string
|
||||
Entries map[chroma.TokenType]*Entry
|
||||
}
|
||||
|
||||
// Get a style entry. Will try sub-category or category if an exact match is not found, and
|
||||
// finally return the entry mapped to `Inherit`.
|
||||
func (s *Style) Get(ttype chroma.TokenType) *Entry {
|
||||
out := s.Entries[ttype]
|
||||
if out == nil {
|
||||
out = s.Entries[ttype.SubCategory()]
|
||||
if out == nil {
|
||||
out = s.Entries[ttype.Category()]
|
||||
if out == nil {
|
||||
out = s.Entries[Inherit]
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// Add an Entry to the Style map.
|
||||
//
|
||||
// See http://pygments.org/docs/styles/#style-rules for details.
|
||||
func (s *Style) Add(ttype chroma.TokenType, entry string) *Style { // nolint: gocyclo
|
||||
out := &Entry{}
|
||||
dupl := s.Entries[ttype.SubCategory()]
|
||||
if dupl == nil {
|
||||
dupl = s.Entries[ttype.Category()]
|
||||
if dupl == nil {
|
||||
dupl = s.Entries[Inherit]
|
||||
}
|
||||
}
|
||||
parent := &Entry{}
|
||||
// Duplicate ancestor node.
|
||||
*parent = *dupl
|
||||
for _, part := range strings.Fields(entry) {
|
||||
switch {
|
||||
case part == "italic":
|
||||
out.Italic = true
|
||||
case part == "noitalic":
|
||||
out.Italic = false
|
||||
case part == "bold":
|
||||
out.Bold = true
|
||||
case part == "nobold":
|
||||
out.Bold = false
|
||||
case part == "underline":
|
||||
out.Underline = true
|
||||
case part == "nounderline":
|
||||
out.Underline = false
|
||||
case part == "noinherit":
|
||||
parent = &Entry{}
|
||||
case strings.HasPrefix(part, "bg:#"):
|
||||
out.Background = ParseColour(part[3:])
|
||||
case strings.HasPrefix(part, "border:#"):
|
||||
out.Border = ParseColour(part[7:])
|
||||
case strings.HasPrefix(part, "#"):
|
||||
out.Colour = ParseColour(part)
|
||||
default:
|
||||
panic("unsupported style entry " + part)
|
||||
}
|
||||
}
|
||||
if parent.Colour != 0 && out.Colour == 0 {
|
||||
out.Colour = parent.Colour
|
||||
}
|
||||
if parent.Background != 0 && out.Background == 0 {
|
||||
out.Background = parent.Background
|
||||
}
|
||||
if parent.Border != 0 && out.Border == 0 {
|
||||
out.Border = parent.Border
|
||||
}
|
||||
if parent.Bold && !out.Bold {
|
||||
out.Bold = true
|
||||
}
|
||||
if parent.Italic && !out.Italic {
|
||||
out.Italic = true
|
||||
}
|
||||
if parent.Underline && !out.Underline {
|
||||
out.Underline = true
|
||||
}
|
||||
s.Entries[ttype] = out
|
||||
return s
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
package styles
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/alecthomas/chroma"
|
||||
)
|
||||
|
||||
func TestStyleAddNoInherit(t *testing.T) {
|
||||
s := New("test", Entries{
|
||||
chroma.Name: "bold #f00",
|
||||
chroma.NameVariable: "noinherit #fff",
|
||||
})
|
||||
require.Equal(t, &Entry{Colour: 0x1000000}, s.Get(chroma.NameVariable))
|
||||
}
|
||||
|
||||
func TestStyleInherit(t *testing.T) {
|
||||
s := New("test", Entries{
|
||||
chroma.Name: "bold #f00",
|
||||
chroma.NameVariable: "#fff",
|
||||
})
|
||||
require.Equal(t, &Entry{Colour: 0x1000000, Bold: true}, s.Get(chroma.NameVariable))
|
||||
}
|
||||
|
||||
func TestColours(t *testing.T) {
|
||||
s := New("test", Entries{
|
||||
chroma.Name: "#f00 bg:#001 border:#ansiblue",
|
||||
})
|
||||
require.Equal(t, &Entry{Colour: 0xff0001, Background: 0x000012, Border: 0x000100}, s.Get(chroma.Name))
|
||||
}
|
@ -1,35 +1,35 @@
|
||||
package styles
|
||||
|
||||
import (
|
||||
. "github.com/alecthomas/chroma" // nolint: golint
|
||||
"github.com/alecthomas/chroma"
|
||||
)
|
||||
|
||||
// Borland style.
|
||||
var Borland = Register(New("borland", Entries{
|
||||
Whitespace: "#bbbbbb",
|
||||
var Borland = Register(chroma.NewStyle("borland", chroma.StyleEntries{
|
||||
chroma.Whitespace: "#bbbbbb",
|
||||
|
||||
Comment: "italic #008800",
|
||||
CommentPreproc: "noitalic #008080",
|
||||
CommentSpecial: "noitalic bold",
|
||||
chroma.Comment: "italic #008800",
|
||||
chroma.CommentPreproc: "noitalic #008080",
|
||||
chroma.CommentSpecial: "noitalic bold",
|
||||
|
||||
String: "#0000FF",
|
||||
StringChar: "#800080",
|
||||
Number: "#0000FF",
|
||||
Keyword: "bold #000080",
|
||||
OperatorWord: "bold",
|
||||
NameTag: "bold #000080",
|
||||
NameAttribute: "#FF0000",
|
||||
chroma.String: "#0000FF",
|
||||
chroma.StringChar: "#800080",
|
||||
chroma.Number: "#0000FF",
|
||||
chroma.Keyword: "bold #000080",
|
||||
chroma.OperatorWord: "bold",
|
||||
chroma.NameTag: "bold #000080",
|
||||
chroma.NameAttribute: "#FF0000",
|
||||
|
||||
GenericHeading: "#999999",
|
||||
GenericSubheading: "#aaaaaa",
|
||||
GenericDeleted: "bg:#ffdddd #000000",
|
||||
GenericInserted: "bg:#ddffdd #000000",
|
||||
GenericError: "#aa0000",
|
||||
GenericEmph: "italic",
|
||||
GenericStrong: "bold",
|
||||
GenericPrompt: "#555555",
|
||||
GenericOutput: "#888888",
|
||||
GenericTraceback: "#aa0000",
|
||||
chroma.GenericHeading: "#999999",
|
||||
chroma.GenericSubheading: "#aaaaaa",
|
||||
chroma.GenericDeleted: "bg:#ffdddd #000000",
|
||||
chroma.GenericInserted: "bg:#ddffdd #000000",
|
||||
chroma.GenericError: "#aa0000",
|
||||
chroma.GenericEmph: "italic",
|
||||
chroma.GenericStrong: "bold",
|
||||
chroma.GenericPrompt: "#555555",
|
||||
chroma.GenericOutput: "#888888",
|
||||
chroma.GenericTraceback: "#aa0000",
|
||||
|
||||
Error: "bg:#e3d2d2 #a61717",
|
||||
chroma.Error: "bg:#e3d2d2 #a61717",
|
||||
}))
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
)
|
||||
|
||||
// SwapOff theme.
|
||||
var SwapOff = Register(New("swapoff", map[chroma.TokenType]string{
|
||||
var SwapOff = Register(chroma.NewStyle("swapoff", map[chroma.TokenType]string{
|
||||
chroma.Number: "bold #ansiyellow",
|
||||
chroma.Comment: "#ansiteal",
|
||||
chroma.CommentPreproc: "bold #ansigreen",
|
||||
|
@ -5,7 +5,7 @@ import (
|
||||
)
|
||||
|
||||
// Trac colour scheme.
|
||||
var Trac = Register(New("trac", map[chroma.TokenType]string{
|
||||
var Trac = Register(chroma.NewStyle("trac", map[chroma.TokenType]string{
|
||||
chroma.Whitespace: "#bbbbbb",
|
||||
chroma.Comment: "italic #999988",
|
||||
chroma.CommentPreproc: "bold noitalic #999999",
|
||||
|
Loading…
x
Reference in New Issue
Block a user