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.
396 lines
10 KiB
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;
|