mirror of
https://github.com/alecthomas/chroma.git
synced 2025-03-19 21:10:15 +02:00
Synthesise meta style-entries on demand.
This includes line highlighting, numbers, etc. Fixes #211.
This commit is contained in:
parent
69c9a262c3
commit
2a59c2c77e
@ -99,34 +99,10 @@ func (f *Formatter) Format(w io.Writer, style *chroma.Style, iterator chroma.Ite
|
|||||||
return f.writeHTML(w, style, iterator.Tokens())
|
return f.writeHTML(w, style, iterator.Tokens())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that style entries exist for highlighting, etc.
|
|
||||||
func (f *Formatter) restyle(style *chroma.Style) (*chroma.Style, error) {
|
|
||||||
builder := style.Builder()
|
|
||||||
bg := builder.Get(chroma.Background)
|
|
||||||
// If we don't have a line highlight colour, make one that is 10% brighter/darker than the background.
|
|
||||||
if !style.Has(chroma.LineHighlight) {
|
|
||||||
highlight := chroma.StyleEntry{Background: bg.Background}
|
|
||||||
highlight.Background = highlight.Background.BrightenOrDarken(0.1)
|
|
||||||
builder.AddEntry(chroma.LineHighlight, highlight)
|
|
||||||
}
|
|
||||||
// If we don't have line numbers, use the text colour but 20% brighter/darker
|
|
||||||
if !style.Has(chroma.LineNumbers) {
|
|
||||||
text := chroma.StyleEntry{Colour: bg.Colour}
|
|
||||||
text.Colour = text.Colour.BrightenOrDarken(0.5)
|
|
||||||
builder.AddEntry(chroma.LineNumbers, text)
|
|
||||||
builder.AddEntry(chroma.LineNumbersTable, text)
|
|
||||||
}
|
|
||||||
return builder.Build()
|
|
||||||
}
|
|
||||||
|
|
||||||
// We deliberately don't use html/template here because it is two orders of magnitude slower (benchmarked).
|
// We deliberately don't use html/template here because it is two orders of magnitude slower (benchmarked).
|
||||||
//
|
//
|
||||||
// OTOH we need to be super careful about correct escaping...
|
// OTOH we need to be super careful about correct escaping...
|
||||||
func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.Token) (err error) { // nolint: gocyclo
|
func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []chroma.Token) (err error) { // nolint: gocyclo
|
||||||
style, err = f.restyle(style)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
css := f.styleToCSS(style)
|
css := f.styleToCSS(style)
|
||||||
if !f.Classes {
|
if !f.Classes {
|
||||||
for t, style := range css {
|
for t, style := range css {
|
||||||
|
42
style.go
42
style.go
@ -247,15 +247,7 @@ func (s *Style) Builder() *StyleBuilder {
|
|||||||
//
|
//
|
||||||
// This is distinct from Get() which will merge parent tokens.
|
// This is distinct from Get() which will merge parent tokens.
|
||||||
func (s *Style) Has(ttype TokenType) bool {
|
func (s *Style) Has(ttype TokenType) bool {
|
||||||
return !s.get(ttype).IsZero()
|
return !s.get(ttype).IsZero() || s.synthesisable(ttype)
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Style) get(ttype TokenType) StyleEntry {
|
|
||||||
out := s.entries[ttype]
|
|
||||||
if out.IsZero() && s.parent != nil {
|
|
||||||
return s.parent.get(ttype)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a style entry. Will try sub-category or category if an exact match is not found, and
|
// Get a style entry. Will try sub-category or category if an exact match is not found, and
|
||||||
@ -268,6 +260,38 @@ func (s *Style) Get(ttype TokenType) StyleEntry {
|
|||||||
s.get(ttype.SubCategory()))
|
s.get(ttype.SubCategory()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Style) get(ttype TokenType) StyleEntry {
|
||||||
|
out := s.entries[ttype]
|
||||||
|
if out.IsZero() && s.synthesisable(ttype) {
|
||||||
|
out = s.synthesise(ttype)
|
||||||
|
}
|
||||||
|
if out.IsZero() && s.parent != nil {
|
||||||
|
return s.parent.get(ttype)
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Style) synthesise(ttype TokenType) StyleEntry {
|
||||||
|
bg := s.get(Background)
|
||||||
|
text := StyleEntry{Colour: bg.Colour}
|
||||||
|
text.Colour = text.Colour.BrightenOrDarken(0.5)
|
||||||
|
|
||||||
|
switch ttype {
|
||||||
|
// If we don't have a line highlight colour, make one that is 10% brighter/darker than the background.
|
||||||
|
case LineHighlight:
|
||||||
|
return StyleEntry{Background: bg.Background.BrightenOrDarken(0.1)}
|
||||||
|
|
||||||
|
// If we don't have line numbers, use the text colour but 20% brighter/darker
|
||||||
|
case LineNumbers, LineNumbersTable:
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
return StyleEntry{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Style) synthesisable(ttype TokenType) bool {
|
||||||
|
return ttype == LineHighlight || ttype == LineNumbers || ttype == LineNumbersTable
|
||||||
|
}
|
||||||
|
|
||||||
// ParseStyleEntry parses a Pygments style entry.
|
// ParseStyleEntry parses a Pygments style entry.
|
||||||
func ParseStyleEntry(entry string) (StyleEntry, error) { // nolint: gocyclo
|
func ParseStyleEntry(entry string) (StyleEntry, error) { // nolint: gocyclo
|
||||||
out := StyleEntry{}
|
out := StyleEntry{}
|
||||||
|
@ -35,3 +35,16 @@ func TestStyleClone(t *testing.T) {
|
|||||||
assert.Equal(t, "#00ff00 bg:#ffffff", clone.Get(Comment).String())
|
assert.Equal(t, "#00ff00 bg:#ffffff", clone.Get(Comment).String())
|
||||||
assert.Equal(t, "bg:#ffffff", parent.Get(Comment).String())
|
assert.Equal(t, "bg:#ffffff", parent.Get(Comment).String())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSynthesisedStyleEntries(t *testing.T) {
|
||||||
|
style, err := NewStyle("test", StyleEntries{
|
||||||
|
Background: "bg:#ffffff",
|
||||||
|
})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
assert.True(t, style.Has(LineHighlight))
|
||||||
|
assert.True(t, style.Has(LineNumbersTable))
|
||||||
|
assert.True(t, style.Has(LineNumbers))
|
||||||
|
assert.Equal(t, "bg:#e5e5e5", style.Get(LineHighlight).String())
|
||||||
|
assert.Equal(t, "#7f7f7f bg:#ffffff", style.Get(LineNumbers).String())
|
||||||
|
assert.Equal(t, "#7f7f7f bg:#ffffff", style.Get(LineNumbersTable).String())
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user