#!/bin/bash # # Helper program used by Rosegarden to preview and print Lilypond output. # Copyright 2004-2008 Chris Cannam and Fervent Software Ltd. # Copyright 2006-2008 Heikki Junes. # Distributed under the GNU General Public License. tmpdir=/tmp/$$_lilypondview mkdir "$tmpdir" || exit 1 trap "rm -rf \"$tmpdir\"" 0 # Requirements, actual or potential: # # lilypond (that actually runs, of course) # mktemp OR tempfile # kpdf OR kghostview OR gpdf OR xpdf OR evince OR acroread # kdialog [for graphical mode only] # kprinter OR gtklp prog_lilypond="" prog_temp_file="" prog_kdialog="" prog_pdf_view="" prog_printer="" set eval -- `getopt -n$0 --longoptions="graphical,pdf,print,version,conftest" "gpPv" "$@"` input_files="" pdf_view="" printing="" graphical="" while [ $# -gt 0 ] do # Parse options case "$1" in -g|--graphical) graphical=true ;; -p|--print) printing=true ;; -P|--pdf) pdf_view=true ;; -v|--version) print_version=true ;; --conftest) conftest=true ;; esac # Check and list the listed LilyPond input files # getopt adds quotation marks ('): "'input.ly'" if [ "`expr match $1 '.*.ly'`" == "`expr length $1 - 1`" -o \ "`expr match $1 '.*.ly.gz'`" == "`expr length $1 - 1`" ]; then input="${1:1:`expr length "$1" - 2`}" if [ ! -f "$input" ]; then echo "Error: Can't open \"$input\" for reading" 1>&2 exit 1 fi input_files="$input_files $input" fi shift done #echo "input files: $input_files" if [ -n "$print_version" ]; then echo "rosegarden-lilypondview v1.6" 1>&2 exit 0 fi if [ -x "`type -path lilypond`" ]; then lilypond_version="`lilypond --version | grep LilyPond | head -1 | sed 's/^.* //'`" case "$lilypond_version" in 1.*|2.[0-5].*) echo "rosegarden-lilypondview: Unsupported LilyPond version ($lilypond_version)" 1>&2 echo "Required: LilyPond v2.6 or newer";; *) prog_lilypond=lilypond;; esac else echo "rosegarden-lilypondview: LilyPond unavailable" 1>&2 echo "Required: LilyPond" fi reqd= for x in mktemp tempfile; do if [ -x "`type -path $x`" ]; then prog_temp_file=$x break; fi done if [ -z "$prog_temp_file" ]; then reqd="mktemp OR tempfile, $reqd" echo "rosegarden-lilypondview: No temporary file utility found" 1>&2 fi if [ -x "`type -path kdialog`" ]; then prog_kdialog=kdialog fi for x in acroread kpdf kghostview gpdf xpdf evince; do if [ -x "`type -path $x`" ]; then prog_pdf_view=$x break; fi done if [ -z "$prog_pdf_view" ]; then reqd="kpdf OR kghostview OR gpdf OR xpdf OR evince OR acroread, $reqd" echo "rosegarden-lilypondview: No PDF viewer found" 1>&2 fi for x in kprinter gtklp; do if [ -x "`type -path $x`" ]; then case "$x" in kprinter) x="$x --stdin";; esac prog_printer=$x break; fi done if [ -z "$prog_printer" ]; then reqd="kprinter OR gtklp, $reqd" echo "rosegarden-lilypondview: No printing program found" 1>&2 fi if [ -n "$conftest" ]; then if [ -n "$reqd" ]; then echo "Required: "${reqd%%, } fi fi [ -z "$prog_lilypond" ] && exit 1 [ -z "$prog_pdf_view" ] && exit 1 [ -z "$prog_temp_file" ] && exit 1 if [ -n "$conftest" ]; then echo "LilyPond version: $lilypond_version" exit 0 fi if [ -z "$prog_kdialog" ]; then # can't do graphical mode echo "rosegarden-lilypondview: Graphical progress dialog requires kdialog utility" 1>&2 graphical="" fi if [ -z "$input" ]; then cat < ./"$include" fi done fileversion=`grep '\\version ' "$base" | head -1 | \ sed -e 's/\\version //' -e 's/[^0-9.]//g'` args="" convert="" echo "LilyPond version is $lilypond_version, file version is $fileversion" case "$lilypond_version" in 2.6.*) args="--format=pdf" case "$fileversion" in 1.*|2.[0-5].*) convert=true;; esac;; 2.8.*) args="--format=pdf" case "$fileversion" in 1.*|2.[0-7].*) convert=true;; esac;; 2.10.*) args="--format=pdf" case "$fileversion" in 1.*|2.[0-9].*) convert=true;; esac;; esac logfile="lilypond-output.log" cat "$logfile" if [ -n "$convert" ]; then echo "File version is $fileversion against LilyPond version $lilypond_version -- converting..." 1>&2 send_dcop setLabel "Updating LilyPond file..." for srcfile in "$base" $includes; do if [ ! -f "$srcfile" ]; then continue; fi case "$fileversion" in 1.*|2.[012345].*) grep -v override-auto-beam-setting "$srcfile" > "${srcfile}_tmp" mv "${srcfile}_tmp" "$srcfile" ;; esac if [ -n "$graphical" ]; then convert-ly "$srcfile" > "${srcfile}_converted" 2> "$logfile" && mv "${srcfile}_converted" "$srcfile" else convert-ly "$srcfile" > "${srcfile}_converted" && mv "${srcfile}_converted" "$srcfile" fi done send_dcop setLabel "Processing LilyPond file..." fi if [ -n "$graphical" ] ; then # special bar comment syntax RG exports -- hopefully benign if absent bars=`grep '^%% [0-9][0-9]*$' "$base" | sort -k 1 -n | tail -1 | awk '{ print $2; }'` if [ -z "$bars" ]; then staffs=`grep 'Staff *[=<]' "$base" | wc -l` [ "$staffs" -eq 0 ] && staffs=1 bars=`grep -v '^ *%' "$base" | wc -l` bars=$(($bars / $staffs)) fi bars=$(($bars + 5)) count=$(($bars * 7 / 3)) indev=/dev/pts/0 if [ ! -c "$indev" ]; then indev=/dev/ptya0; fi PROGRESS=`$prog_temp_file` # echo "Running $prog_lilypond $args \"$base\"" $prog_lilypond $args "$base" <$indev 2>&1 | tee -a "$logfile" | \ perl -e ' $| = 1; print "0\n"; $state = 0; $n = ""; $base = 0; while (defined ($key = getc)) { if ($key eq "[") { # bar number start mark $state = 1; } elsif ($key eq "]") { # bar number end mark $state = 2; $val = int( ($base + $n) * 100 / '$count' ); if ($val > 100) { $val = 100; } print " $val"; print "\n"; $n = ""; } elsif ($key eq "\n") { if ($state == 2) { $base = $base + '$bars'; $state = 0; } } elsif ($state == 1) { # bar number $n = $n . $key; } } print "end\n" ' >& $PROGRESS & PROCESSINGSTAGE=0 # # Stages: # 0 -- Process LilyPond file # 1 -- Create PDF output # 2 -- Finished # until [ "$PROCESSINGSTAGE" != "0" ]; do sleep 0.2 PROGRESSVALUE=`tail -c 4 $PROGRESS` ## Debugging code: # cat $PROGRESS # echo "= $PROGRESSVALUE ==" if [ "$PROGRESSVALUE" == "end" ]; then # # Processing was terminated: # - either the number of bars was not known, # - or there appeared an error during processing. # send_dcop setProgress 100 PROCESSINGSTAGE=2 elif [ "$PROGRESSVALUE" == "100" ]; then PROCESSINGSTAGE=1 # # Note: percentage is 100 only after PDF has been created. # send_dcop setProgress 99 send_dcop setLabel "Creating PDF output..." else send_dcop setProgress $PROGRESSVALUE fi if [ "true" == `send_dcop wasCancelled` ]; then send_dcop close rm $PROGRESS exit 1; fi done until [ "$PROCESSINGSTAGE" == "2" ]; do sleep 0.2 if [ "true" == `send_dcop wasCancelled` ]; then send_dcop close rm $PROGRESS exit 1; fi PROGRESSVALUE=`tail -c 4 $PROGRESS` if [ "$PROGRESSVALUE" == "end" ]; then PROCESSINGSTAGE=2 send_dcop setProgress 100 fi done ( sleep 2 ; send_dcop close ) & rm $PROGRESS else # echo "running $prog_lilypond $args \"$base\"..." $prog_lilypond $args "$base" fi target="${base%.*}.pdf" if [ -f "$target" ]; then if [ -z "$printing" ]; then $prog_pdf_view "$target" else if [ -n "$pdf_view" ]; then $prog_pdf_view "$target" fi if [ -n "$printing" ]; then $prog_printer < "$target" fi fi exit 0 elif [ -n "$graphical" ]; then cat $logfile 1>&2 echo 1>&2 echo "LilyPond failed" 1>&2 LOGGINGFILE=`$prog_temp_file` if [ -n "$graphical" ]; then ( echo echo " ERROR: LilyPond processing failed." echo " LilyPond output follows:" echo cat "$logfile" ) > $LOGGINGFILE $prog_kdialog --textbox $LOGGINGFILE 600 200 fi rm $LOGGINGFILE else echo 1>&2 echo "LilyPond processing failed." 1>&2 fi exit 1 ) ;; *) ;; esac done;