#!/bin/bash #*****************************************************# # Script for making image files from lilypond source # # suitable for use as musical examples to insert in a # # document or web page. # # Creator - Jonathan Kulp # # Johnny come lately assistant - Patrick Horgan # #*****************************************************# # Change log # # 1.1.2 Added platform recognition--Darwin or Linux # Known issue: does not handle spaces in directory names # 1.1.1 Added -a, -V and much comments # 1.1 Added checking of return codes so we could # abort if something failed. # 1.0 Initial release # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # setformatlist - gets the list of all the things that # you can convert to #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ setformatlist() { currentdir=`pwd` # Remember our current directory examp=`which ppmtojpeg` # find out where the progs are returnstatus=$? if [ $returnstatus -eq 0 ] ; then OUTDIR="`dirname $examp`" #grab the directory cd $OUTDIR # change to it so we can # find all the programs starting with ppmtoxxxx # and remove the initial part so that we can # figure out what ppms can be converted to ppmtos=`ls ppmto* | sed -n s/ppmto//p` # same for pnmto pnmtos=`ls pnmto* | sed -n s/pnmto//p` # Now combine the two, change the space separated # list into individ line that sort can sort with # -u to throw away duplicates, then change newlines # back to spaces so we have a sorted list without # duplicate of all things we can convert to alltos=`echo $ppmtos $pnmtos | tr " " "\n" | sort -u | tr "\n" " "` fi cd $currentdir # Change back so we don't affect anything } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # usage is called when we're called incorrectly. # it never returns #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ usage() { echo "Usage: " `basename $0` " [-v] [-t] [-rN] [-fFORMAT] filename" echo " -v print version number and quit" echo " -a about - tell about us and exit" echo " -t indicates transparency is desired" echo " -r=N set resolution to N (usually 72-2000)" echo " -f=FORMAT set format to FORMAT one of:" echo " jpeg, png, tiff, gif, pcx, bmp" echo " -V=viewer set image viewer, examp: -V=evince" echo " filename a lilypond file" exit -1 } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # about - tell about us and exit #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ about() { echo `basename $0` echo " Creator Jonathan Kulp" echo " Johnny-come-lately Patrick Horgan" exit 0 } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Set prompt to the prompt you want to give a user # goodvals to the list of acceptable values # call getval # when it returns your value is in outval #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ getval() { flag="notdone" address@hidden until [ $flag == "done" ] ; do echo -n $prompt " " read inval if [ A$inval == "A" ] ; then # inval is empty if [ A$default != 'A' ] ; then # default is set to something inval=$default default="" else #inval is empty, no default echo You must enter a value index=0 echo -n "Expecting one of : " while [ "$index" -lt "$elementcount" ] ; do echo -n "${goodvals["$index"]}" " " let index++ done echo fi fi if [ A$inval != "A" ] ; then # inval not empty, either they sent us something # or we got it from the default index=0 while [ "$index" -lt "$elementcount" ] ; do # Walk through list of goodvals to see if we got one if [ ${goodvals[$index]} == $inval ] ; then # Yep! We're done. flag="done" outval=${goodvals[$index]} fi let index++ done if [ $flag != "done" ] ; then # inval not in goodvals, let them know index=0 echo -n "Expecting one of : " while [ "$index" -lt "$elementcount" ] ; do echo -n "${goodvals["$index"]}" " " let index++ done echo fi fi done } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Set prompt to the prompt you want to give a user # call getnumval # when it returns your value is in outval #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ getnumval() { flag="notdone" until [ $flag == "done" ] ; do echo -n $prompt " " read inval if [ A$inval == "A" ] ; then # inval is empty if [ A$default != 'A' ] ; then # but default is not, so use it inval=$default default="" else # no inval, no default echo You must enter a value, expecting a positive numeric value fi fi if [ "A"$inval != 'A' ] ; then # inval set either from user or default case $inval in *[^0-9]*) echo "Error: expecting positive numeric value" ;; * ) flag="done" ;; esac fi done outval=$inval } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # validatearg() # set inarg to the value of the argument # set goodvals to the list of acceptable values # set prompt to the error message you'd like to give, # for example "ERROR: bad value for transparency arg" # this routine will append to it, " expecting: " and # the list of values from goodvals, then call usage # to exit #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ validatearg() { flag="notgood" address@hidden index=0 if [ "A"$inarg != "A" ] ; then while [ "$index" -lt "$elementcount" ] ; do if [ ${goodvals[$index]} == $inarg ] ; then flag="good" outval=${goodvals[$index]} fi let index++ done fi if [ $flag != "good" ] ; then index=0 echo -n $prompt echo -n " expecting one of : " while [ "$index" -lt "$elementcount" ] ; do echo -n "${goodvals["$index"]}" " " let index++ done echo usage fi } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # getopt_simple - Orig by Chris Morgan, stolen from # the ABS Guide and modified a bit #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ getopt_simple() { until [ -z "$1" ] ; do if [ ${1:0:1} = '-' ] ; then tmp=${1:1} # Strip off leading '-' . . . if [ ${tmp:0:1} = '-' ] ; then tmp=${tmp:1} # Allow double - fi parameter=${tmp%%=*} # Extract name. value=${tmp##*=} # Extract value. eval $parameter=$value else filename=$1 fi shift done } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Our program starts here. This is the equivalent of # our main() #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Give initial defaults to things so we can tell if they # change alltos="" transparency='no' t='no' resolution=0 r=0 format='none' f='none' V='eog' filename="none" version=1.1 setformatlist # Gets list of all image formats we can convert to if [ $returnstatus -ne 0 ] ; then # Apparently none! echo "Sorry, you have to have the netpbm utilities installed to use this." exit 1 fi # process all the options getopt_simple $* if [ "$v" == 'v' ] ; then # version echo `basename $0` version $version exit fi viewer=$V # default to eog if [ "$a" == 'a' ] ; then about fi if [ $filename == "none" ] ; then usage fi if [ $t != 'no' ] ; then # We let them use -t or --transparency, so if they used -t, we shove # the value in $transparency so we don't have to deal with both later transparency=$t fi if [ $transparency != 'no' ] ; then # if transparency is set, make that setting be 'Y' cause that's what # we check for later. transparency='Y' fi # We know $r starts numeric cause we initialize it to 0 if it's not numeric # now the user put something in in not numeric case $r in *[^0-9]*) echo "Error: resolution not numeric"; usage ;; esac if [ $r -ne 0 ] ; then # same as with -t, two versions of args, -r and --resolution resolution=$r fi # Now check resolution for numeric...if it came from -r it has already # been checked, but no harm checking again case $resolution in *[^0-9]*) echo "Error: resolution must be positive numeric"; usage ;; esac if [ $f != 'none' ] ; then # fold -f into --format format=$f fi if [ $format != "none" ] ; then # They set format so check it inarg=$format goodvals=( $alltos ) prompt="Error: format arg incorrect" validatearg fi # get filename from first argument srcfile="`basename $filename`" # get filename without .ly extension STEM="`basename $filename .ly`" # determine output directory OUTDIR="`dirname $filename`" # determine whether user is on Linux or mac OSX OS=$(uname) if [[ $resolution -ne 0 ]] ; then echo Resolution set to $resolution dots per inch. RES=$resolution else # ask for output resolution prompt="Enter output resolution in DPI 72, 100, 300, 600, etc...(72): " default=72 getnumval RES=$outval fi # If transparency is not set, then prompt for it if format is not set yet, or # if format is set to one of the ones that supports transparency, i.e. gif, png if [ "$transparency" == 'no' ] ; then if [[ ( "$format" == 'gif') || ( "$format" == 'png' ) || ( "$format" == 'none' ) ]] ; then # only prompt for transparency if format unset or set to gif or png prompt="Transparency? y/N" default="N" goodvals=("y" "Y" "n" "N") getval transparency=$outval fi fi # ask for desired final output format with a lot of complications based on # whether transparency is set. if [[ ( "$transparency" == "Y" ) || ( "$transparency" == "y" ) ]] ; then if [[ ( "$format" != 'gif') && ( "$format" != 'png' ) ]] ; then # if they ask for transparency and format's set to something other # than gif or png we can't procede--it makes no sense, get them to # resolve it. if [[ "$format" != 'none' ]] ; then echo "You ask for transparency which doesn't work with" $format fi prompt="Enter desired output format png, gif (png): " default="png" goodvals=("png" "gif") getval FORMAT=$outval else FORMAT=$format fi else # we know transparency's not Y or y, but make any other value be 'no' # so we only have one thing to check for later transparency="no" # transparency's not set, so if they gave us a format on the command # line use that, else ask them for one. if [[ $format != 'none' ]] ; then echo Output format is $format FORMAT=$format else prompt="Enter desired output format jpeg, png, tiff, gif, pcx, bmp ... (png) : " default='png' goodvals=( $alltos ) getval FORMAT=$outval fi fi cd $OUTDIR # run lilypond on file with png output for further processing... # command determined by result of "uname" command earlier if [ "$OS" == "Darwin" ] then /Applications/LilyPond.app/Contents/Resources/bin/lilypond --format=png -dresolution=$RES $srcfile else lilypond --format=png -dresolution=$RES $srcfile fi returnstatus=$? if [ "$returnstatus" -ne 0 ] ; then echo lilypond failed--aborting exit $returnstatus fi # The next commands crop the png file so that # it only includes the example instead of an entire page. # First convert image to pnm for processing with netpbm tools pngtopnm $STEM.png > $STEM.pnm returnstatus=$? if [ "$returnstatus" -ne 0 ] ; then echo pngtopnm failed converting the file to pnm so it could be cropped--aborting exit $returnstatus fi # crop all the white space off pnmcrop -white $STEM.pnm > $STEM-cropped.pnm returnstatus=$? if [ "$returnstatus" -ne 0 ] ; then echo pnmcrop failed--aborting exit $returnstatus fi # Now look for a command to do the final conversion, assume we won't find it... outcmd="invalid" # assume ppmto$FORMAT will be found which >& /dev/null ppmto$FORMAT if [ $? -eq 0 ] ; then outcmd=ppmto$FORMAT else # Nope, try pnmto$FORMAT and see if we find that which >& /dev/null pnmto$FORMAT if [ $? -eq 0 ] ; then outcmd=pnmto$FORMAT fi fi if [ $outcmd == "invalid" ] ; then # Baboo! Didn't find the command echo "Sorry, can't find a command for that format." exit -1 fi # convert to end format if [[ $transparency != 'no' ]] ; then echo $outcmd -transparent '#ffffff' $STEM-cropped.pnm $outcmd -transparent '#ffffff' $STEM-cropped.pnm > $STEM.$FORMAT else echo $outcmd $STEM-cropped.pnm $outcmd $STEM-cropped.pnm > $STEM.$FORMAT fi returnstatus=$? if [ "$returnstatus" -ne 0 ] ; then echo $outcmd failed converting to final output--aborting exit $returnstatus fi # removes pnm and ps files rm *.pnm if [ $FORMAT != 'ps' ] ; then rm $STEM.ps fi # open final image as background process in "Eye of Gnome" Image Viewer # or alternate viewer set via the -V argument if [ "$OS" == "Darwin" ] then open $STEM.$FORMAT else $viewer $STEM.$FORMAT & fi