-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtstyle
executable file
·291 lines (247 loc) · 7.18 KB
/
tstyle
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
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
#!/bin/bash -eu
reset=$'\E(B\E[m'
italic=$'\E[3m'
bold=$'\E[1m'
underline=$'\E[4m'
reverse=$'\E[7m'
dim=$'\E[2m'
input=
output=
trailing=
environment=
trailing_newline=true
function usage {
local program_name
local n
local i
local b
local u
local d
local c_0
local c_1
local c_2
local c_3
local c_4
local c_5
local c_6
local c_7
local c_8
local c_9
local c_10
local c_11
local c_12
local c_13
local c_14
local c_15
program_name="$(basename "$0")"
n="$reset"
i="$italic"
b="$bold"
u="$underline"
d="$dim"
c_0=$(tput setaf 0)
c_1=$(tput setaf 1)
c_2=$(tput setaf 2)
c_3=$(tput setaf 3)
c_4=$(tput setaf 4)
c_5=$(tput setaf 5)
c_6=$(tput setaf 6)
c_7=$(tput setaf 7)
c_8=$(tput setaf 8)
c_9=$(tput setaf 9)
c_10=$(tput setaf 10)
c_11=$(tput setaf 11)
c_12=$(tput setaf 12)
c_13=$(tput setaf 13)
c_14=$(tput setaf 14)
c_15=$(tput setaf 15)
echo "Usage:"
echo " $program_name [-b <${i}color${n}>] [-f <${i}color${n}>] [-n] [${i}argument${n}]"
echo
echo -n "Formats and prints ${i}argument${n} if present, ${i}stdin${n} otherwise. "
echo "Formatting rules:"
echo " 1. Text surrounded by single *asterisks* will be rendered in italic"
echo " 2. Double **asterisks** in bold"
echo " 3. Single _underscores_ in underline"
echo " 4. Double __underscores__ in reverse mode"
echo " 5. Single ^caret^ in half-bright mode"
echo
echo " ${b}${u}Options${n}"
echo
echo " -b, --background <${i}color${n}> set a background color for the entire output"
echo " -f, --foreground <${i}color${n}> set a foreground color"
echo " -n, --no-newline do not print trailing newline"
echo " -h, --help print this help"
echo " --colors print all color codes"
echo
echo " ${b}${u}Colors${n}"
echo
echo "The following colors can be used through their names or codes. "
echo -n "Additionally numbers from 16 to 255 are accepted. "
echo "Run ${d}$program_name --colors${n} to see all codes."
echo " 0: ${c_0}■${n} black 1: ${c_1}■${n} red 2: ${c_2}■${n} green"
echo " 3: ${c_3}■${n} yellow 4: ${c_4}■${n} blue 5: ${c_5}■${n} magenta"
echo " 6: ${c_6}■${n} cyan 7: ${c_7}■${n} white "
echo
echo " 8: ${c_8}■${n} Black 9: ${c_9}■${n} Red 10: ${c_10}■${n} Green"
echo " 11: ${c_11}■${n} Yellow 12: ${c_12}■${n} Blue 13: ${c_13}■${n} Magenta"
echo " 14: ${c_14}■${n} Cyan 15: ${c_15}■${n} White"
echo
}
function print-colors {
for code in {0..255}; do
[ "$(( code % 4 ))" -eq 0 ] && echo
if [ $code -lt 10 ]; then
printf " "
elif [ $code -lt 100 ]; then
printf " "
fi
printf " %s:" "$code" # print number
printf "%s" "$(tput setab $code) " # set the background and print
printf "%s" "$reset" # reset
done
echo
}
function parse-color-name {
case "$1" in
black) printf 0 ;;
red) printf 1 ;;
green) printf 2 ;;
yellow) printf 3 ;;
blue) printf 4 ;;
magenta) printf 5 ;;
cyan) printf 6 ;;
white) printf 7 ;;
Black) printf 8 ;;
Red) printf 9 ;;
Green) printf 10 ;;
Yellow) printf 11 ;;
Blue) printf 12 ;;
Magenta) printf 13 ;;
Cyan) printf 14 ;;
White) printf 15 ;;
*) return 1 ;;
esac
return 0
}
function valid-color-code {
printf -v code "%d" "$1" 2>/dev/null
[ "$1" = "$code" ] && [ "$code" -ge 0 ] && [ "$code" -le 255 ]
}
function parse-color {
local input="$1"
local parsed_input
if valid-color-code "$input"; then
printf "%s" "$input"
elif parsed_input=$(parse-color-name "$input"); then
printf "%s" "$parsed_input"
else
return 1
fi
return 0
}
function set-color {
local tput_param="$1"
local input_color="$2"
local color_code
if color_code=$(parse-color "$input_color"); then
environment="${environment}$(tput "$tput_param" "$color_code")"
return 0
elif [ -z "$input_color" ]; then
echo "${italic}color${reset} parameter is missing" 1>&2
else
echo "$(tput setaf 1)${input_color}${reset} is not a valid color" 1>&2
fi
return 1
}
function parse-input-argument {
if [ -z "$input" ]; then
input="$1"
return 0
else
usage 1>&2
# /usr/include/sysexits.h defines 64 as the
# preferable exit code for usage errors.
return 64
fi
}
while [ $# -gt 0 ]; do
case "$1" in
-b|--background)
set-color setab "${2:-}" || exit $?
shift
;;
-f|--foreground)
set-color setaf "${2:-}" || exit $?
shift
;;
-n|--no-newline)
trailing_newline=false
;;
-h|--help)
usage
exit 0
;;
--colors)
print-colors
exit 0
;;
*)
parse-input-argument "$1" || exit $?
;;
esac
shift ||:
done
[ -z "$input" ] && input=$(cat)
# shellcheck disable=SC2034
single_asterisk=false # italic $(tput sitm)
# shellcheck disable=SC2034
double_asterisk=false # bold $(tput bold)
# shellcheck disable=SC2034
single_underscore=false # underline $(tput smul)
# shellcheck disable=SC2034
double_underscore=false # reverse $(tput rev)
# shellcheck disable=SC2034
single_caret=false # half-bright $(tput dim)
function not {
$1 && printf false || printf true
}
function toggle-environment {
local environment_var="$1"
local special_char="$2"
if "${!environment_var}"; then
environment="${environment//$special_char}"
output="${output}${reset}${environment}"
else
environment="${environment}${special_char}"
output="${output}${special_char}"
fi
eval "$environment_var=$(not "${!environment_var}")"
}
output="${output}${environment}"
length=${#input}
for (( index=0; index < length; index++ )); do
next_index=$((index+1))
current="${input:$index:1}"
next="${input:$next_index:1}"
if [ "$current" = "\\" ] && [[ "$next" =~ [*_^] ]]; then
output="${output}${next}"
index=$next_index
elif [ "$current" = "*" ] && [ "$next" = "*" ]; then
toggle-environment double_asterisk "$bold"
index=$next_index
elif [ "$current" = "_" ] && [ "$next" = "_" ]; then
toggle-environment double_underscore "$reverse"
index=$next_index
elif [ "$current" = "*" ]; then
toggle-environment single_asterisk "$italic"
elif [ "$current" = "_" ]; then
toggle-environment single_underscore "$underline"
elif [ "$current" = "^" ]; then
toggle-environment single_caret "$dim"
else
output="${output}${current}"
fi
done
$trailing_newline && trailing="${trailing}\\n"
printf "%b%b%b" "$output" "$reset" "$trailing"