-
Notifications
You must be signed in to change notification settings - Fork 0
/
styling.go
80 lines (67 loc) · 1.58 KB
/
styling.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
package highlight
import (
"bytes"
"sort"
"github.com/u-root/u-root/cmds/core/elvish/edit/ui"
)
// Preparing and applying styling.
type Styling struct {
begins []stylingEvent
ends []stylingEvent
}
func (s *Styling) Add(begin, end int, style string) {
if style == "" {
return
}
s.begins = append(s.begins, stylingEvent{begin, style})
s.ends = append(s.ends, stylingEvent{end, style})
}
func (s *Styling) Apply() *StylingApplier {
sort.Sort(stylingEvents(s.begins))
sort.Sort(stylingEvents(s.ends))
return &StylingApplier{s, make(map[string]int), 0, 0, ""}
}
type StylingApplier struct {
*Styling
occurrence map[string]int
ibegin int
iend int
result string
}
func (a *StylingApplier) At(i int) {
changed := false
for a.iend < len(a.ends) && a.ends[a.iend].pos == i {
a.occurrence[a.ends[a.iend].style]--
a.iend++
changed = true
}
for a.ibegin < len(a.begins) && a.begins[a.ibegin].pos == i {
a.occurrence[a.begins[a.ibegin].style]++
a.ibegin++
changed = true
}
if changed {
b := new(bytes.Buffer)
for style, occ := range a.occurrence {
if occ == 0 {
continue
}
if b.Len() > 0 {
b.WriteString(";")
}
b.WriteString(ui.TranslateStyle(style))
}
a.result = b.String()
}
}
func (a *StylingApplier) Get() string {
return a.result
}
type stylingEvent struct {
pos int
style string
}
type stylingEvents []stylingEvent
func (s stylingEvents) Len() int { return len(s) }
func (s stylingEvents) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
func (s stylingEvents) Less(i, j int) bool { return s[i].pos < s[j].pos }