1package termenv
2
3import (
4 "fmt"
5 "strings"
6
7 "github.com/rivo/uniseg"
8)
9
10// Sequence definitions.
11const (
12 ResetSeq = "0"
13 BoldSeq = "1"
14 FaintSeq = "2"
15 ItalicSeq = "3"
16 UnderlineSeq = "4"
17 BlinkSeq = "5"
18 ReverseSeq = "7"
19 CrossOutSeq = "9"
20 OverlineSeq = "53"
21)
22
23// Style is a string that various rendering styles can be applied to.
24type Style struct {
25 profile Profile
26 string
27 styles []string
28}
29
30// String returns a new Style.
31func String(s ...string) Style {
32 return Style{
33 profile: ANSI,
34 string: strings.Join(s, " "),
35 }
36}
37
38func (t Style) String() string {
39 return t.Styled(t.string)
40}
41
42// Styled renders s with all applied styles.
43func (t Style) Styled(s string) string {
44 if t.profile == Ascii {
45 return s
46 }
47 if len(t.styles) == 0 {
48 return s
49 }
50
51 seq := strings.Join(t.styles, ";")
52 if seq == "" {
53 return s
54 }
55
56 return fmt.Sprintf("%s%sm%s%sm", CSI, seq, s, CSI+ResetSeq)
57}
58
59// Foreground sets a foreground color.
60func (t Style) Foreground(c Color) Style {
61 if c != nil {
62 t.styles = append(t.styles, c.Sequence(false))
63 }
64 return t
65}
66
67// Background sets a background color.
68func (t Style) Background(c Color) Style {
69 if c != nil {
70 t.styles = append(t.styles, c.Sequence(true))
71 }
72 return t
73}
74
75// Bold enables bold rendering.
76func (t Style) Bold() Style {
77 t.styles = append(t.styles, BoldSeq)
78 return t
79}
80
81// Faint enables faint rendering.
82func (t Style) Faint() Style {
83 t.styles = append(t.styles, FaintSeq)
84 return t
85}
86
87// Italic enables italic rendering.
88func (t Style) Italic() Style {
89 t.styles = append(t.styles, ItalicSeq)
90 return t
91}
92
93// Underline enables underline rendering.
94func (t Style) Underline() Style {
95 t.styles = append(t.styles, UnderlineSeq)
96 return t
97}
98
99// Overline enables overline rendering.
100func (t Style) Overline() Style {
101 t.styles = append(t.styles, OverlineSeq)
102 return t
103}
104
105// Blink enables blink mode.
106func (t Style) Blink() Style {
107 t.styles = append(t.styles, BlinkSeq)
108 return t
109}
110
111// Reverse enables reverse color mode.
112func (t Style) Reverse() Style {
113 t.styles = append(t.styles, ReverseSeq)
114 return t
115}
116
117// CrossOut enables crossed-out rendering.
118func (t Style) CrossOut() Style {
119 t.styles = append(t.styles, CrossOutSeq)
120 return t
121}
122
123// Width returns the width required to print all runes in Style.
124func (t Style) Width() int {
125 return uniseg.StringWidth(t.string)
126}