-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathwisp-multiline.sh
executable file
·175 lines (141 loc) · 4.97 KB
/
wisp-multiline.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
#!/usr/bin/env bash
# wisp-multiline.sh --- run multiline wisp code
# Copyright (C) 2013 Arne Babenhauserheide <[email protected]>
# Author: Arne Babenhauserheide <[email protected]>
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 3
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
## global variables
# version of this script
version="wisp multiline 0.3"
# aggregated wisp code
wisp=""
# converted lisp code
lispcode=""
## Parse commandline options
getopt -T > /dev/null
if [ $? -eq 4 ]; then
# GNU enhanced getopt is available
eval set -- `getopt --long help,lisp:,verbose,version,output:,wisp:,interactive --options hl:vo:w:i -- "$@"`
else
# Original getopt is available
eval set -- `getopt hl:vo:w:i "$@"`
fi
PROGNAME=`basename $0`
ARGS=`getopt --name "$PROGNAME" --long help,lisp:,verbose,version,output:,wisp:interactive --options hl:vo:w:i -- "$@"`
if [ $? -ne 0 ]; then
exit 1
fi
eval set -- $ARGS
# default options
HELP=no
LISP=guile
verbose=no
VERSION=no
OUTPUT=no
INTERACTIVE=no
WISP="./wisp.py"
# check, if the default wisp exists and can be executed. If not, fall
# back to wisp.py (which might be in PATH).
if [ ! -x $WISP ]; then
WISP="wisp.py"
fi
while [ $# -gt 0 ]; do
case "$1" in
-h | --help) HELP=yes;;
-l | --lisp) LISP="$2"; shift;;
-o | --output) OUTPUT="$2"; shift;;
-w | --wisp) WISP="$2"; shift;;
-v | --verbose) VERBOSE=yes;;
-i | --interactive) INTERACTIVE=yes;;
--version) VERSION=yes;;
--) shift; break;;
esac
shift
done
# Provide help output
if [[ $HELP == "yes" ]]; then
echo "$0 [-h] [-l] [-v] [-i] [[- | SCRIPT] ...]
Run multiline commands through wisp or execute the SCRIPT.
If you use - as script, it reads the script from standard input.
-h | --help) This help output.
-l | --lisp) Select the Lisp interpreter to call.
Options: guile, emacs or the full command to use.
If you use emacs, note that (message) writes to stdout.
Example: -l \"guile -s /dev/stdin/\"
-o | --output) Save the executed wisp code to this file.
-w | --wisp) Select the wisp preprocessor to use.
-v | --verbose) Provide verbose output.
-i | --interactive) Run interactive commands after reading scripts.
Does not work with reading from a pipe (standard input).
--version) Print the version string of this script.
"
exit 0
fi
if [[ $VERSION == "yes" ]]; then
echo "$version"
exit 0
fi
# Select the lisp interpreter
if [[ "${LISP}" == "guile" ]]; then
INTERPRETER="guile -s /dev/stdin"
# the following commented code does not work, sadly. I do not understand, why.
# elif [[ "${LISP}" == "emacs" ]]; then # thanks to http://superuser.com/a/487329
# INTERPRETER="emacs -Q --batch --eval '(with-temp-buffer (progn (condition-case nil (let (line) (while (setq line (read-string \"\")) (insert line)(newline)(forward-char 1))) (error nil)) (eval-current-buffer)))'"
else
INTERPRETER="${LISP}"
fi
## parameters
# if scripts are given, read those.
if [ $# -gt 0 ]; then
# Remaining parameters can be processed
for ARG in "$@"; do
# ignore !#, which just finishes a shebang line comment for scheme
if [[ "${ARG}" == "!#" ]]; then
continue
fi
l=$(${WISP} "${ARG}")
lispcode="${lispcode}
${l}"
done
# if we do not need additional interactive commands, we only need to
# execute the lisp.
if [[ x"${INTERACTIVE}" == x"no" ]]; then
if [[ x"${LISP}" == x"emacs" ]]; then
emacs -Q --batch --eval "${lispcode}"
else
echo "${lispcode}" | eval "${INTERPRETER}"
fi
exit 0
fi
fi
## Read code from interactive input
echo ";; Welcome to wisp. Please enter your code.
;; Finish with two linebreaks, then execute with CTRL-D."
# IFS= ensures that initial blanks are kept)
while IFS= read wispi ; do
wisp="${wisp}
${wispi}"
done
# if the user requests output, copy the pipe with tee and append it to
# the output
if [[ x"$OUTPUT" != x"no" ]]; then
echo "${wisp}" >> "$OUTPUT"
fi
# convert the input to lisp
l=$(echo "${wisp}" | ${WISP} - )
lispcode="${lispcode}
${l}"
# now run the code
if [[ x"${LISP}" == x"emacs" ]]; then
emacs -Q --batch --eval "${lispcode}"
else
echo "${lispcode}" | eval "${INTERPRETER}"
fi