annotate vendor/github.com/alecthomas/chroma/v2/style.go @ 66:787b5ee0289d draft

Use vendored modules Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author yakumo.izuru
date Sun, 23 Jul 2023 13:18:53 +0000
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
66
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
1 package chroma
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
2
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
3 import (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
4 "fmt"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
5 "strings"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
6 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
7
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
8 // Trilean value for StyleEntry value inheritance.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
9 type Trilean uint8
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
10
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
11 // Trilean states.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
12 const (
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
13 Pass Trilean = iota
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
14 Yes
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
15 No
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
16 )
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
17
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
18 func (t Trilean) String() string {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
19 switch t {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
20 case Yes:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
21 return "Yes"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
22 case No:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
23 return "No"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
24 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
25 return "Pass"
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
26 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
27 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
28
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
29 // Prefix returns s with "no" as a prefix if Trilean is no.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
30 func (t Trilean) Prefix(s string) string {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
31 if t == Yes {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
32 return s
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
33 } else if t == No {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
34 return "no" + s
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
35 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
36 return ""
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
37 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
38
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
39 // A StyleEntry in the Style map.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
40 type StyleEntry struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
41 // Hex colours.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
42 Colour Colour
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
43 Background Colour
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
44 Border Colour
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
45
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
46 Bold Trilean
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
47 Italic Trilean
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
48 Underline Trilean
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
49 NoInherit bool
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
50 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
51
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
52 func (s StyleEntry) String() string {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
53 out := []string{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
54 if s.Bold != Pass {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
55 out = append(out, s.Bold.Prefix("bold"))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
56 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
57 if s.Italic != Pass {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
58 out = append(out, s.Italic.Prefix("italic"))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
59 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
60 if s.Underline != Pass {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
61 out = append(out, s.Underline.Prefix("underline"))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
62 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
63 if s.NoInherit {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
64 out = append(out, "noinherit")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
65 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
66 if s.Colour.IsSet() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
67 out = append(out, s.Colour.String())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
68 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
69 if s.Background.IsSet() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
70 out = append(out, "bg:"+s.Background.String())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
71 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
72 if s.Border.IsSet() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
73 out = append(out, "border:"+s.Border.String())
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
74 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
75 return strings.Join(out, " ")
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
76 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
77
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
78 // Sub subtracts e from s where elements match.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
79 func (s StyleEntry) Sub(e StyleEntry) StyleEntry {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
80 out := StyleEntry{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
81 if e.Colour != s.Colour {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
82 out.Colour = s.Colour
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
83 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
84 if e.Background != s.Background {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
85 out.Background = s.Background
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
86 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
87 if e.Bold != s.Bold {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
88 out.Bold = s.Bold
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
89 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
90 if e.Italic != s.Italic {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
91 out.Italic = s.Italic
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
92 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
93 if e.Underline != s.Underline {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
94 out.Underline = s.Underline
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
95 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
96 if e.Border != s.Border {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
97 out.Border = s.Border
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
98 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
99 return out
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
100 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
101
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
102 // Inherit styles from ancestors.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
103 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
104 // Ancestors should be provided from oldest to newest.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
105 func (s StyleEntry) Inherit(ancestors ...StyleEntry) StyleEntry {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
106 out := s
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
107 for i := len(ancestors) - 1; i >= 0; i-- {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
108 if out.NoInherit {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
109 return out
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
110 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
111 ancestor := ancestors[i]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
112 if !out.Colour.IsSet() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
113 out.Colour = ancestor.Colour
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
114 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
115 if !out.Background.IsSet() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
116 out.Background = ancestor.Background
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
117 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
118 if !out.Border.IsSet() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
119 out.Border = ancestor.Border
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
120 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
121 if out.Bold == Pass {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
122 out.Bold = ancestor.Bold
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
123 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
124 if out.Italic == Pass {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
125 out.Italic = ancestor.Italic
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
126 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
127 if out.Underline == Pass {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
128 out.Underline = ancestor.Underline
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
129 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
130 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
131 return out
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
132 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
133
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
134 func (s StyleEntry) IsZero() bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
135 return s.Colour == 0 && s.Background == 0 && s.Border == 0 && s.Bold == Pass && s.Italic == Pass &&
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
136 s.Underline == Pass && !s.NoInherit
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
137 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
138
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
139 // A StyleBuilder is a mutable structure for building styles.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
140 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
141 // Once built, a Style is immutable.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
142 type StyleBuilder struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
143 entries map[TokenType]string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
144 name string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
145 parent *Style
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
146 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
147
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
148 func NewStyleBuilder(name string) *StyleBuilder {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
149 return &StyleBuilder{name: name, entries: map[TokenType]string{}}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
150 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
151
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
152 func (s *StyleBuilder) AddAll(entries StyleEntries) *StyleBuilder {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
153 for ttype, entry := range entries {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
154 s.entries[ttype] = entry
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
155 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
156 return s
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
157 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
158
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
159 func (s *StyleBuilder) Get(ttype TokenType) StyleEntry {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
160 // This is less than ideal, but it's the price for not having to check errors on each Add().
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
161 entry, _ := ParseStyleEntry(s.entries[ttype])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
162 if s.parent != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
163 entry = entry.Inherit(s.parent.Get(ttype))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
164 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
165 return entry
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
166 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
167
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
168 // Add an entry to the Style map.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
169 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
170 // See http://pygments.org/docs/styles/#style-rules for details.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
171 func (s *StyleBuilder) Add(ttype TokenType, entry string) *StyleBuilder { // nolint: gocyclo
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
172 s.entries[ttype] = entry
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
173 return s
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
174 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
175
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
176 func (s *StyleBuilder) AddEntry(ttype TokenType, entry StyleEntry) *StyleBuilder {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
177 s.entries[ttype] = entry.String()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
178 return s
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
179 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
180
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
181 // Transform passes each style entry currently defined in the builder to the supplied
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
182 // function and saves the returned value. This can be used to adjust a style's colours;
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
183 // see Colour's ClampBrightness function, for example.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
184 func (s *StyleBuilder) Transform(transform func(StyleEntry) StyleEntry) *StyleBuilder {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
185 types := make(map[TokenType]struct{})
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
186 for tt := range s.entries {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
187 types[tt] = struct{}{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
188 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
189 if s.parent != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
190 for _, tt := range s.parent.Types() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
191 types[tt] = struct{}{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
192 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
193 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
194 for tt := range types {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
195 s.AddEntry(tt, transform(s.Get(tt)))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
196 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
197 return s
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
198 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
199
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
200 func (s *StyleBuilder) Build() (*Style, error) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
201 style := &Style{
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
202 Name: s.name,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
203 entries: map[TokenType]StyleEntry{},
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
204 parent: s.parent,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
205 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
206 for ttype, descriptor := range s.entries {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
207 entry, err := ParseStyleEntry(descriptor)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
208 if err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
209 return nil, fmt.Errorf("invalid entry for %s: %s", ttype, err)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
210 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
211 style.entries[ttype] = entry
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
212 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
213 return style, nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
214 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
215
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
216 // StyleEntries mapping TokenType to colour definition.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
217 type StyleEntries map[TokenType]string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
218
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
219 // NewStyle creates a new style definition.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
220 func NewStyle(name string, entries StyleEntries) (*Style, error) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
221 return NewStyleBuilder(name).AddAll(entries).Build()
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
222 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
223
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
224 // MustNewStyle creates a new style or panics.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
225 func MustNewStyle(name string, entries StyleEntries) *Style {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
226 style, err := NewStyle(name, entries)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
227 if err != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
228 panic(err)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
229 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
230 return style
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
231 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
232
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
233 // A Style definition.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
234 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
235 // See http://pygments.org/docs/styles/ for details. Semantics are intended to be identical.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
236 type Style struct {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
237 Name string
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
238 entries map[TokenType]StyleEntry
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
239 parent *Style
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
240 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
241
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
242 // Types that are styled.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
243 func (s *Style) Types() []TokenType {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
244 dedupe := map[TokenType]bool{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
245 for tt := range s.entries {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
246 dedupe[tt] = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
247 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
248 if s.parent != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
249 for _, tt := range s.parent.Types() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
250 dedupe[tt] = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
251 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
252 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
253 out := make([]TokenType, 0, len(dedupe))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
254 for tt := range dedupe {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
255 out = append(out, tt)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
256 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
257 return out
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
258 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
259
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
260 // Builder creates a mutable builder from this Style.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
261 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
262 // The builder can then be safely modified. This is a cheap operation.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
263 func (s *Style) Builder() *StyleBuilder {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
264 return &StyleBuilder{
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
265 name: s.Name,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
266 entries: map[TokenType]string{},
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
267 parent: s,
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
268 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
269 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
270
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
271 // Has checks if an exact style entry match exists for a token type.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
272 //
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
273 // This is distinct from Get() which will merge parent tokens.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
274 func (s *Style) Has(ttype TokenType) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
275 return !s.get(ttype).IsZero() || s.synthesisable(ttype)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
276 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
277
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
278 // Get a style entry. Will try sub-category or category if an exact match is not found, and
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
279 // finally return the Background.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
280 func (s *Style) Get(ttype TokenType) StyleEntry {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
281 return s.get(ttype).Inherit(
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
282 s.get(Background),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
283 s.get(Text),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
284 s.get(ttype.Category()),
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
285 s.get(ttype.SubCategory()))
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
286 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
287
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
288 func (s *Style) get(ttype TokenType) StyleEntry {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
289 out := s.entries[ttype]
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
290 if out.IsZero() && s.parent != nil {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
291 return s.parent.get(ttype)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
292 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
293 if out.IsZero() && s.synthesisable(ttype) {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
294 out = s.synthesise(ttype)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
295 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
296 return out
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
297 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
298
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
299 func (s *Style) synthesise(ttype TokenType) StyleEntry {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
300 bg := s.get(Background)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
301 text := StyleEntry{Colour: bg.Colour}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
302 text.Colour = text.Colour.BrightenOrDarken(0.5)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
303
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
304 switch ttype {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
305 // If we don't have a line highlight colour, make one that is 10% brighter/darker than the background.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
306 case LineHighlight:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
307 return StyleEntry{Background: bg.Background.BrightenOrDarken(0.1)}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
308
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
309 // If we don't have line numbers, use the text colour but 20% brighter/darker
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
310 case LineNumbers, LineNumbersTable:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
311 return text
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
312
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
313 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
314 return StyleEntry{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
315 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
316 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
317
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
318 func (s *Style) synthesisable(ttype TokenType) bool {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
319 return ttype == LineHighlight || ttype == LineNumbers || ttype == LineNumbersTable
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
320 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
321
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
322 // ParseStyleEntry parses a Pygments style entry.
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
323 func ParseStyleEntry(entry string) (StyleEntry, error) { // nolint: gocyclo
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
324 out := StyleEntry{}
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
325 parts := strings.Fields(entry)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
326 for _, part := range parts {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
327 switch {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
328 case part == "italic":
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
329 out.Italic = Yes
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
330 case part == "noitalic":
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
331 out.Italic = No
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
332 case part == "bold":
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
333 out.Bold = Yes
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
334 case part == "nobold":
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
335 out.Bold = No
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
336 case part == "underline":
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
337 out.Underline = Yes
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
338 case part == "nounderline":
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
339 out.Underline = No
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
340 case part == "inherit":
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
341 out.NoInherit = false
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
342 case part == "noinherit":
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
343 out.NoInherit = true
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
344 case part == "bg:":
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
345 out.Background = 0
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
346 case strings.HasPrefix(part, "bg:#"):
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
347 out.Background = ParseColour(part[3:])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
348 if !out.Background.IsSet() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
349 return StyleEntry{}, fmt.Errorf("invalid background colour %q", part)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
350 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
351 case strings.HasPrefix(part, "border:#"):
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
352 out.Border = ParseColour(part[7:])
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
353 if !out.Border.IsSet() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
354 return StyleEntry{}, fmt.Errorf("invalid border colour %q", part)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
355 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
356 case strings.HasPrefix(part, "#"):
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
357 out.Colour = ParseColour(part)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
358 if !out.Colour.IsSet() {
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
359 return StyleEntry{}, fmt.Errorf("invalid colour %q", part)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
360 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
361 default:
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
362 return StyleEntry{}, fmt.Errorf("unknown style element %q", part)
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
363 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
364 }
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
365 return out, nil
787b5ee0289d Use vendored modules
yakumo.izuru
parents:
diff changeset
366 }