Fix repetition in manual page
[pipeglade.git] / calc.sh
blob7976d3abc88176cfde5f5ea5ed6ae8e579ac5860
1 #! /usr/bin/env bash
3 coproc dc 2>&1
4 ./pipeglade -i calc.in -o calc.out -b -u calc.ui -O calc.err -l calc.log >/dev/null
6 NUMKEYS=(0 1 2 3 4 5 6 7 8 9 A B C D E F)
7 NUMPAD=("${NUMKEYS[@]}" neg point div mul minus plus squareroot power)
8 STORAGEKEYS=(recall store)
9 OTHERKEYS=(enter edit swap clear drop cancel)
10 VARKEYS=(var_2 var_3 var_a var_b var_c var_d var_e var_f var_g var_h var_i \
11 var_j var_k var_l var_m var_n var_o var_p var_q var_r var_s \
12 var_t var_u var_v var_w var_x var_y var_z)
14 varkeys_set_visible()
15 # expose second keybord level
17 for i in "${VARKEYS[@]}"; do
18 echo "$i:set_visible $1" >calc.in
19 done
22 printstack()
24 echo "entry:set_placeholder_text" >calc.in
25 # tell dc to print its stack
26 echo "f"
27 i=0
28 unset DC_OUT
29 # read dc's response, which may include error messages
30 while read -t .1 DC_OUT[$i]; do (( i++ )); done
31 # check for specific errors
32 if [[ "${DC_OUT[0]}" =~ "stack" || "${DC_OUT[0]}" =~ "zero" ]]; then
33 echo "entry:set_placeholder_text ${DC_OUT[0]}"
34 echo "stack:grab_focus" # unfocussing entry
35 else
36 # display stack in a GtkTreeView
37 echo "stack:clear"
38 echo "stack:set 5 1"
39 ROW=4
40 while [[ $i -gt 0 ]]; do
41 (( i-- ))
42 (( ROW++ ))
43 echo "stack:set $ROW 0 $i"
44 echo "stack:set $ROW 1 ${DC_OUT[$i]}"
45 done
46 echo "stack:scroll $ROW 1"
47 fi >calc.in
50 edittop()
51 # put top of stack into GtkEntry
53 echo "p s!" # talking to dc,
54 read -t .1 DC_OUT # reading dc's response,
55 # and sending it to pipeglade
56 echo "entry:set_text $DC_OUT" >calc.in
60 # initial window dressing
61 echo "precision:set_value 5" >calc.in
62 for i in "${NUMPAD[@]}"; do
63 echo "$i:style border-radius:20px; border-color:darkblue; font-weight:bold; font-size:16px"
64 done >calc.in
65 for i in "${OTHERKEYS[@]}"; do
66 echo "$i:style border-radius:20px; font-weight:bold"
67 done >calc.in
68 for i in "${STORAGEKEYS[@]}"; do
69 echo "$i:style border-radius:20px; border-color:darkgreen; font-weight:bold"
70 done >calc.in
71 for i in "${VARKEYS[@]}"; do
72 echo "$i:style border-radius:10px; border-color:darkgreen; font-style:italic; font-size:16px"
73 done >calc.in
74 echo "off:style color:darkred; border-radius:20px; border-color:darkred; font-weight:bold" >calc.in
75 echo "entry:style font:monospace 12" >calc.in
76 echo "main:style border-radius:20px" >calc.in
80 # main loop; stdin and stdout are connected to the dc coprocess
81 printstack
82 while true; do
83 # receive feedback from GUI
84 read IN <calc.out
85 # if feedback came from a button, it ends ":clicked"
86 C="${IN%:clicked}" # remove ":clicked"
87 if [[ "${#C}" -eq 1 ]]; then
88 # our digit buttons all have one-character names
89 # string the digits together
90 NUM="$NUM$C"
91 # and put them into our GtkEntry
92 echo "entry:set_text $NUM" >calc.in
93 elif [[ "$IN" =~ "entry:text " ]]; then
94 # feedback from our GtkEntry
95 CURRENT_ENTRY="${IN#entry:text }"
96 NUM="$CURRENT_ENTRY"
97 # dc uses '_' as a negative sign
98 CURRENT_ENTRY="${CURRENT_ENTRY//-/_}"
99 elif [[ "$IN" =~ "var_" ]]; then
100 # freedback from variable buttons
101 VAR="${IN#var_}"
102 VAR="${VAR%:clicked}"
103 if [[ "$VARMODE" == "recall" ]]; then
104 echo "L$VAR"
105 elif [[ "$VARMODE" == "store" ]]; then
106 echo "S$VAR"
108 printstack
109 varkeys_set_visible 0
110 elif [[ "$IN" =~ "radix:value " ]]; then
111 # feedback from the radix scale
112 RADIX="${IN#radix:value }"
113 RADIX="${RADIX/.[0-9]*}"
114 # telling dc what to do
115 echo "A i $RADIX o $RADIX i"
116 printstack
117 # graying out meaningless digit keys
118 for i in "${NUMKEYS[@]:2:(( $RADIX - 1 ))}"; do
119 echo "$i:set_sensitive 1" >calc.in
120 done
121 for i in "${NUMKEYS[@]:$RADIX}"; do
122 echo "$i:set_sensitive 0" >calc.in
123 done
124 elif [[ $IN =~ "precision:value " ]]; then
125 # feedback from the precision scale
126 PRECISION="${IN#precision:value }"
127 PRECISION="${PRECISION/.[0-9]*}"
128 echo "$PRECISION k"
129 elif [[ $IN == "main:closed" ]]; then
130 # exit gracefully when GUI gets killed by window manager
131 exit
132 elif [[ -n $C ]]; then
133 # here, $C is a multi-character button name that doesn't look like "var_x"
134 case "$C" in
135 point)
136 NUM="$NUM."
137 echo "entry:set_text $NUM" >calc.in
139 neg)
140 if [[ -n "$CURRENT_ENTRY" ]]; then
141 echo "$CURRENT_ENTRY _1 *"
142 edittop
143 else
144 echo "_1 *"
145 unset NUM
146 unset CURRENT_ENTRY
147 printstack
150 edit)
151 edittop
152 printstack
154 enter)
155 if [[ -n "$CURRENT_ENTRY" ]]; then
156 echo "$CURRENT_ENTRY"
157 echo "entry:set_text" >calc.in
158 else
159 echo "d"
161 unset NUM
162 unset CURRENT_ENTRY
163 printstack
165 div)
166 if [[ -n "$CURRENT_ENTRY" ]]; then
167 echo "$CURRENT_ENTRY"
168 echo "entry:set_text" >calc.in
170 echo "/"
171 unset NUM
172 unset CURRENT_ENTRY
173 printstack
175 mul)
176 if [[ -n "$CURRENT_ENTRY" ]]; then
177 echo "$CURRENT_ENTRY"
178 echo "entry:set_text" >calc.in
180 echo "*"
181 unset NUM
182 unset CURRENT_ENTRY
183 printstack
185 minus)
186 if [[ -n "$CURRENT_ENTRY" ]]; then
187 echo "$CURRENT_ENTRY"
188 echo "entry:set_text" >calc.in
190 echo "-"
191 unset NUM
192 unset CURRENT_ENTRY
193 printstack
195 plus)
196 if [[ -n "$CURRENT_ENTRY" ]]; then
197 echo "$CURRENT_ENTRY"
198 echo "entry:set_text" >calc.in
200 echo "+"
201 unset NUM
202 unset CURRENT_ENTRY
203 printstack
205 power)
206 if [[ -n "$CURRENT_ENTRY" ]]; then
207 echo "$CURRENT_ENTRY"
208 echo "entry:set_text" >calc.in
210 echo "^"
211 unset NUM
212 unset CURRENT_ENTRY
213 printstack
215 squareroot)
216 if [[ -n "$CURRENT_ENTRY" ]]; then
217 echo "$CURRENT_ENTRY"
218 echo "entry:set_text" >calc.in
220 echo "v"
221 unset NUM
222 unset CURRENT_ENTRY
223 printstack
225 swap)
226 if [[ -n "$CURRENT_ENTRY" ]]; then
227 echo "$CURRENT_ENTRY"
228 echo "entry:set_text" >calc.in
230 # portability kludge. The parentheses are dc variable names
231 echo "s(s)L(L)"
232 unset NUM
233 unset CURRENT_ENTRY
234 printstack
236 drop)
237 if [[ -z "$CURRENT_ENTRY" ]]; then
238 # portabilty kludge (and memory leak)
239 echo "s!"
241 echo "entry:set_text" >calc.in
242 unset NUM
243 unset CURRENT_ENTRY
244 printstack
246 clear)
247 echo "c"
248 echo "entry:set_text" >calc.in
249 unset NUM
250 unset CURRENT_ENTRY
251 printstack
253 cancel)
254 varkeys_set_visible 0
255 echo "entry:set_text" >calc.in
256 unset NUM
257 unset CURRENT_ENTRY
258 printstack
260 recall)
261 VARMODE="recall"
262 varkeys_set_visible 1
264 store)
265 VARMODE="store"
266 if [[ -n "$CURRENT_ENTRY" ]]; then
267 echo "LE: $CURRENT_ENTRY" >>ttt
268 echo "$CURRENT_ENTRY"
269 echo "entry:set_text" >calc.in
270 unset NUM
271 unset CURRENT_ENTRY
273 varkeys_set_visible 1
275 off)
276 echo "_:main_quit" >calc.in
277 exit
279 esac
281 done
282 } <&"${COPROC[0]}" >&"${COPROC[1]}"