1
0
mirror of https://github.com/alecthomas/chroma.git synced 2025-07-15 01:14:21 +02:00

Support for highlighting ranges of lines.

This commit is contained in:
Alec Thomas
2017-09-20 14:15:06 +10:00
parent 3f230ec717
commit a5637e60b2
5 changed files with 165 additions and 118 deletions

View File

@ -32,12 +32,11 @@ func WithLineNumbers() Option {
}
}
// HighlightLines higlights the given line ranges.
// HighlightLines higlights the given line ranges with the Highlight style.
//
// A range is the beginning and ending of a range as 1-based line numbers, inclusive.
func HighlightLines(style string, ranges [][2]int) Option {
func HighlightLines(ranges [][2]int) Option {
return func(f *Formatter) {
f.highlightStyle = style
f.highlightRanges = ranges
sort.Sort(f.highlightRanges)
}
@ -59,7 +58,6 @@ type Formatter struct {
classes bool
tabWidth int
lineNumbers bool
highlightStyle string
highlightRanges highlightRanges
}
@ -104,7 +102,21 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []*chroma
fmt.Fprintf(w, "<pre%s>\n", f.styleAttr(css, chroma.Background))
lines := splitTokensIntoLines(tokens)
lineDigits := len(fmt.Sprintf("%d", len(lines)))
highlightIndex := 0
for line, tokens := range lines {
highlight := false
for highlightIndex < len(f.highlightRanges) && line+1 > f.highlightRanges[highlightIndex][1] {
highlightIndex++
}
if highlightIndex < len(f.highlightRanges) {
hrange := f.highlightRanges[highlightIndex]
if line+1 >= hrange[0] && line+1 <= hrange[1] {
highlight = true
}
}
if highlight {
fmt.Fprintf(w, "<span class=\"hl\">")
}
if f.lineNumbers {
fmt.Fprintf(w, "<span class=\"ln\">%*d</span>", lineDigits, line+1)
}
@ -117,6 +129,9 @@ func (f *Formatter) writeHTML(w io.Writer, style *chroma.Style, tokens []*chroma
}
fmt.Fprint(w, html)
}
if highlight {
fmt.Fprintf(w, "</span>")
}
}
fmt.Fprint(w, "</pre>\n")
@ -134,7 +149,7 @@ func (f *Formatter) class(tt chroma.TokenType) string {
return "chroma"
case chroma.LineNumbers:
return "ln"
case chroma.Highlight:
case chroma.LineHighlight:
return "hl"
}
if tt < 0 {
@ -173,11 +188,6 @@ func (f *Formatter) WriteCSS(w io.Writer, style *chroma.Style) error {
if _, err := fmt.Fprintf(w, "/* %s */ .chroma { %s }\n", chroma.Background, css[chroma.Background]); err != nil {
return err
}
// No line-numbers, add a default.
if _, ok := css[chroma.LineNumbers]; !ok {
css[chroma.LineNumbers] = "color: #888"
}
css[chroma.LineNumbers] += "; margin-right: 0.5em"
tts := []int{}
for tt := range css {
tts = append(tts, int(tt))
@ -199,11 +209,6 @@ func (f *Formatter) WriteCSS(w io.Writer, style *chroma.Style) error {
func (f *Formatter) styleToCSS(style *chroma.Style) map[chroma.TokenType]string {
bg := style.Get(chroma.Background)
classes := map[chroma.TokenType]string{}
// Insert highlight colour if needed.
if len(f.highlightRanges) > 0 {
highlight := chroma.ParseStyleEntry(bg, f.highlightStyle).Sub(bg)
classes[chroma.Highlight] = StyleEntryToCSS(highlight)
}
// Convert the style.
for t := range style.Entries {
e := style.Entries[t]
@ -213,6 +218,8 @@ func (f *Formatter) styleToCSS(style *chroma.Style) map[chroma.TokenType]string
classes[t] = StyleEntryToCSS(e)
}
classes[chroma.Background] += f.tabWidthStyle()
classes[chroma.LineNumbers] += "; margin-right: 0.5em"
classes[chroma.LineHighlight] += "; display: block; width: 100%"
return classes
}