]> git.donarmstrong.com Git - lilypond.git/blob - scripts/convert-ly.py
* lily/parser.yy: get rid off < > in markups by treating { } as
[lilypond.git] / scripts / convert-ly.py
1 #!@PYTHON@
2 #
3 # convert-ly.py -- Update old LilyPond input files (fix name?)
4 #
5 # source file of the GNU LilyPond music typesetter
6 #
7 # (c) 1998--2004  Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 #                 Jan Nieuwenhuizen <janneke@gnu.org>
9
10
11 # TODO
12 #   use -f and -t for -s output
13
14 # NEWS
15 # 0.2
16 #  - rewrite in python
17
18 import os
19 import sys
20 import __main__
21 import getopt
22 import  string
23 import re
24 import time
25
26 program_name = sys.argv[0]
27
28 version = '@TOPLEVEL_VERSION@'
29
30 # Did we ever have \mudela-version?  I doubt it.
31 # lilypond_version_re_str = '\\\\version *\"(.*)\"'
32 lilypond_version_re_str = '\\\\(mudela-)?version *\"([^"]+)\"'
33 lilypond_version_re = re.compile (lilypond_version_re_str)
34 add_version = 1
35
36
37 def program_id ():
38         return '%s (GNU LilyPond) %s' % (program_name, version)
39
40 def identify ():
41         sys.stderr.write (program_id () + '\n')
42
43 def usage ():
44         sys.stdout.write (
45                 r"""Usage: %s [OPTIONS]... [FILE]...
46 Try to convert to newer lilypond-versions.  The version number of the
47 input is guessed by default from \version directive.
48
49 Options:
50   -h, --help             print this help
51   -e, --edit             edit in place
52   -f, --from=VERSION     start from version [default: \version found in file]
53   -s, --show-rules       print all rules
54   -t, --to=VERSION       end at version [default: @TOPLEVEL_VERSION@]
55   -n, --no-version       don't add new version stamp
56       --version          print program version
57
58 Report bugs to bugs-gnu-music@gnu.org.
59
60 """ % program_name)
61         
62         
63         sys.exit (0)
64
65 def print_version ():
66         
67         sys.stdout.write (r"""%s
68
69 This is free software.  It is covered by the GNU General Public
70 License, and you are welcome to change it and/or distribute copies of
71 it under certain conditions.  invoke as `%s --warranty' for more
72 information.
73
74 """ % (program_id (), program_name))
75         
76 def str_to_tuple (s):
77         return tuple (map (string.atoi, string.split (s, '.')))
78
79 def tup_to_str (t):
80         return string.join (map (lambda x: '%s' % x, list (t)), '.')
81
82 def version_cmp (t1, t2):
83         for x in [0, 1, 2]:
84                 if t1[x] - t2[x]:
85                         return t1[x] - t2[x]
86         return 0
87
88 def guess_lilypond_version (filename):
89         s = open (filename).read ()
90         m = lilypond_version_re.search (s)
91         if m:
92                 return m.group (2)
93         else:
94                 return ''
95
96 class FatalConversionError:
97         pass
98
99 conversions = []
100
101 def show_rules (file):
102         for x in conversions:
103                 if (not from_version or x[0] > from_version) \
104                    and (not to_version or x[0] <= to_version):
105                         file.write  ('%s: %s\n' % (tup_to_str (x[0]), x[2]))
106
107 ############################
108                 
109 if 1:
110         def conv(str):
111                 if re.search ('\\\\multi', str):
112                         sys.stderr.write ('\nNot smart enough to convert \\multi')
113                 return str
114         
115         conversions.append (((0,1,9), conv, '\\header { key = concat + with + operator }'))
116
117 if 1:                                   # need new a namespace
118         def conv (str):
119                 if re.search ('\\\\octave', str):
120                         sys.stderr.write ('\nNot smart enough to convert \\octave')
121                 #       raise FatalConversionError()
122                 
123                 return str
124
125         conversions.append ((
126                 ((0,1,19), conv, 'deprecated \\octave; can\'t convert automatically')))
127
128
129 if 1:                                   # need new a namespace
130         def conv (str):
131                 str = re.sub ('\\\\textstyle([^;]+);',
132                                          '\\\\property Lyrics . textstyle = \\1', str)
133                 # harmful to current .lys
134                 # str = re.sub ('\\\\key([^;]+);', '\\\\accidentals \\1;', str)
135                         
136                 return str
137
138         conversions.append ((
139                 ((0,1,20), conv, 'deprecated \\textstyle, new \\key syntax')))
140
141
142 if 1:
143         def conv (str):
144                 str = re.sub ('\\\\musical_pitch', '\\\\musicalpitch',str)
145                 str = re.sub ('\\\\meter', '\\\\time',str)
146                         
147                 return str
148
149         conversions.append ((
150                 ((0,1,21), conv, '\\musical_pitch -> \\musicalpitch, '+
151                  '\\meter -> \\time')))
152
153 if 1:
154         def conv (str):
155                 return str
156
157         conversions.append ((
158                 ((1,0,0), conv, '0.1.21 -> 1.0.0 ')))
159
160
161 if 1:
162         def conv (str):
163                 str = re.sub ('\\\\accidentals', '\\\\keysignature',str)
164                 str = re.sub ('specialaccidentals *= *1', 'keyoctaviation = 0',str)
165                 str = re.sub ('specialaccidentals *= *0', 'keyoctaviation = 1',str)
166                         
167                 return str
168
169         conversions.append ((
170                 ((1,0,1), conv, '\\accidentals -> \\keysignature, ' +
171                  'specialaccidentals -> keyoctaviation')))
172
173 if 1:
174         def conv(str):
175                 if re.search ('\\\\header', str):
176                         sys.stderr.write ('\nNot smart enough to convert to new \\header format')
177                 return str
178         
179         conversions.append (((1,0,2), conv, '\\header { key = concat + with + operator }'))
180
181 if 1:
182         def conv(str):
183                 str =  re.sub ('\\\\melodic([^a-zA-Z])', '\\\\notes\\1',str)
184                 return str
185         
186         conversions.append (((1,0,3), conv, '\\melodic -> \\notes'))
187
188 if 1:
189         def conv(str):
190                 str =  re.sub ('default_paper *=', '',str)
191                 str =  re.sub ('default_midi *=', '',str)
192                 return str
193         
194         conversions.append (((1,0,4), conv, 'default_{paper,midi}'))
195
196 if 1:
197         def conv(str):
198                 str =  re.sub ('ChoireStaff', 'ChoirStaff',str)
199                 str =  re.sub ('\\\\output', 'output = ',str)
200                         
201                 return str
202         
203         conversions.append (((1,0,5), conv, 'ChoireStaff -> ChoirStaff'))
204
205 if 1:
206         def conv(str):
207                 if re.search ('[a-zA-Z]+ = *\\translator',str):
208                         sys.stderr.write ('\nNot smart enough to change \\translator syntax')
209                 #       raise FatalConversionError()
210                 return str
211         
212         conversions.append (((1,0,6), conv, 'foo = \\translator {\\type .. } ->\\translator {\\type ..; foo; }'))
213
214
215 if 1:
216         def conv(str):
217                 str =  re.sub ('\\\\lyrics*', '\\\\lyrics',str)
218                         
219                 return str
220         
221         conversions.append (((1,0,7), conv, '\\lyric -> \\lyrics'))
222
223 if 1:
224         def conv(str):
225                 str =  re.sub ('\\\\\\[/3+', '\\\\times 2/3 { ',str)
226                 str =  re.sub ('\\[/3+', '\\\\times 2/3 { [',str)
227                 str =  re.sub ('\\\\\\[([0-9/]+)', '\\\\times \\1 {',str)
228                 str =  re.sub ('\\[([0-9/]+)', '\\\\times \\1 { [',str)
229                 str =  re.sub ('\\\\\\]([0-9/]+)', '}', str)
230                 str =  re.sub ('\\\\\\]', '}',str)
231                 str =  re.sub ('\\]([0-9/]+)', '] }', str)
232                 return str
233         
234         conversions.append (((1,0,10), conv, '[2/3 ]1/1 -> \\times 2/3 '))
235
236 if 1:
237         def conv(str):
238                 return str
239         conversions.append (((1,0,12), conv, 'Chord syntax stuff'))
240
241
242 if 1:
243         def conv(str):
244                 
245                 
246                 str =  re.sub ('<([^>~]+)~([^>]*)>','<\\1 \\2> ~', str)
247                         
248                 return str
249         
250         conversions.append (((1,0,13), conv, '<a ~ b> c -> <a b> ~ c'))
251
252 if 1:
253         def conv(str):
254                 str =  re.sub ('<\\[','[<', str)
255                 str =  re.sub ('\\]>','>]', str)
256                         
257                 return str
258         
259         conversions.append (((1,0,14), conv, '<[a b> <a b]>c -> [<a b> <a b>]'))
260
261
262 if 1:
263         def conv(str):
264                 str =  re.sub ('\\\\type([^\n]*engraver)','\\\\TYPE\\1', str)
265                 str =  re.sub ('\\\\type([^\n]*performer)','\\\\TYPE\\1', str)
266                 str =  re.sub ('\\\\type','\\\\context', str)
267                 str =  re.sub ('\\\\TYPE','\\\\type', str)
268                 str =  re.sub ('textstyle','textStyle', str)
269                         
270                 return str
271         
272         conversions.append (((1,0,16), conv, '\\type -> \\context, textstyle -> textStyle'))
273
274
275 if 1:
276         def conv(str):
277                 if re.search ('\\\\repeat',str):
278                         sys.stderr.write ('\nNot smart enough to convert \\repeat')
279                 #       raise FatalConversionError()
280                 return str
281         
282         conversions.append (((1,0,18), conv,
283                 '\\repeat NUM Music Alternative -> \\repeat FOLDSTR Music Alternative'))
284
285 if 1:
286         def conv(str):
287                 str =  re.sub ('SkipBars','skipBars', str)
288                 str =  re.sub ('fontsize','fontSize', str)
289                 str =  re.sub ('midi_instrument','midiInstrument', str)                 
290                         
291                 return str
292
293         conversions.append (((1,0,19), conv,
294                 'fontsize -> fontSize, midi_instrument -> midiInstrument, SkipBars -> skipBars'))
295
296
297 if 1:
298         def conv(str):
299                 str =  re.sub ('tieydirection','tieVerticalDirection', str)
300                 str =  re.sub ('slurydirection','slurVerticalDirection', str)
301                 str =  re.sub ('ydirection','verticalDirection', str)                   
302                         
303                 return str
304
305         conversions.append (((1,0,20), conv,
306                 '{,tie,slur}ydirection -> {v,tieV,slurV}erticalDirection'))
307
308
309 if 1:
310         def conv(str):
311                 str =  re.sub ('hshift','horizontalNoteShift', str)
312                         
313                 return str
314
315         conversions.append (((1,0,21), conv,
316                 'hshift -> horizontalNoteShift'))
317
318
319 if 1:
320         def conv(str):
321                 str =  re.sub ('\\\\grouping[^;]*;','', str)
322                         
323                 return str
324
325         conversions.append (((1,1,52), conv,
326                 'deprecate \\grouping'))
327
328
329 if 1:
330         def conv(str):
331                 str =  re.sub ('\\\\wheel','\\\\coda', str)
332                         
333                 return str
334
335         conversions.append (((1,1,55), conv,
336                 '\\wheel -> \\coda'))
337
338 if 1:
339         def conv(str):
340                 str =  re.sub ('keyoctaviation','keyOctaviation', str)
341                 str =  re.sub ('slurdash','slurDash', str)
342                         
343                 return str
344
345         conversions.append (((1,1,65), conv,
346                 'slurdash -> slurDash, keyoctaviation -> keyOctaviation'))
347
348 if 1:
349         def conv(str):
350                 str =  re.sub ('\\\\repeat *\"?semi\"?','\\\\repeat "volta"', str)
351                         
352                 return str
353
354         conversions.append (((1,1,66), conv,
355                 'semi -> volta'))
356
357
358 if 1:
359         def conv(str):
360                 str =  re.sub ('\"?beamAuto\"? *= *\"?0?\"?','noAutoBeaming = "1"', str)
361                         
362                 return str
363
364         conversions.append (((1,1,67), conv,
365                 'beamAuto -> noAutoBeaming'))
366
367 if 1:
368         def conv(str):
369                 str =  re.sub ('automaticMelismas', 'automaticMelismata', str)
370                         
371                 return str
372
373         conversions.append (((1,2,0), conv,
374                 'automaticMelismas -> automaticMelismata'))
375
376 if 1:
377         def conv(str):
378                 str =  re.sub ('dynamicDir\\b', 'dynamicDirection', str)
379                         
380                 return str
381
382         conversions.append (((1,2,1), conv,
383                 'dynamicDir -> dynamicDirection'))
384
385 if 1:
386         def conv(str):
387                 str =  re.sub ('\\\\cadenza *0 *;', '\\\\cadenzaOff', str)
388                 str =  re.sub ('\\\\cadenza *1 *;', '\\\\cadenzaOn', str)               
389                         
390                 return str
391
392         conversions.append (((1,3,4), conv,
393                 '\\cadenza -> \\cadenza{On|Off}'))
394
395 if 1:
396         def conv (str):
397                 str = re.sub ('"?beamAuto([^"=]+)"? *= *"([0-9]+)/([0-9]+)" *;*',
398                               'beamAuto\\1 = #(make-moment \\2 \\3)',
399                               str)
400                 return str
401
402         conversions.append (((1,3,5), conv, 'beamAuto moment properties'))
403
404 if 1:
405         def conv (str):
406                 str = re.sub ('stemStyle',
407                               'flagStyle',
408                               str)
409                 return str
410
411         conversions.append (((1,3,17), conv, 'stemStyle -> flagStyle'))
412
413 if 1:
414         def conv (str):
415                 str = re.sub ('staffLineLeading',
416                               'staffSpace',
417                               str)
418                 return str
419
420         conversions.append (((1,3,18), conv, 'staffLineLeading -> staffSpace'))
421
422
423 if 1:
424         def conv(str):
425                 if re.search ('\\\\repetitions',str):
426                         sys.stderr.write ('\nNot smart enough to convert \\repetitions')
427                 #       raise FatalConversionError()
428                 return str
429         
430         conversions.append (((1,3,23), conv,
431                 '\\\\repetitions feature dropped'))
432
433
434 if 1:
435         def conv (str):
436                 str = re.sub ('textEmptyDimension *= *##t',
437                               'textNonEmpty = ##f',
438                               str)
439                 str = re.sub ('textEmptyDimension *= *##f',
440                               'textNonEmpty = ##t',
441                               str)
442                 return str
443
444         conversions.append (((1,3,35), conv, 'textEmptyDimension -> textNonEmpty'))
445
446 if 1:
447         def conv (str):
448                 str = re.sub ("([a-z]+)[ \t]*=[ \t]*\\\\musicalpitch *{([- 0-9]+)} *\n",
449                               "(\\1 . (\\2))\n", str)
450                 str = re.sub ("\\\\musicalpitch *{([0-9 -]+)}",
451                               "\\\\musicalpitch #'(\\1)", str)
452                 if re.search ('\\\\notenames',str):
453                         sys.stderr.write ('\nNot smart enough to convert to new \\notenames format')
454                 return str
455
456         conversions.append (((1,3,38), conv, '\musicalpitch { a b c } -> #\'(a b c)'))
457
458 if 1:
459         def conv (str):
460                 def replace (match):
461                         return '\\key %s;' % string.lower (match.group (1))
462                 
463                 str = re.sub ("\\\\key ([^;]+);",  replace, str)
464                 return str
465         
466         conversions.append (((1,3,39), conv, '\\key A ;  ->\\key a;'))
467
468 if 1:
469         def conv (str):
470                 if re.search ('\\[:',str):
471                         sys.stderr.write ('\nNot smart enough to convert to new tremolo format')
472                 return str
473
474         conversions.append (((1,3,41), conv,
475                 '[:16 c4 d4 ] -> \\repeat "tremolo" 2 { c16 d16 }'))
476
477 if 1:
478         def conv (str):
479                 str = re.sub ('Staff_margin_engraver' , 'Instrument_name_engraver', str)
480                 return str
481
482         conversions.append (((1,3,42), conv,
483                 'Staff_margin_engraver deprecated, use Instrument_name_engraver'))
484
485 if 1:
486         def conv (str):
487                 str = re.sub ('note[hH]eadStyle\\s*=\\s*"?(\\w+)"?' , "noteHeadStyle = #'\\1", str)
488                 return str
489
490         conversions.append (((1,3,49), conv,
491                 'noteHeadStyle value: string -> symbol'))
492
493 if 1:
494         def conv (str):
495                 if re.search ('\\\\keysignature', str):
496                         sys.stderr.write ('\nNot smart enough to convert to new tremolo format')
497                 return str
498
499
500         conversions.append (((1,3,58), conv,
501                 'noteHeadStyle value: string -> symbol'))
502
503 if 1:
504         def conv (str):
505                 str = re.sub (r"""\\key *([a-z]+) *;""", r"""\\key \1 \major;""",str);
506                 return str
507         conversions.append (((1,3,59), conv,
508                 '\key X ; -> \key X major; '))
509
510 if 1:
511         def conv (str):
512                 str = re.sub (r'latexheaders *= *"\\\\input ',
513                               'latexheaders = "',
514                               str)
515                 return str
516         conversions.append (((1,3,68), conv, 'latexheaders = "\\input global" -> latexheaders = "global"'))
517
518
519
520
521 # TODO: lots of other syntax change should be done here as well
522 if 1:
523         def conv (str):
524                 str = re.sub ('basicCollisionProperties', 'NoteCollision', str)
525                 str = re.sub ('basicVoltaSpannerProperties' , "VoltaBracket", str)
526                 str = re.sub ('basicKeyProperties' , "KeySignature", str)
527
528                 str = re.sub ('basicClefItemProperties' ,"Clef", str)
529
530
531                 str = re.sub ('basicLocalKeyProperties' ,"Accidentals", str)
532                 str = re.sub ('basicMarkProperties' ,"Accidentals", str)
533                 str = re.sub ('basic([A-Za-z_]+)Properties', '\\1', str)
534
535                 str = re.sub ('Repeat_engraver' ,'Volta_engraver', str)
536                 return str
537         
538         conversions.append (((1,3,92), conv, 'basicXXXProperties -> XXX, Repeat_engraver -> Volta_engraver'))
539
540 if 1:
541         def conv (str):
542                 # Ugh, but meaning of \stemup changed too
543                 # maybe we should do \stemup -> \stemUp\slurUp\tieUp ?
544                 str = re.sub ('\\\\stemup', '\\\\stemUp', str)
545                 str = re.sub ('\\\\stemdown', '\\\\stemDown', str)
546                 str = re.sub ('\\\\stemboth', '\\\\stemBoth', str)
547                 
548                 str = re.sub ('\\\\slurup', '\\\\slurUp', str)
549                 str = re.sub ('\\\\slurboth', '\\\\slurBoth', str)
550                 str = re.sub ('\\\\slurdown', '\\\\slurDown', str)
551                 str = re.sub ('\\\\slurdotted', '\\\\slurDotted', str)
552                 str = re.sub ('\\\\slurnormal', '\\\\slurNoDots', str)          
553                 
554                 str = re.sub ('\\\\shiftoff', '\\\\shiftOff', str)
555                 str = re.sub ('\\\\shifton', '\\\\shiftOn', str)
556                 str = re.sub ('\\\\shiftonn', '\\\\shiftOnn', str)
557                 str = re.sub ('\\\\shiftonnn', '\\\\shiftOnnn', str)
558
559                 str = re.sub ('\\\\onevoice', '\\\\oneVoice', str)
560                 str = re.sub ('\\\\voiceone', '\\\\voiceOne', str)
561                 str = re.sub ('\\\\voicetwo', '\\\\voiceTwo', str)
562                 str = re.sub ('\\\\voicethree', '\\\\voiceThree', str)
563                 str = re.sub ('\\\\voicefour', '\\\\voiceFour', str)
564
565                 # I don't know exactly when these happened...
566                 # ugh, we loose context setting here...
567                 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\stemUp\\\\slurUp\\\\tieUp', str)
568                 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\stemDown\\\\slurDown\\\\tieDown', str)
569                 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\\\stemBoth\\\\slurBoth\\\\tieBoth', str)
570
571                 str = re.sub ('verticalDirection[^=]*= *#?"?(1|(\\\\up))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #1', str)
572                 str = re.sub ('verticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #-1', str)
573                 str = re.sub ('verticalDirection[^=]*= *#?"?(0|(\\\\center))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #0', str)
574                 
575                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\\\1Up', str)
576                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\\\1Down', str)
577                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\\\\\1Both', str)
578
579                 # (lacks capitalisation slur -> Slur)
580                 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\1 \\\\override #\'direction = #1', str)
581                 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\1 \\override #\'direction = #-1', str)
582                 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\1 \\\\override #\'direction = #0', str)
583
584                 ## dynamic..
585                 str = re.sub ('\\\\property *[^ .]*[.]?dynamicDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\dynamicUp', str)
586                 str = re.sub ('\\\\property *[^ .]*[.]?dyn[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\dynamicDown', str)
587                 str = re.sub ('\\\\property *[^ .]*[.]?dyn[^=]*= *#?"?(0|(\\\\center))"?', '\\\\dynamicBoth', str)
588
589                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)Dash[^=]*= *#?"?(0|(""))"?', '\\\\\\1NoDots', str)
590                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)Dash[^=]*= *#?"?([1-9]+)"?', '\\\\\\1Dotted', str)
591
592                 str = re.sub ('\\\\property *[^ .]*[.]?noAutoBeaming[^=]*= *#?"?(0|(""))"?', '\\\\autoBeamOn', str)
593                 str = re.sub ('\\\\property *[^ .]*[.]?noAutoBeaming[^=]*= *#?"?([1-9]+)"?', '\\\\autoBeamOff', str)
594
595
596
597                 return str
598         
599         conversions.append (((1,3,93), conv,
600                 'property definiton case (eg. onevoice -> oneVoice)'))
601
602
603 if 1:
604         def conv (str):
605                 str = re.sub ('ChordNames*', 'ChordNames', str)
606                 if re.search ('\\\\textscript "[^"]* *"[^"]*"', str):
607                         sys.stderr.write ('\nNot smart enough to convert to new \\textscript markup text')
608
609                 str = re.sub ('\\textscript +("[^"]*")', '\\textscript #\\1', str)
610
611                 return str
612         
613         conversions.append (((1,3,97), conv, 'ChordName -> ChordNames'))
614
615
616 # TODO: add lots of these
617         
618 if 1:
619         def conv (str):
620                 str = re.sub ('\\\\property *"?Voice"? *[.] *"?textStyle"? *= *"([^"]*)"', '\\\\property Voice.TextScript \\\\set #\'font-style = #\'\\1', str)
621                 str = re.sub ('\\\\property *"?Lyrics"? *[.] *"?textStyle"? *= *"([^"]*)"', '\\\\property Lyrics.LyricText \\\\set #\'font-style = #\'\\1', str)
622
623                 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?timeSignatureStyle"? *= *"([^"]*)"', '\\\\property \\1.TimeSignature \\\\override #\'style = #\'\\2', str)
624
625                 str = re.sub ('"?timeSignatureStyle"? *= *#?""', 'TimeSignature \\\\override #\'style = ##f', str)
626                 
627                 str = re.sub ('"?timeSignatureStyle"? *= *#?"([^"]*)"', 'TimeSignature \\\\override #\'style = #\'\\1', str)
628                 
629                 str = re.sub ('#\'style *= #*"([^"])"', '#\'style = #\'\\1', str)
630                 
631                 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?horizontalNoteShift"? *= *"?#?([-0-9]+)"?', '\\\\property \\1.NoteColumn \\\\override #\'horizontal-shift = #\\2', str)
632
633                 # ugh
634                 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?flagStyle"? *= *""', '\\\\property \\1.Stem \\\\override #\'flag-style = ##f', str)
635                 
636                 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?flagStyle"? *= *"([^"]*)"', '\\\\property \\1.Stem \\\\override #\'flag-style = #\'\\2', str)
637                 return str
638         
639         conversions.append (((1,3,98), conv, 'CONTEXT.textStyle -> GROB.#font-style '))
640
641 if 1:
642         def conv (str):
643                 str = re.sub ('"?beamAutoEnd_([0-9]*)"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(end 1 \\1 * *) = \\2', str)
644                 str = re.sub ('"?beamAutoBegin_([0-9]*)"? *= *(#\\([^)]*\))', 'autoBeamSettings \\push #\'(begin 1 \\1 * *) = \\2', str)
645                 str = re.sub ('"?beamAutoEnd"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(end * * * *) = \\1', str)
646                 str = re.sub ('"?beamAutoBegin"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(begin * * * *) = \\1', str)
647
648
649                 return str
650         
651         conversions.append (((1,3,102), conv, 'beamAutoEnd -> autoBeamSettings \\push (end * * * *)'))
652
653
654 if 1:
655         def conv (str):
656                 str = re.sub ('\\\\push', '\\\\override', str)
657                 str = re.sub ('\\\\pop', '\\\\revert', str)
658
659                 return str
660         
661         conversions.append (((1,3,111), conv, '\\push -> \\override, \\pop -> \\revert'))
662
663 if 1:
664         def conv (str):
665                 str = re.sub ('LyricVoice', 'LyricsVoice', str)
666                 # old fix
667                 str = re.sub ('Chord[Nn]ames*.Chord[Nn]ames*', 'ChordNames.ChordName', str)
668                 str = re.sub ('Chord[Nn]ames([ \t\n]+\\\\override)', 'ChordName\\1', str)
669                 return str
670         
671         conversions.append (((1,3,113), conv, 'LyricVoice -> LyricsVoice'))
672
673 def regularize_id (str):
674         s = ''
675         lastx = ''
676         for x in str:
677                 if x == '_':
678                         lastx = x
679                         continue
680                 elif x in string.digits:
681                         x = chr(ord (x) - ord ('0')  +ord ('A'))
682                 elif x not in string.letters:
683                         x = 'x'
684                 elif x in string.lowercase and lastx == '_':
685                         x = string.upper (x)
686                 s = s + x
687                 lastx = x
688         return s
689
690 if 1:
691         def conv (str):
692                 
693                 def regularize_dollar_reference (match):
694                         return regularize_id (match.group (1))
695                 def regularize_assignment (match):
696                         return '\n' + regularize_id (match.group (1)) + ' = '
697                 str = re.sub ('\$([^\t\n ]+)', regularize_dollar_reference, str)
698                 str = re.sub ('\n([^ \t\n]+)[ \t]*= *', regularize_assignment, str)
699                 return str
700         
701         conversions.append (((1,3,117), conv, 'identifier names: $!foo_bar_123 -> xfooBarABC'))
702
703
704 if 1:
705         def conv (str):
706                 def regularize_paper (match):
707                         return regularize_id (match.group (1))
708                 
709                 str = re.sub ('(paper_[a-z]+)', regularize_paper, str)
710                 str = re.sub ('sustainup', 'sustainUp', str)
711                 str = re.sub ('nobreak', 'noBreak', str)
712                 str = re.sub ('sustaindown', 'sustainDown', str)
713                 str = re.sub ('sostenutoup', 'sostenutoUp', str)
714                 str = re.sub ('sostenutodown', 'sostenutoDown', str)
715                 str = re.sub ('unachorda', 'unaChorda', str)
716                 str = re.sub ('trechorde', 'treChorde', str)
717         
718                 return str
719         
720         conversions.append (((1,3,120), conv, 'paper_xxx -> paperXxxx, pedalup -> pedalUp.'))
721
722 if 1:
723         def conv (str):
724                 str = re.sub ('drarnChords', 'chordChanges', str)
725                 str = re.sub ('\\musicalpitch', '\\pitch', str)
726                 return str
727         
728         conversions.append (((1,3,122), conv, 'drarnChords -> chordChanges, \\musicalpitch -> \\pitch'))
729
730 if 1:
731         def conv (str):
732                 str = re.sub ('ly-([sg])et-elt-property', 'ly-\\1et-grob-property', str)
733                 return str
734         
735         conversions.append (((1,3,136), conv, 'ly-X-elt-property -> ly-X-grob-property'))
736
737 if 1:
738         def conv (str):
739                 str = re.sub ('point-and-click +#t', 'point-and-click line-column-location', str)
740                 return str
741         
742         conversions.append (((1,3,138), conv, 'point-and-click argument changed to procedure.'))
743
744 if 1:
745         def conv (str):
746                 str = re.sub ('followThread', 'followVoice', str)
747                 str = re.sub ('Thread.FollowThread', 'Voice.VoiceFollower', str)
748                 str = re.sub ('FollowThread', 'VoiceFollower', str)
749                 return str
750         
751         conversions.append (((1,3,138), conv, 'followThread -> followVoice.'))
752
753 if 1:
754         def conv (str):
755                 str = re.sub ('font-point-size', 'font-design-size', str)
756                 return str
757         
758         conversions.append (((1,3,139), conv, 'font-point-size -> font-design-size.'))
759
760 if 1:
761         def conv (str):
762                 str = re.sub ('([a-zA-Z]*)NoDots', '\\1Solid', str)
763                 return str
764         
765         conversions.append (((1,3,141), conv, 'xNoDots -> xSolid'))
766
767 if 1:
768         def conv (str):
769                 str = re.sub ('([Cc])hord([ea])', '\\1ord\\2', str)
770                 return str
771         
772         conversions.append (((1,3,144), conv, 'Chorda -> Corda'))
773
774
775 if 1:
776         def conv (str):
777                 str = re.sub ('([A-Za-z]+)MinimumVerticalExtent', 'MinimumV@rticalExtent', str)
778                 str = re.sub ('([A-Za-z]+)ExtraVerticalExtent', 'ExtraV@rticalExtent', str)
779                 str = re.sub ('([A-Za-z]+)VerticalExtent', 'VerticalExtent', str)
780                 str = re.sub ('ExtraV@rticalExtent', 'ExtraVerticalExtent', str)
781                 str = re.sub ('MinimumV@rticalExtent', 'MinimumVerticalExtent', str)            
782                 return str
783
784         conversions.append (((1,3,145), conv,
785         'ContextNameXxxxVerticalExtent -> XxxxVerticalExtent'))
786
787 if 1:
788         def conv (str):
789                 str = re.sub ('\\\\key[ \t]*;', '\\key \\default;', str)
790                 str = re.sub ('\\\\mark[ \t]*;', '\\mark \\default;', str)
791
792                 # Make sure groups of more than one ; have space before
793                 # them, so that non of them gets removed by next rule
794                 str = re.sub ("([^ \n\t;]);(;+)", "\\1 ;\\2", str)
795                 
796                 # Only remove ; that are not after spaces, # or ;
797                 # Otherwise  we interfere with Scheme comments,
798                 # which is badbadbad.
799                 str = re.sub ("([^ \t;#]);", "\\1", str)
800
801                 return str
802         conversions.append (((1,3,146), conv, 'semicolons removed'))
803
804 if 1:
805         def conv (str):
806                 str = re.sub ('default-neutral-direction', 'neutral-direction',str)
807                 return str
808         conversions.append (((1,3,147), conv, 'default-neutral-direction -> neutral-direction'))
809
810 if 1:
811         def conv (str):
812                 str = re.sub ('\(align', '(axis', str)
813                 str = re.sub ('\(rows', '(columns', str)
814                 return str
815         conversions.append (((1,3,148), conv, '"(align" -> "(axis", "(rows" -> "(columns"'))
816
817
818 if 1:
819         def conv (str):
820                 str = re.sub ('SystemStartDelimiter', 'systemStartDelimiter', str)
821                 return str
822         conversions.append (((1,5,33), conv, 'SystemStartDelimiter -> systemStartDelimiter'))
823
824 if 1:
825         def conv (str):
826                 str = re.sub ('arithmetic-multiplier', 'spacing-increment', str)
827                 str = re.sub ('arithmetic-basicspace', 'shortest-duration-space', str)          
828                 return str
829         
830         conversions.append (((1,5,38), conv, 'SystemStartDelimiter -> systemStartDelimiter'))
831
832
833 if 1:
834         def conv (str):
835         
836                 def func(match):
837                         break_dict = {
838                         "Instrument_name": "instrument-name",
839                         "Left_edge_item": "left-edge",
840                         "Span_bar": "span-bar",
841                         "Breathing_sign": "breathing-sign",
842                         "Staff_bar": "staff-bar",
843                         "Clef_item": "clef",
844                         "Key_item": "key-signature",
845                         "Time_signature": "time-signature",
846                         "Custos": "custos"
847                         }
848                         props =  match.group (1)
849                         for (k,v) in break_dict.items():
850                                 props = re.sub (k, v, props)
851                         return  "breakAlignOrder = #'(%s)" % props
852
853                 str = re.sub ("breakAlignOrder *= *#'\\(([a-z_\n\tA-Z ]+)\\)",
854                               func, str)
855                 return str
856
857         # 40 ?
858         conversions.append (((1,5,40), conv, 'breakAlignOrder property names'))
859         
860
861 if 1:
862         def conv (str):
863                 str = re.sub ('noAutoBeaming *= *##f', 'autoBeaming = ##t', str)
864                 str = re.sub ('noAutoBeaming *= *##t', 'autoBeaming = ##f', str)
865                 return str
866         
867         conversions.append (((1,5,49), conv, 'noAutoBeaming -> autoBeaming'))
868
869 if 1:
870         def conv (str):
871                 str = re.sub ('tuplet-bracket-visibility', 'bracket-visibility', str)
872                 str = re.sub ('tuplet-number-visibility', 'number-visibility', str)             
873                 return str
874         
875         conversions.append (((1,5,52), conv, 'tuplet-X-visibility -> X-visibility'))
876
877 if 1:
878         def conv (str):
879                 str = re.sub ('Pitch::transpose', 'ly-transpose-pitch', str)
880
881                 return str
882         
883         conversions.append (((1,5,56), conv, 'Pitch::transpose -> ly-transpose-pitch'))
884
885 if 1:
886         def conv (str):
887                 str = re.sub ('textNonEmpty *= *##t', "TextScript \\set #'no-spacing-rods = ##f", str)
888                 str = re.sub ('textNonEmpty *= *##f', "TextScript \\set #'no-spacing-rods = ##t", str)
889                 return str
890         
891         conversions.append (((1,5,58), conv, 'deprecate textNonEmpty'))
892
893
894 if 1:
895         def conv (str):
896                 str = re.sub ('MinimumVerticalExtent', 'minimumV@rticalExtent', str)
897                 str = re.sub ('minimumVerticalExtent', 'minimumV@rticalExtent', str)            
898                 str = re.sub ('ExtraVerticalExtent', 'extraV@rticalExtent', str)
899                 str = re.sub ('extraVerticalExtent', 'extraV@rticalExtent', str)                
900                 str = re.sub ('VerticalExtent', 'verticalExtent', str)
901                 str = re.sub ('extraV@rticalExtent', 'extraVerticalExtent', str)
902                 str = re.sub ('minimumV@rticalExtent', 'minimumVerticalExtent', str)            
903                 return str
904
905         conversions.append (((1,5,59), conv,
906         'XxxxVerticalExtent -> xxxVerticalExtent'))
907
908 if 1:
909         def conv (str):
910                 str = re.sub ('visibility-lambda', 'break-visibility', str)
911                 return str
912
913         conversions.append (((1,5,62), conv,
914         'visibility-lambda -> break-visibility'))
915         
916
917 if 1:
918         def conv (str):
919                 if re.search (r'\addlyrics',str) \
920                        and re.search ('automaticMelismata', str)  == None:
921                         sys.stderr.write  ('automaticMelismata is turned on by default since 1.5.67. Please fix this by hand.')
922                         raise FatalConversionError()
923                 return str
924
925         conversions.append (((1,5,67), conv,
926                              'automaticMelismata turned on by default'))
927
928 if 1:
929         def conv (str):
930                 str = re.sub ('ly-set-grob-property([^!])', 'ly-set-grob-property!\1', str)
931                 str = re.sub ('ly-set-mus-property([^!])', 'ly-set-mus-property!\1', str)               
932                 return str
933         
934         conversions.append (((1,5,68), conv, 'ly-set-X-property -> ly-set-X-property!'))
935
936 if 1:
937         def conv (str):
938                 str = re.sub ('extent-X', 'X-extent', str)
939                 str = re.sub ('extent-Y', 'Y-extent', str)              
940                 return str
941         
942         conversions.append (((1,5,71), conv, 'extent-[XY] -> [XY]-extent'))
943
944
945 if 1:
946         def conv (str):
947                 str = re.sub ("""#\(set! +point-and-click +line-column-location\)""",
948                               """#(set-point-and-click! \'line-column)""", str)
949                 str = re.sub ("""#\(set![ \t]+point-and-click +line-location\)""",
950                               '#(set-point-and-click! \'line)', str)
951                 str = re.sub ('#\(set! +point-and-click +#f\)',
952                               '#(set-point-and-click! \'none)', str)
953                 return str
954         
955         conversions.append (((1,5,72), conv, 'set! point-and-click -> set-point-and-click!'))
956
957
958 if 1:
959         def conv (str):
960                 str = re.sub ('flag-style', 'stroke-style', str)
961                 str = re.sub (r"""Stem([ ]+)\\override #'style""", r"""Stem \\override #'flag-style""", str);
962                 str = re.sub (r"""Stem([ ]+)\\set([ ]+)#'style""", r"""Stem \\set #'flag-style""", str);
963                 return str
964         
965         conversions.append (((1,6,5), conv, 'Stems: flag-style -> stroke-style; style -> flag-style'))
966
967
968 if 1:
969         def subst_req_name (match):
970                 return "(make-music-by-name \'%sEvent)" % regularize_id (match.group(1))
971
972         def conv (str):
973                 str = re.sub ('\\(ly-make-music *\"([A-Z][a-z_]+)_req\"\\)', subst_req_name, str)
974                 str = re.sub ('Request_chord', 'EventChord', str)
975                 return str
976         
977         conversions.append (((1,7,1), conv, 'ly-make-music foo_bar_req -> make-music-by-name FooBarEvent'))
978
979
980 if 1:
981         spanner_subst ={
982                 "text" : 'TextSpanEvent',
983                 "decrescendo" : 'DecrescendoEvent',
984                 "crescendo" : 'CrescendoEvent',
985                 "Sustain" : 'SustainPedalEvent',
986                 "slur" : 'SlurEvent',
987                 "UnaCorda" : 'UnaCordaEvent',
988                 "Sostenuto" : 'SostenutoEvent',
989                 }
990         def subst_ev_name (match):
991                 stype = 'STOP'
992                 if re.search ('start', match.group(1)):
993                         stype= 'START'
994
995                 mtype = spanner_subst[match.group(2)]
996                 return "(make-span-event '%s %s)" % (mtype , stype)
997
998         def subst_definition_ev_name(match):
999                 return ' = #%s' % subst_ev_name (match)
1000         def subst_inline_ev_name (match):
1001                 s = subst_ev_name (match)
1002                 return '#(ly-export %s)' % s
1003         def subst_csp_definition (match):
1004                 return ' = #(make-event-chord (list %s))' % subst_ev_name (match)
1005         def subst_csp_inline (match):
1006                 return '#(ly-export (make-event-chord (list %s)))' % subst_ev_name (match)
1007                 
1008         def conv (str):
1009                 str = re.sub (r' *= *\\spanrequest *([^ ]+) *"([^"]+)"', subst_definition_ev_name, str)
1010                 str = re.sub (r'\\spanrequest *([^ ]+) *"([^"]+)"', subst_inline_ev_name, str)
1011                 str = re.sub (r' *= *\\commandspanrequest *([^ ]+) *"([^"]+)"', subst_csp_definition, str)
1012                 str = re.sub (r'\\commandspanrequest *([^ ]+) *"([^"]+)"', subst_csp_inline, str)
1013                 str = re.sub (r'ly-id ', 'ly-import ', str)
1014
1015                 str = re.sub (r' *= *\\script "([^"]+)"', ' = #(make-articulation "\\1")', str)
1016                 str = re.sub (r'\\script "([^"]+)"', '#(ly-export (make-articulation "\\1"))', str)
1017                 return str
1018
1019         conversions.append (((1,7,2), conv, '\\spanrequest -> #(make-span-event .. ), \script -> #(make-articulation .. )'))
1020
1021 if 1:
1022         def conv(str):
1023                 str = re.sub (r'\(ly-', '(ly:', str)
1024
1025                 changed = [
1026                         r'duration\?',
1027                         r'font-metric\?',
1028                         r'molecule\?',
1029                         r'moment\?',
1030                         r'music\?',
1031                         r'pitch\?',
1032                         'make-duration',
1033                         'music-duration-length',
1034                         'duration-log',
1035                         'duration-dotcount',
1036                         'intlog2',
1037                         'duration-factor',
1038                         'transpose-key-alist',
1039                         'get-system',
1040                         'get-broken-into',
1041                         'get-original',
1042                         'set-point-and-click!',
1043                         'make-moment',
1044                         'make-pitch',
1045                         'pitch-octave',
1046                         'pitch-alteration',
1047                         'pitch-notename',
1048                         'pitch-semitones',
1049                         r'pitch<\?',
1050                         r'dir\?',
1051                         'music-duration-compress',
1052                         'set-point-and-click!'
1053                         ]
1054
1055                 origre = r'\b(%s)' % string.join (changed, '|')
1056                 
1057                 str = re.sub (origre, r'ly:\1',str)
1058                 str = re.sub ('set-point-and-click!', 'set-point-and-click', str)
1059                 
1060                 return str
1061         
1062         conversions.append (((1,7,3), conv, 'ly- -> ly:'))
1063
1064 if 1:
1065         def conv(str):
1066                 if re.search ('new-chords-done',str):
1067                         return str
1068                 
1069                 str = re.sub (r'<<', '< <', str)
1070                 str = re.sub (r'>>', '> >', str)
1071                 return str
1072         
1073         conversions.append (((1,7,4), conv, '<< >> -> < <  > >'))
1074
1075 if 1:
1076         def conv(str):
1077                 str = re.sub (r"\\transpose", r"\\transpose c'", str)
1078                 str = re.sub (r"\\transpose c' *([a-z]+)'", r"\\transpose c \1", str)
1079                 return str
1080         conversions.append (((1,7,5), conv, '\\transpose TO -> \\transpose FROM  TO'))
1081
1082 if 1:
1083         def conv(str):
1084                 kws =   ['arpeggio',
1085                          'sustainDown',
1086                          'sustainUp',
1087                          'f',
1088                          'p',
1089                          'pp',
1090                          'ppp',
1091                          'fp',
1092                          'ff',
1093                          'mf',
1094                          'mp',
1095                          'sfz',
1096                          ]
1097
1098                 origstr = string.join (kws, '|')
1099                 str = re.sub (r'([^_^-])\\(%s)\b' % origstr, r'\1-\\\2', str)
1100                 return str
1101         conversions.append (((1,7,6), conv, 'note\\script -> note-\script'))
1102
1103
1104 if 1:
1105         def conv(str):
1106                 str = re.sub (r"\\property *ChordNames *\. *ChordName *\\(set|override) *#'style *= *#('[a-z]+)",
1107                               r"#(set-chord-name-style \2)", str)
1108                 str = re.sub (r"\\property *ChordNames *\. *ChordName *\\revert *#'style",
1109                               r"", str)
1110                 return str
1111         conversions.append (((1,7,10), conv, "\property ChordName #'style -> #(set-chord-name-style 'style)"))
1112         
1113
1114
1115 if 1:
1116         def conv(str):
1117                 str = re.sub (r"ly:transpose-pitch", "ly:pitch-transpose", str)
1118                 
1119                 return str
1120         conversions.append (((1,7,11), conv, "transpose-pitch -> pitch-transpose"))
1121
1122 if 1:
1123         def conv(str):
1124                 str = re.sub (r"ly:get-molecule-extent", "ly:molecule-get-extent", str)
1125                 str = re.sub (r"ly:set-molecule-extent!", "ly:molecule-set-extent!", str)
1126                 str = re.sub (r"ly:add-molecule", "ly:molecule-add", str)
1127                 str = re.sub (r"ly:combine-molecule-at-edge", "ly:molecule-combine-at-edge", str)
1128                 str = re.sub (r"ly:align-to!", "ly:molecule-align-to!", str)
1129                 
1130                 return str
1131         
1132         conversions.append (((1,7,13), conv, "ly:XX-molecule-YY -> ly:molecule-XX-YY")) 
1133
1134 if 1:
1135         def conv(str):
1136                 str = re.sub (r"linewidth *= *-[0-9.]+ *(\\mm|\\cm|\\in|\\pt)?", 'raggedright = ##t', str )
1137                 return str
1138         
1139         conversions.append (((1,7,15), conv, "linewidth = -1 -> raggedright = ##t"))    
1140
1141 if 1:
1142         def conv(str):
1143                 str = re.sub ("divisiomaior",
1144                               "divisioMaior", str)
1145                 str = re.sub ("divisiominima",
1146                               "divisioMinima", str)
1147                 str = re.sub ("divisiomaxima",
1148                               "divisioMaxima", str)
1149                 return str
1150         
1151         conversions.append (((1,7,16), conv, "divisiomaior -> divisioMaior"))
1152
1153 if 1:
1154         def conv(str):
1155                 str = re.sub ("Skip_req_swallow_translator",
1156                               "Skip_event_swallow_translator", str)
1157                 return str
1158         
1159         conversions.append (((1,7,17), conv, "Skip_req  -> Skip_event"))
1160
1161 if 1:
1162         def conv(str):
1163                 str = re.sub ("groupOpen",
1164                               "startGroup", str)
1165                 str = re.sub ("groupClose",
1166                               "stopGroup", str)
1167                 str = re.sub ("#'outer",
1168                               "#'enclose-bounds", str)
1169
1170                 return str
1171         
1172         conversions.append (((1,7,18), conv,
1173                              """groupOpen/Close  -> start/stopGroup,
1174                              #'outer  -> #'enclose-bounds
1175                              """))
1176
1177 if 1:
1178         def conv(str):
1179                 if re.search( r'\\GraceContext', str):
1180                         sys.stderr.write ("GraceContext has been removed")
1181                         sys.stderr.write ("please use #(add-to-grace-init .. )")
1182                         raise FatalConversionError()
1183
1184                 str = re.sub ('HaraKiriStaffContext', 'RemoveEmptyStaffContext', str)
1185                 return str
1186         
1187         conversions.append (((1,7,19), conv,"remove GraceContext"))
1188
1189
1190
1191 if 1:
1192         def conv(str):
1193                 str = re.sub (
1194                         r"(set|override|revert) *#'type",
1195                         r"\1 #'style",
1196                         str)
1197                 return str
1198         
1199         conversions.append (((1,7,22), conv,"#'type -> #'style"))
1200
1201 if 1:
1202         def conv(str):
1203                 str = re.sub (
1204                         "barNonAuto *= *##t",
1205                         "automaticBars = ##f",
1206                         str)
1207                 str = re.sub (
1208                         "barNonAuto *= *##f",
1209                         "automaticBars = ##t",
1210                         str)
1211                 return str
1212         
1213         conversions.append (((1,7,23), conv,"barNonAuto -> automaticBars"))
1214         
1215
1216 if 1:
1217         def conv(str):
1218                 if re.search( r'-(start|stop)Cluster', str):
1219                         sys.stderr.write ("""Cluster syntax has been changed.
1220 Please refer to the manual for details, and convert manually.
1221 """)
1222                         
1223                         raise FatalConversionError()
1224
1225                 return str
1226         
1227         conversions.append (((1,7,24), conv,"cluster syntax"))
1228
1229 if 1:
1230         def conv(str):
1231                 str = re.sub (r"\\property *Staff\.(Sustain|Sostenuto|UnaCorda)Pedal *\\(override|set) *#'pedal-type *",
1232                                 r"\property Staff.pedal\1Style ", str)
1233                 str = re.sub (r"\\property *Staff\.(Sustain|Sostenuto|UnaCorda)Pedal *\\revert *#'pedal-type", '', str)
1234                 return str
1235         
1236         conversions.append (((1,7,28), conv,"new Pedal style syntax"))
1237
1238
1239
1240 if 1:
1241
1242         def sub_chord (m):
1243                 str = m.group(1)
1244
1245                 origstr =  '<%s>' % str
1246                 if re.search (r'\\\\', str):
1247                         return origstr
1248
1249                 if re.search (r'\\property', str):
1250                         return origstr
1251
1252                 if re.match (r'^\s*\)?\s*\\[a-zA-Z]+', str):
1253                         return origstr
1254
1255                 durs = []
1256                 def sub_durs (m, durs = durs):
1257                         durs.append(m.group(2))
1258                         return m.group (1)
1259
1260                 str = re.sub (r"([a-z]+[,'!? ]*)([0-9]+\.*)", sub_durs, str)
1261                 dur_str = ''
1262
1263                 for d in durs:
1264                         if dur_str == '':
1265                                 dur_str = d
1266                         if dur_str <> d:
1267                                 return '<%s>' % m.group (1)
1268
1269                 pslur_strs = ['']
1270                 dyns = ['']
1271                 slur_strs = ['']
1272
1273                 last_str = ''
1274                 while last_str <> str:
1275                         last_str = str
1276
1277                         def sub_tremolos (m, slur_strs = slur_strs):
1278                                 tr = m.group (2)
1279                                 if tr not in slur_strs:
1280                                         slur_strs.append (tr)
1281                                 return  m.group (1)
1282                         
1283                         str = re.sub (r"([a-z]+[',!? ]*)(:[0-9]+)",
1284                                       sub_tremolos, str)
1285
1286                         def sub_dyn_end (m, dyns = dyns):
1287                                 dyns.append (' \!')
1288                                 return ' ' + m.group(2)
1289
1290                         str = re.sub (r'(\\!)\s*([a-z]+)', sub_dyn_end, str)
1291                         def sub_slurs(m, slur_strs = slur_strs):
1292                                 if '-)' not in slur_strs:
1293                                         slur_strs.append (')')
1294                                 return m.group(1)
1295                         
1296                         def sub_p_slurs(m, slur_strs = slur_strs):
1297                                 if '-\)' not in slur_strs:
1298                                         slur_strs.append ('\)')
1299                                 return m.group(1)
1300                         
1301                         str = re.sub (r"\)[ ]*([a-z]+)", sub_slurs, str)
1302                         str = re.sub (r"\\\)[ ]*([a-z]+)", sub_p_slurs, str)
1303                         def sub_begin_slurs(m, slur_strs = slur_strs):
1304                                 if '-(' not in slur_strs:
1305                                         slur_strs.append ('(')
1306                                 return m.group(1)
1307                         
1308                         str = re.sub (r"([a-z]+[,'!?0-9 ]*)\(",
1309                                       sub_begin_slurs, str)
1310                         def sub_begin_p_slurs(m, slur_strs = slur_strs):
1311                                 if '-\(' not in slur_strs:
1312                                         slur_strs.append ('\(')
1313                                 return m.group(1)
1314
1315                         str = re.sub (r"([a-z]+[,'!?0-9 ]*)\\\(",
1316                                 sub_begin_p_slurs, str)
1317
1318                         def sub_dyns (m, slur_strs = slur_strs):
1319                                 s = m.group(0)
1320                                 if s == '@STARTCRESC@':
1321                                         slur_strs.append ("\\<")
1322                                 elif s == '@STARTDECRESC@':
1323                                         slur_strs.append ("\\>")
1324                                 elif s == r'-?\\!':
1325                                         slur_strs.append ('\\!')
1326                                 return ''
1327
1328                         str = re.sub (r'@STARTCRESC@', sub_dyns, str)
1329                         str = re.sub (r'-?\\!', sub_dyns, str)
1330
1331                         def sub_articulations (m, slur_strs = slur_strs):
1332                                 a = m.group(1)
1333                                 if a not in slur_strs:
1334                                         slur_strs.append (a)
1335                                 return ''
1336
1337                         str = re.sub (r"([_^-]\@ACCENT\@)", sub_articulations,
1338                                       str)
1339                         str = re.sub (r"([_^-]\\[a-z]+)", sub_articulations,
1340                                       str)
1341                         str = re.sub (r"([_^-][>_.+|^-])", sub_articulations,
1342                                       str)
1343                         str = re.sub (r'([_^-]"[^"]+")', sub_articulations,
1344                                       str)
1345
1346                         def sub_pslurs(m, slur_strs = slur_strs):
1347                                 slur_strs.append (' \\)')
1348                                 return m.group(1)
1349                         str = re.sub (r"\\\)[ ]*([a-z]+)", sub_pslurs, str)
1350
1351                 ## end of while <>
1352
1353                 suffix = string.join (slur_strs, '') + string.join (pslur_strs,
1354                                                                     '') \
1355                          + string.join (dyns, '')
1356
1357                 return '@STARTCHORD@%s@ENDCHORD@%s%s' % (str , dur_str, suffix)
1358
1359
1360
1361         def sub_chords (str):
1362                 simend = '>'
1363                 simstart = '<'
1364                 chordstart = '<<'
1365                 chordend = '>>'
1366                 marker_str = '%% new-chords-done %%'
1367
1368                 if re.search (marker_str,str):
1369                         return str
1370                 str = re.sub ('<<', '@STARTCHORD@', str)
1371                 str = re.sub ('>>', '@ENDCHORD@', str)
1372                 
1373                 str = re.sub (r'\\<', '@STARTCRESC@', str)
1374                 str = re.sub (r'\\>', '@STARTDECRESC@', str)
1375                 str = re.sub (r'([_^-])>', r'\1@ACCENT@', str)
1376                 str = re.sub (r'<([^<>{}]+)>', sub_chord, str)
1377
1378                 # add dash: -[, so that [<<a b>> c d] becomes
1379                 #                      <<a b>>-[ c d]
1380                 # and gets skipped by articulation_substitute
1381                 str = re.sub (r'\[ *(@STARTCHORD@[^@]+@ENDCHORD@[0-9.]*)',
1382                               r'\1-[', str)
1383                 str = re.sub (r'\\! *(@STARTCHORD@[^@]+@ENDCHORD@[0-9.]*)',
1384                               r'\1-\\!', str)
1385                 
1386                 str = re.sub (r'<([^?])', r'%s\1' % simstart, str)
1387                 str = re.sub (r'>([^?])', r'%s\1' % simend,  str)
1388                 str = re.sub ('@STARTCRESC@', r'\\<', str)
1389                 str = re.sub ('@STARTDECRESC@', r'\\>' ,str)
1390                 str = re.sub (r'\\context *Voice *@STARTCHORD@',
1391                               '@STARTCHORD@', str)
1392                 str = re.sub ('@STARTCHORD@', chordstart, str)
1393                 str = re.sub ('@ENDCHORD@', chordend, str)
1394                 str = re.sub (r'@ACCENT@', '>', str)
1395                 return str
1396
1397         def text_markup (str):
1398                 str = re.sub (r"""([-_^]) *# *' *\( *music *(\"[^"]*\") *\)""",
1399                                 r"\1\\markup { \\musicglyph #\2 }", str)
1400                 str = re.sub (r"""([-_^]) *# *' *\( *([a-z]+) *([^()]*)\)""",
1401                                 r"\1\\markup { \\\2 \3 }", str)
1402                 str = re.sub (r"""\\mark *# *' *\( *music *(\"[^"]*\") *\)""",
1403                                 r"\\mark \\markup { \\musicglyph #\1 }", str)
1404                 str = re.sub (r"""\\mark *# *' *\( *([a-z]+) *([^()]*)\)""",
1405                                 r"\\mark \\markup { \\\1 \2 }", str)
1406                 return str      
1407
1408         def articulation_substitute (str):
1409                 str = re.sub (r"""([^-])\[ *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1410                               r"\1 \2[", str)
1411                 str = re.sub (r"""([^-])\\\) *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1412                               r"\1 \2\\)", str)
1413                 str = re.sub (r"""([^-\\])\) *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1414                               r"\1 \2)", str)
1415                 str = re.sub (r"""([^-])\\! *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1416                               r"\1 \2\\!", str)
1417                 return str
1418         
1419         def conv_relative(str):
1420                 if re.search (r"\\relative", str):
1421                         str= "#(ly:set-option 'old-relative)\n" + str
1422
1423                 return str
1424         
1425         def conv (str):
1426                 str = re.sub (r"#'\(\)", "@SCM_EOL@", str)
1427                 str =  conv_relative (str)
1428                 str = sub_chords (str)
1429
1430                 str = text_markup (str)
1431                 str = articulation_substitute (str)
1432                 str = re.sub ("@SCM_EOL@", "#'()", str)
1433                 
1434                 return str
1435         
1436         conversions.append (((1,9,0), conv, """New relative mode,
1437 Postfix articulations, new text markup syntax, new chord syntax."""))
1438
1439 if 1:
1440         def conv (str):
1441                 if re.search ("font-style",str):
1442                         sys.stderr.write ("font-style is deprecated. Please remove.")
1443                         raise FatalConversionError()
1444                         
1445                 str = re.sub (r'-\\markup', r'@\\markup', str)
1446                 str = re.sub (r'-\\', r'\\', str)
1447                 str = re.sub (r'-\)', ')', str)
1448                 str = re.sub (r'-\(', '(', str)
1449                 str = re.sub ('-\[', '[', str)
1450                 str = re.sub ('-\]', ']', str)
1451                 str = re.sub ('-~', '~', str)
1452                 str = re.sub (r'@\\markup', r'-\\markup', str)
1453                 return str
1454
1455         conversions.append (((1,9,1), conv, """Remove - before articulation"""))
1456 if 1:
1457         def conv (str):
1458                 str = re.sub ('ly:set-context-property',
1459                               'ly:set-context-property!', str)
1460                 str = re.sub ('\\\\newcontext', '\\\\new', str)
1461                 str = re.sub ('\\\\grace[\t\n ]*([^{ ]+)',
1462                               r'\\grace { \1 }', str)
1463                 str = re.sub ("\\\\grace[\t\n ]*{([^}]+)}",
1464                               r"""\\grace {
1465   \\property Voice.Stem \\override #'stroke-style = #"grace"
1466   \1
1467   \\property Voice.Stem \\revert #'stroke-style }
1468 """, str)
1469                 
1470                 return str
1471         
1472         conversions.append (((1,9,2), conv, """\\newcontext -> \\new"""))
1473
1474 if 1:
1475         def conv (str):
1476                 str = re.sub ('accacciatura',
1477                               'acciaccatura', str)
1478
1479                 if re.search ("context-spec-music", str):
1480                         sys.stderr.write ("context-spec-music takes a symbol for the context now. Update by hand.")
1481                                         
1482                         raise FatalConversionError()
1483                 
1484                 str = re.sub ('fingerHorizontalDirection *= *#(LEFT|-1)',
1485                               "fingeringOrientations = #'(up down left)", str)
1486                 str = re.sub ('fingerHorizontalDirection *= *#(RIGHT|1)',
1487                               "fingeringOrientations = #'(up down right)", str)
1488
1489                 return str
1490         
1491         conversions.append (((1,9,3), conv,
1492                              """\\acciaccatura misspelling, fingerHorizontalDirection -> fingeringOrientations"""))
1493
1494
1495 def conv (str):
1496         if re.search ('\\figures', str):
1497                 sys.stderr.write ("Warning: attempting automatic \\figures conversion.  Check results!");
1498                 
1499         
1500         def figures_replace (m):
1501                 s = m.group (1)
1502                 s = re.sub ('<', '@FIGOPEN@',s)
1503                 s = re.sub ('>', '@FIGCLOSE@',s)
1504                 return '\\figures { %s }' % s
1505         
1506         str = re.sub (r'\\figures[ \t\n]*{([^}]+)}', figures_replace, str)
1507         str = re.sub (r'\\<', '@STARTCRESC@', str)
1508         str = re.sub (r'\\>', '@STARTDECRESC@', str)
1509         str = re.sub (r'([-^_])>', r'\1@ACCENT@', str)
1510         str = re.sub (r'<<', '@STARTCHORD@', str)
1511         str = re.sub (r'>>', '@ENDCHORD@', str)
1512         str = re.sub (r'>', '@ENDSIMUL@', str)
1513         str = re.sub (r'<', '@STARTSIMUL@', str)
1514         str = re.sub ('@STARTDECRESC@', '\\>', str)
1515         str = re.sub ('@STARTCRESC@', '\\<', str)
1516         str = re.sub ('@ACCENT@', '>', str)
1517         str = re.sub ('@ENDCHORD@', '>', str)
1518         str = re.sub ('@STARTCHORD@', '<', str)
1519         str = re.sub ('@STARTSIMUL@', '<<', str)
1520         str = re.sub ('@ENDSIMUL@', '>>', str)
1521         str = re.sub ('@FIGOPEN@', '<', str)
1522         str = re.sub ('@FIGCLOSE@', '>', str)
1523
1524         return str
1525
1526 conversions.append (((1,9,4), conv, 'Swap < > and << >>'))
1527
1528
1529 def conv (str):
1530         str = re.sub ('HaraKiriVerticalGroup', 'RemoveEmptyVerticalGroup', str)
1531
1532         return str
1533
1534 conversions.append (((1,9,5), conv, 'HaraKiriVerticalGroup -> RemoveEmptyVerticalGroup'))
1535
1536 def conv (str):
1537         if re.search ("ly:get-font", str) :
1538                 sys.stderr.write (r"(ly:get-font foo ..)  has been replaced by" + \
1539                                   " (ly:paper-get-font (ly:grob-get-paper foo) .. ).\n" +\
1540                                   "please update manually.")
1541                 
1542                 raise FatalConversionError()
1543         
1544         if re.search ("\\pitch *#", str) :
1545                 sys.stderr.write (r"\\pitch has been deprecated. " +\
1546                                   " Use Scheme code to construct arbitrary note events.")
1547                 
1548                 raise FatalConversionError()
1549         
1550         return str
1551                 
1552
1553 conversions.append (((1,9,6), conv, 'ly:get-font deprecated.'))
1554
1555 def conv (str):
1556         def sub_alteration (m):
1557                 alt = m.group (3)
1558                 alt = {
1559                         '-1': 'FLAT',
1560                         '-2': 'DOUBLE-FLAT',
1561                         '0': 'NATURAL',
1562                         '1': 'SHARP',
1563                         '2': 'DOUBLE-SHARP',
1564                         }[alt]
1565                 
1566                 return '(ly:make-pitch %s %s %s)' % (m.group(1), m.group (2),
1567                                                      alt)
1568         
1569         str =re.sub ("\\(ly:make-pitch *([0-9-]+) *([0-9-]+) *([0-9-]+) *\\)",
1570                      sub_alteration, str)
1571
1572
1573         str = re.sub ("ly:verbose", "ly:get-option 'verbose", str)
1574
1575         m= re.search ("\\\\outputproperty #([^#]+)[\t\n ]*#'([^ ]+)", str)
1576         if m:
1577                 sys.stderr.write (\
1578                         r"""\outputproperty found,
1579 Please hand-edit, using
1580
1581   \applyoutput #(outputproperty-compatibility %s '%s <GROB PROPERTY VALUE>)
1582
1583 as a substitution text.""" % (m.group (1), m.group (2)) )
1584                 raise FatalConversionError ()
1585
1586         if re.search ("ly:(make-pitch|pitch-alteration)", str) \
1587                or re.search ("keySignature", str):
1588                 sys.stderr.write (
1589 """The alteration field of Scheme pitches was multiplied by 2
1590 to support quarter tone accidentals. You have to edit the following constructs by hand:
1591
1592 * calls of  ly:make-pitch and ly:pitch-alteration
1593 * keySignature settings made with \property
1594 """)
1595                 raise FatalConversionError ()
1596         
1597         return str
1598 conversions.append (((1,9,7), conv,
1599                      '''use symbolic constants for alterations,
1600 remove \\outputproperty, move ly:verbose into ly:get-option'''))
1601
1602
1603 def conv (str):
1604         if re.search ("dash-length",str):
1605                 sys.stderr.write ("""dash-length has been removed. Use dash-fraction instead.""")
1606                 raise FatalConversionError()
1607         return str
1608
1609 conversions.append (((1,9,8), conv, """dash-length -> dash-fraction"""))
1610
1611
1612 def conv (str):
1613         def func(match):
1614                 return "#'font-size = #%d" % (2*string.atoi (match.group (1))) 
1615                 
1616         str =re.sub (r"#'font-relative-size\s*=\s*#\+?([0-9-]+)", func, str)
1617         str =re.sub (r"#'font-family\s*=\s*#'ancient",
1618                      r"#'font-family = #'music", str)
1619         
1620         return str
1621
1622 conversions.append (((2,1,1), conv, """font-relative-size -> font-size"""))
1623
1624 def conv (str):
1625         str =re.sub (r"ly:get-music-length", "ly:music-length", str)
1626         return str
1627
1628 conversions.append (((2,1,2), conv, """ly:get-music-length -> ly:music-length"""))
1629
1630 def conv (str):
1631         str =re.sub (r"\.\s+stz=", ". instr ", str)
1632         return str
1633
1634 conversions.append (((2,1,3), conv, """stanza -> instrument"""))
1635
1636 def conv (str):
1637         def func (match):
1638                 c = match.group (1)
1639                 b = match.group (2)
1640                 
1641                 if b == 't':
1642                         if c == 'Score':
1643                                 return ''
1644                         else:
1645                                 return r" \property %s.melismaBusyProperties \unset"  % c
1646                 elif b == 'f':
1647                         return r"\property %s.melismaBusyProperties = #'(melismaBusy)"  % c
1648                 
1649         str =re.sub (r"\\property ([a-zA-Z]+)\s*\.\s*automaticMelismata\s*=\s*##([ft])", func, str)
1650         return str
1651
1652 conversions.append (((2,1,4), conv, """removal of automaticMelismata; use melismaBusyProperties instead."""))
1653
1654
1655
1656 def conv (str):
1657         str =re.sub (r"\\translator\s+([a-zA-Z]+)", r"\\change \1", str)
1658         return str
1659
1660 conversions.append (((2,1,7), conv, """\\translator Staff -> \\change Staff"""))
1661
1662 def conv (str):
1663         str =re.sub (r"\\newaddlyrics", r"\\lyricsto", str)
1664         return str
1665
1666 conversions.append (((2,1,10), conv, """\\newaddlyrics -> \\lyricsto"""))
1667
1668 def conv (str):
1669         str = re.sub (r'\\include\s*"paper([0-9]+)(-init)?.ly"',
1670                       r"#(set-staff-size \1)", str)
1671
1672         def sub_note (match):
1673                 dur = ''
1674                 log = string.atoi (match.group (1))
1675                 dots = string.atoi (match.group (2))
1676                 
1677                 if log >= 0:
1678                         dur = '%d' % (1 << log)
1679                 else:
1680                         dur = { -1 : 'breve',
1681                                 -2 : 'longa',
1682                                 -3 : 'maxima'}[log]
1683
1684                 dur += ('.' * dots)
1685                 
1686                 return r'\note #"%s" #%s' % (dur, match.group (3))
1687         
1688         str = re.sub (r'\\note\s+#([0-9-]+)\s+#([0-9]+)\s+#([0-9.-]+)',
1689                       sub_note, str)
1690         return str
1691
1692 conversions.append (((2,1,11), conv, """\\include "paper16.ly" -> #(set-staff-size 16)
1693 \\note #3 #1 #1 -> \\note #"8." #1
1694 """))
1695
1696
1697 def conv (str):
1698         str =re.sub (r"OttavaSpanner", r"OttavaBracket", str)
1699         return str
1700
1701 conversions.append (((2,1,12), conv, """OttavaSpanner -> OttavaBracket"""))
1702
1703
1704 def conv (str):
1705         str =re.sub (r"\(set-staff-size ", r"(set-global-staff-size ", str)
1706         return str
1707
1708 conversions.append (((2,1,13), conv, """set-staff-size -> set-global-staff-size"""))
1709
1710 def conv (str):
1711         str =re.sub (r"#'style\s*=\s*#'dotted-line",
1712                      r"#'dash-fraction = #0.0 ", str)
1713         return str
1714
1715 conversions.append (((2,1,14), conv, """style = dotted -> dash-fraction = 0"""))
1716
1717 def conv (str):
1718         str =re.sub (r'LyricsVoice\s*\.\s*instrument\s*=\s*("[^"]*")',
1719                      r'LyricsVoice . vocalName = \1', str)
1720         
1721         str =re.sub (r'LyricsVoice\s*\.\s*instr\s*=\s*("[^"]*")',
1722                      r'LyricsVoice . vocNam = \1', str)
1723         return str
1724
1725 conversions.append (((2,1,15), conv, """LyricsVoice . instr(ument) -> vocalName"""))
1726
1727 def conv (str):
1728         def sub_acc (m):
1729                 d = {
1730                 '4': 'doublesharp',
1731                 '3': 'threeqsharp',
1732                 '2': 'sharp',
1733                 '1': 'semisharp',
1734                 '0': 'natural',
1735                 '-1': 'semiflat',
1736                 '-2': 'flat',
1737                 '-3': 'threeqflat',
1738                 '-4': 'doubleflat'}
1739                 return '\\%s' %  d[m.group (1)]
1740                      
1741         str = re.sub (r'\\musicglyph\s*#"accidentals-([0-9-]+)"',
1742                       sub_acc, str)
1743         return str
1744
1745 conversions.append (((2,1,16), conv, """\\musicglyph #"accidentals-NUM" -> \\sharp/flat/etc."""))
1746
1747
1748 def conv (str):
1749
1750         if re.search (r'\\partcombine', str):
1751                 sys.stderr.write ('Warning: \\partcombine has been changed. '
1752                                   +'Check conversion manually!')
1753
1754                 raise FatalConversionError()
1755
1756         # this rule doesn't really work,
1757         # too lazy to figure out why.
1758         str = re.sub (r'\\context\s+Voice\s*=\s*one\s*\\partcombine\s+Voice\s*\\context\s+Thread\s*=\s*one(.*)\s*'
1759                       + r'\\context\s+Thread\s*=\s*two',
1760                       '\\\\newpartcombine\n\\1\n', str)
1761         
1762         
1763         return str
1764
1765 conversions.append (((2,1,17), conv, """\\partcombine syntax change to \\newpartcombine"""))
1766
1767
1768 def conv (str):
1769         str = re.sub (r'\\newpartcombine', r'\\partcombine', str)
1770         str = re.sub (r'\\autochange\s+Staff', r'\\autochange ', str)
1771         return str
1772
1773 conversions.append (((2,1,18), conv, """\\newpartcombine -> \\partcombine,
1774 \\autochange Staff -> \\autochange
1775 """))
1776
1777
1778
1779
1780 def conv (str):
1781         str = re.sub (r'\\include "drumpitch-init.ly"','', str)
1782         str = re.sub (r'\\pitchnames ','pitchnames = ', str)
1783         str = re.sub (r'\\chordmodifiers ','chordmodifiers = ', str)
1784         str = re.sub (r'\bdrums\b\s*=','drumContents = ', str)
1785         str = re.sub (r'\\drums\b','\\drumContents ', str)
1786         
1787
1788         if re.search ('drums->paper', str):
1789                 sys.stderr.write ("\nDrum notation found. Check file manually!")
1790                 
1791         str = re.sub (r"""\\apply\s+#\(drums->paper\s+'([a-z]+)\)""",
1792                       r"""\property DrumStaff.drumStyleTable = #\1-style""",
1793                       str)
1794
1795         if re.search ('Thread', str):
1796                 sys.stderr.write ("\nThread found. Check file manually!\n");
1797
1798         str = re.sub (r"""(\\once\s*)?\\property\s+Thread\s*\.\s*NoteHead\s*"""
1799                       + r"""\\(set|override)\s*#'style\s*=\s*#'harmonic"""
1800                       + r"""\s+([a-z]+[,'=]*)([0-9]*\.*)"""                   
1801                       ,r"""<\3\\harmonic>\4""", str)
1802
1803         str = re.sub (r"""\\new Thread""", """\context Voice""", str)
1804         str = re.sub (r"""Thread""", """Voice""", str)
1805
1806         if re.search ('\bLyrics\b', str):
1807                 sys.stderr.write ("\nLyrics found. Check file manually!\n");
1808
1809         str = re.sub (r"""LyricsVoice""", r"""L@ricsVoice""", str)
1810         str = re.sub (r"""\bLyrics\b""", r"""LyricsVoice""", str)
1811         str = re.sub (r"""LyricsContext""", r"""LyricsVoiceContext""", str)
1812         str = re.sub (r"""L@ricsVoice""", r"""LyricsVoice""",str)
1813         
1814         
1815         return str
1816
1817 conversions.append (((2,1,19), conv, """Drum notation changes, Removing \\chordmodifiers, \\notenames.
1818 Harmonic notes. Thread context removed. Lyrics context removed."""))
1819
1820 def conv (str):
1821         str = re.sub (r'nonevent-skip', 'skip-music', str)
1822         return str
1823
1824 conversions.append (((2,1,20), conv, """nonevent-skip -> skip-music""" ))
1825
1826 def conv (str):
1827         str = re.sub (r'molecule-callback', 'print-function', str)
1828         str = re.sub (r'brew_molecule', 'print', str)
1829         str = re.sub (r'brew-new-markup-molecule', 'Text_item::print', str)
1830         str = re.sub (r'LyricsVoice', 'Lyrics', str)
1831         str = re.sub (r'tupletInvisible',
1832                       r"TupletBracket \\set #'transparent", str)
1833 #       str = re.sub (r'molecule', 'collage', str)
1834 #molecule -> collage
1835         str = re.sub (r"\\property\s+[a-zA-Z]+\s*\.\s*[a-zA-Z]+\s*"
1836                       + r"\\set\s*#'X-extent-callback\s*=\s*#Grob::preset_extent",
1837                       "", str)
1838
1839         return str
1840
1841 conversions.append (((2,1,21), conv, """molecule-callback -> print-function,
1842 brew_molecule -> print
1843 brew-new-markup-molecule -> Text_item::print
1844 LyricsVoice -> Lyrics
1845 tupletInvisible -> TupletBracket \set #'transparent
1846 Grob::preset_extent removed.
1847 """ ))
1848
1849
1850 def conv (str):
1851         str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\=]+)\s*\\(set|override)',
1852                       r"\\overrid@ \1.\2 ", str)
1853         str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\= ]+)\s*=\s*',
1854                       r'\\s@t \1.\2 = ', str)
1855         str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\= ]+)\s*\\unset',
1856                       r'\\uns@t \1.\2 ', str)
1857         str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\= ]+)\s*\\revert'
1858                       + r"\s*#'([-a-z0-9_]+)",
1859                       r"\\rev@rt \1.\2 #'\3", str)
1860         str = re.sub (r'Voice\.', '', str)
1861         str = re.sub (r'Lyrics\.', '', str)
1862         str = re.sub (r'ChordNames\.', '', str)
1863         
1864         str = re.sub ('rev@rt', 'revert',str)
1865         str = re.sub ('s@t', 'set',str)
1866         str = re.sub ('overrid@', 'override',str)
1867
1868         str = re.sub ('molecule', 'stencil', str)
1869         str = re.sub ('Molecule', 'Stencil', str)
1870         return str
1871
1872 conversions.append (((2,1,22), conv, """new syntax for property settings:
1873         \\set A.B = #C , \\unset A.B
1874         \\override A.B #C = #D, \\revert A.B #C
1875
1876 """))
1877
1878 def conv (str):
1879         def subst_in_trans (match):
1880                 s = match.group (0)
1881                 s = re.sub (r'\s([a-zA-Z]+)\s*\\override',
1882                               r' \\override \1', s)
1883                 s = re.sub (r'\s([a-zA-Z]+)\s*\\set',
1884                               r' \\override \1', s)
1885                 s = re.sub (r'\s([a-zA-Z]+)\s*\\revert',
1886                               r' \\revert \1', s)
1887                 return s
1888         str = re.sub (r'\\(translator|with)\s*{[^}]+}',  subst_in_trans, str)
1889
1890         def sub_abs (m):
1891                 
1892                 context = m.group ('context')
1893                 d = m.groupdict ()
1894                 if context:
1895                         context = " '%s" % context[:-1] # -1: remove . 
1896                 else:
1897                         context = ''
1898
1899                 d['context'] = context
1900                 
1901                 return r"""#(override-auto-beam-setting %(prop)s %(num)s %(den)s%(context)s)""" % d
1902
1903         str = re.sub (r"""\\override\s*(?P<context>[a-zA-Z]+\s*\.\s*)?autoBeamSettings"""
1904                       +r"""\s*#(?P<prop>[^=]+)\s*=\s*#\(ly:make-moment\s+(?P<num>\d+)\s+(?P<den>\d)\s*\)""",
1905                       sub_abs, str)
1906         
1907         return str
1908         
1909 conversions.append (((2,1,23), conv, """Property setting syntax in \\translator{ }"""))
1910 def conv (str):
1911         str = re.sub (r'music-list\?', 'ly:music-list?', str)
1912         str = re.sub (r'\|\s*~', '~ |', str)   
1913         return str
1914
1915 conversions.append (((2,1,24), conv, """music-list? -> ly:music-list?"""))
1916
1917 def conv (str):
1918         str = re.sub (r'ly:get-spanner-bound', 'ly:spanner-get-bound', str)
1919         str = re.sub (r'ly:get-extent', 'ly:grob-extent', str)
1920         str = re.sub (r'ly:get-system', 'ly:grob-system', str)
1921         str = re.sub (r'ly:get-original', 'ly:grob-original', str)
1922         str = re.sub (r'ly:get-parent', 'ly:grob-parent', str)
1923         str = re.sub (r'ly:get-broken-into', 'ly:spanner-broken-into', str)
1924         str = re.sub (r'Melisma_engraver', 'Melisma_translator', str)
1925         if re.search ("ly:get-paper-variable", str):
1926                 sys.stderr.write ('use (ly:paper-lookup (ly:grob-paper ))')
1927                 raise FatalConversionError()
1928
1929         str = re.sub (r'\\defaultAccidentals', "#(set-accidental-style 'default)", str)
1930         str = re.sub (r'\\voiceAccidentals', "#(set-accidental-style 'voice)", str)
1931         str = re.sub (r'\\modernAccidentals', "#(set-accidental-style 'modern)", str)
1932         str = re.sub (r'\\modernCautionaries', "#(set-accidental-style 'modern-cautionary)", str)
1933         str = re.sub (r'\\modernVoiceAccidental', "#(set-accidental-style 'modern-voice)", str)
1934         str = re.sub (r'\\modernVoiceCautionaries', "#(set-accidental-style 'modern-voice-cautionary)", str)
1935         str = re.sub (r'\\pianoAccidentals', "#(set-accidental-style 'piano)", str)
1936         str = re.sub (r'\\pianoCautionaries', "#(set-accidental-style 'piano-cautionary)", str)
1937         str = re.sub (r'\\forgetAccidentals', "#(set-accidental-style 'forget)", str)
1938         str = re.sub (r'\\noResetKey', "#(set-accidental-style 'no-reset)", str)
1939         
1940         return str
1941
1942 conversions.append (((2,1,25), conv, """Scheme grob function renaming"""))
1943
1944
1945 def conv (str):
1946         str = re.sub ('ly:set-grob-property!', 'ly:grob-set-property!',str)
1947         str = re.sub ('ly:set-mus-property!', 'ly:music-set-property!',str)     
1948         str = re.sub ('ly:set-context-property!', 'ly:context-set-property!', str)      
1949         str = re.sub ('ly:get-grob-property', 'ly:grob-property',str)
1950         str = re.sub ('ly:get-mus-property', 'ly:music-property',str)
1951         str = re.sub ('ly:get-context-property', 'ly:context-property',str)
1952         
1953         return str
1954
1955 conversions.append (((2,1,26), conv, """More Scheme function renaming"""))
1956
1957 def conv (str):
1958         def subst (m):
1959                 g = string.atoi (m.group (2))
1960                 o = g / 12
1961                 g -= o * 12
1962                 if g <  0:
1963                         g += 12
1964                         o -= 1
1965
1966
1967                 lower_pitches = filter (lambda x : x <= g, [0, 2, 4, 5, 7, 9, 11, 12])
1968                 s = len (lower_pitches) -1 
1969                 a = g - lower_pitches [-1]
1970
1971
1972                 print s , lower_pitches, g, a, s 
1973                 str = 'cdefgab' [s]
1974                 str += ['eses', 'es', '', 'is', 'isis'][a + 2]
1975                 if o < 0:
1976                         str += ',' * (-o - 1)
1977                 elif o >= 0:
1978                         str += "'" * (o + 1)
1979                         
1980                 return '\\transposition %s ' % str
1981
1982         
1983         str = re.sub (r"\\set ([A-Za-z]+\s*\.\s*)?transposing\s*=\s*#([-0-9]+)",
1984                       subst, str)
1985         return str
1986
1987 conversions.append (((2,1,27), conv, """property transposing -> tuning"""))
1988
1989 def conv (str):
1990         str = re.sub (r'make-music-by-name', 'make-music', str)
1991         str = re.sub (r"\\override\s+.*Arpeggio\s+#.print-function\s+=\s+\\arpeggioBracket", r"\\arpeggioBracket", str)
1992         return str
1993
1994 conversions.append (((2,1,28), conv,
1995                      """make-music-by-name -> make-music,
1996 new syntax for setting \\arpeggioBracket"""))
1997
1998 def conv (str):
1999         str = re.sub (r'\\center([^-])', '\\center-align\\1', str)
2000         str = re.sub (r'\\translator', '\\context', str)
2001         return str
2002
2003 conversions.append (((2,1,29), conv,
2004                      '\\center -> \\center-align, \\translator -> \\context'))
2005
2006
2007 def conv (str):
2008         str = re.sub (r'\\threeq(flat|sharp)', r'\\sesqui\1', str)
2009         str = re.sub (r'ly:stencil-get-extent',
2010                       'ly:stencil-extent', str)
2011         str = re.sub (r'ly:translator-find',
2012                       'ly:context-find', str)
2013         str = re.sub ('ly:unset-context-property','ly:context-unset-property',
2014                       str)
2015                      
2016         str = re.sub (r'ly:get-mutable-properties',
2017                       'ly:mutable-music-properties',str)
2018         str = re.sub (r'centralCPosition',
2019                       'middleCPosition',str)
2020         return str
2021
2022 conversions.append (((2,1,30), conv,
2023                      '''\\threeq{flat,sharp} -> \\sesqui{flat,sharp}
2024 ly:get-mutable-properties -> ly:mutable-music-properties
2025 centralCPosition -> middleCPosition
2026 ly:unset-context-property -> ly:context-unset-property
2027 ly:translator-find -> ly:context-find
2028 ly:get-stencil-extent -> ly:stencil-extent
2029 '''))
2030
2031
2032 def conv (str):
2033         str = re.sub (r'\\alias\s*"?Timing"?', '', str)
2034         return str
2035
2036 conversions.append (((2,1,31), conv,
2037                      '''remove \\alias Timing'''))
2038
2039 def conv (str):
2040         str = re.sub (r"(\\set\s+)?(?P<context>(Score\.)?)breakAlignOrder\s*=\s*#'(?P<list>[^\)]+)",
2041                       r"\n\\override \g<context>BreakAlignment #'break-align-orders = "
2042                       + "#(make-vector 3 '\g<list>)", str)
2043                       
2044         return str
2045
2046 conversions.append (((2,1,33), conv,
2047                      '''breakAlignOrder -> break-align-orders.'''))
2048
2049 def conv (str):
2050         str = re.sub (r"\(set-paper-size",
2051                       "(set-default-paper-size",str)
2052         return str
2053
2054 conversions.append (((2,1,34), conv,
2055                      '''set-paper-size -> set-default-paper-size.'''))
2056
2057 def conv (str):
2058         str = re.sub (r"ly:mutable-music-properties",
2059                       "ly:music-mutable-properties", str)
2060         return str
2061
2062 conversions.append (((2,1, 36), conv,
2063                      '''ly:mutable-music-properties -> ly:music-mutable-properties'''))
2064
2065
2066
2067 def conv (str):
2068         return str
2069
2070 conversions.append (((2, 2, 0), conv,
2071                      '''clean up version. '''))
2072
2073 def conv (str):
2074         return re.sub (r'\\apply\b', r'\\applymusic', str)
2075
2076 conversions.append (((2, 3, 1), conv,
2077                      '''\\apply -> \\applymusic'''))
2078
2079 def conv (str):
2080         if re.search ('textheight', str):
2081                 sys.stderr.write("\nWarning: tuning of page layout has changed. See reference manual.\n")
2082                 
2083         str = re.sub (r'\\OrchestralScoreContext', '\\Score', str)
2084         def func(m):
2085                 if m.group(1) not in ['RemoveEmptyStaff',
2086                                       'AncientRemoveEmptyStaffContext',
2087                                       'EasyNotation']:
2088                         return '\\' + m.group (1)
2089                 else:
2090                         return m.group (0)
2091                 
2092                 
2093         str = re.sub (r'\\([a-zA-Z]+)Context\b', func, str)
2094
2095         str = re.sub ('ly:paper-lookup', 'ly:output-def-lookup', str)
2096         return str
2097
2098 conversions.append (((2, 3, 2), conv,
2099                      '''\\FooContext -> \\Foo'''))
2100
2101 def conv (str):
2102         str = re.sub (r'\\notes\b', '', str)
2103         
2104         return str
2105
2106 conversions.append (((2, 3, 4), conv,
2107                      '''remove \\notes'''))
2108
2109
2110
2111 def conv (str):
2112         str = re.sub (r'lastpagefill\s*=\s*"?1"', 'raggedlastbottom = ##t', str)
2113         return str
2114
2115 conversions.append (((2, 3, 6), conv,
2116                      '''lastpagefill -> raggedlastbottom'''))
2117
2118
2119
2120 def conv (str):
2121         str = re.sub (r'\\consistsend', '\\consists', str)
2122         str = re.sub (r'\\lyricsto\s+("?[a-zA-Z]+"?)(\s*\\new Lyrics\s*)?\\lyrics',
2123                       r'\\lyricsto \1 \2', str)
2124         return str
2125
2126 conversions.append (((2, 3, 8), conv,
2127                      '''remove \\consistsend, strip \\lyrics from \\lyricsto.'''))
2128
2129 def conv (str):
2130         str = re.sub (r'neo_mensural', 'neomensural', str)
2131         str = re.sub (r'if-text-padding', 'bound-padding', str)
2132         return str
2133
2134 conversions.append (((2, 3, 9), conv,
2135                      '''neo_mensural -> neomensural, if-text-padding -> bound-padding'''))
2136
2137
2138
2139 def conv (str):
2140         str = re.sub (r'\\addlyrics', r'\\oldaddlyrics', str)
2141         str = re.sub (r'\\newlyrics', r'\\addlyrics', str)
2142         if re.search (r"\\override\s*TextSpanner", str):
2143                 sys.stderr.write ("\nWarning: TextSpanner has been split into DynamicTextSpanner and TextSpanner\n") 
2144         return str
2145
2146 conversions.append (((2, 3, 10), conv,
2147                      '''\\addlyrics -> \\oldaddlyrics, \\newlyrics -> \\addlyrics'''))
2148
2149 def conv (str):
2150         str = re.sub (r'\\setMmRestFermata\s+(R[0-9.*/]*)',
2151                       r'\1^\\fermataMarkup', str)
2152         return str
2153
2154 conversions.append (((2, 3, 11), conv,
2155                      '''\\setMmRestFermata -> ^\\fermataMarkup'''))
2156
2157 def conv (str):
2158         str = re.sub (r'\\newpage', r'\\pageBreak', str)
2159         str = re.sub (r'\\scriptUp', r"""{
2160   \\override TextScript  #'direction = #1
2161   \\override Script  #'direction = #1
2162 }""", str)
2163         str = re.sub (r'\\scriptDown', r"""{
2164   \\override TextScript  #'direction = #-1
2165   \\override Script  #'direction = #-1
2166 }""", str)
2167         str = re.sub (r'\\scriptBoth', r"""{
2168   \\revert TextScript  #'direction
2169   \\revert Script  #'direction
2170 }""", str)
2171         str = re.sub ('soloADue', 'printPartCombineTexts', str)
2172         str = re.sub (r'\\applymusic\s*#notes-to-clusters',
2173                       '\\makeClusters', str)
2174
2175         str = re.sub (r'pagenumber\s*=', 'firstpagenumber', str)
2176         return str
2177
2178 conversions.append (((2, 3, 12), conv,
2179                      '''\\newpage -> \\pageBreak, junk \\script{up,down,both},
2180 soloADue -> printPartCombineTexts, #notes-to-clusters -> \\makeClusters
2181 '''))
2182
2183
2184 def conv (str):
2185         str = re.sub (r'\\chords\b', r'\\chordmode', str)
2186         str = re.sub (r'\\lyrics\b', r'\\lyricmode', str)
2187         str = re.sub (r'\\figures\b', r'\\figuremode', str)
2188         str = re.sub (r'\\notes\b', r'\\notemode', str)
2189         str = re.sub (r'\\drums\b', r'\\drummode', str)
2190         str = re.sub (r'\\chordmode\s*\\new ChordNames', r'\\chords', str)
2191         str = re.sub (r'\\new ChordNames\s*\\chordmode', r'\\chords', str)
2192         str = re.sub (r'\\new FiguredBass\s*\\figuremode', r'\\figures', str)
2193         str = re.sub (r'\\figuremode\s*\new FiguredBass', r'\\figures', str)
2194         str = re.sub (r'\\new DrumStaff\s*\\drummode', r'\\drums', str)
2195         str = re.sub (r'\\drummode\s*\\new DrumStaff', r'\\drums', str)
2196
2197         return str
2198
2199 conversions.append (((2, 3, 16), conv,
2200                      '''\foo -> \foomode (for chords, notes, etc.)
2201 fold \new FooContext \foomode into \foo.'''))
2202
2203 def conv (str):
2204         str = re.sub (r'(slur|stem|phrasingSlur|tie|dynamic|dots|tuplet|arpeggio|)Both', r'\1Neutral', str)
2205         str = re.sub (r"\\applymusic\s*#\(remove-tag\s*'([a-z-0-9]+)\)",
2206                       r"\\removeWithTag #'\1", str)
2207         return str
2208
2209 conversions.append (((2, 3, 17), conv,
2210                      '''\foo -> \foomode (for chords, notes, etc.)
2211 fold \new FooContext \foomode into \foo.'''))
2212
2213
2214 def conv (str):
2215         str = re.sub (r'Text_item', 'Text_interface', str)
2216         return str
2217
2218 conversions.append (((2, 3, 18),
2219                      conv,
2220                      '''Text_item -> Text_interface''' ))
2221
2222 def conv (str):
2223         str = re.sub (r'\\paper', r'\\layout', str)
2224         str = re.sub (r'\\bookpaper', r'\\paper', str)
2225         if re.search ('paper-set-staff-size', str):
2226                 sys.stderr.write ('''\nWarning: staff size should be changed at top-level
2227 with
2228
2229   #(set-global-staff-size <STAFF-HEIGHT-IN-POINT>)
2230
2231 ''')
2232                 
2233                 
2234         str = re.sub (r'#\(paper-set-staff-size', '%Use set-global-staff-size at toplevel\n% #(layout-set-staff-size', str)
2235         return str
2236
2237 conversions.append (((2, 3, 22),
2238                      conv,
2239                      '''paper -> layout
2240  bookpaper -> paper''' ))
2241
2242
2243 def conv (str):
2244         str = re.sub (r'\\context\s+([a-zA-Z]+)\s*=\s*([a-z]+)\s',
2245                       r'\\context \1 = "\2" ',
2246                       str )
2247         return str
2248
2249 conversions.append (((2, 3, 23),
2250                      conv,
2251                      '''\context Foo = NOTENAME -> \context Foo = "NOTENAME"'''))
2252
2253
2254 def conv (str):
2255         return str
2256
2257 conversions.append (((2, 4, 0),
2258                      conv,
2259                      ''))
2260
2261
2262 def conv (str):
2263         str = re.sub (r'\\quote\s+"?([a-zA-Z0-9]+)"?\s+([0-9.*/]+)',
2264                       r'\\quoteDuring #"\1" { \skip \2 }',
2265                       str
2266                       )
2267         return str
2268
2269 conversions.append (((2, 5, 0),
2270                      conv,
2271                      ''))
2272
2273
2274 def conv (str):
2275         str = re.sub (r'ly:import-module',
2276                       r'ly:module-copy', str) 
2277         return str
2278
2279 conversions.append (((2, 5, 1),
2280                      conv,
2281                      'ly:import-module -> ly:module-copy'))
2282
2283 def conv (str):
2284         str = re.sub (r'\\(column|fill-line|dir-column|center-align|right-align|left-align|bracketed-y-column)\s*<([^<]*)>',
2285                       r'\\\1 {\2}', str)
2286         str = re.sub (r'\\(column|fill-line|dir-column|center-align|right-align|left-align|bracketed-y-column)\s*<([^<]*)>',
2287                       r'\\\1 {\2}', str)
2288         str = re.sub (r'\\(column|fill-line|dir-column|center-align|right-align|left-align|bracketed-y-column)\s*<([^<]*)>',
2289                       r'\\\1 {\2}', str)
2290         return str
2291
2292 conversions.append (((2, 5, 2),
2293                      conv,
2294                      '\markup .. < .. > .. -> \markup .. { .. } ..'))
2295
2296 ################################
2297 #       END OF CONVERSIONS      
2298 ################################
2299
2300 def get_conversions (from_version, to_version):
2301         def version_b (v, f = from_version, t = to_version):
2302                 return version_cmp (v[0], f) > 0 and version_cmp (v[0], t) <= 0
2303         return filter (version_b, conversions)
2304
2305
2306 def latest_version ():
2307         return conversions[-1][0]
2308
2309 def do_conversion (infile, from_version, outfile, to_version):
2310         conv_list = get_conversions (from_version, to_version)
2311
2312         sys.stderr.write ('Applying conversions: ')
2313         str = infile.read ()
2314         last_conversion = ()
2315         try:
2316                 for x in conv_list:
2317                         sys.stderr.write (tup_to_str (x[0]) + ', ')
2318                         str = x[1] (str)
2319                         last_conversion = x[0]
2320
2321         except FatalConversionError:
2322                 sys.stderr.write ('Error while converting; I won\'t convert any further')
2323
2324         if last_conversion:
2325                 sys.stderr.write ('\n')
2326                 new_ver =  '\\version \"%s\"' % tup_to_str (last_conversion)
2327
2328                 if re.search (lilypond_version_re_str, str):
2329                         str = re.sub (lilypond_version_re_str,'\\'+new_ver, str)
2330                 elif add_version:
2331                         str = new_ver + '\n' + str
2332
2333                 outfile.write (str)
2334
2335         return last_conversion
2336         
2337 class UnknownVersion:
2338         pass
2339
2340 def do_one_file (infile_name):
2341         sys.stderr.write ('Processing `%s\' ... '% infile_name)
2342         outfile_name = ''
2343         if __main__.edit:
2344                 outfile_name = infile_name + '.NEW'
2345         elif __main__.outfile_name:
2346                 outfile_name = __main__.outfile_name
2347
2348         if __main__.from_version:
2349                 from_version = __main__.from_version
2350         else:
2351                 guess = guess_lilypond_version (infile_name)
2352                 if not guess:
2353                         raise UnknownVersion ()
2354                 from_version = str_to_tuple (guess)
2355
2356         if __main__.to_version:
2357                 to_version = __main__.to_version
2358         else:
2359                 to_version = latest_version ()
2360
2361
2362         if infile_name:
2363                 infile = open (infile_name,'r')
2364         else:
2365                 infile = sys.stdin
2366
2367         if outfile_name:
2368                 outfile =  open (outfile_name, 'w')
2369         else:
2370                 outfile = sys.stdout
2371
2372         touched = do_conversion (infile, from_version, outfile, to_version)
2373
2374         if infile_name:
2375                 infile.close ()
2376
2377         if outfile_name:
2378                 outfile.close ()
2379
2380         if __main__.edit and touched:
2381                 try:
2382                         os.remove(infile_name + '~')
2383                 except:
2384                         pass
2385                 os.rename (infile_name, infile_name + '~')
2386                 os.rename (infile_name + '.NEW', infile_name)
2387
2388         sys.stderr.write ('\n')
2389         sys.stderr.flush ()
2390
2391 edit = 0
2392 assume_old = 0
2393 to_version = ()
2394 from_version = ()
2395 outfile_name = ''
2396 show_rules_p = 0
2397
2398 (options, files) = getopt.getopt (sys.argv[1:], 'ao:f:t:senh',
2399                                   ['no-version', 'version', 'output',
2400                                   'show-rules', 'help', 'edit',
2401                                   'from=', 'to='])
2402
2403 for opt in options:
2404         o = opt[0]
2405         a = opt[1]
2406         if o == '--help' or o == '-h':
2407                 usage ()
2408                 sys.exit (0)
2409         elif o == '--version' or o == '-v':
2410                 print_version ()
2411                 sys.exit (0)
2412         elif o== '--from' or o=='-f':
2413                 from_version = str_to_tuple (a)
2414         elif o== '--to' or o=='-t':
2415                 to_version = str_to_tuple (a)
2416         elif o== '--edit' or o == '-e':
2417                 edit = 1
2418         elif o== '--show-rules' or o == '-s':
2419                 show_rules_p = 1
2420         elif o == '--output' or o == '-o':
2421                 outfile_name = a
2422         elif o == '--no-version' or o == '-n':
2423                 add_version = 0
2424         else:
2425                 print o
2426                 raise getopt.error
2427
2428 # should parse files[] to read \version?
2429 if show_rules_p:
2430         show_rules (sys.stdout)
2431         sys.exit (0)
2432                 
2433 identify ()
2434 for f in files:
2435         if f == '-':
2436                 f = ''
2437         elif not os.path.isfile (f):
2438                 continue
2439         try:
2440                 do_one_file (f)
2441         except UnknownVersion:
2442                 sys.stderr.write ('\n')
2443                 sys.stderr.write ("%s: can't determine version for `%s'" % (program_name, f))
2444                 sys.stderr.write ('\n')
2445                 if assume_old:
2446                         fv = from_version
2447                         from_version = (0, 0, 0)
2448                         do_one_file (f)
2449                         from_version = fv
2450                 else:
2451                         sys.stderr.write ("%s: skipping: `%s' " % (program_name,  f))
2452                 pass
2453
2454 sys.stderr.write ('\n')