-
Notifications
You must be signed in to change notification settings - Fork 0
/
string_to_cells.go
100 lines (80 loc) · 1.9 KB
/
string_to_cells.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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package string_to_cells
import (
"github.com/nsf/termbox-go"
"github.com/terryhay/dolly/man_style_help/runes"
"github.com/terryhay/dolly/tools/index"
)
type foreground struct {
stackFG []termbox.Attribute
fg termbox.Attribute
}
func makeForeground(stackSize index.Index) foreground {
return foreground{
stackFG: make([]termbox.Attribute, 0, stackSize),
}
}
func (fg *foreground) Get() termbox.Attribute {
if fg == nil {
return termbox.Attribute(0)
}
return fg.fg
}
func (fg *foreground) Set(attr termbox.Attribute) {
if fg == nil {
return
}
fg.stackFG = append(fg.stackFG, attr)
fg.fg |= attr
}
func (fg *foreground) DropBack() {
if fg == nil || len(fg.stackFG) == 0 {
return
}
lastFG := fg.stackFG[len(fg.stackFG)-1]
fg.fg &= ^lastFG
fg.stackFG = fg.stackFG[:len(fg.stackFG)-1]
}
// StringToCells converts styled string to termbox cells
func StringToCells(fromString string) []termbox.Cell {
if len(fromString) == 0 {
return nil
}
const countStyleMax = 2
fg := makeForeground(countStyleMax)
from := []rune(fromString)
to := make([]termbox.Cell, 0, len(from))
for i := 0; i < len(from); i++ {
r := from[i]
if r == runes.RuneEsc {
fg, i = getStyle(fg, i, from)
continue
}
to = append(to, termbox.Cell{
Ch: r,
Fg: fg.Get(),
})
}
return to
}
func getStyle(fg foreground, indexBeginStyleSeq int, fromRunes []rune) (foreground, int) {
indexEndStyleSeq := indexBeginStyleSeq + 1
for ; indexEndStyleSeq < len(fromRunes); indexEndStyleSeq++ {
if fromRunes[indexEndStyleSeq] == runes.RuneLwM {
break
}
}
mark := string(fromRunes[indexBeginStyleSeq+1 : indexEndStyleSeq+1])
switch {
case mark == "[1m":
fg.Set(termbox.AttrBold)
return fg, indexEndStyleSeq
case mark == "[0m":
fg.DropBack()
return fg, indexEndStyleSeq
case mark == "[4m":
fg.Set(termbox.AttrUnderline)
return fg, indexEndStyleSeq
default:
return fg, indexBeginStyleSeq
}
}