]> git.donarmstrong.com Git - lilypond.git/blob - bin/convert-mudela.pl
release: 0.1.65
[lilypond.git] / bin / convert-mudela.pl
1 #!@PERL@ -w
2 # -*-perl-*-
3
4 =head1 TODO
5
6     detect \lyrics and \melodic, and do substitution accordingly.
7     count <> and {} ?
8
9 Ugh . Perl sux. Anybody for Python?
10     
11 =cut    
12
13
14
15 #
16 # version of "supporting" engine, not mudela conversions.
17
18
19
20
21
22 $convert_mudela_version = "0.1.2";
23
24 use Getopt::Long;
25
26
27 sub version_compare
28 {
29     local ($a,$b)=@_;
30     return &cmpver;
31 }
32     
33
34 sub  cmpver 
35 {       
36         my(@a)= split /\./,$a;
37         my(@b)= split /\./,$b;
38
39         for $i (0,1,2) {
40             return $a[$i] <=> $b[$i] if ($a[$i] != $b[$i]);
41         }
42         return $a cmp $b;
43 }
44
45 sub version_string_conv
46 {
47     my ($from_version, $to_version) = @_;
48     s/\version \"$from_version\"/\version \"$to_version\"/g;
49 }
50
51 ################################################################
52
53 sub no_conv
54 {
55 }
56  
57 sub convert_0_0_52_to_0_0_53
58 {
59
60     s/include \"/$1\\include \"/g;
61 }
62
63   
64 sub convert_0_0_54_to_0_0_55
65 {
66     s/%{/% {/g;
67 }
68
69   
70 sub convert_0_0_53_to_0_0_54
71 {
72     print STDERR "Not smart enough to convert \\transpose\n"    if (/\\transpose/) ;
73 }
74
75 # we-re not at 58 yet, but this is at least one of the rules
76 sub convert_0_0_55_to_0_0_56
77 {
78     s/\"\|\|\"/\"|.\"/g;
79 }
80
81 sub convert_0_0_56_to_0_0_57
82 {
83     s/\(([ \]\[|\t-\.>]|\\[<!>a-z]+)*\)/\~ $1/g;
84 }
85
86 sub convert_0_0_57_to_0_0_58
87 {
88     s/\[ *([^\[\]]*)\] *([1-9]*) *\/ *([1-9]*)/[$2\/$3 $1]1\/1/g;
89 }
90
91 sub convert_0_0_58_to_0_0_59
92 {
93     die "Not smart enough to convert 0.0.58 to 0.0.59\n";
94 }
95
96 sub convert_0_0_59_to_0_0_60
97 {
98     s/(\\unitspace [0-9.mcptin\\ ]+|\\geometric [0-9.]+|\\width [0-9.mcp\\tin]+)/$1;/g;
99     s/(\\output \"[^\"]+\")/$1;/;
100     s/(\\tempo  [0-9: ]+)/$1;/;
101 }
102
103 sub convert_0_0_60_to_0_0_61
104 {
105     s/(\\unitspace|\\geometric|\\width)/$1=/g;
106    
107 }
108
109 sub convert_0_1_0_to_0_1_1
110 {
111     s/\\tempo (.*):(.*);/\\tempo $1 = $2;/g
112 }
113
114 sub convert_0_1_2_to_0_1_3
115 {
116     s/\\stem *(\\up|1) *;/\\stemup/g;
117     s/\\stem *(\\down|-1) *;/\\stemdown/g;
118     s/\\stem *0 *;/\\stemboth/g;
119     s/\\hshift ([^;]+) *;/\\property Voice.hshift = $1/g;
120 }
121
122 my $header_b = 0;
123
124 sub generic_conversion_scan
125 {
126     if (/\\header *\{/)
127     {
128         $header_b = 1;
129     }
130     if ($header_b && /^ *\}/)
131     {
132         $header_b = 0;
133     }
134 }
135 sub convert_0_1_4_to_0_1_5
136 {
137     s/([<{]) *\\id "Piano" (.+);/\\type Grandstaff = $3 $1/;    
138     s/([<{]) *\\id (.+) (.+);/\\type $2 = $3 $1/;
139 }
140
141        
142 sub convert_0_1_5_to_0_1_6
143 {
144     s/< *\\multi (.*);/\\multi $1 </;
145 }
146
147 sub convert_0_1_6_to_0_1_7
148 {
149     if ($header_b) 
150     {
151         s/^([a-zA-z]+)[ \t]+(.*)$/$1 =\t \"$2\";/;
152         s/^([ \t])+(.*)$/$1 \"$2\";/;
153     }
154 }  
155
156 sub convert_0_1_7_to_0_1_8
157 {
158     s/\\plet *1 *\/ *1 *;/\\]/;    
159     s/\\plet *([1-9][0-9]*) *\/ *([2-9][0-9]*) *;/\\[$1\/$2/;    
160 }  
161
162 sub convert_0_1_8_to_0_1_9
163 {
164 # sticky plet shorthand...
165 #  print "introduced plet and finger shorthands...\n";
166 }
167
168 sub convert_0_1_9_to_0_1_10
169 {
170     s/Grandstaff/Grand_staff/;    
171 }
172
173 sub convert_0_1_10_to_0_1_14
174 {
175     while ( /([ \n\t\]\[<>()])\'+[a-zA-Z]/ )
176     {
177         s/([ \n\t\[<>()\]])\'(\'*[a-zA-Z]+)/$1$2,/g;
178     }
179 }
180 sub convert_0_1_14_to_0_1_15
181 {
182 # junked \duration last and \duration 4, 8, 16 etc.
183 # junked \octave relative
184     print STDERR "Not smart enough to convert \\duration\n"    if (/\\duration/) ;
185     print STDERR "Not smart enough to convert \\octave relative\n"    if (/\\octave relative/) ;    
186 }
187
188 ###############################################################
189
190 sub    last_conversion
191 {
192     my @v = &versions;
193     return pop @v;
194 }
195 sub identify
196 {
197     
198     print STDERR "This is convert-mudela " . $convert_mudela_version . 
199         " (up to mudela version ", last_conversion,     ")\n";
200 }
201   
202   
203  sub usage
204   {
205      print STDERR "Usage: convert-mudela [options] [mudela-file]...\n"
206      . "Convert old mudela source from mudela-file or stdin\n\n"
207      . "Options:\n"
208      . "  -e, --edit             perform in-place conversion\n"
209      . "  -f, --from=PATHLEVEL   use source version 0.0.PATCHLEVEL\n"
210      . "  -h, --help             print this help\n"
211      . "  -o, --output=FILE      name output file\n"
212      . "  -s, --show-rules       print all known conversion rules\n"
213      . "  -t, --to=VERSION       convert to version VERSION\n"
214   }
215       
216
217 my %minor_conversions = ("0.0.50" => \&no_conv,
218                          "0.0.52" => \&convert_0_0_50_to_0_0_52,
219                          "0.0.53" => \&convert_0_0_52_to_0_0_53,
220                          "0.0.54" => \&convert_0_0_53_to_0_0_54,
221                          "0.0.55" => \&convert_0_0_54_to_0_0_55,
222                          "0.0.56" => \&convert_0_0_55_to_0_0_56,
223                          "0.0.57" => \&convert_0_0_56_to_0_0_57,
224                          "0.0.58" => \&convert_0_0_57_to_0_0_58,
225                          "0.0.59" => \&convert_0_0_58_to_0_0_59,
226                          "0.0.60" => \&convert_0_0_59_to_0_0_60,
227                          "0.0.61" => \&convert_0_0_60_to_0_0_61,
228                          "0.1.1" => \&convert_0_1_0_to_0_1_1,
229                          "0.1.2" => \&no_conv,
230                          "0.1.3" => \&convert_0_1_2_to_0_1_3,
231                          "0.1.4" => \&no_conv,
232                          "0.1.5" => \&convert_0_1_4_to_0_1_5,
233                          "0.1.6" => \&convert_0_1_5_to_0_1_6
234                          ,"0.1.7" => \&convert_0_1_6_to_0_1_7
235                          ,"0.1.8" => \&convert_0_1_7_to_0_1_8
236                          ,"0.1.9" => \&convert_0_1_8_to_0_1_9
237                          ,"0.1.10" => \&convert_0_1_9_to_0_1_10
238                          , "0.1.14" => \&convert_0_1_10_to_0_1_14
239                          , "0.1.15" => \&convert_0_1_14_to_0_1_15
240                          );
241
242  
243
244 sub versions 
245 {
246     return (sort { cmpver; } (keys %minor_conversions));
247 }
248
249
250 sub show_rules
251 {
252     my (@v) = versions;
253
254     print "Rules: ", join(", ", @v), "\n";
255     
256 }
257
258 sub do_conversion
259 {
260     my ($from,$to) = @_;
261
262     my @applicable_conversion;
263     my @mudela_levels;
264     
265     my @v = versions;
266     foreach $ver (@v) {
267         if (version_compare($ver, $from) > 0 && version_compare($ver,$to) <= 0 ){ 
268             push @applicable_conversion, $minor_conversions{$ver};
269             push @mudela_levels, $ver;
270         }
271     }
272     
273     print STDERR "Applying following rules: ", join(", ", @mudela_levels) , "\n";
274
275     while (<INLY>) {
276         generic_conversion_scan;
277         foreach $subroutine (@applicable_conversion) {
278         
279             &$subroutine;
280             
281         }
282         version_string_conv $from, $to;
283         print OUTLY;
284     }
285 }
286
287 sub get_auto_from
288 {
289     my ($fn)=@_;
290     my ($ver);
291     open INLY, $fn || die "Can't open";
292
293     while (<INLY>) {
294         s/^.*\\version \"([^\"]*)\".*$//;
295         if (defined ($1)) {
296             print STDERR "Guessing version: ", $1, ".. ";
297             $ver = $1;
298             last;
299         }
300     }
301     if (!defined($ver)){
302         print STDERR "can't determine mudela version in $fn.\n";
303         my $u;
304         return $u;
305     }
306     close INLY;
307     return $ver;
308 }   
309
310 sub  set_files 
311 {
312     $infile = "-";
313     $outfile = "-";
314     $outfile = $opt_output if (defined($opt_output));
315
316     if ($ARGV [0])  {
317         $infile = $ARGV[0];
318     } 
319     if (!(-f $infile) && !($infile =~ /\.ly$/s)) {
320         $infile .= ".ly";
321     }
322     if ($opt_edit && $infile ne "-") {
323         $opt_edit = 1;
324         $outfile = "$infile.NEW";
325         $infile = "$infile";
326     }
327     print STDERR "Input ", (($infile eq "-") ?"STDIN" : $infile), " .. ";
328
329 }
330
331 sub do_one_arg
332 {
333     set_files;
334
335     local ($from_version, $to_version);
336     $from_version = $opt_from;
337     $to_version = $opt_to;
338     
339     ($from_version = get_auto_from $infile) unless defined($opt_from);
340     return if (!defined($from_version));
341     
342     ($to_version =  last_conversion) unless (defined($opt_to));
343
344     die "can't open \`$infile\'" unless open INLY,$infile ;
345     die "can't open \`$outfile\'" unless open OUTLY, ">$outfile";
346     
347     do_conversion $from_version, $to_version;
348     close INLY;
349     close OUTLY;
350
351     if ($opt_edit) {
352         rename $infile, "$infile~";
353         rename $outfile, "$infile";
354     }
355 }
356
357 ## "main"
358
359 identify;
360
361
362 GetOptions ("help", "output=s", "from=s", "to=s", "minor=i", "edit", "show-rules");
363
364 if ($opt_help) {
365     usage();
366     $opt_help = 0;      # to extinguish typo check.
367     exit 0;
368 }
369
370 if ($opt_show_rules) { 
371     show_rules ;
372     $opt_show_rules = 0;        # to extinguish typo check.
373     exit 0;
374 }
375
376 local ( $infile,$outfile);
377 my $processed_one=0;
378
379 while (defined($ARGV[0])) {
380     do_one_arg;
381     shift @ARGV;
382     $processed_one = 1;
383 }
384 do_one_arg unless ($processed_one);
385
386