]> git.donarmstrong.com Git - lilypond.git/blob - scripts/convert-ly.py
* lily/part-combine-engraver.cc: rename soloADue ->
[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 text_markup (str):
1410                 str = re.sub (r"""([-_^]) *# *' *\( *music *(\"[^"]*\") *\)""",
1411                                 r"\1\\markup { \\musicglyph #\2 }", str)
1412                 str = re.sub (r"""([-_^]) *# *' *\( *([a-z]+) *([^()]*)\)""",
1413                                 r"\1\\markup { \\\2 \3 }", str)
1414                 str = re.sub (r"""\\mark *# *' *\( *music *(\"[^"]*\") *\)""",
1415                                 r"\\mark \\markup { \\musicglyph #\1 }", str)
1416                 str = re.sub (r"""\\mark *# *' *\( *([a-z]+) *([^()]*)\)""",
1417                                 r"\\mark \\markup { \\\1 \2 }", str)
1418                 return str      
1419
1420         def articulation_substitute (str):
1421                 str = re.sub (r"""([^-])\[ *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1422                               r"\1 \2[", str)
1423                 str = re.sub (r"""([^-])\\\) *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1424                               r"\1 \2\\)", str)
1425                 str = re.sub (r"""([^-\\])\) *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1426                               r"\1 \2)", str)
1427                 str = re.sub (r"""([^-])\\! *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1428                               r"\1 \2\\!", str)
1429                 return str
1430         
1431         def conv_relative(str):
1432                 if re.search (r"\\relative", str):
1433                         str= "#(ly:set-option 'old-relative)\n" + str
1434
1435                 return str
1436         
1437         def conv (str):
1438                 str = re.sub (r"#'\(\)", "@SCM_EOL@", str)
1439                 str =  conv_relative (str)
1440                 str = sub_chords (str)
1441
1442                 str = text_markup (str)
1443                 str = articulation_substitute (str)
1444                 str = re.sub ("@SCM_EOL@", "#'()", str)
1445                 
1446                 return str
1447         
1448         conversions.append (((1,9,0), conv, """New relative mode,
1449 Postfix articulations, new text markup syntax, new chord syntax."""))
1450
1451 if 1:
1452         def conv (str):
1453                 if re.search ("font-style",str):
1454                         sys.stderr.write ("font-style is deprecated. Please remove.")
1455                         raise FatalConversionError()
1456                         
1457                 str = re.sub (r'-\\markup', r'@\\markup', str)
1458                 str = re.sub (r'-\\', r'\\', str)
1459                 str = re.sub (r'-\)', ')', str)
1460                 str = re.sub (r'-\(', '(', str)
1461                 str = re.sub ('-\[', '[', str)
1462                 str = re.sub ('-\]', ']', str)
1463                 str = re.sub ('-~', '~', str)
1464                 str = re.sub (r'@\\markup', r'-\\markup', str)
1465                 return str
1466
1467         conversions.append (((1,9,1), conv, """Remove - before articulation"""))
1468 if 1:
1469         def conv (str):
1470                 str = re.sub ('ly:set-context-property',
1471                               'ly:set-context-property!', str)
1472                 str = re.sub ('\\\\newcontext', '\\\\new', str)
1473                 str = re.sub ('\\\\grace[\t\n ]*([^{ ]+)',
1474                               r'\\grace { \1 }', str)
1475                 str = re.sub ("\\\\grace[\t\n ]*{([^}]+)}",
1476                               r"""\\grace {
1477   \\property Voice.Stem \\override #'stroke-style = #"grace"
1478   \1
1479   \\property Voice.Stem \\revert #'stroke-style }
1480 """, str)
1481                 
1482                 return str
1483         
1484         conversions.append (((1,9,2), conv, """\\newcontext -> \\new"""))
1485
1486 if 1:
1487         def conv (str):
1488                 str = re.sub ('accacciatura',
1489                               'acciaccatura', str)
1490
1491                 if re.search ("context-spec-music", str):
1492                         sys.stderr.write ("context-spec-music takes a symbol for the context now. Update by hand.")
1493                                         
1494                         raise FatalConversionError()
1495                 
1496                 str = re.sub ('fingerHorizontalDirection *= *#(LEFT|-1)',
1497                               "fingeringOrientations = #'(up down left)", str)
1498                 str = re.sub ('fingerHorizontalDirection *= *#(RIGHT|1)',
1499                               "fingeringOrientations = #'(up down right)", str)
1500
1501                 return str
1502         
1503         conversions.append (((1,9,3), conv,
1504                              """\\acciaccatura misspelling, fingerHorizontalDirection -> fingeringOrientations"""))
1505
1506
1507 def conv (str):
1508         if re.search ('\\figures', str):
1509                 sys.stderr.write ("Warning: attempting automatic \\figures conversion.  Check results!");
1510                 
1511         
1512         def figures_replace (m):
1513                 s = m.group (1)
1514                 s = re.sub ('<', '@FIGOPEN@',s)
1515                 s = re.sub ('>', '@FIGCLOSE@',s)
1516                 return '\\figures { %s }' % s
1517         
1518         str = re.sub (r'\\figures[ \t\n]*{([^}]+)}', figures_replace, str)
1519         str = re.sub (r'\\<', '@STARTCRESC@', str)
1520         str = re.sub (r'\\>', '@STARTDECRESC@', str)
1521         str = re.sub (r'([-^_])>', r'\1@ACCENT@', str)
1522         str = re.sub (r'<<', '@STARTCHORD@', str)
1523         str = re.sub (r'>>', '@ENDCHORD@', str)
1524         str = re.sub (r'>', '@ENDSIMUL@', str)
1525         str = re.sub (r'<', '@STARTSIMUL@', str)
1526         str = re.sub ('@STARTDECRESC@', '\\>', str)
1527         str = re.sub ('@STARTCRESC@', '\\<', str)
1528         str = re.sub ('@ACCENT@', '>', str)
1529         str = re.sub ('@ENDCHORD@', '>', str)
1530         str = re.sub ('@STARTCHORD@', '<', str)
1531         str = re.sub ('@STARTSIMUL@', '<<', str)
1532         str = re.sub ('@ENDSIMUL@', '>>', str)
1533         str = re.sub ('@FIGOPEN@', '<', str)
1534         str = re.sub ('@FIGCLOSE@', '>', str)
1535
1536         return str
1537
1538 conversions.append (((1,9,4), conv, 'Swap < > and << >>'))
1539
1540
1541 def conv (str):
1542         str = re.sub ('HaraKiriVerticalGroup', 'RemoveEmptyVerticalGroup', str)
1543
1544         return str
1545
1546 conversions.append (((1,9,5), conv, 'HaraKiriVerticalGroup -> RemoveEmptyVerticalGroup'))
1547
1548 def conv (str):
1549         if re.search ("ly:get-font", str) :
1550                 sys.stderr.write (r"(ly:get-font foo ..)  has been replaced by" + \
1551                                   " (ly:paper-get-font (ly:grob-get-paper foo) .. ).\n" +\
1552                                   "please update manually.")
1553                 
1554                 raise FatalConversionError()
1555         
1556         if re.search ("\\pitch *#", str) :
1557                 sys.stderr.write (r"\\pitch has been deprecated. " +\
1558                                   " Use Scheme code to construct arbitrary note events.")
1559                 
1560                 raise FatalConversionError()
1561         
1562         return str
1563                 
1564
1565 conversions.append (((1,9,6), conv, 'ly:get-font deprecated.'))
1566
1567 def conv (str):
1568         def sub_alteration (m):
1569                 alt = m.group (3)
1570                 alt = {
1571                         '-1': 'FLAT',
1572                         '-2': 'DOUBLE-FLAT',
1573                         '0': 'NATURAL',
1574                         '1': 'SHARP',
1575                         '2': 'DOUBLE-SHARP',
1576                         }[alt]
1577                 
1578                 return '(ly:make-pitch %s %s %s)' % (m.group(1), m.group (2),
1579                                                      alt)
1580         
1581         str =re.sub ("\\(ly:make-pitch *([0-9-]+) *([0-9-]+) *([0-9-]+) *\\)",
1582                      sub_alteration, str)
1583
1584
1585         str = re.sub ("ly:verbose", "ly:get-option 'verbose", str)
1586
1587         m= re.search ("\\\\outputproperty #([^#]+)[\t\n ]*#'([^ ]+)", str)
1588         if m:
1589                 sys.stderr.write (\
1590                         r"""\outputproperty found,
1591 Please hand-edit, using
1592
1593   \applyoutput #(outputproperty-compatibility %s '%s <GROB PROPERTY VALUE>)
1594
1595 as a substitution text.""" % (m.group (1), m.group (2)) )
1596                 raise FatalConversionError ()
1597
1598         if re.search ("ly:(make-pitch|pitch-alteration)", str) \
1599                or re.search ("keySignature", str):
1600                 sys.stderr.write (
1601 """The alteration field of Scheme pitches was multiplied by 2
1602 to support quarter tone accidentals. You have to edit the following constructs by hand:
1603
1604 * calls of  ly:make-pitch and ly:pitch-alteration
1605 * keySignature settings made with \property
1606 """)
1607                 raise FatalConversionError ()
1608         
1609         return str
1610 conversions.append (((1,9,7), conv,
1611                      '''use symbolic constants for alterations,
1612 remove \\outputproperty, move ly:verbose into ly:get-option'''))
1613
1614
1615 def conv (str):
1616         if re.search ("dash-length",str):
1617                 sys.stderr.write ("""dash-length has been removed. Use dash-fraction instead.""")
1618                 raise FatalConversionError()
1619         return str
1620
1621 conversions.append (((1,9,8), conv, """dash-length -> dash-fraction"""))
1622
1623
1624 def conv (str):
1625         def func(match):
1626                 return "#'font-size = #%d" % (2*string.atoi (match.group (1))) 
1627                 
1628         str =re.sub (r"#'font-relative-size\s*=\s*#\+?([0-9-]+)", func, str)
1629         str =re.sub (r"#'font-family\s*=\s*#'ancient",
1630                      r"#'font-family = #'music", str)
1631         
1632         return str
1633
1634 conversions.append (((2,1,1), conv, """font-relative-size -> font-size"""))
1635
1636 def conv (str):
1637         str =re.sub (r"ly:get-music-length", "ly:music-length", str)
1638         return str
1639
1640 conversions.append (((2,1,2), conv, """ly:get-music-length -> ly:music-length"""))
1641
1642 def conv (str):
1643         str =re.sub (r"\.\s+stz=", ". instr ", str)
1644         return str
1645
1646 conversions.append (((2,1,3), conv, """stanza -> instrument"""))
1647
1648 def conv (str):
1649         def func (match):
1650                 c = match.group (1)
1651                 b = match.group (2)
1652                 
1653                 if b == 't':
1654                         if c == 'Score':
1655                                 return ''
1656                         else:
1657                                 return r" \property %s.melismaBusyProperties \unset"  % c
1658                 elif b == 'f':
1659                         return r"\property %s.melismaBusyProperties = #'(melismaBusy)"  % c
1660                 
1661         str =re.sub (r"\\property ([a-zA-Z]+)\s*\.\s*automaticMelismata\s*=\s*##([ft])", func, str)
1662         return str
1663
1664 conversions.append (((2,1,4), conv, """removal of automaticMelismata; use melismaBusyProperties instead."""))
1665
1666
1667
1668 def conv (str):
1669         str =re.sub (r"\\translator\s+([a-zA-Z]+)", r"\\change \1", str)
1670         return str
1671
1672 conversions.append (((2,1,7), conv, """\\translator Staff -> \\change Staff"""))
1673
1674 def conv (str):
1675         str =re.sub (r"\\newaddlyrics", r"\\lyricsto", str)
1676         return str
1677
1678 conversions.append (((2,1,10), conv, """\\newaddlyrics -> \\lyricsto"""))
1679
1680 def conv (str):
1681         str = re.sub (r'\\include\s*"paper([0-9]+)(-init)?.ly"',
1682                       r"#(set-staff-size \1)", str)
1683
1684         def sub_note (match):
1685                 dur = ''
1686                 log = string.atoi (match.group (1))
1687                 dots = string.atoi (match.group (2))
1688                 
1689                 if log >= 0:
1690                         dur = '%d' % (1 << log)
1691                 else:
1692                         dur = { -1 : 'breve',
1693                                 -2 : 'longa',
1694                                 -3 : 'maxima'}[log]
1695
1696                 dur += ('.' * dots)
1697                 
1698                 return r'\note #"%s" #%s' % (dur, match.group (3))
1699         
1700         str = re.sub (r'\\note\s+#([0-9-]+)\s+#([0-9]+)\s+#([0-9.-]+)',
1701                       sub_note, str)
1702         return str
1703
1704 conversions.append (((2,1,11), conv, """\\include "paper16.ly" -> #(set-staff-size 16)
1705 \\note #3 #1 #1 -> \\note #"8." #1
1706 """))
1707
1708
1709 def conv (str):
1710         str =re.sub (r"OttavaSpanner", r"OttavaBracket", str)
1711         return str
1712
1713 conversions.append (((2,1,12), conv, """OttavaSpanner -> OttavaBracket"""))
1714
1715
1716 def conv (str):
1717         str =re.sub (r"\(set-staff-size ", r"(set-global-staff-size ", str)
1718         return str
1719
1720 conversions.append (((2,1,13), conv, """set-staff-size -> set-global-staff-size"""))
1721
1722 def conv (str):
1723         str =re.sub (r"#'style\s*=\s*#'dotted-line",
1724                      r"#'dash-fraction = #0.0 ", str)
1725         return str
1726
1727 conversions.append (((2,1,14), conv, """style = dotted -> dash-fraction = 0"""))
1728
1729 def conv (str):
1730         str =re.sub (r'LyricsVoice\s*\.\s*instrument\s*=\s*("[^"]*")',
1731                      r'LyricsVoice . vocalName = \1', str)
1732         
1733         str =re.sub (r'LyricsVoice\s*\.\s*instr\s*=\s*("[^"]*")',
1734                      r'LyricsVoice . vocNam = \1', str)
1735         return str
1736
1737 conversions.append (((2,1,15), conv, """LyricsVoice . instr(ument) -> vocalName"""))
1738
1739 def conv (str):
1740         def sub_acc (m):
1741                 d = {
1742                 '4': 'doublesharp',
1743                 '3': 'threeqsharp',
1744                 '2': 'sharp',
1745                 '1': 'semisharp',
1746                 '0': 'natural',
1747                 '-1': 'semiflat',
1748                 '-2': 'flat',
1749                 '-3': 'threeqflat',
1750                 '-4': 'doubleflat'}
1751                 return '\\%s' %  d[m.group (1)]
1752                      
1753         str = re.sub (r'\\musicglyph\s*#"accidentals-([0-9-]+)"',
1754                       sub_acc, str)
1755         return str
1756
1757 conversions.append (((2,1,16), conv, """\\musicglyph #"accidentals-NUM" -> \\sharp/flat/etc."""))
1758
1759
1760 def conv (str):
1761
1762         if re.search (r'\\partcombine', str):
1763                 sys.stderr.write ('Warning: \\partcombine has been changed. '
1764                                   +'Check conversion manually!')
1765
1766                 raise FatalConversionError()
1767
1768         # this rule doesn't really work,
1769         # too lazy to figure out why.
1770         str = re.sub (r'\\context\s+Voice\s*=\s*one\s*\\partcombine\s+Voice\s*\\context\s+Thread\s*=\s*one(.*)\s*'
1771                       + r'\\context\s+Thread\s*=\s*two',
1772                       '\\\\newpartcombine\n\\1\n', str)
1773         
1774         
1775         return str
1776
1777 conversions.append (((2,1,17), conv, """\\partcombine syntax change to \\newpartcombine"""))
1778
1779
1780 def conv (str):
1781         str = re.sub (r'\\newpartcombine', r'\\partcombine', str)
1782         str = re.sub (r'\\autochange\s+Staff', r'\\autochange ', str)
1783         return str
1784
1785 conversions.append (((2,1,18), conv, """\\newpartcombine -> \\partcombine,
1786 \\autochange Staff -> \\autochange
1787 """))
1788
1789
1790
1791
1792 def conv (str):
1793         str = re.sub (r'\\include "drumpitch-init.ly"','', str)
1794         str = re.sub (r'\\pitchnames ','pitchnames = ', str)
1795         str = re.sub (r'\\chordmodifiers ','chordmodifiers = ', str)
1796         str = re.sub (r'\bdrums\b\s*=','drumContents = ', str)
1797         str = re.sub (r'\\drums\b','\\drumContents ', str)
1798         
1799
1800         if re.search ('drums->paper', str):
1801                 sys.stderr.write ("\nDrum notation found. Check file manually!")
1802                 
1803         str = re.sub (r"""\\apply\s+#\(drums->paper\s+'([a-z]+)\)""",
1804                       r"""\property DrumStaff.drumStyleTable = #\1-style""",
1805                       str)
1806
1807         if re.search ('Thread', str):
1808                 sys.stderr.write ("\nThread found. Check file manually!\n");
1809
1810         str = re.sub (r"""(\\once\s*)?\\property\s+Thread\s*\.\s*NoteHead\s*"""
1811                       + r"""\\(set|override)\s*#'style\s*=\s*#'harmonic"""
1812                       + r"""\s+([a-z]+[,'=]*)([0-9]*\.*)"""                   
1813                       ,r"""<\3\\harmonic>\4""", str)
1814
1815         str = re.sub (r"""\\new Thread""", """\context Voice""", str)
1816         str = re.sub (r"""Thread""", """Voice""", str)
1817
1818         if re.search ('\bLyrics\b', str):
1819                 sys.stderr.write ("\nLyrics found. Check file manually!\n");
1820
1821         str = re.sub (r"""LyricsVoice""", r"""L@ricsVoice""", str)
1822         str = re.sub (r"""\bLyrics\b""", r"""LyricsVoice""", str)
1823         str = re.sub (r"""LyricsContext""", r"""LyricsVoiceContext""", str)
1824         str = re.sub (r"""L@ricsVoice""", r"""LyricsVoice""",str)
1825         
1826         
1827         return str
1828
1829 conversions.append (((2,1,19), conv, """Drum notation changes, Removing \\chordmodifiers, \\notenames.
1830 Harmonic notes. Thread context removed. Lyrics context removed."""))
1831
1832 def conv (str):
1833         str = re.sub (r'nonevent-skip', 'skip-music', str)
1834         return str
1835
1836 conversions.append (((2,1,20), conv, """nonevent-skip -> skip-music""" ))
1837
1838 def conv (str):
1839         str = re.sub (r'molecule-callback', 'print-function', str)
1840         str = re.sub (r'brew_molecule', 'print', str)
1841         str = re.sub (r'brew-new-markup-molecule', 'Text_item::print', str)
1842         str = re.sub (r'LyricsVoice', 'Lyrics', str)
1843         str = re.sub (r'tupletInvisible',
1844                       r"TupletBracket \\set #'transparent", str)
1845 #       str = re.sub (r'molecule', 'collage', str)
1846 #molecule -> collage
1847         str = re.sub (r"\\property\s+[a-zA-Z]+\s*\.\s*[a-zA-Z]+\s*"
1848                       + r"\\set\s*#'X-extent-callback\s*=\s*#Grob::preset_extent",
1849                       "", str)
1850
1851         return str
1852
1853 conversions.append (((2,1,21), conv, """molecule-callback -> print-function,
1854 brew_molecule -> print
1855 brew-new-markup-molecule -> Text_item::print
1856 LyricsVoice -> Lyrics
1857 tupletInvisible -> TupletBracket \set #'transparent
1858 Grob::preset_extent removed.
1859 """ ))
1860
1861
1862 def conv (str):
1863         str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\=]+)\s*\\(set|override)',
1864                       r"\\overrid@ \1.\2 ", str)
1865         str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\= ]+)\s*=\s*',
1866                       r'\\s@t \1.\2 = ', str)
1867         str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\= ]+)\s*\\unset',
1868                       r'\\uns@t \1.\2 ', str)
1869         str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\= ]+)\s*\\revert'
1870                       + r"\s*#'([-a-z0-9_]+)",
1871                       r"\\rev@rt \1.\2 #'\3", str)
1872         str = re.sub (r'Voice\.', '', str)
1873         str = re.sub (r'Lyrics\.', '', str)
1874         str = re.sub (r'ChordNames\.', '', str)
1875         
1876         str = re.sub ('rev@rt', 'revert',str)
1877         str = re.sub ('s@t', 'set',str)
1878         str = re.sub ('overrid@', 'override',str)
1879
1880         str = re.sub ('molecule', 'stencil', str)
1881         str = re.sub ('Molecule', 'Stencil', str)
1882         return str
1883
1884 conversions.append (((2,1,22), conv, """new syntax for property settings:
1885         \\set A.B = #C , \\unset A.B
1886         \\override A.B #C = #D, \\revert A.B #C
1887
1888 """))
1889
1890 def conv (str):
1891         def subst_in_trans (match):
1892                 s = match.group (0)
1893                 s = re.sub (r'\s([a-zA-Z]+)\s*\\override',
1894                               r' \\override \1', s)
1895                 s = re.sub (r'\s([a-zA-Z]+)\s*\\set',
1896                               r' \\override \1', s)
1897                 s = re.sub (r'\s([a-zA-Z]+)\s*\\revert',
1898                               r' \\revert \1', s)
1899                 return s
1900         str = re.sub (r'\\(translator|with)\s*{[^}]+}',  subst_in_trans, str)
1901
1902         def sub_abs (m):
1903                 
1904                 context = m.group ('context')
1905                 d = m.groupdict ()
1906                 if context:
1907                         context = " '%s" % context[:-1] # -1: remove . 
1908                 else:
1909                         context = ''
1910
1911                 d['context'] = context
1912                 
1913                 return r"""#(override-auto-beam-setting %(prop)s %(num)s %(den)s%(context)s)""" % d
1914
1915         str = re.sub (r"""\\override\s*(?P<context>[a-zA-Z]+\s*\.\s*)?autoBeamSettings"""
1916                       +r"""\s*#(?P<prop>[^=]+)\s*=\s*#\(ly:make-moment\s+(?P<num>\d+)\s+(?P<den>\d)\s*\)""",
1917                       sub_abs, str)
1918         
1919         return str
1920         
1921 conversions.append (((2,1,23), conv, """Property setting syntax in \\translator{ }"""))
1922 def conv (str):
1923         str = re.sub (r'music-list\?', 'ly:music-list?', str)
1924         str = re.sub (r'\|\s*~', '~ |', str)   
1925         return str
1926
1927 conversions.append (((2,1,24), conv, """music-list? -> ly:music-list?"""))
1928
1929 def conv (str):
1930         str = re.sub (r'ly:get-spanner-bound', 'ly:spanner-get-bound', str)
1931         str = re.sub (r'ly:get-extent', 'ly:grob-extent', str)
1932         str = re.sub (r'ly:get-system', 'ly:grob-system', str)
1933         str = re.sub (r'ly:get-original', 'ly:grob-original', str)
1934         str = re.sub (r'ly:get-parent', 'ly:grob-parent', str)
1935         str = re.sub (r'ly:get-broken-into', 'ly:spanner-broken-into', str)
1936         str = re.sub (r'Melisma_engraver', 'Melisma_translator', str)
1937         if re.search ("ly:get-paper-variable", str):
1938                 sys.stderr.write ('use (ly:paper-lookup (ly:grob-paper ))')
1939                 raise FatalConversionError()
1940
1941         str = re.sub (r'\\defaultAccidentals', "#(set-accidental-style 'default)", str)
1942         str = re.sub (r'\\voiceAccidentals', "#(set-accidental-style 'voice)", str)
1943         str = re.sub (r'\\modernAccidentals', "#(set-accidental-style 'modern)", str)
1944         str = re.sub (r'\\modernCautionaries', "#(set-accidental-style 'modern-cautionary)", str)
1945         str = re.sub (r'\\modernVoiceAccidental', "#(set-accidental-style 'modern-voice)", str)
1946         str = re.sub (r'\\modernVoiceCautionaries', "#(set-accidental-style 'modern-voice-cautionary)", str)
1947         str = re.sub (r'\\pianoAccidentals', "#(set-accidental-style 'piano)", str)
1948         str = re.sub (r'\\pianoCautionaries', "#(set-accidental-style 'piano-cautionary)", str)
1949         str = re.sub (r'\\forgetAccidentals', "#(set-accidental-style 'forget)", str)
1950         str = re.sub (r'\\noResetKey', "#(set-accidental-style 'no-reset)", str)
1951         
1952         return str
1953
1954 conversions.append (((2,1,25), conv, """Scheme grob function renaming"""))
1955
1956
1957 def conv (str):
1958         str = re.sub ('ly:set-grob-property!', 'ly:grob-set-property!',str)
1959         str = re.sub ('ly:set-mus-property!', 'ly:music-set-property!',str)     
1960         str = re.sub ('ly:set-context-property!', 'ly:context-set-property!', str)      
1961         str = re.sub ('ly:get-grob-property', 'ly:grob-property',str)
1962         str = re.sub ('ly:get-mus-property', 'ly:music-property',str)
1963         str = re.sub ('ly:get-context-property', 'ly:context-property',str)
1964         
1965         return str
1966
1967 conversions.append (((2,1,26), conv, """More Scheme function renaming"""))
1968
1969 def conv (str):
1970         def subst (m):
1971                 g = string.atoi (m.group (2))
1972                 o = g / 12
1973                 g -= o * 12
1974                 if g <  0:
1975                         g += 12
1976                         o -= 1
1977
1978
1979                 lower_pitches = filter (lambda x : x <= g, [0, 2, 4, 5, 7, 9, 11, 12])
1980                 s = len (lower_pitches) -1 
1981                 a = g - lower_pitches [-1]
1982
1983
1984                 print s , lower_pitches, g, a, s 
1985                 str = 'cdefgab' [s]
1986                 str += ['eses', 'es', '', 'is', 'isis'][a + 2]
1987                 if o < 0:
1988                         str += ',' * (-o - 1)
1989                 elif o >= 0:
1990                         str += "'" * (o + 1)
1991                         
1992                 return '\\transposition %s ' % str
1993
1994         
1995         str = re.sub (r"\\set ([A-Za-z]+\s*\.\s*)?transposing\s*=\s*#([-0-9]+)",
1996                       subst, str)
1997         return str
1998
1999 conversions.append (((2,1,27), conv, """property transposing -> tuning"""))
2000
2001 def conv (str):
2002         str = re.sub (r'make-music-by-name', 'make-music', str)
2003         str = re.sub (r"\\override\s+.*Arpeggio\s+#.print-function\s+=\s+\\arpeggioBracket", r"\\arpeggioBracket", str)
2004         return str
2005
2006 conversions.append (((2,1,28), conv,
2007                      """make-music-by-name -> make-music,
2008 new syntax for setting \\arpeggioBracket"""))
2009
2010 def conv (str):
2011         str = re.sub (r'\\center([^-])', '\\center-align\\1', str)
2012         str = re.sub (r'\\translator', '\\context', str)
2013         return str
2014
2015 conversions.append (((2,1,29), conv,
2016                      '\\center -> \\center-align, \\translator -> \\context'))
2017
2018
2019 def conv (str):
2020         str = re.sub (r'\\threeq(flat|sharp)', r'\\sesqui\1', str)
2021         str = re.sub (r'ly:stencil-get-extent',
2022                       'ly:stencil-extent', str)
2023         str = re.sub (r'ly:translator-find',
2024                       'ly:context-find', str)
2025         str = re.sub ('ly:unset-context-property','ly:context-unset-property',
2026                       str)
2027                      
2028         str = re.sub (r'ly:get-mutable-properties',
2029                       'ly:mutable-music-properties',str)
2030         str = re.sub (r'centralCPosition',
2031                       'middleCPosition',str)
2032         return str
2033
2034 conversions.append (((2,1,30), conv,
2035                      '''\\threeq{flat,sharp} -> \\sesqui{flat,sharp}
2036 ly:get-mutable-properties -> ly:mutable-music-properties
2037 centralCPosition -> middleCPosition
2038 ly:unset-context-property -> ly:context-unset-property
2039 ly:translator-find -> ly:context-find
2040 ly:get-stencil-extent -> ly:stencil-extent
2041 '''))
2042
2043
2044 def conv (str):
2045         str = re.sub (r'\\alias\s*"?Timing"?', '', str)
2046         return str
2047
2048 conversions.append (((2,1,31), conv,
2049                      '''remove \\alias Timing'''))
2050
2051 def conv (str):
2052         str = re.sub (r"(\\set\s+)?(?P<context>(Score\.)?)breakAlignOrder\s*=\s*#'(?P<list>[^\)]+)",
2053                       r"\n\\override \g<context>BreakAlignment #'break-align-orders = "
2054                       + "#(make-vector 3 '\g<list>)", str)
2055                       
2056         return str
2057
2058 conversions.append (((2,1,33), conv,
2059                      '''breakAlignOrder -> break-align-orders.'''))
2060
2061 def conv (str):
2062         str = re.sub (r"\(set-paper-size",
2063                       "(set-default-paper-size",str)
2064         return str
2065
2066 conversions.append (((2,1,34), conv,
2067                      '''set-paper-size -> set-default-paper-size.'''))
2068
2069 def conv (str):
2070         str = re.sub (r"ly:mutable-music-properties",
2071                       "ly:music-mutable-properties", str)
2072         return str
2073
2074 conversions.append (((2,1, 36), conv,
2075                      '''ly:mutable-music-properties -> ly:music-mutable-properties'''))
2076
2077
2078
2079 def conv (str):
2080         return str
2081
2082 conversions.append (((2,2, 0), conv,
2083                      '''clean up version. '''))
2084
2085 def conv (str):
2086         return re.sub (r'\\apply\b', r'\\applymusic', str)
2087
2088 conversions.append (((2, 3, 1), conv,
2089                      '''\\apply -> \\applymusic'''))
2090
2091 def conv (str):
2092         str = re.sub (r'\\OrchestralScoreContext', '\\Score', str)
2093         def func(m):
2094                 if m.group(1) not in ['RemoveEmptyStaff',
2095                                       'AncientRemoveEmptyStaffContext',
2096                                       'EasyNotation']:
2097                         return '\\' + m.group (1)
2098                 else:
2099                         return m.group (0)
2100                 
2101                 
2102         str = re.sub (r'\\([a-zA-Z]+)Context\b', func, str)
2103
2104         str = re.sub ('ly:paper-lookup', 'ly:output-def-lookup', str)
2105         return str
2106
2107 conversions.append (((2, 3, 2), conv,
2108                      '''\\FooContext -> \\Foo'''))
2109
2110 def conv (str):
2111         str = re.sub (r'\\notes\b', '', str)
2112         
2113         return str
2114
2115 conversions.append (((2, 3, 4), conv,
2116                      '''remove \\notes'''))
2117
2118
2119
2120 def conv (str):
2121         str = re.sub (r'\\consistsend', '\\consists', str)
2122         str = re.sub (r'\\lyricsto\s+("?[a-zA-Z]+"?)(\s*\\new Lyrics\s*)?\\lyrics',
2123                       r'\\lyricsto \1 \2', str)
2124         return str
2125
2126 conversions.append (((2, 3, 8), conv,
2127                      '''remove \\consistsend, strip \\lyrics from \\lyricsto.'''))
2128
2129 def conv (str):
2130         str = re.sub (r'neo_mensural', 'neomensural', str)
2131         str = re.sub (r'if-text-padding', 'bound-padding', str)
2132         return str
2133
2134 conversions.append (((2, 3, 9), conv,
2135                      '''neo_mensural -> neomensural, if-text-padding -> bound-padding'''))
2136
2137
2138
2139 def conv (str):
2140         str = re.sub (r'\\addlyrics', r'\\oldaddlyrics', str)
2141         str = re.sub (r'\\newlyrics', r'\\addlyrics', str)
2142         return str
2143
2144 conversions.append (((2, 3, 10), conv,
2145                      '''\\addlyrics -> \\oldaddlyrics, \\newlyrics -> \\addlyrics'''))
2146
2147 def conv (str):
2148         str = re.sub (r'\\setMmRestFermata\s+(R[0-9.*/]*)',
2149                       r'\1^\\fermataMarkup', str)
2150         return str
2151
2152 conversions.append (((2, 3, 11), conv,
2153                      '''\\setMmRestFermata -> ^\\fermataMarkup'''))
2154
2155 def conv (str):
2156         str = re.sub (r'\\newpage', r'\\pageBreak', str)
2157         str = re.sub (r'\\scriptUp', r"""{
2158   \\override TextScript  #'direction = #1
2159   \\override Script  #'direction = #1
2160 }""", str)
2161         str = re.sub (r'\\scriptDown', r"""{
2162   \\override TextScript  #'direction = #-1
2163   \\override Script  #'direction = #-1
2164 }""", str)
2165         str = re.sub (r'\\scriptBoth', r"""{
2166   \\revert TextScript  #'direction
2167   \\override Script  #'direction
2168 }""", str)
2169         str = re.sub ('soloADue', 'printPartCombineTexts', str)
2170         return str
2171
2172 conversions.append (((2, 3, 12), conv,
2173                      '''\\newpage -> \\pageBreak'''))
2174
2175
2176 def conv_mode_experiment (str):
2177         str = re.sub (r'\\chords\b', r'\\chordmode', str)
2178         str = re.sub (r'\\lyrics\b', r'\\lyricmode', str)
2179         str = re.sub (r'\\figures\b', r'\\figuremode', str)
2180         str = re.sub (r'\\drums\b', r'\\drummode', str)
2181         str = re.sub (r'\\chordmode\s*\\new ChordNames', r'\\chords', str)
2182         str = re.sub (r'\\new ChordNames\s*\\chordmode', r'\\chords', str)
2183         str = re.sub (r'\\new FiguredBass\s*\\figuremode', r'\\figures', str)
2184         str = re.sub (r'\\figuremode\s*\new FiguredBass', r'\\figures', str)
2185         str = re.sub (r'\\new DrumStaff\s*\\drummode', r'\\drums', str)
2186         str = re.sub (r'\\drummode\s*\\new DrumStaff', r'\\drums', str)
2187
2188         return str
2189
2190 #conversions.append (((2, 3, 9), conv,
2191 #                    '''fold \new FooContext \foomode into \foo.'''))
2192
2193 ################################
2194 #       END OF CONVERSIONS      
2195 ################################
2196
2197 def get_conversions (from_version, to_version):
2198         def version_b (v, f = from_version, t = to_version):
2199                 return version_cmp (v[0], f) > 0 and version_cmp (v[0], t) <= 0
2200         return filter (version_b, conversions)
2201
2202
2203 def latest_version ():
2204         return conversions[-1][0]
2205
2206 def do_conversion (infile, from_version, outfile, to_version):
2207         conv_list = get_conversions (from_version, to_version)
2208
2209         sys.stderr.write ('Applying conversions: ')
2210         str = infile.read ()
2211         last_conversion = ()
2212         try:
2213                 for x in conv_list:
2214                         sys.stderr.write (tup_to_str (x[0])  + ', ')
2215                         str = x[1] (str)
2216                         last_conversion = x[0]
2217
2218         except FatalConversionError:
2219                 sys.stderr.write ('Error while converting; I won\'t convert any further')
2220
2221         if last_conversion:
2222                 sys.stderr.write ('\n')
2223                 new_ver =  '\\version \"%s\"' % tup_to_str (last_conversion)
2224
2225                 if re.search (lilypond_version_re_str, str):
2226                         str = re.sub (lilypond_version_re_str,'\\'+new_ver , str)
2227                 elif add_version:
2228                         str = new_ver + '\n' + str
2229
2230                 outfile.write(str)
2231
2232         return last_conversion
2233         
2234 class UnknownVersion:
2235         pass
2236
2237 def do_one_file (infile_name):
2238         sys.stderr.write ('Processing `%s\' ... '% infile_name)
2239         outfile_name = ''
2240         if __main__.edit:
2241                 outfile_name = infile_name + '.NEW'
2242         elif __main__.outfile_name:
2243                 outfile_name = __main__.outfile_name
2244
2245         if __main__.from_version:
2246                 from_version = __main__.from_version
2247         else:
2248                 guess = guess_lilypond_version (infile_name)
2249                 if not guess:
2250                         raise UnknownVersion()
2251                 from_version = str_to_tuple (guess)
2252
2253         if __main__.to_version:
2254                 to_version = __main__.to_version
2255         else:
2256                 to_version = latest_version ()
2257
2258
2259         if infile_name:
2260                 infile = open (infile_name,'r')
2261         else:
2262                 infile = sys.stdin
2263
2264         if outfile_name:
2265                 outfile =  open (outfile_name, 'w')
2266         else:
2267                 outfile = sys.stdout
2268
2269         touched = do_conversion (infile, from_version, outfile, to_version)
2270
2271         if infile_name:
2272                 infile.close ()
2273
2274         if outfile_name:
2275                 outfile.close ()
2276
2277         if __main__.edit and touched:
2278                 try:
2279                         os.remove(infile_name + '~')
2280                 except:
2281                         pass
2282                 os.rename (infile_name, infile_name + '~')
2283                 os.rename (infile_name + '.NEW', infile_name)
2284
2285         sys.stderr.write ('\n')
2286         sys.stderr.flush ()
2287
2288 edit = 0
2289 assume_old = 0
2290 to_version = ()
2291 from_version = ()
2292 outfile_name = ''
2293
2294 (options, files) = getopt.getopt (
2295         sys.argv[1:], 'ao:f:t:senh', ['no-version', 'version', 'output', 'show-rules', 'help', 'edit', 'from=', 'to='])
2296
2297 for opt in options:
2298         o = opt[0]
2299         a = opt[1]
2300         if o== '--help' or o == '-h':
2301                 usage ()
2302                 sys.exit (0)
2303         if o == '--version' or o == '-v':
2304                 print_version ()
2305                 sys.exit (0)
2306         elif o== '--from' or o=='-f':
2307                 from_version = str_to_tuple (a)
2308         elif o== '--to' or o=='-t':
2309                 to_version = str_to_tuple (a)
2310         elif o== '--edit' or o == '-e':
2311                 edit = 1
2312         elif o== '--show-rules' or o == '-s':
2313                 show_rules (sys.stdout)
2314                 sys.exit(0)
2315         elif o == '--output' or o == '-o':
2316                 outfile_name = a
2317         elif o == '--no-version' or o == '-n':
2318                 add_version = 0
2319         else:
2320                 print o
2321                 raise getopt.error
2322
2323 identify ()
2324 for f in files:
2325         if f == '-':
2326                 f = ''
2327         elif not os.path.isfile (f):
2328                 continue
2329         try:
2330                 do_one_file (f)
2331         except UnknownVersion:
2332                 sys.stderr.write ('\n')
2333                 sys.stderr.write ("%s: can't determine version for `%s'" % (program_name, f))
2334                 sys.stderr.write ('\n')
2335                 if assume_old:
2336                         fv = from_version
2337                         from_version = (0,0,0)
2338                         do_one_file (f)
2339                         from_version = fv
2340                 else:
2341                         sys.stderr.write ("%s: skipping: `%s' " % (program_name,  f))
2342                 pass
2343
2344 sys.stderr.write ('\n')