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