forked from railwayapp/cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtext.go
216 lines (173 loc) · 4.61 KB
/
text.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
package ui
import (
"fmt"
"math"
"sort"
"strings"
_aurora "github.com/logrusorgru/aurora"
)
var aurora = _aurora.NewAurora(true)
func DisableTextStyles() {
aurora = _aurora.NewAurora(false)
}
func Bold(payload string) _aurora.Value {
return aurora.Bold(payload)
}
func RedText(payload string) _aurora.Value {
return aurora.Red(payload)
}
func MagentaText(payload string) _aurora.Value {
return aurora.Magenta(payload)
}
func BlueText(payload string) _aurora.Value {
return aurora.Blue(payload)
}
func GrayText(payload string) _aurora.Value {
return aurora.Gray(10, payload)
}
func LightGrayText(payload string) _aurora.Value {
return aurora.Gray(14, payload)
}
func GreenText(payload string) _aurora.Value {
return aurora.Green(payload)
}
func YellowText(payload string) _aurora.Value {
return aurora.Yellow(payload)
}
func Heading(text string) string {
return _aurora.Sprintf(_aurora.Bold("==> %s\n").Magenta(), Bold(text))
}
func AlertDanger(text string) string {
return _aurora.Sprintf(_aurora.Bold("🚨 %s\n").Red(), text)
}
func AlertWarning(text string) string {
return _aurora.Sprintf(_aurora.Bold("⚠️ %s\n").Yellow(), text)
}
func AlertInfo(text string) string {
return _aurora.Sprintf(GrayText(Bold("💁 %s\n").String()), text)
}
func VerboseInfo(isVerbose bool, text string) string {
if isVerbose {
return _aurora.Sprintf(MagentaText("💁 %s\n"), text)
} else {
return ""
}
}
func Truncate(text string, maxLength int) string {
ellipsis := "..."
overflow := len(text) + len(ellipsis) - maxLength
if overflow < 0 {
return text
}
visibleSize := float64(len(text)-overflow) / 2
if visibleSize < 1 {
visibleSize = 1
}
// Account for visibleSize not being whole number
prefixLen := int(math.Ceil(visibleSize))
suffixLen := int(math.Floor(visibleSize))
prefix := text[:prefixLen]
suffix := text[len(text)-suffixLen:]
return prefix + ellipsis + suffix
}
func ObscureText(text string) string {
return strings.Repeat("*", len(text))
}
func UnorderedList(items []string) string {
text := ""
for _, item := range items {
text += fmt.Sprintf("%s %s\n", Bold(LightGrayText("-").String()), item)
}
return text
}
func OrderedList(items []string) string {
text := ""
for i, item := range items {
index := Bold(LightGrayText(fmt.Sprintf("%d)", i+1)).String())
text += fmt.Sprintf("%s %s\n", index, item)
}
return text
}
// Indent adds two space characters to the start of every line in the text
func Indent(text string) string {
return PrefixLines(text, " ")
}
// Paragraph automatically wraps text (by word) to 60 chars
func Paragraph(text string) string {
const maxLineLength = 60
lines := make([]string, 0)
currentLine := ""
for _, word := range strings.Split(text, " ") {
currentLineWithNextWord := currentLine
if currentLineWithNextWord == "" {
currentLineWithNextWord += word
} else {
currentLineWithNextWord += " " + word
}
if len(currentLineWithNextWord) > maxLineLength {
lines = append(lines, currentLine)
currentLine = word
} else {
currentLine = currentLineWithNextWord
}
}
// Add unfinished line if there was one
if currentLine != "" {
lines = append(lines, currentLine)
}
return strings.Join(lines, "\n") + "\n"
}
// BlockQuote adds two space characters to the start of every line in the text
func BlockQuote(text string) string {
wrapped := strings.TrimSpace(Paragraph(text))
return PrefixLines(wrapped, GrayText("> ").String())
}
// PrefixLines adds a string to the start of every line in the text
func PrefixLines(text, prefix string) string {
newText := ""
for _, line := range strings.Split(text, "\n") {
newText += fmt.Sprintf("%s%s\n", prefix, line)
}
return newText
}
func KeyValues(items map[string]string) string {
type pair struct {
Key string
Value string
}
// Need to move them into slice because maps have random order
pairs := make([]pair, 0)
var maxKeyLengthWithPadding = 50
var longestKey = 0
// Add pairs to slice and find longest key
for k, v := range items {
pairs = append(pairs, pair{Key: k, Value: v})
if len(k) > longestKey {
longestKey = len(k)
}
}
text := ""
// order the pairs by key
sort.Slice(pairs, func(i, j int) bool {
return strings.Compare(pairs[j].Key, pairs[i].Key) > 0
})
nameLength := min(longestKey, maxKeyLengthWithPadding)
for _, pair := range pairs {
prettyKey := fmt.Sprintf("%s:", GreenText(pair.Key))
padding := strings.Repeat(" ", max(0, nameLength-len(pair.Key)))
text += fmt.Sprintf("%s%s %s\n", prettyKey, padding, pair.Value)
}
return text
}
func max(x, y int) int {
if x > y {
return x
}
return y
}
func min(x, y int) int {
if x < y {
return x
}
return y
}