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())
|
||||
}
|
||||
|
||||
// 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).
|
||||
//
|
||||
// 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
|
||||
style, err = f.restyle(style)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
css := f.styleToCSS(style)
|
||||
if !f.Classes {
|
||||
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.
|
||||
func (s *Style) Has(ttype TokenType) bool {
|
||||
return !s.get(ttype).IsZero()
|
||||
}
|
||||
|
||||
func (s *Style) get(ttype TokenType) StyleEntry {
|
||||
out := s.entries[ttype]
|
||||
if out.IsZero() && s.parent != nil {
|
||||
return s.parent.get(ttype)
|
||||
}
|
||||
return out
|
||||
return !s.get(ttype).IsZero() || s.synthesisable(ttype)
|
||||
}
|
||||
|
||||
// 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()))
|
||||
}
|
||||
|
||||
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.
|
||||
func ParseStyleEntry(entry string) (StyleEntry, error) { // nolint: gocyclo
|
||||
out := StyleEntry{}
|
||||
|
@ -35,3 +35,16 @@ func TestStyleClone(t *testing.T) {
|
||||
assert.Equal(t, "#00ff00 bg:#ffffff", clone.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