You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
rosegarden/src/helpers/rosegarden-lilypondview

396 lines
10 KiB

#!/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;