#!/bin/bash
# wisp-multiline.sh --- run multiline wisp code
# Copyright (C) 2013 Arne Babenhauserheide <arne_bab@web.de>
# Author: Arne Babenhauserheide <arne_bab@web.de>
# 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 "$PN" --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