diff options
Diffstat (limited to 'src/helpers/rosegarden-lilypondview')
-rwxr-xr-x | src/helpers/rosegarden-lilypondview | 395 |
1 files changed, 395 insertions, 0 deletions
diff --git a/src/helpers/rosegarden-lilypondview b/src/helpers/rosegarden-lilypondview new file mode 100755 index 0000000..95cc25e --- /dev/null +++ b/src/helpers/rosegarden-lilypondview @@ -0,0 +1,395 @@ +#!/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 <<End-of-Usage-message +Process LilyPond files to PDF files and print/view them. + +Usage: rosegarden-lilypondview [OPTION] file.ly ... + +Options: + -g, --graphical : show Lilypond progress in a graphical dialog + -P, --pdf : view created PDF files (DEFAULT) + -p, --print : print created PDF files; together with '--pdf', viewing starts first + -v, --version : print version of rosegarden-lilypondview + --conftest : check that all dependencies are present + +example: rosegarden-lilypondview -g file.ly + +End-of-Usage-message + exit 2 +fi + +for x in $input_files; do + case "$x" in + *.ly|*.ly.gz) + input="$x" + cp "$input" "$tmpdir/" || exit 1 + +( + dir=`dirname "$input"` + base=`basename "$input"` + cd "$tmpdir" + + if [ -n "$graphical" ]; then + dcopRef=`kdialog --title "Processing" --icon "rosegarden" --progressbar "Processing LilyPond file..." 100` + fi + + send_dcop() { + if [ -n "$graphical" ]; then + dcop $dcopRef "$@" + fi + } + + trap "send_dcop close" 0 + + send_dcop showCancelButton true + + if file "$base" | grep -q gzip; then + gunzip "$base" + base=`basename "$base" .gz` + fi + + includes=`\ + grep '\\include ' "$base" | \ + sed -e 's/\\include//' \ + -e 's/^.*[^a-zA-Z0-9-]\([a-zA-Z0-9-][a-zA-Z0-9-]*.ly\).*$/\1/'` + + for include in $includes; do + if [ -r "$dir/$include" ]; then + cp "$dir/$include" . + elif [ -r "$dir/$include.gz" ]; then + gunzip -c "$dir/$include" > ./"$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 </dev/null >"$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; |