]> git.donarmstrong.com Git - lilypond.git/blob - scripts/convert-ly.py
release commit
[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 program_name = 'convert-ly'
19 version = '@TOPLEVEL_VERSION@'
20
21 import os
22 import sys
23 import __main__
24 import getopt
25 import  string
26 import re
27 import time
28
29 # Did we ever have \mudela-version?  I doubt it.
30 # lilypond_version_re_str = '\\\\version *\"(.*)\"'
31 lilypond_version_re_str = '\\\\(mudela-)?version *\"(.*)\"'
32 lilypond_version_re = re.compile (lilypond_version_re_str)
33 add_version = 1
34
35
36 def program_id ():
37         return '%s (GNU LilyPond) %s' %(program_name,  version);
38
39 def identify ():
40         sys.stderr.write (program_id () + '\n')
41
42 def usage ():
43         sys.stdout.write (
44                 r"""Usage: %s [OPTIONS]... [FILE]...
45 Try to convert to newer lilypond-versions.  The version number of the
46 input is guessed by default from \version directive.
47
48 Options:
49   -h, --help             print this help
50   -e, --edit             edit in place
51   -f, --from=VERSION     start from version; overrides \version found in file
52   -s, --show-rules       print all rules
53   -t, --to=VERSION       show target version
54   -n, --no-version       don't add new version stamp
55       --version          print program version
56
57 Report bugs to bugs-gnu-music@gnu.org.
58
59 """ % program_name)
60         
61         
62         sys.exit (0)
63
64 def print_version ():
65         
66         sys.stdout.write (r"""%s
67
68 This is free software.  It is covered by the GNU General Public
69 License, and you are welcome to change it and/or distribute copies of
70 it under certain conditions.  invoke as `%s --warranty' for more
71 information.
72
73 """ % (program_id() , program_name))
74         
75 def gulp_file(f):
76         try:
77                 i = open(f)
78                 i.seek (0, 2)
79                 n = i.tell ()
80                 i.seek (0,0)
81         except:
82                 print 'can\'t open file: ' + f + '\n'
83                 return ''
84         s = i.read (n)
85         if len (s) <= 0:
86                 print 'gulped empty file: ' + f + '\n'
87         i.close ()
88         return s
89
90 def str_to_tuple (s):
91         return tuple (map (string.atoi, string.split (s,'.')))
92
93 def tup_to_str (t):
94         return string.join (map (lambda x: '%s' % x, list (t)), '.')
95
96 def version_cmp (t1, t2):
97         for x in [0,1,2]:
98                 if t1[x] - t2[x]:
99                         return t1[x] - t2[x]
100         return 0
101
102 def guess_lilypond_version (filename):
103         s = gulp_file (filename)
104         m = lilypond_version_re.search (s)
105         if m:
106                 return m.group (2)
107         else:
108                 return ''
109
110 class FatalConversionError:
111         pass
112
113 conversions = []
114
115 def show_rules (file):
116         for x in conversions:
117                 file.write  ('%s: %s\n' % (tup_to_str (x[0]), x[2]))
118
119 ############################
120                 
121 if 1:
122         def conv(str):
123                 if re.search ('\\\\multi', str):
124                         sys.stderr.write ('\nNot smart enough to convert \\multi')
125                 return str
126         
127         conversions.append (((0,1,9), conv, '\\header { key = concat + with + operator }'))
128
129 if 1:                                   # need new a namespace
130         def conv (str):
131                 if re.search ('\\\\octave', str):
132                         sys.stderr.write ('\nNot smart enough to convert \\octave')
133                 #       raise FatalConversionError()
134                 
135                 return str
136
137         conversions.append ((
138                 ((0,1,19), conv, 'deprecated \\octave; can\'t convert automatically')))
139
140
141 if 1:                                   # need new a namespace
142         def conv (str):
143                 str = re.sub ('\\\\textstyle([^;]+);',
144                                          '\\\\property Lyrics . textstyle = \\1', str)
145                 # harmful to current .lys
146                 # str = re.sub ('\\\\key([^;]+);', '\\\\accidentals \\1;', str)
147                         
148                 return str
149
150         conversions.append ((
151                 ((0,1,20), conv, 'deprecated \\textstyle, new \key syntax')))
152
153
154 if 1:
155         def conv (str):
156                 str = re.sub ('\\\\musical_pitch', '\\\\musicalpitch',str)
157                 str = re.sub ('\\\\meter', '\\\\time',str)
158                         
159                 return str
160
161         conversions.append ((
162                 ((0,1,21), conv, '\\musical_pitch -> \\musicalpitch, '+
163                  '\\meter -> \\time')))
164
165 if 1:
166         def conv (str):
167                 return str
168
169         conversions.append ((
170                 ((1,0,0), conv, '0.1.21 -> 1.0.0 ')))
171
172
173 if 1:
174         def conv (str):
175                 str = re.sub ('\\\\accidentals', '\\\\keysignature',str)
176                 str = re.sub ('specialaccidentals *= *1', 'keyoctaviation = 0',str)
177                 str = re.sub ('specialaccidentals *= *0', 'keyoctaviation = 1',str)
178                         
179                 return str
180
181         conversions.append ((
182                 ((1,0,1), conv, '\\accidentals -> \\keysignature, ' +
183                  'specialaccidentals -> keyoctaviation')))
184
185 if 1:
186         def conv(str):
187                 if re.search ('\\\\header', str):
188                         sys.stderr.write ('\nNot smart enough to convert to new \\header format')
189                 return str
190         
191         conversions.append (((1,0,2), conv, '\\header { key = concat + with + operator }'))
192
193 if 1:
194         def conv(str):
195                 str =  re.sub ('\\\\melodic([^a-zA-Z])', '\\\\notes\\1',str)
196                 return str
197         
198         conversions.append (((1,0,3), conv, '\\melodic -> \\notes'))
199
200 if 1:
201         def conv(str):
202                 str =  re.sub ('default_paper *=', '',str)
203                 str =  re.sub ('default_midi *=', '',str)
204                 return str
205         
206         conversions.append (((1,0,4), conv, 'default_{paper,midi}'))
207
208 if 1:
209         def conv(str):
210                 str =  re.sub ('ChoireStaff', 'ChoirStaff',str)
211                 str =  re.sub ('\\\\output', 'output = ',str)
212                         
213                 return str
214         
215         conversions.append (((1,0,5), conv, 'ChoireStaff -> ChoirStaff'))
216
217 if 1:
218         def conv(str):
219                 if re.search ('[a-zA-Z]+ = *\\translator',str):
220                         sys.stderr.write ('\nNot smart enough to change \\translator syntax')
221                 #       raise FatalConversionError()
222                 return str
223         
224         conversions.append (((1,0,6), conv, 'foo = \\translator {\\type .. } ->\\translator {\\type ..; foo; }'))
225
226
227 if 1:
228         def conv(str):
229                 str =  re.sub ('\\\\lyrics*', '\\\\lyrics',str)
230                         
231                 return str
232         
233         conversions.append (((1,0,7), conv, '\\lyric -> \\lyrics'))
234
235 if 1:
236         def conv(str):
237                 str =  re.sub ('\\\\\\[/3+', '\\\\times 2/3 { ',str)
238                 str =  re.sub ('\\[/3+', '\\\\times 2/3 { [',str)
239                 str =  re.sub ('\\\\\\[([0-9/]+)', '\\\\times \\1 {',str)
240                 str =  re.sub ('\\[([0-9/]+)', '\\\\times \\1 { [',str)
241                 str =  re.sub ('\\\\\\]([0-9/]+)', '}', str)
242                 str =  re.sub ('\\\\\\]', '}',str)
243                 str =  re.sub ('\\]([0-9/]+)', '] }', str)
244                 return str
245         
246         conversions.append (((1,0,10), conv, '[2/3 ]1/1 -> \\times 2/3 '))
247
248 if 1:
249         def conv(str):
250                 return str
251         conversions.append (((1,0,12), conv, 'Chord syntax stuff'))
252
253
254 if 1:
255         def conv(str):
256                 
257                 
258                 str =  re.sub ('<([^>~]+)~([^>]*)>','<\\1 \\2> ~', str)
259                         
260                 return str
261         
262         conversions.append (((1,0,13), conv, '<a ~ b> c -> <a b> ~ c'))
263
264 if 1:
265         def conv(str):
266                 str =  re.sub ('<\\[','[<', str)
267                 str =  re.sub ('\\]>','>]', str)
268                         
269                 return str
270         
271         conversions.append (((1,0,14), conv, '<[a b> <a b]>c -> [<a b> <a b>]'))
272
273
274 if 1:
275         def conv(str):
276                 str =  re.sub ('\\\\type([^\n]*engraver)','\\\\TYPE\\1', str)
277                 str =  re.sub ('\\\\type([^\n]*performer)','\\\\TYPE\\1', str)
278                 str =  re.sub ('\\\\type','\\\\context', str)
279                 str =  re.sub ('\\\\TYPE','\\\\type', str)
280                 str =  re.sub ('textstyle','textStyle', str)
281                         
282                 return str
283         
284         conversions.append (((1,0,16), conv, '\\type -> \\context, textstyle -> textStyle'))
285
286
287 if 1:
288         def conv(str):
289                 if re.search ('\\\\repeat',str):
290                         sys.stderr.write ('\nNot smart enough to convert \\repeat')
291                 #       raise FatalConversionError()
292                 return str
293         
294         conversions.append (((1,0,18), conv,
295                 '\\repeat NUM Music Alternative -> \\repeat FOLDSTR Music Alternative'))
296
297 if 1:
298         def conv(str):
299                 str =  re.sub ('SkipBars','skipBars', str)
300                 str =  re.sub ('fontsize','fontSize', str)
301                 str =  re.sub ('midi_instrument','midiInstrument', str)                 
302                         
303                 return str
304
305         conversions.append (((1,0,19), conv,
306                 'fontsize -> fontSize, midi_instrument -> midiInstrument, SkipBars -> skipBars'))
307
308
309 if 1:
310         def conv(str):
311                 str =  re.sub ('tieydirection','tieVerticalDirection', str)
312                 str =  re.sub ('slurydirection','slurVerticalDirection', str)
313                 str =  re.sub ('ydirection','verticalDirection', str)                   
314                         
315                 return str
316
317         conversions.append (((1,0,20), conv,
318                 '{,tie,slur}ydirection -> {v,tieV,slurV}erticalDirection'))
319
320
321 if 1:
322         def conv(str):
323                 str =  re.sub ('hshift','horizontalNoteShift', str)
324                         
325                 return str
326
327         conversions.append (((1,0,21), conv,
328                 'hshift -> horizontalNoteShift'))
329
330
331 if 1:
332         def conv(str):
333                 str =  re.sub ('\\\\grouping[^;]*;','', str)
334                         
335                 return str
336
337         conversions.append (((1,1,52), conv,
338                 'deprecate \\grouping'))
339
340
341 if 1:
342         def conv(str):
343                 str =  re.sub ('\\\\wheel','\\\\coda', str)
344                         
345                 return str
346
347         conversions.append (((1,1,55), conv,
348                 '\\wheel -> \\coda'))
349
350 if 1:
351         def conv(str):
352                 str =  re.sub ('keyoctaviation','keyOctaviation', str)
353                 str =  re.sub ('slurdash','slurDash', str)
354                         
355                 return str
356
357         conversions.append (((1,1,65), conv,
358                 'slurdash -> slurDash, keyoctaviation -> keyOctaviation'))
359
360 if 1:
361         def conv(str):
362                 str =  re.sub ('\\\\repeat *\"?semi\"?','\\\\repeat "volta"', str)
363                         
364                 return str
365
366         conversions.append (((1,1,66), conv,
367                 'semi -> volta'))
368
369
370 if 1:
371         def conv(str):
372                 str =  re.sub ('\"?beamAuto\"? *= *\"?0?\"?','noAutoBeaming = "1"', str)
373                         
374                 return str
375
376         conversions.append (((1,1,67), conv,
377                 'beamAuto -> noAutoBeaming'))
378
379 if 1:
380         def conv(str):
381                 str =  re.sub ('automaticMelismas', 'automaticMelismata', str)
382                         
383                 return str
384
385         conversions.append (((1,2,0), conv,
386                 'automaticMelismas -> automaticMelismata'))
387
388 if 1:
389         def conv(str):
390                 str =  re.sub ('dynamicDir\\b', 'dynamicDirection', str)
391                         
392                 return str
393
394         conversions.append (((1,2,1), conv,
395                 'dynamicDir -> dynamicDirection'))
396
397 if 1:
398         def conv(str):
399                 str =  re.sub ('\\\\cadenza *0 *;', '\\\\cadenzaOff', str)
400                 str =  re.sub ('\\\\cadenza *1 *;', '\\\\cadenzaOn', str)               
401                         
402                 return str
403
404         conversions.append (((1,3,4), conv,
405                 '\\cadenza -> \cadenza{On|Off}'))
406
407 if 1:
408         def conv (str):
409                 str = re.sub ('"?beamAuto([^"=]+)"? *= *"([0-9]+)/([0-9]+)" *;*',
410                               'beamAuto\\1 = #(make-moment \\2 \\3)',
411                               str)
412                 return str
413
414         conversions.append (((1,3,5), conv, 'beamAuto moment properties'))
415
416 if 1:
417         def conv (str):
418                 str = re.sub ('stemStyle',
419                               'flagStyle',
420                               str)
421                 return str
422
423         conversions.append (((1,3,17), conv, 'stemStyle -> flagStyle'))
424
425 if 1:
426         def conv (str):
427                 str = re.sub ('staffLineLeading',
428                               'staffSpace',
429                               str)
430                 return str
431
432         conversions.append (((1,3,18), conv, 'staffLineLeading -> staffSpace'))
433
434
435 if 1:
436         def conv(str):
437                 if re.search ('\\\\repetitions',str):
438                         sys.stderr.write ('\nNot smart enough to convert \\repetitions')
439                 #       raise FatalConversionError()
440                 return str
441         
442         conversions.append (((1,3,23), conv,
443                 '\\\\repetitions feature dropped'))
444
445
446 if 1:
447         def conv (str):
448                 str = re.sub ('textEmptyDimension *= *##t',
449                               'textNonEmpty = ##f',
450                               str)
451                 str = re.sub ('textEmptyDimension *= *##f',
452                               'textNonEmpty = ##t',
453                               str)
454                 return str
455
456         conversions.append (((1,3,35), conv, 'textEmptyDimension -> textNonEmpty'))
457
458 if 1:
459         def conv (str):
460                 str = re.sub ("([a-z]+)[ \t]*=[ \t]*\\\\musicalpitch *{([- 0-9]+)} *\n",
461                               "(\\1 . (\\2))\n", str)
462                 str = re.sub ("\\\\musicalpitch *{([0-9 -]+)}",
463                               "\\\\musicalpitch #'(\\1)", str)
464                 if re.search ('\\\\notenames',str):
465                         sys.stderr.write ('\nNot smart enough to convert to new \\notenames format')
466                 return str
467
468         conversions.append (((1,3,38), conv, '\musicalpitch { a b c } -> #\'(a b c)'))
469
470 if 1:
471         def conv (str):
472                 def replace (match):
473                         return '\\key %s;' % string.lower (match.group (1))
474                 
475                 str = re.sub ("\\\\key ([^;]+);",  replace, str)
476                 return str
477         
478         conversions.append (((1,3,39), conv, '\\key A ;  ->\\key a;'))
479
480 if 1:
481         def conv (str):
482                 if re.search ('\\[:',str):
483                         sys.stderr.write ('\nNot smart enough to convert to new tremolo format')
484                 return str
485
486         conversions.append (((1,3,41), conv,
487                 '[:16 c4 d4 ] -> \\repeat "tremolo" 2 { c16 d16 }'))
488
489 if 1:
490         def conv (str):
491                 str = re.sub ('Staff_margin_engraver' , 'Instrument_name_engraver', str)
492                 return str
493
494         conversions.append (((1,3,42), conv,
495                 'Staff_margin_engraver deprecated, use Instrument_name_engraver'))
496
497 if 1:
498         def conv (str):
499                 str = re.sub ('note[hH]eadStyle\\s*=\\s*"?(\\w+)"?' , "noteHeadStyle = #'\\1", str)
500                 return str
501
502         conversions.append (((1,3,49), conv,
503                 'noteHeadStyle value: string -> symbol'))
504
505 if 1:
506         def conv (str):
507                 if re.search ('\\\\keysignature', str):
508                         sys.stderr.write ('\nNot smart enough to convert to new tremolo format')
509                 return str
510
511
512         conversions.append (((1,3,58), conv,
513                 'noteHeadStyle value: string -> symbol'))
514
515 if 1:
516         def conv (str):
517                 str = re.sub (r"""\\key *([a-z]+) *;""", r"""\\key \1 \major;""",str);
518                 return str
519         conversions.append (((1,3,59), conv,
520                 '\key X ; -> \key X major; '))
521
522 if 1:
523         def conv (str):
524                 str = re.sub (r'latexheaders *= *"\\\\input ',
525                               'latexheaders = "',
526                               str)
527                 return str
528         conversions.append (((1,3,68), conv, 'latexheaders = "\\input global" -> latexheaders = "global"'))
529
530
531
532
533 # TODO: lots of other syntax change should be done here as well
534 if 1:
535         def conv (str):
536                 str = re.sub ('basicCollisionProperties', 'NoteCollision', str)
537                 str = re.sub ('basicVoltaSpannerProperties' , "VoltaBracket", str)
538                 str = re.sub ('basicKeyProperties' , "KeySignature", str)
539
540                 str = re.sub ('basicClefItemProperties' ,"Clef", str)
541
542
543                 str = re.sub ('basicLocalKeyProperties' ,"Accidentals", str)
544                 str = re.sub ('basicMarkProperties' ,"Accidentals", str)
545                 str = re.sub ('basic([A-Za-z_]+)Properties', '\\1', str)
546
547                 str = re.sub ('Repeat_engraver' ,'Volta_engraver', str)
548                 return str
549         
550         conversions.append (((1,3,92), conv, 'basicXXXProperties -> XXX, Repeat_engraver -> Volta_engraver'))
551
552 if 1:
553         def conv (str):
554                 # Ugh, but meaning of \stemup changed too
555                 # maybe we should do \stemup -> \stemUp\slurUp\tieUp ?
556                 str = re.sub ('\\\\stemup', '\\\\stemUp', str)
557                 str = re.sub ('\\\\stemdown', '\\\\stemDown', str)
558                 str = re.sub ('\\\\stemboth', '\\\\stemBoth', str)
559                 
560                 str = re.sub ('\\\\slurup', '\\\\slurUp', str)
561                 str = re.sub ('\\\\slurboth', '\\\\slurBoth', str)
562                 str = re.sub ('\\\\slurdown', '\\\\slurDown', str)
563                 str = re.sub ('\\\\slurdotted', '\\\\slurDotted', str)
564                 str = re.sub ('\\\\slurnormal', '\\\\slurNoDots', str)          
565                 
566                 str = re.sub ('\\\\shiftoff', '\\\\shiftOff', str)
567                 str = re.sub ('\\\\shifton', '\\\\shiftOn', str)
568                 str = re.sub ('\\\\shiftonn', '\\\\shiftOnn', str)
569                 str = re.sub ('\\\\shiftonnn', '\\\\shiftOnnn', str)
570
571                 str = re.sub ('\\\\onevoice', '\\\\oneVoice', str)
572                 str = re.sub ('\\\\voiceone', '\\\\voiceOne', str)
573                 str = re.sub ('\\\\voicetwo', '\\\\voiceTwo', str)
574                 str = re.sub ('\\\\voicethree', '\\\\voiceThree', str)
575                 str = re.sub ('\\\\voicefour', '\\\\voiceFour', str)
576
577                 # I don't know exactly when these happened...
578                 # ugh, we loose context setting here...
579                 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\stemUp\\\\slurUp\\\\tieUp', str)
580                 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\stemDown\\\\slurDown\\\\tieDown', str)
581                 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\\\stemBoth\\\\slurBoth\\\\tieBoth', str)
582
583                 str = re.sub ('verticalDirection[^=]*= *#?"?(1|(\\\\up))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #1', str)
584                 str = re.sub ('verticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #-1', str)
585                 str = re.sub ('verticalDirection[^=]*= *#?"?(0|(\\\\center))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #0', str)
586                 
587                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\\\1Up', str)
588                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\\\1Down', str)
589                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\\\\\1Both', str)
590
591                 # (lacks capitalisation slur -> Slur)
592                 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\1 \\\\override #\'direction = #1', str)
593                 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\1 \\override #\'direction = #-1', str)
594                 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\1 \\\\override #\'direction = #0', str)
595
596                 ## dynamic..
597                 str = re.sub ('\\\\property *[^ .]*[.]?dynamicDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\dynamicUp', str)
598                 str = re.sub ('\\\\property *[^ .]*[.]?dyn[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\dynamicDown', str)
599                 str = re.sub ('\\\\property *[^ .]*[.]?dyn[^=]*= *#?"?(0|(\\\\center))"?', '\\\\dynamicBoth', str)
600
601                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)Dash[^=]*= *#?"?(0|(""))"?', '\\\\\\1NoDots', str)
602                 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)Dash[^=]*= *#?"?([1-9]+)"?', '\\\\\\1Dotted', str)
603
604                 str = re.sub ('\\\\property *[^ .]*[.]?noAutoBeaming[^=]*= *#?"?(0|(""))"?', '\\\\autoBeamOn', str)
605                 str = re.sub ('\\\\property *[^ .]*[.]?noAutoBeaming[^=]*= *#?"?([1-9]+)"?', '\\\\autoBeamOff', str)
606
607
608
609                 return str
610         
611         conversions.append (((1,3,93), conv,
612                 'property definiton case (eg. onevoice -> oneVoice)'))
613
614
615 if 1:
616         def conv (str):
617                 str = re.sub ('ChordNames*', 'ChordNames', str)
618                 if re.search ('\\\\textscript "[^"]* *"[^"]*"', str):
619                         sys.stderr.write ('\nNot smart enough to convert to new \\textscript markup text')
620
621                 str = re.sub ('\\textscript +("[^"]*")', '\\textscript #\\1', str)
622
623                 return str
624         
625         conversions.append (((1,3,97), conv, 'ChordName -> ChordNames'))
626
627
628 # TODO: add lots of these
629         
630 if 1:
631         def conv (str):
632                 str = re.sub ('\\\\property *"?Voice"? *[.] *"?textStyle"? *= *"([^"]*)"', '\\\\property Voice.TextScript \\\\set #\'font-style = #\'\\1', str)
633                 str = re.sub ('\\\\property *"?Lyrics"? *[.] *"?textStyle"? *= *"([^"]*)"', '\\\\property Lyrics.LyricText \\\\set #\'font-style = #\'\\1', str)
634
635                 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?timeSignatureStyle"? *= *"([^"]*)"', '\\\\property \\1.TimeSignature \\\\override #\'style = #\'\\2', str)
636
637                 str = re.sub ('"?timeSignatureStyle"? *= *#?""', 'TimeSignature \\\\override #\'style = ##f', str)
638                 
639                 str = re.sub ('"?timeSignatureStyle"? *= *#?"([^"]*)"', 'TimeSignature \\\\override #\'style = #\'\\1', str)
640                 
641                 str = re.sub ('#\'style *= #*"([^"])"', '#\'style = #\'\\1', str)
642                 
643                 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?horizontalNoteShift"? *= *"?#?([-0-9]+)"?', '\\\\property \\1.NoteColumn \\\\override #\'horizontal-shift = #\\2', str)
644
645                 # ugh
646                 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?flagStyle"? *= *""', '\\\\property \\1.Stem \\\\override #\'flag-style = ##f', str)
647                 
648                 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?flagStyle"? *= *"([^"]*)"', '\\\\property \\1.Stem \\\\override #\'flag-style = #\'\\2', str)
649                 return str
650         
651         conversions.append (((1,3,98), conv, 'CONTEXT.textStyle -> GROB.#font-style '))
652
653 if 1:
654         def conv (str):
655                 str = re.sub ('"?beamAutoEnd_([0-9]*)"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(end 1 \\1 * *) = \\2', str)
656                 str = re.sub ('"?beamAutoBegin_([0-9]*)"? *= *(#\\([^)]*\))', 'autoBeamSettings \\push #\'(begin 1 \\1 * *) = \\2', str)
657                 str = re.sub ('"?beamAutoEnd"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(end * * * *) = \\1', str)
658                 str = re.sub ('"?beamAutoBegin"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(begin * * * *) = \\1', str)
659
660
661                 return str
662         
663         conversions.append (((1,3,102), conv, 'beamAutoEnd -> autoBeamSettings \\push (end * * * *)'))
664
665
666 if 1:
667         def conv (str):
668                 str = re.sub ('\\\\push', '\\\\override', str)
669                 str = re.sub ('\\\\pop', '\\\\revert', str)
670
671                 return str
672         
673         conversions.append (((1,3,111), conv, '\\push -> \\override, \\pop -> \\revert'))
674
675 if 1:
676         def conv (str):
677                 str = re.sub ('LyricVoice', 'LyricsVoice', str)
678                 # old fix
679                 str = re.sub ('Chord[Nn]ames*.Chord[Nn]ames*', 'ChordNames.ChordName', str)
680                 str = re.sub ('Chord[Nn]ames([ \t\n]+\\\\override)', 'ChordName\\1', str)
681                 return str
682         
683         conversions.append (((1,3,113), conv, 'LyricVoice -> LyricsVoice'))
684
685 def regularize_id (str):
686         s = ''
687         lastx = ''
688         for x in str:
689                 if x == '_':
690                         lastx = x
691                         continue
692                 elif x in string.digits:
693                         x = chr(ord (x) - ord ('0')  +ord ('A'))
694                 elif x not in string.letters:
695                         x = 'x'
696                 elif x in string.lowercase and lastx == '_':
697                         x = string.upper (x)
698                 s = s + x
699                 lastx = x
700         return s
701
702 if 1:
703         def conv (str):
704                 
705                 def regularize_dollar_reference (match):
706                         return regularize_id (match.group (1))
707                 def regularize_assignment (match):
708                         return '\n' + regularize_id (match.group (1)) + ' = '
709                 str = re.sub ('\$([^\t\n ]+)', regularize_dollar_reference, str)
710                 str = re.sub ('\n([^ \t\n]+)[ \t]*= *', regularize_assignment, str)
711                 return str
712         
713         conversions.append (((1,3,117), conv, 'identifier names: $!foo_bar_123 -> xfooBarABC'))
714
715
716 if 1:
717         def conv (str):
718                 def regularize_paper (match):
719                         return regularize_id (match.group (1))
720                 
721                 str = re.sub ('(paper_[a-z]+)', regularize_paper, str)
722                 str = re.sub ('sustainup', 'sustainUp', str)
723                 str = re.sub ('nobreak', 'noBreak', str)
724                 str = re.sub ('sustaindown', 'sustainDown', str)
725                 str = re.sub ('sostenutoup', 'sostenutoUp', str)
726                 str = re.sub ('sostenutodown', 'sostenutoDown', str)
727                 str = re.sub ('unachorda', 'unaChorda', str)
728                 str = re.sub ('trechorde', 'treChorde', str)
729         
730                 return str
731         
732         conversions.append (((1,3,120), conv, 'paper_xxx -> paperXxxx, pedalup -> pedalUp.'))
733
734 if 1:
735         def conv (str):
736                 str = re.sub ('drarnChords', 'chordChanges', str)
737                 str = re.sub ('\\musicalpitch', '\\pitch', str)
738                 return str
739         
740         conversions.append (((1,3,122), conv, 'drarnChords -> chordChanges, \\musicalpitch -> \\pitch'))
741
742 if 1:
743         def conv (str):
744                 str = re.sub ('ly-([sg])et-elt-property', 'ly-\\1et-grob-property', str)
745                 return str
746         
747         conversions.append (((1,3,136), conv, 'ly-X-elt-property -> ly-X-grob-property'))
748
749 if 1:
750         def conv (str):
751                 str = re.sub ('point-and-click +#t', 'point-and-click line-column-location', str)
752                 return str
753         
754         conversions.append (((1,3,138), conv, 'point-and-click argument changed to procedure.'))
755
756 if 1:
757         def conv (str):
758                 str = re.sub ('followThread', 'followVoice', str)
759                 str = re.sub ('Thread.FollowThread', 'Voice.VoiceFollower', str)
760                 str = re.sub ('FollowThread', 'VoiceFollower', str)
761                 return str
762         
763         conversions.append (((1,3,138), conv, 'followThread -> followVoice.'))
764
765 if 1:
766         def conv (str):
767                 str = re.sub ('font-point-size', 'font-design-size', str)
768                 return str
769         
770         conversions.append (((1,3,139), conv, 'font-point-size -> font-design-size.'))
771
772 if 1:
773         def conv (str):
774                 str = re.sub ('([a-zA-Z]*)NoDots', '\\1Solid', str)
775                 return str
776         
777         conversions.append (((1,3,141), conv, 'xNoDots -> xSolid'))
778
779 if 1:
780         def conv (str):
781                 str = re.sub ('([Cc])hord([ea])', '\\1ord\\2', str)
782                 return str
783         
784         conversions.append (((1,3,144), conv, 'Chorda -> Corda'))
785
786
787 if 1:
788         def conv (str):
789                 str = re.sub ('([A-Za-z]+)MinimumVerticalExtent', 'MinimumV@rticalExtent', str)
790                 str = re.sub ('([A-Za-z]+)ExtraVerticalExtent', 'ExtraV@rticalExtent', str)
791                 str = re.sub ('([A-Za-z]+)VerticalExtent', 'VerticalExtent', str)
792                 str = re.sub ('ExtraV@rticalExtent', 'ExtraVerticalExtent', str)
793                 str = re.sub ('MinimumV@rticalExtent', 'MinimumVerticalExtent', str)            
794                 return str
795
796         conversions.append (((1,3,145), conv,
797         'ContextNameXxxxVerticalExtent -> XxxxVerticalExtent'))
798
799 if 1:
800         def conv (str):
801                 str = re.sub ('\\\\key[ \t]*;', '\\key \\default;', str)
802                 str = re.sub ('\\\\mark[ \t]*;', '\\mark \\default;', str)
803
804                 # Make sure groups of more than one ; have space before
805                 # them, so that non of them gets removed by next rule
806                 str = re.sub ("([^ \n\t;]);(;+)", "\\1 ;\\2", str)
807                 
808                 # Only remove ; that are not after spaces, # or ;
809                 # Otherwise  we interfere with Scheme comments,
810                 # which is badbadbad.
811                 str = re.sub ("([^ \t;#]);", "\\1", str)
812
813                 return str
814         conversions.append (((1,3,146), conv, 'semicolons removed'))
815
816 if 1:
817         def conv (str):
818                 str = re.sub ('default-neutral-direction', 'neutral-direction',str)
819                 return str
820         conversions.append (((1,3,147), conv, 'default-neutral-direction -> neutral-direction'))
821
822 if 1:
823         def conv (str):
824                 str = re.sub ('\(align', '(axis', str)
825                 str = re.sub ('\(rows', '(columns', str)
826                 return str
827         conversions.append (((1,3,148), conv, '"(align" -> "(axis", "(rows" -> "(columns"'))
828
829
830 if 1:
831         def conv (str):
832                 str = re.sub ('SystemStartDelimiter', 'systemStartDelimiter', str)
833                 return str
834         conversions.append (((1,5,33), conv, 'SystemStartDelimiter -> systemStartDelimiter'))
835
836 if 1:
837         def conv (str):
838                 str = re.sub ('arithmetic-multiplier', 'spacing-increment', str)
839                 str = re.sub ('arithmetic-basicspace', 'shortest-duration-space', str)          
840                 return str
841         
842         conversions.append (((1,5,38), conv, 'SystemStartDelimiter -> systemStartDelimiter'))
843
844
845 if 1:
846         def conv (str):
847         
848                 def func(match):
849                         break_dict = {
850                         "Instrument_name": "instrument-name",
851                         "Left_edge_item": "left-edge",
852                         "Span_bar": "span-bar",
853                         "Breathing_sign": "breathing-sign",
854                         "Staff_bar": "staff-bar",
855                         "Clef_item": "clef",
856                         "Key_item": "key-signature",
857                         "Time_signature": "time-signature",
858                         "Custos": "custos"
859                         }
860                         props =  match.group (1)
861                         for (k,v) in break_dict.items():
862                                 props = re.sub (k, v, props)
863                         return  "breakAlignOrder = #'(%s)" % props
864
865                 str = re.sub ("breakAlignOrder *= *#'\\(([a-z_\n\tA-Z ]+)\\)",
866                               func, str)
867                 return str
868
869         # 40 ?
870         conversions.append (((1,5,40), conv, 'breakAlignOrder property names'))
871         
872
873 if 1:
874         def conv (str):
875                 str = re.sub ('noAutoBeaming *= *##f', 'autoBeaming = ##t', str)
876                 str = re.sub ('noAutoBeaming *= *##t', 'autoBeaming = ##f', str)
877                 return str
878         
879         conversions.append (((1,5,49), conv, 'noAutoBeaming -> autoBeaming'))
880
881 if 1:
882         def conv (str):
883                 str = re.sub ('tuplet-bracket-visibility', 'bracket-visibility', str)
884                 str = re.sub ('tuplet-number-visibility', 'number-visibility', str)             
885                 return str
886         
887         conversions.append (((1,5,52), conv, 'tuplet-X-visibility -> X-visibility'))
888
889 if 1:
890         def conv (str):
891                 str = re.sub ('Pitch::transpose', 'ly-transpose-pitch', str)
892
893                 return str
894         
895         conversions.append (((1,5,56), conv, 'Pitch::transpose -> ly-transpose-pitch'))
896
897 if 1:
898         def conv (str):
899                 str = re.sub ('textNonEmpty *= *##t', "TextScript \\set #'no-spacing-rods = ##f", str)
900                 str = re.sub ('textNonEmpty *= *##f', "TextScript \\set #'no-spacing-rods = ##t", str)
901                 return str
902         
903         conversions.append (((1,5,58), conv, 'deprecate textNonEmpty'))
904
905
906 if 1:
907         def conv (str):
908                 str = re.sub ('MinimumVerticalExtent', 'minimumV@rticalExtent', str)
909                 str = re.sub ('minimumVerticalExtent', 'minimumV@rticalExtent', str)            
910                 str = re.sub ('ExtraVerticalExtent', 'extraV@rticalExtent', str)
911                 str = re.sub ('extraVerticalExtent', 'extraV@rticalExtent', str)                
912                 str = re.sub ('VerticalExtent', 'verticalExtent', str)
913                 str = re.sub ('extraV@rticalExtent', 'extraVerticalExtent', str)
914                 str = re.sub ('minimumV@rticalExtent', 'minimumVerticalExtent', str)            
915                 return str
916
917         conversions.append (((1,5,59), conv,
918         'XxxxVerticalExtent -> xxxVerticalExtent'))
919
920 if 1:
921         def conv (str):
922                 str = re.sub ('visibility-lambda', 'break-visibility', str)
923                 return str
924
925         conversions.append (((1,5,62), conv,
926         'visibility-lambda -> break-visibility'))
927         
928
929 if 1:
930         def conv (str):
931                 if re.search (r'\addlyrics',str) \
932                        and re.search ('automaticMelismata', str)  == None:
933                         sys.stderr.write  ('automaticMelismata is turned on by default since 1.5.67. Please fix this by hand.')
934                         raise FatalConversionError()
935                 return str
936
937         conversions.append (((1,5,67), conv,
938                              'automaticMelismata turned on by default'))
939
940 if 1:
941         def conv (str):
942                 str = re.sub ('ly-set-grob-property([^!])', 'ly-set-grob-property!\1', str)
943                 str = re.sub ('ly-set-mus-property([^!])', 'ly-set-mus-property!\1', str)               
944                 return str
945         
946         conversions.append (((1,5,68), conv, 'ly-set-X-property -> ly-set-X-property!'))
947
948 if 1:
949         def conv (str):
950                 str = re.sub ('extent-X', 'X-extent', str)
951                 str = re.sub ('extent-Y', 'Y-extent', str)              
952                 return str
953         
954         conversions.append (((1,5,71), conv, 'extent-[XY] -> [XY]-extent'))
955
956
957 if 1:
958         def conv (str):
959                 str = re.sub ("""#\(set! +point-and-click +line-column-location\)""",
960                               """#(set-point-and-click! \'line-column)""", str)
961                 str = re.sub ("""#\(set![ \t]+point-and-click +line-location\)""",
962                               '#(set-point-and-click! \'line)', str)
963                 str = re.sub ('#\(set! +point-and-click +#f\)',
964                               '#(set-point-and-click! \'none)', str)
965                 return str
966         
967         conversions.append (((1,5,72), conv, 'set! point-and-click -> set-point-and-click!'))
968
969
970 if 1:
971         def conv (str):
972                 str = re.sub ('flag-style', 'stroke-style', str)
973                 str = re.sub (r"""Stem([ ]+)\\override #'style""", r"""Stem \\override #'flag-style""", str);
974                 str = re.sub (r"""Stem([ ]+)\\set([ ]+)#'style""", r"""Stem \\set #'flag-style""", str);
975                 return str
976         
977         conversions.append (((1,6,5), conv, 'Stems: flag-style -> stroke-style; style -> flag-style'))
978
979
980 if 1:
981         def subst_req_name (match):
982                 return "(make-music-by-name \'%sEvent)" % regularize_id (match.group(1))
983
984         def conv (str):
985                 str = re.sub ('\\(ly-make-music *\"([A-Z][a-z_]+)_req\"\\)', subst_req_name, str)
986                 str = re.sub ('Request_chord', 'EventChord', str)
987                 return str
988         
989         conversions.append (((1,7,1), conv, 'ly-make-music foo_bar_req -> make-music-by-name FooBarEvent'))
990
991
992 if 1:
993         spanner_subst ={
994                 "text" : 'TextSpanEvent',
995                 "decrescendo" : 'DecrescendoEvent',
996                 "crescendo" : 'CrescendoEvent',
997                 "Sustain" : 'SustainPedalEvent',
998                 "slur" : 'SlurEvent',
999                 "UnaCorda" : 'UnaCordaEvent',
1000                 "Sostenuto" : 'SostenutoEvent',
1001                 }
1002         def subst_ev_name (match):
1003                 stype = 'STOP'
1004                 if re.search ('start', match.group(1)):
1005                         stype= 'START'
1006
1007                 mtype = spanner_subst[match.group(2)]
1008                 return "(make-span-event '%s %s)" % (mtype , stype)
1009
1010         def subst_definition_ev_name(match):
1011                 return ' = #%s' % subst_ev_name (match)
1012         def subst_inline_ev_name (match):
1013                 s = subst_ev_name (match)
1014                 return '#(ly-export %s)' % s
1015         def subst_csp_definition (match):
1016                 return ' = #(make-event-chord (list %s))' % subst_ev_name (match)
1017         def subst_csp_inline (match):
1018                 return '#(ly-export (make-event-chord (list %s)))' % subst_ev_name (match)
1019                 
1020         def conv (str):
1021                 str = re.sub (r' *= *\\spanrequest *([^ ]+) *"([^"]+)"', subst_definition_ev_name, str)
1022                 str = re.sub (r'\\spanrequest *([^ ]+) *"([^"]+)"', subst_inline_ev_name, str)
1023                 str = re.sub (r' *= *\\commandspanrequest *([^ ]+) *"([^"]+)"', subst_csp_definition, str)
1024                 str = re.sub (r'\\commandspanrequest *([^ ]+) *"([^"]+)"', subst_csp_inline, str)
1025                 str = re.sub (r'ly-id ', 'ly-import ', str)
1026
1027                 str = re.sub (r' *= *\\script "([^"]+)"', ' = #(make-articulation "\\1")', str)
1028                 str = re.sub (r'\\script "([^"]+)"', '#(ly-export (make-articulation "\\1"))', str)
1029                 return str
1030
1031         conversions.append (((1,7,2), conv, '\\spanrequest -> #(make-span-event .. ), \script -> #(make-articulation .. )'))
1032
1033 if 1:
1034         def conv(str):
1035                 str = re.sub (r'\(ly-', '(ly:', str)
1036
1037                 changed = [
1038                         r'duration\?',
1039                         r'font-metric\?',
1040                         r'molecule\?',
1041                         r'moment\?',
1042                         r'music\?',
1043                         r'pitch\?',
1044                         'make-duration',
1045                         'music-duration-length',
1046                         'duration-log',
1047                         'duration-dotcount',
1048                         'intlog2',
1049                         'duration-factor',
1050                         'transpose-key-alist',
1051                         'get-system',
1052                         'get-broken-into',
1053                         'get-original',
1054                         'set-point-and-click!',
1055                         'make-moment',
1056                         'make-pitch',
1057                         'pitch-octave',
1058                         'pitch-alteration',
1059                         'pitch-notename',
1060                         'pitch-semitones',
1061                         r'pitch<\?',
1062                         r'dir\?',
1063                         'music-duration-compress',
1064                         'set-point-and-click!'
1065                         ]
1066
1067                 origre = r'\b(%s)' % string.join (changed, '|')
1068                 
1069                 str = re.sub (origre, r'ly:\1',str)
1070                 str = re.sub ('set-point-and-click!', 'set-point-and-click', str)
1071                 
1072                 return str
1073         
1074         conversions.append (((1,7,3), conv, 'ly- -> ly:'))
1075
1076 if 1:
1077         def conv(str):
1078                 if re.search ('new-chords-done',str):
1079                         return str
1080                 
1081                 str = re.sub (r'<<', '< <', str)
1082                 str = re.sub (r'>>', '> >', str)
1083                 return str
1084         
1085         conversions.append (((1,7,4), conv, '<< >> -> < <  > >'))
1086
1087 if 1:
1088         def conv(str):
1089                 str = re.sub (r"\\transpose", r"\\transpose c'", str)
1090                 str = re.sub (r"\\transpose c' *([a-z]+)'", r"\\transpose c \1", str)
1091                 return str
1092         conversions.append (((1,7,5), conv, '\\transpose TO -> \\transpose FROM  TO'))
1093
1094 if 1:
1095         def conv(str):
1096                 kws =   ['arpeggio',
1097                          'sustainDown',
1098                          'sustainUp',
1099                          'f',
1100                          'p',
1101                          'pp',
1102                          'ppp',
1103                          'fp',
1104                          'ff',
1105                          'mf',
1106                          'mp',
1107                          'sfz',
1108                          ]
1109
1110                 origstr = string.join (kws, '|')
1111                 str = re.sub (r'([^_^-])\\(%s)\b' % origstr, r'\1-\\\2', str)
1112                 return str
1113         conversions.append (((1,7,6), conv, 'note\\script -> note-\script'))
1114
1115
1116 if 1:
1117         def conv(str):
1118                 str = re.sub (r"\\property *ChordNames *\. *ChordName *\\(set|override) *#'style *= *#('[a-z]+)",
1119                               r"#(set-chord-name-style \2)", str)
1120                 str = re.sub (r"\\property *ChordNames *\. *ChordName *\\revert *#'style",
1121                               r"", str)
1122                 return str
1123         conversions.append (((1,7,10), conv, "\property ChordName #'style -> #(set-chord-name-style 'style)"))
1124         
1125
1126
1127 if 1:
1128         def conv(str):
1129                 str = re.sub (r"ly:transpose-pitch", "ly:pitch-transpose", str)
1130                 
1131                 return str
1132         conversions.append (((1,7,11), conv, "transpose-pitch -> pitch-transpose"))
1133
1134 if 1:
1135         def conv(str):
1136                 str = re.sub (r"ly:get-molecule-extent", "ly:molecule-get-extent", str)
1137                 str = re.sub (r"ly:set-molecule-extent!", "ly:molecule-set-extent!", str)
1138                 str = re.sub (r"ly:add-molecule", "ly:molecule-add", str)
1139                 str = re.sub (r"ly:combine-molecule-at-edge", "ly:molecule-combine-at-edge", str)
1140                 str = re.sub (r"ly:align-to!", "ly:molecule-align-to!", str)
1141                 
1142                 return str
1143         
1144         conversions.append (((1,7,13), conv, "ly:XX-molecule-YY -> ly:molecule-XX-YY")) 
1145
1146 if 1:
1147         def conv(str):
1148                 str = re.sub (r"linewidth *= *-[0-9.]+ *(\\mm|\\cm|\\in|\\pt)?", 'raggedright = ##t', str )
1149                 return str
1150         
1151         conversions.append (((1,7,15), conv, "linewidth = -1 -> raggedright = ##t"))    
1152
1153 if 1:
1154         def conv(str):
1155                 str = re.sub ("divisiomaior",
1156                               "divisioMaior", str)
1157                 str = re.sub ("divisiominima",
1158                               "divisioMinima", str)
1159                 str = re.sub ("divisiomaxima",
1160                               "divisioMaxima", str)
1161                 return str
1162         
1163         conversions.append (((1,7,16), conv, "divisiomaior -> divisioMaior"))
1164
1165 if 1:
1166         def conv(str):
1167                 str = re.sub ("Skip_req_swallow_translator",
1168                               "Skip_event_swallow_translator", str)
1169                 return str
1170         
1171         conversions.append (((1,7,17), conv, "Skip_req  -> Skip_event"))
1172
1173 if 1:
1174         def conv(str):
1175                 str = re.sub ("groupOpen",
1176                               "startGroup", str)
1177                 str = re.sub ("groupClose",
1178                               "stopGroup", str)
1179                 str = re.sub ("#'outer",
1180                               "#'enclose-bounds", str)
1181
1182                 return str
1183         
1184         conversions.append (((1,7,18), conv,
1185                              """groupOpen/Close  -> start/stopGroup,
1186                              #'outer  -> #'enclose-bounds
1187                              """))
1188
1189 if 1:
1190         def conv(str):
1191                 if re.search( r'\\GraceContext', str):
1192                         sys.stderr.write ("GraceContext has been removed")
1193                         sys.stderr.write ("please use #(add-to-grace-init .. )")
1194                         raise FatalConversionError()
1195
1196                 str = re.sub ('HaraKiriStaffContext', 'RemoveEmptyStaffContext', str)
1197                 return str
1198         
1199         conversions.append (((1,7,19), conv,"remove GraceContext"))
1200
1201
1202
1203 if 1:
1204         def conv(str):
1205                 str = re.sub (
1206                         r"(set|override|revert) *#'type",
1207                         r"\1 #'style",
1208                         str)
1209                 return str
1210         
1211         conversions.append (((1,7,22), conv,"#'type -> #'style"))
1212
1213 if 1:
1214         def conv(str):
1215                 str = re.sub (
1216                         "barNonAuto *= *##t",
1217                         "automaticBars = ##f",
1218                         str)
1219                 str = re.sub (
1220                         "barNonAuto *= *##f",
1221                         "automaticBars = ##t",
1222                         str)
1223                 return str
1224         
1225         conversions.append (((1,7,23), conv,"barNonAuto -> automaticBars"))
1226         
1227
1228 if 1:
1229         def conv(str):
1230                 if re.search( r'-(start|stop)Cluster', str):
1231                         sys.stderr.write ("""Cluster syntax has been changed.
1232 Please refer to the manual for details, and convert manually.
1233 """)
1234                         
1235                         raise FatalConversionError()
1236
1237                 return str
1238         
1239         conversions.append (((1,7,24), conv,"cluster syntax"))
1240
1241 if 1:
1242         def conv(str):
1243                 str = re.sub (r"\\property *Staff\.(Sustain|Sostenuto|UnaCorda)Pedal *\\(override|set) *#'pedal-type *",
1244                                 r"\property Staff.pedal\1Style ", str)
1245                 str = re.sub (r"\\property *Staff\.(Sustain|Sostenuto|UnaCorda)Pedal *\\revert *#'pedal-type", '', str)
1246                 return str
1247         
1248         conversions.append (((1,7,28), conv,"new Pedal style syntax"))
1249
1250
1251
1252 if 1:
1253
1254         def sub_chord (m):
1255                 str = m.group(1)
1256
1257                 origstr =  '<%s>' % str
1258                 if re.search (r'\\\\', str):
1259                         return origstr
1260
1261                 if re.search (r'\\property', str):
1262                         return origstr
1263
1264                 if re.match (r'^\s*\)?\s*\\[a-zA-Z]+', str):
1265                         return origstr
1266
1267                 durs = []
1268                 def sub_durs (m, durs = durs):
1269                         durs.append(m.group(2))
1270                         return m.group (1)
1271
1272                 str = re.sub (r"([a-z]+[,'!? ]*)([0-9]+\.*)", sub_durs, str)
1273                 dur_str = ''
1274
1275                 for d in durs:
1276                         if dur_str == '':
1277                                 dur_str = d
1278                         if dur_str <> d:
1279                                 return '<%s>' % m.group (1)
1280
1281                 pslur_strs = ['']
1282                 dyns = ['']
1283                 slur_strs = ['']
1284
1285                 last_str = ''
1286                 while last_str <> str:
1287                         last_str = str
1288
1289                         def sub_tremolos (m, slur_strs = slur_strs):
1290                                 tr = m.group (2)
1291                                 if tr not in slur_strs:
1292                                         slur_strs.append (tr)
1293                                 return  m.group (1)
1294                         
1295                         str = re.sub (r"([a-z]+[',!? ]*)(:[0-9]+)",
1296                                       sub_tremolos, str)
1297
1298                         def sub_dyn_end (m, dyns = dyns):
1299                                 dyns.append (' \!')
1300                                 return ' ' + m.group(2)
1301
1302                         str = re.sub (r'(\\!)\s*([a-z]+)', sub_dyn_end, str)
1303                         def sub_slurs(m, slur_strs = slur_strs):
1304                                 if '-)' not in slur_strs:
1305                                         slur_strs.append (')')
1306                                 return m.group(1)
1307                         
1308                         def sub_p_slurs(m, slur_strs = slur_strs):
1309                                 if '-\)' not in slur_strs:
1310                                         slur_strs.append ('\)')
1311                                 return m.group(1)
1312                         
1313                         str = re.sub (r"\)[ ]*([a-z]+)", sub_slurs, str)
1314                         str = re.sub (r"\\\)[ ]*([a-z]+)", sub_p_slurs, str)
1315                         def sub_begin_slurs(m, slur_strs = slur_strs):
1316                                 if '-(' not in slur_strs:
1317                                         slur_strs.append ('(')
1318                                 return m.group(1)
1319                         
1320                         str = re.sub (r"([a-z]+[,'!?0-9 ]*)\(",
1321                                       sub_begin_slurs, str)
1322                         def sub_begin_p_slurs(m, slur_strs = slur_strs):
1323                                 if '-\(' not in slur_strs:
1324                                         slur_strs.append ('\(')
1325                                 return m.group(1)
1326
1327                         str = re.sub (r"([a-z]+[,'!?0-9 ]*)\\\(",
1328                                 sub_begin_p_slurs, str)
1329
1330                         def sub_dyns (m, slur_strs = slur_strs):
1331                                 s = m.group(0)
1332                                 if s == '@STARTCRESC@':
1333                                         slur_strs.append ("\\<")
1334                                 elif s == '@STARTDECRESC@':
1335                                         slur_strs.append ("\\>")
1336                                 elif s == r'-?\\!':
1337                                         slur_strs.append ('\\!')
1338                                 return ''
1339
1340                         str = re.sub (r'@STARTCRESC@', sub_dyns, str)
1341                         str = re.sub (r'-?\\!', sub_dyns, str)
1342
1343                         def sub_articulations (m, slur_strs = slur_strs):
1344                                 a = m.group(1)
1345                                 if a not in slur_strs:
1346                                         slur_strs.append (a)
1347                                 return ''
1348
1349                         str = re.sub (r"([_^-]\@ACCENT\@)", sub_articulations,
1350                                       str)
1351                         str = re.sub (r"([_^-]\\[a-z]+)", sub_articulations,
1352                                       str)
1353                         str = re.sub (r"([_^-][>_.+|^-])", sub_articulations,
1354                                       str)
1355                         str = re.sub (r'([_^-]"[^"]+")', sub_articulations,
1356                                       str)
1357
1358                         def sub_pslurs(m, slur_strs = slur_strs):
1359                                 slur_strs.append (' \\)')
1360                                 return m.group(1)
1361                         str = re.sub (r"\\\)[ ]*([a-z]+)", sub_pslurs, str)
1362
1363                 ## end of while <>
1364
1365                 suffix = string.join (slur_strs, '') + string.join (pslur_strs,
1366                                                                     '') \
1367                          + string.join (dyns, '')
1368
1369                 return '@STARTCHORD@%s@ENDCHORD@%s%s' % (str , dur_str, suffix)
1370
1371
1372
1373         def sub_chords (str):
1374                 simend = '>'
1375                 simstart = '<'
1376                 chordstart = '<<'
1377                 chordend = '>>'
1378                 marker_str = '%% new-chords-done %%'
1379
1380                 if re.search (marker_str,str):
1381                         return str
1382                 str = re.sub ('<<', '@STARTCHORD@', str)
1383                 str = re.sub ('>>', '@ENDCHORD@', str)
1384                 
1385                 str = re.sub (r'\\<', '@STARTCRESC@', str)
1386                 str = re.sub (r'\\>', '@STARTDECRESC@', str)
1387                 str = re.sub (r'([_^-])>', r'\1@ACCENT@', str)
1388                 str = re.sub (r'<([^<>{}]+)>', sub_chord, str)
1389
1390                 # add dash: -[, so that [<<a b>> c d] becomes
1391                 #                      <<a b>>-[ c d]
1392                 # and gets skipped by articulation_substitute
1393                 str = re.sub (r'\[ *(@STARTCHORD@[^@]+@ENDCHORD@[0-9.]*)',
1394                               r'\1-[', str)
1395                 str = re.sub (r'\\! *(@STARTCHORD@[^@]+@ENDCHORD@[0-9.]*)',
1396                               r'\1-\\!', str)
1397                 
1398                 str = re.sub (r'<([^?])', r'%s\1' % simstart, str)
1399                 str = re.sub (r'>([^?])', r'%s\1' % simend,  str)
1400                 str = re.sub ('@STARTCRESC@', r'\\<', str)
1401                 str = re.sub ('@STARTDECRESC@', r'\\>' ,str)
1402                 str = re.sub (r'\\context *Voice *@STARTCHORD@',
1403                               '@STARTCHORD@', str)
1404                 str = re.sub ('@STARTCHORD@', chordstart, str)
1405                 str = re.sub ('@ENDCHORD@', chordend, str)
1406                 str = re.sub (r'@ACCENT@', '>', str)
1407                 return str
1408
1409         def articulation_substitute (str):
1410                 str = re.sub (r"""([^-])\[ *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1411                               r"\1 \2[", str)
1412                 str = re.sub (r"""([^-])\\\) *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1413                               r"\1 \2\\)", str)
1414                 str = re.sub (r"""([^-\\])\) *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1415                               r"\1 \2)", str)
1416                 str = re.sub (r"""([^-])\\! *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1417                               r"\1 \2\\!", str)
1418                 return str
1419         
1420         def conv_relative(str):
1421                 if re.search (r"\\relative", str):
1422                         str= "#(ly:set-option 'old-relative)\n" + str
1423
1424                 return str
1425         
1426         def conv (str):
1427                 str = re.sub (r"#'\(\)", "@SCM_EOL@", str)
1428                 str =  conv_relative (str)
1429                 str = sub_chords (str)
1430
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 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 '\\tuning %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 ################################
2058 #       END OF CONVERSIONS      
2059 ################################
2060
2061 def get_conversions (from_version, to_version):
2062         def version_b (v, f = from_version, t = to_version):
2063                 return version_cmp (v[0], f) > 0 and version_cmp (v[0], t) <= 0
2064         return filter (version_b, conversions)
2065
2066
2067 def latest_version ():
2068         return conversions[-1][0]
2069
2070 def do_conversion (infile, from_version, outfile, to_version):
2071         conv_list = get_conversions (from_version, to_version)
2072
2073         sys.stderr.write ('Applying conversions: ')
2074         str = infile.read ()
2075         last_conversion = ()
2076         try:
2077                 for x in conv_list:
2078                         sys.stderr.write (tup_to_str (x[0])  + ', ')
2079                         str = x[1] (str)
2080                         last_conversion = x[0]
2081
2082         except FatalConversionError:
2083                 sys.stderr.write ('Error while converting; I won\'t convert any further')
2084
2085         if last_conversion:
2086                 sys.stderr.write ('\n')
2087                 new_ver =  '\\version \"%s\"' % tup_to_str (last_conversion)
2088
2089                 if re.search (lilypond_version_re_str, str):
2090                         str = re.sub (lilypond_version_re_str,'\\'+new_ver , str)
2091                 elif add_version:
2092                         str = new_ver + '\n' + str
2093
2094                 outfile.write(str)
2095
2096         return last_conversion
2097         
2098 class UnknownVersion:
2099         pass
2100
2101 def do_one_file (infile_name):
2102         sys.stderr.write ('Processing `%s\' ... '% infile_name)
2103         outfile_name = ''
2104         if __main__.edit:
2105                 outfile_name = infile_name + '.NEW'
2106         elif __main__.outfile_name:
2107                 outfile_name = __main__.outfile_name
2108
2109         if __main__.from_version:
2110                 from_version = __main__.from_version
2111         else:
2112                 guess = guess_lilypond_version (infile_name)
2113                 if not guess:
2114                         raise UnknownVersion()
2115                 from_version = str_to_tuple (guess)
2116
2117         if __main__.to_version:
2118                 to_version = __main__.to_version
2119         else:
2120                 to_version = latest_version ()
2121
2122
2123         if infile_name:
2124                 infile = open (infile_name,'r')
2125         else:
2126                 infile = sys.stdin
2127
2128         if outfile_name:
2129                 outfile =  open (outfile_name, 'w')
2130         else:
2131                 outfile = sys.stdout
2132
2133         touched = do_conversion (infile, from_version, outfile, to_version)
2134
2135         if infile_name:
2136                 infile.close ()
2137
2138         if outfile_name:
2139                 outfile.close ()
2140
2141         if __main__.edit and touched:
2142                 try:
2143                         os.remove(infile_name + '~')
2144                 except:
2145                         pass
2146                 os.rename (infile_name, infile_name + '~')
2147                 os.rename (infile_name + '.NEW', infile_name)
2148
2149         sys.stderr.write ('\n')
2150         sys.stderr.flush ()
2151
2152 edit = 0
2153 assume_old = 0
2154 to_version = ()
2155 from_version = ()
2156 outfile_name = ''
2157
2158 (options, files) = getopt.getopt (
2159         sys.argv[1:], 'ao:f:t:senh', ['no-version', 'version', 'output', 'show-rules', 'help', 'edit', 'from=', 'to='])
2160
2161 for opt in options:
2162         o = opt[0]
2163         a = opt[1]
2164         if o== '--help' or o == '-h':
2165                 usage ()
2166                 sys.exit (0)
2167         if o == '--version' or o == '-v':
2168                 print_version ()
2169                 sys.exit (0)
2170         elif o== '--from' or o=='-f':
2171                 from_version = str_to_tuple (a)
2172         elif o== '--to' or o=='-t':
2173                 to_version = str_to_tuple (a)
2174         elif o== '--edit' or o == '-e':
2175                 edit = 1
2176         elif o== '--show-rules' or o == '-s':
2177                 show_rules (sys.stdout)
2178                 sys.exit(0)
2179         elif o == '--output' or o == '-o':
2180                 outfile_name = a
2181         elif o == '--no-version' or o == '-n':
2182                 add_version = 0
2183         else:
2184                 print o
2185                 raise getopt.error
2186
2187 identify ()
2188 for f in files:
2189         if f == '-':
2190                 f = ''
2191         elif not os.path.isfile (f):
2192                 continue
2193         try:
2194                 do_one_file (f)
2195         except UnknownVersion:
2196                 sys.stderr.write ('\n')
2197                 sys.stderr.write ("%s: can't determine version for `%s'" % (program_name, f))
2198                 sys.stderr.write ('\n')
2199                 if assume_old:
2200                         fv = from_version
2201                         from_version = (0,0,0)
2202                         do_one_file (f)
2203                         from_version = fv
2204                 else:
2205                         sys.stderr.write ("%s: skipping: `%s' " % (program_name,  f))
2206                 pass
2207
2208 sys.stderr.write ('\n')