#!/usr/bin/perl -w =head1 TODO detect \lyrics and \melodic, and do substitution accordingly. =cut # # version of "supporting" engine, not mudela conversions. # $convert_mudela_version = "0.1"; use Getopt::Long; sub version_string_conv { my ($from_version, $to_version) = @_; s/\version \"0.0.$from_version\"/\version \"0.0.$to_version\"/g; } ################################################################ sub no_conv { } sub convert_0_0_52_to_0_0_53 { s/include \"/$1\\include \"/g; } sub convert_0_0_54_to_0_0_55 { s/%{/% {/g; } sub convert_0_0_53_to_0_0_54 { print STDERR "Not smart enough to convert \\transpose\n" if (/\\transpose/) ; } # we-re not at 58 yet, but this is at least one of the rules sub convert_0_0_55_to_0_0_56 { s/\"\|\|\"/\"|.\"/g; } sub convert_0_0_56_to_0_0_57 { s/\(([ \]\[|\t-\.>]|\\[a-z]+)*\)/\~ $1/g; } ############################################################### sub last_conversion { my @v = &versions; return pop @v; } sub identify { print STDERR "This is convert-mudela " . $convert_mudela_version . " (up to mudela version 0.0.", last_conversion, ")\n"; } sub usage { print STDERR "Usage: convert-mudela [options] [mudela-file]...\n" . "Convert old mudela source from mudela-file or stdin\n\n" . "Options:\n" . " -e, --edit perform in-place conversion\n" . " -f, --from=PATHLEVEL use source version 0.0.PATCHLEVEL\n" . " -h, --help print this help\n" . " -o, --output=FILE name output file\n" . " -s, --show-rules print all known conversion rules\n" . " -t, --to=PATCHLEVEL convert to version 0.0.PATCHLEVEL\n" } # beware of the year 2000 my %minor_conversions = (50 => \&no_conv, 52 => \&convert_0_0_50_to_0_0_52, 53 => \&convert_0_0_52_to_0_0_53, 54 => \&convert_0_0_53_to_0_0_54, 55 => \&convert_0_0_54_to_0_0_55, 56 => \&convert_0_0_55_to_0_0_56, 57 => \&convert_0_0_56_to_0_0_57 ); sub versions { return (sort keys %minor_conversions); } sub show_rules { print "Rules: ", join(", ", sort keys %minor_conversions), "\n"; } sub do_conversion { my ($from,$to) = @_; my @applicable_conversion; my @mudela_levels; die "This is too old to convert " if $from < 50; my @v = versions; foreach $a (@v) { if ($a > $from && $a <= $to ){ push @applicable_conversion, $minor_conversions{$a}; push @mudela_levels, $a; } } print STDERR "Applying following rules: ", join(", ", @mudela_levels) , "\n"; while () { foreach $subroutine (@applicable_conversion) { &$subroutine; } version_string_conv $from, $to; print OUTLY; } } sub get_auto_from { my ($fn)=@_; my ($ver); open INLY, $fn || die "Can't open"; while () { s/^.*\\version \"([^\"]*)\".*$//; if (defined ($1)) { print STDERR "Guessing version: ", $1, ".. "; $ver = $1; last; } } if (!defined($ver)){ print STDERR "can't determine mudela version in $fn.\n"; my $u; return $u; } $ver =~ s/0\.0\.// ; close INLY; return $ver; } sub set_files { $infile = "-"; $outfile = "-"; $outfile = $opt_output if (defined($opt_output)); if ($ARGV [0]) { $infile = $ARGV[0]; } if (( ! -f $infile) && (! $infile =~ /\\.ly$/s ) ){ $infile .= ".ly"; } if ($opt_edit && $infile ne "-") { $opt_edit = 1; $outfile = "$infile.NEW"; $infile = "$infile"; } print STDERR "Input ", (($infile eq "-") ?"STDIN" : $infile), " .. "; } sub do_one_arg { set_files; local ($from_version, $to_version); $from_version = $opt_from; $to_version = $opt_to; ($from_version = get_auto_from $infile) unless defined($opt_from); return if (!defined($from_version)); ($to_version = last_conversion) unless (defined($opt_to)); die "can't open \`$infile\'" unless open INLY,$infile ; die "can't open \`$outfile\'" unless open OUTLY, ">$outfile"; do_conversion $from_version, $to_version; close INLY; close OUTLY; if ($opt_edit) { rename $infile, "$infile~"; rename $outfile, "$infile"; } } ## "main" identify; GetOptions ("help", "output=s", "from=i", "to=i", "minor=i", "edit", "show-rules"); if ($opt_help) { usage(); $opt_help = 0; # to extinguish typo check. exit 0; } if ($opt_show_rules) { show_rules ; $opt_show_rules = 0; # to extinguish typo check. exit 0; } local ( $infile,$outfile); my $processed_one=0; while (defined($ARGV[0])) { do_one_arg; shift @ARGV; $processed_one = 1; } do_one_arg unless ($processed_one);