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