mirror of
				https://github.com/alecthomas/chroma.git
				synced 2025-10-30 23:57:49 +02:00 
			
		
		
		
	Synthesise meta style-entries on demand.
This includes line highlighting, numbers, etc. Fixes #211.
This commit is contained in:
		| @@ -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()) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user