This repository has been archived by the owner on Feb 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
libshgif.sh
executable file
·179 lines (162 loc) · 5.6 KB
/
libshgif.sh
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
#!/usr/bin/env bash
#
# copyright (c) 2018 Cj-bc
# This software is released under MIT License
#
# DEBUG options
debug_stdout="stdout.log"
debug_drawLog="draw_log.log"
# @param <string file_path> <string Aarray var name> <string Aarray var name>
Shgif::SetColorFile() {
local file=$1
local -n fore_ref=$2
local -n back_ref=$3
local lfore="$(head -n1 $file )"
local lback="$(head -n2 $file | tail -n1)"
local line
while read -rd ',' line;do
[ "${DEBUG:-0}" -eq 2 ] && echo ecexuted >&3 # DEBUG
[ "${DEBUG:-0}" -eq 2 ] && echo "line: $line" >&3 # DEBUG
# avoid non-exist tput subcommand
if [[ ! "${line#*=}" = [0-9]* ]]; then
case "${line#*=}" in
"blink"|"bold" ) fore_ref[${line%=*}]="${line#*=}";;
* ) :;
esac
else
fore_ref[${line%=*}]="${line#*=}"
fi
done < <(echo "$lfore")
[ "${DEBUG:-0}" -eq 2 ] && echo "fore_ref[G]: ${fore_ref[G]}" >&3 # DEBUG
[ "${DEBUG:-0}" -eq 2 ] && echo "fore_ref[B]: ${fore_ref[B]}" >&3 # DEBUG
while read -rd ',' line;do
if [[ ! "${line#*=}" = [0-9]* ]]; then
case "${line#*=}" in
"blink"|"bold" ) back_ref[${line%=*}]="${line#*=}";;
* ) :;
esac
else
back_ref[${line%=*}]="${line#*=}"
fi
done < <(echo "$lback")
[ "${DEBUG:-0}" -eq 2 ] && echo "back_ref[W]: ${back_ref[W]}" >&3 # DEBUG
}
# combine picture txt and color layer
Shgif::GenerateColoerdPicture() {
local lfile=$1
local color_file="${lfile%/*}/color/${lfile##*/}"
local -n output="$2" # this will be returned
local -i i=1
local -a parsedColorFile=()
local -a parsedFile=()
local -A col_fore=() # contains key:value pair for foreground_color
local -A col_back=() # contains key:value pair for background_color
local -A prev_param=([fore]="" [back]="") # contains previous char's color infomation
# parse files into Array
File::ParseToArray "$lfile" "parsedFile"
File::ParseToArray "$color_file" "parsedColorFile"
Shgif::SetColorFile "$color_file" col_fore col_back
[ "${DEBUG:-0}" -eq 1 ] && echo "col_fore1 is: $(declare -p col_fore)" >> $debug_drawLog
[ "${DEBUG:-0}" -eq 1 ] && echo "col_back1 is: $(declare -p col_back)" >> $debug_drawLog
set -f
parsedColorFile=("${parsedColorFile[@]:2}")
set +f
# treat line by line
for ((lineno=0;lineno<=${#parsedFile[@]};lineno++)); do
local output_line=""
local line="${parsedFile[$lineno]}"
local color_line="${parsedColorFile[$lineno]}"
# treat each char by char
for ((charno=0;charno<=${#line};charno++)); do
local ch=${line:$charno:1}
local ch_col=${color_line:$charno:1}
local expr
local col_num
# if no color char is set, just add original char
# or not, insert color change befor char
# with full ornaments:
# output+="$(tput setaf <int number>)$(tput setab <int number>)<string char>"
# or with no color:
# output+="$(tput sgr0)<string char>"
if [[ "$ch" = "$ch_col" ]];then
# if previous char have any color infomation, reset it.
if [[ "${prev_param[fore]}" != "" || "${prev_param[back]}" != "" ]]; then
output_line+='$(tput sgr0)' # reset if other color is set
prev_param=([fore]="" [back]="")
fi
ch=${ch/\\/\\\\}
ch=${ch/\$/\\\$}
output_line+="$ch"
else
# 1. check foreground color
# 2. check background color
for key in "${!col_fore[@]}"; do
if [ "$ch_col" = "$key" ]; then
if [[ "$ch_col" != "${prev_param[fore]}" ]]; then
[ "${DEBUG:-0}" -eq 1 ] && echo "In setaf: ${ch_col}" >> $debug_drawLog
expr='$(tput setaf'
col_num="${col_fore[$ch_col]}"
if [[ "$col_num" = [0-9]* ]]; then
output_line+="${expr} ${col_num})"
else
output_line+="$(tput ${col_num})"
fi
prev_param[fore]="$ch_col"
fi
fi
done
for key in "${!col_back[@]}"; do
if [ "$ch_col" = "$key" ]; then
if [[ "$ch_col" != "${prev_param[back]}" ]]; then
[ "${DEBUG:-0}" -eq 2 ] && echo "In setbf: ${ch_col}" >> $debug_drawLog
expr='$(tput setab'
col_num="${col_back[$ch_col]}"
if [[ "$col_num" = [0-9]* ]]; then
output_line+="${expr} ${col_num})"
else
output_line+="$(tput ${col_num})"
fi
prev_param[back]="$ch_col"
fi
fi
done
ch=${ch/\\/\\\\} # escape letters
ch=${ch/\$/\\\$} # escape letters
output_line+="$ch"
fi
done
output=("${output[@]}" "$output_line")
done
# DEBUG
set -f
[ "${DEBUG:-0}" -eq 1 ] && {
echo "parsedColorFile is: $(declare -p parsedColorFile)"
echo "parsedFile is: $(declare -p parsedFile)"
echo "col_fore is: $(declare -p col_fore)"
echo "col_back is: $(declare -p col_back)"
echo "------------------------"
echo "output: $(declare -p file)"
} >> $debug_drawLog
set +f
}
# draw picture at <x> <y>
# color file will be set automatically
# @param <int x> <int y> <string file>
Shgif::DrawAt() {
local pos_x=$1
local pos_y=$2
local -a file=()
# generate color mapped file
Shgif::GenerateColoerdPicture "$3" 'file'
tput civis # hide cursor
tput cup "$pos_y" "$pos_x"
[ "${DEBUG:-0}" -eq 1 ] && eval 'echo "File[0]: ' ${file[0]} '"' >> $debug_stdout
local -i i=0
for line in "${file[@]}"; do
[ "${DEBUG:-0}" -eq 1 ] && eval 'echo "' "$line" '"' >> $debug_stdout
eval 'echo -E "' "$line" '"'
i+=1
tput cup $(( pos_y + i)) "$pos_x"
done
tput cnorm # appear cursor
}