]> git.donarmstrong.com Git - lilypond.git/blob - scripts/convert-ly.py
* scripts/convert-ly.py: Attempt to do a smarter update of
[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         submarkup_start = re.compile(r"\(\s*([a-zA-Z]+)")
1443         leftpar = re.compile(r"\(")
1444         rightpar = re.compile(r"\)")
1445
1446         def text_markup (str):
1447                 result = ''
1448                 # Find the beginning of each markup:
1449                 match = markup_start.search (str)
1450                 while match:
1451                         result = result + str[:match.end (1)] + " \markup"
1452                         str = str[match.end( 2):]
1453                         # Count matching parentheses to find the end of the 
1454                         # current markup:
1455                         nesting_level = 0
1456                         pars = re.finditer(r"[()]",str)
1457                         for par in pars:
1458                                 if par.group () == '(':
1459                                         nesting_level = nesting_level + 1
1460                                 else:
1461                                         nesting_level = nesting_level - 1
1462                                 if nesting_level == 0:
1463                                         markup_end = par.end ()
1464                                         break
1465                         # The full markup in old syntax:
1466                         markup = str[:markup_end]
1467                         # Modify to new syntax:
1468                         markup = musicglyph.sub (r"{\\musicglyph", markup)
1469                         markup = submarkup_start.sub (r"{\\\1", markup)
1470                         markup = leftpar.sub ("{", markup)
1471                         markup = rightpar.sub ("}", markup)
1472         
1473                         result = result + markup
1474                         # Find next markup
1475                         str = str[markup_end:]
1476                         match = markup_start.search(str)
1477                 result = result + str
1478                 return result
1479
1480         def articulation_substitute (str):
1481                 str = re.sub (r"""([^-])\[ *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1482                               r"\1 \2[", 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                 return str
1490
1491         def conv_relative(str):
1492                 if re.search (r"\\relative", str):
1493                         str= "#(ly:set-option 'old-relative)\n" + str
1494
1495                 return str
1496
1497         def conv (str):
1498                 str = re.sub (r"#'\(\)", "@SCM_EOL@", str)
1499                 str =  conv_relative (str)
1500                 str = sub_chords (str)
1501
1502                 str = text_markup (str)
1503                 str = articulation_substitute (str)
1504                 str = re.sub ("@SCM_EOL@", "#'()", str)
1505
1506                 return str
1507
1508         conversions.append (((1,9,0), conv, """New relative mode,
1509 Postfix articulations, new text markup syntax, new chord syntax."""))
1510
1511 if 1:
1512         def conv (str):
1513                 if re.search ("font-style",str):
1514                         sys.stderr.write ('\n')
1515                         sys.stderr.write (NOT_SMART % "font-sytle")
1516                         sys.stderr.write ('\n')
1517                         sys.stderr.write (UPDATE_MANUALLY)
1518                         sys.stderr.write ('\n')
1519
1520                         raise FatalConversionError ()
1521
1522                 str = re.sub (r'-\\markup', r'@\\markup', str)
1523                 str = re.sub (r'-\\', r'\\', str)
1524                 str = re.sub (r'-\)', ')', str)
1525                 str = re.sub (r'-\(', '(', str)
1526                 str = re.sub ('-\[', '[', str)
1527                 str = re.sub ('-\]', ']', str)
1528                 str = re.sub ('-~', '~', str)
1529                 str = re.sub (r'@\\markup', r'-\\markup', str)
1530                 return str
1531
1532         conversions.append (((1,9,1), conv, """Remove - before articulation"""))
1533 if 1:
1534         def conv (str):
1535                 str = re.sub ('ly:set-context-property',
1536                               'ly:set-context-property!', str)
1537                 str = re.sub ('\\\\newcontext', '\\\\new', str)
1538                 str = re.sub ('\\\\grace[\t\n ]*([^{ ]+)',
1539                               r'\\grace { \1 }', str)
1540                 str = re.sub ("\\\\grace[\t\n ]*{([^}]+)}",
1541                               r"""\\grace {
1542   \\property Voice.Stem \\override #'stroke-style = #"grace"
1543   \1
1544   \\property Voice.Stem \\revert #'stroke-style }
1545 """, str)
1546
1547                 return str
1548
1549         conversions.append (((1,9,2), conv, """\\newcontext -> \\new"""))
1550
1551 if 1:
1552         def conv (str):
1553                 str = re.sub ('accacciatura',
1554                               'acciaccatura', str)
1555
1556                 if re.search ("context-spec-music", str):
1557                         sys.stderr.write ('\n')
1558                         sys.stderr.write (NOT_SMART % "context-spec-music")
1559                         sys.stderr.write ('\n')
1560                         sys.stderr.write (UPDATE_MANUALLY)
1561                         sys.stderr.write ('\n')
1562
1563                         raise FatalConversionError ()
1564
1565                 str = re.sub ('fingerHorizontalDirection *= *#(LEFT|-1)',
1566                               "fingeringOrientations = #'(up down left)", str)
1567                 str = re.sub ('fingerHorizontalDirection *= *#(RIGHT|1)',
1568                               "fingeringOrientations = #'(up down right)", str)
1569
1570                 return str
1571
1572         conversions.append (((1,9,3), conv,
1573                              """\\acciaccatura misspelling, fingerHorizontalDirection -> fingeringOrientations"""))
1574
1575
1576 def conv (str):
1577         if re.search ('\\figures', str):
1578                 sys.stderr.write ("Warning: attempting automatic \\figures conversion.  Check results!");
1579
1580
1581         def figures_replace (m):
1582                 s = m.group (1)
1583                 s = re.sub ('<', '@FIGOPEN@',s)
1584                 s = re.sub ('>', '@FIGCLOSE@',s)
1585                 return '\\figures { %s }' % s
1586
1587         str = re.sub (r'\\figures[ \t\n]*{([^}]+)}', figures_replace, str)
1588         str = re.sub (r'\\<', '@STARTCRESC@', str)
1589         str = re.sub (r'\\>', '@STARTDECRESC@', str)
1590         str = re.sub (r'([-^_])>', r'\1@ACCENT@', str)
1591         str = re.sub (r'<<', '@STARTCHORD@', str)
1592         str = re.sub (r'>>', '@ENDCHORD@', str)
1593         str = re.sub (r'>', '@ENDSIMUL@', str)
1594         str = re.sub (r'<', '@STARTSIMUL@', str)
1595         str = re.sub ('@STARTDECRESC@', '\\>', str)
1596         str = re.sub ('@STARTCRESC@', '\\<', str)
1597         str = re.sub ('@ACCENT@', '>', str)
1598         str = re.sub ('@ENDCHORD@', '>', str)
1599         str = re.sub ('@STARTCHORD@', '<', str)
1600         str = re.sub ('@STARTSIMUL@', '<<', str)
1601         str = re.sub ('@ENDSIMUL@', '>>', str)
1602         str = re.sub ('@FIGOPEN@', '<', str)
1603         str = re.sub ('@FIGCLOSE@', '>', str)
1604
1605         return str
1606
1607 conversions.append (((1,9,4), conv, 'Swap < > and << >>'))
1608
1609
1610 def conv (str):
1611         str = re.sub ('HaraKiriVerticalGroup', 'RemoveEmptyVerticalGroup', str)
1612
1613         return str
1614
1615 conversions.append (((1,9,5), conv, 'HaraKiriVerticalGroup -> RemoveEmptyVerticalGroup'))
1616
1617 def conv (str):
1618         if re.search ("ly:get-font", str) :
1619                 sys.stderr.write ('\n')
1620                 sys.stderr.write (NOT_SMART % "(ly:-get-font")
1621                 sys.stderr.write ('\n')
1622                 sys.stderr.write (FROM_TO \
1623                                   % ("(ly:paper-get-font (ly:grob-get-paper foo) .. )",
1624                                      "(ly:paper-get-font (ly:grob-get-paper foo) .. )"))
1625                 sys.stderr.write (UPDATE_MANUALLY)
1626                 sys.stderr.write ('\n')
1627                 raise FatalConversionError ()
1628
1629         if re.search ("\\pitch *#", str) :
1630                 sys.stderr.write ('\n')
1631                 sys.stderr.write (NOT_SMART % "\\pitch")
1632                 sys.stderr.write ('\n')
1633                 sys.stderr.write ("Use Scheme code to construct arbitrary note events.")
1634                 sys.stderr.write ('\n')
1635
1636                 raise FatalConversionError ()
1637
1638         return str
1639
1640
1641 conversions.append (((1,9,6), conv, 'ly:get-font deprecated.'))
1642
1643 def conv (str):
1644         def sub_alteration (m):
1645                 alt = m.group (3)
1646                 alt = {
1647                         '-1': 'FLAT',
1648                         '-2': 'DOUBLE-FLAT',
1649                         '0': 'NATURAL',
1650                         '1': 'SHARP',
1651                         '2': 'DOUBLE-SHARP',
1652                         }[alt]
1653
1654                 return '(ly:make-pitch %s %s %s)' % (m.group(1), m.group (2),
1655                                                      alt)
1656
1657         str =re.sub ("\\(ly:make-pitch *([0-9-]+) *([0-9-]+) *([0-9-]+) *\\)",
1658                      sub_alteration, str)
1659
1660
1661         str = re.sub ("ly:verbose", "ly:get-option 'verbose", str)
1662
1663         m= re.search ("\\\\outputproperty #([^#]+)[\t\n ]*#'([^ ]+)", str)
1664         if m:
1665                 sys.stderr.write (\
1666                         r"""\outputproperty found,
1667 Please hand-edit, using
1668
1669   \applyoutput #(outputproperty-compatibility %s '%s <GROB PROPERTY VALUE>)
1670
1671 as a substitution text.""" % (m.group (1), m.group (2)) )
1672                 raise FatalConversionError ()
1673
1674         if re.search ("ly:(make-pitch|pitch-alteration)", str) \
1675                or re.search ("keySignature", str):
1676                 sys.stderr.write ('\n')
1677                 sys.stderr.write (NOT_SMART % "pitches")
1678                 sys.stderr.write ('\n')
1679                 sys.stderr.write (
1680 """The alteration field of Scheme pitches was multiplied by 2
1681 to support quarter tone accidentals.  You must update the following constructs by manually:
1682
1683 * calls of ly:make-pitch and ly:pitch-alteration
1684 * keySignature settings made with \property
1685 """)
1686                 raise FatalConversionError ()
1687
1688         return str
1689 conversions.append (((1,9,7), conv,
1690                      '''use symbolic constants for alterations,
1691 remove \\outputproperty, move ly:verbose into ly:get-option'''))
1692
1693
1694 def conv (str):
1695         if re.search ("dash-length",str):
1696                 sys.stderr.write ('\n')
1697                 sys.stderr.write (NOT_SMART % "dash-length")
1698                 sys.stderr.write ('\n')
1699                 sys.stderr.write (FROM_TO % ("dash-length", "dash-fraction"))
1700                 sys.stderr.write ('\n')
1701                 sys.stderr.write (UPDATE_MANUALLY)
1702                 sys.stderr.write ('\n')
1703                 raise FatalConversionError ()
1704         return str
1705
1706 conversions.append (((1,9,8), conv, """dash-length -> dash-fraction"""))
1707
1708
1709 def conv (str):
1710         def func(match):
1711                 return "#'font-size = #%d" % (2*string.atoi (match.group (1)))
1712
1713         str =re.sub (r"#'font-relative-size\s*=\s*#\+?([0-9-]+)", func, str)
1714         str =re.sub (r"#'font-family\s*=\s*#'ancient",
1715                      r"#'font-family = #'music", str)
1716
1717         return str
1718
1719 conversions.append (((2,1,1), conv, """font-relative-size -> font-size"""))
1720
1721 def conv (str):
1722         str =re.sub (r"ly:get-music-length", "ly:music-length", str)
1723         return str
1724
1725 conversions.append (((2,1,2), conv, """ly:get-music-length -> ly:music-length"""))
1726
1727 def conv (str):
1728         str =re.sub (r"\.\s+stz=", ". instr ", str)
1729         return str
1730
1731 conversions.append (((2,1,3), conv, """stanza -> instrument"""))
1732
1733 def conv (str):
1734         def func (match):
1735                 c = match.group (1)
1736                 b = match.group (2)
1737
1738                 if b == 't':
1739                         if c == 'Score':
1740                                 return ''
1741                         else:
1742                                 return r" \property %s.melismaBusyProperties \unset"  % c
1743                 elif b == 'f':
1744                         return r"\property %s.melismaBusyProperties = #'(melismaBusy)"  % c
1745
1746         str = re.sub (r"\\property ([a-zA-Z]+)\s*\.\s*automaticMelismata\s*=\s*##([ft])", func, str)
1747         return str
1748
1749 conversions.append (((2,1,4), conv, """removal of automaticMelismata; use melismaBusyProperties instead."""))
1750
1751
1752
1753 def conv (str):
1754         str =re.sub (r"\\translator\s+([a-zA-Z]+)", r"\\change \1", str)
1755         return str
1756
1757 conversions.append (((2,1,7), conv, """\\translator Staff -> \\change Staff"""))
1758
1759 def conv (str):
1760         str =re.sub (r"\\newaddlyrics", r"\\lyricsto", str)
1761         return str
1762
1763 conversions.append (((2,1,10), conv, """\\newaddlyrics -> \\lyricsto"""))
1764
1765 def conv (str):
1766         str = re.sub (r'\\include\s*"paper([0-9]+)(-init)?.ly"',
1767                       r"#(set-staff-size \1)", str)
1768
1769         def sub_note (match):
1770                 dur = ''
1771                 log = string.atoi (match.group (1))
1772                 dots = string.atoi (match.group (2))
1773
1774                 if log >= 0:
1775                         dur = '%d' % (1 << log)
1776                 else:
1777                         dur = { -1 : 'breve',
1778                                 -2 : 'longa',
1779                                 -3 : 'maxima'}[log]
1780
1781                 dur += ('.' * dots)
1782
1783                 return r'\note #"%s" #%s' % (dur, match.group (3))
1784
1785         str = re.sub (r'\\note\s+#([0-9-]+)\s+#([0-9]+)\s+#([0-9.-]+)',
1786                       sub_note, str)
1787         return str
1788
1789 conversions.append (((2,1,11), conv, """\\include "paper16.ly" -> #(set-staff-size 16)
1790 \\note #3 #1 #1 -> \\note #"8." #1
1791 """))
1792
1793
1794 def conv (str):
1795         str =re.sub (r"OttavaSpanner", r"OttavaBracket", str)
1796         return str
1797
1798 conversions.append (((2,1,12), conv, """OttavaSpanner -> OttavaBracket"""))
1799
1800
1801 def conv (str):
1802         str =re.sub (r"\(set-staff-size ", r"(set-global-staff-size ", str)
1803         return str
1804
1805 conversions.append (((2,1,13), conv, """set-staff-size -> set-global-staff-size"""))
1806
1807 def conv (str):
1808         str =re.sub (r"#'style\s*=\s*#'dotted-line",
1809                      r"#'dash-fraction = #0.0 ", str)
1810         return str
1811
1812 conversions.append (((2,1,14), conv, """style = dotted -> dash-fraction = 0"""))
1813
1814 def conv (str):
1815         str =re.sub (r'LyricsVoice\s*\.\s*instrument\s*=\s*("[^"]*")',
1816                      r'LyricsVoice . vocalName = \1', str)
1817
1818         str =re.sub (r'LyricsVoice\s*\.\s*instr\s*=\s*("[^"]*")',
1819                      r'LyricsVoice . vocNam = \1', str)
1820         return str
1821
1822 conversions.append (((2,1,15), conv, """LyricsVoice . instr(ument) -> vocalName"""))
1823
1824 def conv (str):
1825         def sub_acc (m):
1826                 d = {
1827                 '4': 'doublesharp',
1828                 '3': 'threeqsharp',
1829                 '2': 'sharp',
1830                 '1': 'semisharp',
1831                 '0': 'natural',
1832                 '-1': 'semiflat',
1833                 '-2': 'flat',
1834                 '-3': 'threeqflat',
1835                 '-4': 'doubleflat'}
1836                 return '\\%s' %  d[m.group (1)]
1837
1838         str = re.sub (r'\\musicglyph\s*#"accidentals-([0-9-]+)"',
1839                       sub_acc, str)
1840         return str
1841
1842 conversions.append (((2,1,16), conv, """\\musicglyph #"accidentals-NUM" -> \\sharp/flat/etc."""))
1843
1844
1845 def conv (str):
1846
1847         if re.search (r'\\partcombine', str):
1848                 sys.stderr.write ('\n')
1849                 sys.stderr.write (NOT_SMART % "\\partcombine")
1850                 sys.stderr.write ('\n')
1851                 sys.stderr.write (UPDATE_MANUALLY)
1852                 sys.stderr.write ('\n')
1853                 raise FatalConversionError ()
1854
1855         # this rule doesn't really work,
1856         # too lazy to figure out why.
1857         str = re.sub (r'\\context\s+Voice\s*=\s*one\s*\\partcombine\s+Voice\s*\\context\s+Thread\s*=\s*one(.*)\s*'
1858                       + r'\\context\s+Thread\s*=\s*two',
1859                       '\\\\newpartcombine\n\\1\n', str)
1860
1861
1862         return str
1863
1864 conversions.append (((2,1,17), conv, """\\partcombine syntax change to \\newpartcombine"""))
1865
1866
1867 def conv (str):
1868         str = re.sub (r'\\newpartcombine', r'\\partcombine', str)
1869         str = re.sub (r'\\autochange\s+Staff', r'\\autochange ', str)
1870         return str
1871
1872 conversions.append (((2,1,18), conv, """\\newpartcombine -> \\partcombine,
1873 \\autochange Staff -> \\autochange
1874 """))
1875
1876
1877
1878
1879 def conv (str):
1880         str = re.sub (r'\\include "drumpitch-init.ly"','', str)
1881         str = re.sub (r'\\pitchnames ','pitchnames = ', str)
1882         str = re.sub (r'\\chordmodifiers ','chordmodifiers = ', str)
1883         str = re.sub (r'\bdrums\b\s*=','drumContents = ', str)
1884         str = re.sub (r'\\drums\b','\\drumContents ', str)
1885
1886
1887         if re.search ('drums->paper', str):
1888                 sys.stderr.write ("\nDrum notation found. Check file manually!")
1889
1890         str = re.sub (r"""\\apply\s+#\(drums->paper\s+'([a-z]+)\)""",
1891                       r"""\property DrumStaff.drumStyleTable = #\1-style""",
1892                       str)
1893
1894         if re.search ('Thread', str):
1895                 sys.stderr.write ("\nThread found. Check file manually!\n");
1896
1897         str = re.sub (r"""(\\once\s*)?\\property\s+Thread\s*\.\s*NoteHead\s*"""
1898                       + r"""\\(set|override)\s*#'style\s*=\s*#'harmonic"""
1899                       + r"""\s+([a-z]+[,'=]*)([0-9]*\.*)"""
1900                       ,r"""<\3\\harmonic>\4""", str)
1901
1902         str = re.sub (r"""\\new Thread""", """\context Voice""", str)
1903         str = re.sub (r"""Thread""", """Voice""", str)
1904
1905         if re.search ('\bLyrics\b', str):
1906                 sys.stderr.write ("\nLyrics found. Check file manually!\n");
1907
1908         str = re.sub (r"""LyricsVoice""", r"""L@ricsVoice""", str)
1909         str = re.sub (r"""\bLyrics\b""", r"""LyricsVoice""", str)
1910         str = re.sub (r"""LyricsContext""", r"""LyricsVoiceContext""", str)
1911         str = re.sub (r"""L@ricsVoice""", r"""LyricsVoice""",str)
1912
1913
1914         return str
1915
1916 conversions.append (((2,1,19), conv, """Drum notation changes, Removing \\chordmodifiers, \\notenames.
1917 Harmonic notes. Thread context removed. Lyrics context removed."""))
1918
1919 def conv (str):
1920         str = re.sub (r'nonevent-skip', 'skip-music', str)
1921         return str
1922
1923 conversions.append (((2,1,20), conv, """nonevent-skip -> skip-music""" ))
1924
1925 def conv (str):
1926         str = re.sub (r'molecule-callback', 'print-function', str)
1927         str = re.sub (r'brew_molecule', 'print', str)
1928         str = re.sub (r'brew-new-markup-molecule', 'Text_item::print', str)
1929         str = re.sub (r'LyricsVoice', 'Lyrics', str)
1930         str = re.sub (r'tupletInvisible',
1931                       r"TupletBracket \\set #'transparent", str)
1932 #       str = re.sub (r'molecule', 'collage', str)
1933 #molecule -> collage
1934         str = re.sub (r"\\property\s+[a-zA-Z]+\s*\.\s*[a-zA-Z]+\s*"
1935                       + r"\\set\s*#'X-extent-callback\s*=\s*#Grob::preset_extent",
1936                       "", str)
1937
1938         return str
1939
1940 conversions.append (((2,1,21), conv, """molecule-callback -> print-function,
1941 brew_molecule -> print
1942 brew-new-markup-molecule -> Text_item::print
1943 LyricsVoice -> Lyrics
1944 tupletInvisible -> TupletBracket \set #'transparent
1945 Grob::preset_extent removed.
1946 """ ))
1947
1948
1949 def conv (str):
1950         str = re.sub (r'(\\property[^=]+)=\s*([-0-9]+)',
1951                       r'\1= #\2', str)
1952         str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\=]+)\s*\\(set|override)',
1953                       r"\\overrid@ \1.\2 ", str)
1954         str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\= ]+)\s*=\s*',
1955                       r'\\s@t \1.\2 = ', str)
1956         str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\= ]+)\s*\\unset',
1957                       r'\\uns@t \1.\2 ', str)
1958         str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\= ]+)\s*\\revert'
1959                       + r"\s*#'([-a-z0-9_]+)",
1960                       r"\\rev@rt \1.\2 #'\3", str)
1961         str = re.sub (r'Voice\.', '', str)
1962         str = re.sub (r'Lyrics\.', '', str)
1963         str = re.sub (r'ChordNames\.', '', str)
1964
1965         str = re.sub ('rev@rt', 'revert',str)
1966         str = re.sub ('s@t', 'set',str)
1967         str = re.sub ('overrid@', 'override',str)
1968
1969         str = re.sub ('molecule', 'stencil', str)
1970         str = re.sub ('Molecule', 'Stencil', str)
1971         return str
1972
1973 conversions.append (((2,1,22), conv, """new syntax for property settings:
1974         \\set A.B = #C , \\unset A.B
1975         \\override A.B #C = #D, \\revert A.B #C
1976
1977 """))
1978
1979 def conv (str):
1980         def subst_in_trans (match):
1981                 s = match.group (0)
1982                 s = re.sub (r'\s([a-zA-Z]+)\s*\\override',
1983                               r' \\override \1', s)
1984                 s = re.sub (r'\s([a-zA-Z]+)\s*\\set',
1985                               r' \\override \1', s)
1986                 s = re.sub (r'\s([a-zA-Z]+)\s*\\revert',
1987                               r' \\revert \1', s)
1988                 return s
1989         str = re.sub (r'\\(translator|with)\s*{[^}]+}',  subst_in_trans, str)
1990
1991         def sub_abs (m):
1992
1993                 context = m.group ('context')
1994                 d = m.groupdict ()
1995                 if context:
1996                         context = " '%s" % context[:-1] # -1: remove .
1997                 else:
1998                         context = ''
1999
2000                 d['context'] = context
2001
2002                 return r"""#(override-auto-beam-setting %(prop)s %(num)s %(den)s%(context)s)""" % d
2003
2004         str = re.sub (r"""\\override\s*(?P<context>[a-zA-Z]+\s*\.\s*)?autoBeamSettings"""
2005                       +r"""\s*#(?P<prop>[^=]+)\s*=\s*#\(ly:make-moment\s+(?P<num>\d+)\s+(?P<den>\d)\s*\)""",
2006                       sub_abs, str)
2007
2008         return str
2009
2010 conversions.append (((2,1,23), conv, """Property setting syntax in \\translator{ }"""))
2011 def conv (str):
2012         str = re.sub (r'music-list\?', 'ly:music-list?', str)
2013         str = re.sub (r'\|\s*~', '~ |', str)
2014         return str
2015
2016 conversions.append (((2,1,24), conv, """music-list? -> ly:music-list?"""))
2017
2018 def conv (str):
2019         str = re.sub (r'ly:get-spanner-bound', 'ly:spanner-get-bound', str)
2020         str = re.sub (r'ly:get-extent', 'ly:grob-extent', str)
2021         str = re.sub (r'ly:get-system', 'ly:grob-system', str)
2022         str = re.sub (r'ly:get-original', 'ly:grob-original', str)
2023         str = re.sub (r'ly:get-parent', 'ly:grob-parent', str)
2024         str = re.sub (r'ly:get-broken-into', 'ly:spanner-broken-into', str)
2025         str = re.sub (r'Melisma_engraver', 'Melisma_translator', str)
2026         if re.search ("ly:get-paper-variable", str):
2027                 sys.stderr.write ('\n')
2028                 sys.stderr.write (NOT_SMART % "ly:paper-get-variable")
2029                 sys.stderr.write ('\n')
2030                 sys.stderr.write ('use (ly:paper-lookup (ly:grob-paper ))')
2031                 sys.stderr.write ('\n')
2032                 raise FatalConversionError ()
2033
2034         str = re.sub (r'\\defaultAccidentals', "#(set-accidental-style 'default)", str)
2035         str = re.sub (r'\\voiceAccidentals', "#(set-accidental-style 'voice)", str)
2036         str = re.sub (r'\\modernAccidentals', "#(set-accidental-style 'modern)", str)
2037         str = re.sub (r'\\modernCautionaries', "#(set-accidental-style 'modern-cautionary)", str)
2038         str = re.sub (r'\\modernVoiceAccidental', "#(set-accidental-style 'modern-voice)", str)
2039         str = re.sub (r'\\modernVoiceCautionaries', "#(set-accidental-style 'modern-voice-cautionary)", str)
2040         str = re.sub (r'\\pianoAccidentals', "#(set-accidental-style 'piano)", str)
2041         str = re.sub (r'\\pianoCautionaries', "#(set-accidental-style 'piano-cautionary)", str)
2042         str = re.sub (r'\\forgetAccidentals', "#(set-accidental-style 'forget)", str)
2043         str = re.sub (r'\\noResetKey', "#(set-accidental-style 'no-reset)", str)
2044
2045         return str
2046
2047 conversions.append (((2,1,25), conv, """Scheme grob function renaming"""))
2048
2049
2050 def conv (str):
2051         str = re.sub ('ly:set-grob-property!', 'ly:grob-set-property!',str)
2052         str = re.sub ('ly:set-mus-property!', 'ly:music-set-property!',str)
2053         str = re.sub ('ly:set-context-property!', 'ly:context-set-property!', str)
2054         str = re.sub ('ly:get-grob-property', 'ly:grob-property',str)
2055         str = re.sub ('ly:get-mus-property', 'ly:music-property',str)
2056         str = re.sub ('ly:get-context-property', 'ly:context-property',str)
2057
2058         return str
2059
2060 conversions.append (((2,1,26), conv, """More Scheme function renaming"""))
2061
2062 def conv (str):
2063         def subst (m):
2064                 g = string.atoi (m.group (2))
2065                 o = g / 12
2066                 g -= o * 12
2067                 if g <  0:
2068                         g += 12
2069                         o -= 1
2070
2071
2072                 lower_pitches = filter (lambda x : x <= g, [0, 2, 4, 5, 7, 9, 11, 12])
2073                 s = len (lower_pitches) -1
2074                 a = g - lower_pitches [-1]
2075
2076
2077                 print s , lower_pitches, g, a, s
2078                 str = 'cdefgab' [s]
2079                 str += ['eses', 'es', '', 'is', 'isis'][a + 2]
2080                 if o < 0:
2081                         str += ',' * (-o - 1)
2082                 elif o >= 0:
2083                         str += "'" * (o + 1)
2084
2085                 return '\\transposition %s ' % str
2086
2087
2088         str = re.sub (r"\\set ([A-Za-z]+\s*\.\s*)?transposing\s*=\s*#([-0-9]+)",
2089                       subst, str)
2090         return str
2091
2092 conversions.append (((2,1,27), conv, """property transposing -> tuning"""))
2093
2094 def conv (str):
2095         str = re.sub (r'make-music-by-name', 'make-music', str)
2096         str = re.sub (r"\\override\s+.*Arpeggio\s+#.print-function\s+=\s+\\arpeggioBracket", r"\\arpeggioBracket", str)
2097         return str
2098
2099 conversions.append (((2,1,28), conv,
2100                      """make-music-by-name -> make-music,
2101 new syntax for setting \\arpeggioBracket"""))
2102
2103 def conv (str):
2104         str = re.sub (r'\\center([^-])', '\\center-align\\1', str)
2105         str = re.sub (r'\\translator', '\\context', str)
2106         return str
2107
2108 conversions.append (((2,1,29), conv,
2109                      '\\center -> \\center-align, \\translator -> \\context'))
2110
2111
2112 def conv (str):
2113         str = re.sub (r'\\threeq(flat|sharp)', r'\\sesqui\1', str)
2114         str = re.sub (r'ly:stencil-get-extent',
2115                       'ly:stencil-extent', str)
2116         str = re.sub (r'ly:translator-find',
2117                       'ly:context-find', str)
2118         str = re.sub ('ly:unset-context-property','ly:context-unset-property',
2119                       str)
2120
2121         str = re.sub (r'ly:get-mutable-properties',
2122                       'ly:mutable-music-properties',str)
2123         str = re.sub (r'centralCPosition',
2124                       'middleCPosition',str)
2125         return str
2126
2127 conversions.append (((2,1,30), conv,
2128                      '''\\threeq{flat,sharp} -> \\sesqui{flat,sharp}
2129 ly:get-mutable-properties -> ly:mutable-music-properties
2130 centralCPosition -> middleCPosition
2131 ly:unset-context-property -> ly:context-unset-property
2132 ly:translator-find -> ly:context-find
2133 ly:get-stencil-extent -> ly:stencil-extent
2134 '''))
2135
2136
2137 def conv (str):
2138         str = re.sub (r'\\alias\s*"?Timing"?', '', str)
2139         return str
2140
2141 conversions.append (((2,1,31), conv,
2142                      '''remove \\alias Timing'''))
2143
2144 def conv (str):
2145         str = re.sub (r"(\\set\s+)?(?P<context>(Score\.)?)breakAlignOrder\s*=\s*#'(?P<list>[^\)]+)",
2146                       r"\n\\override \g<context>BreakAlignment #'break-align-orders = "
2147                       + "#(make-vector 3 '\g<list>)", str)
2148
2149         return str
2150
2151 conversions.append (((2,1,33), conv,
2152                      '''breakAlignOrder -> break-align-orders.'''))
2153
2154 def conv (str):
2155         str = re.sub (r"\(set-paper-size",
2156                       "(set-default-paper-size",str)
2157         return str
2158
2159 conversions.append (((2,1,34), conv,
2160                      '''set-paper-size -> set-default-paper-size.'''))
2161
2162 def conv (str):
2163         str = re.sub (r"ly:mutable-music-properties",
2164                       "ly:music-mutable-properties", str)
2165         return str
2166
2167 conversions.append (((2,1, 36), conv,
2168                      '''ly:mutable-music-properties -> ly:music-mutable-properties'''))
2169
2170
2171
2172 def conv (str):
2173         return str
2174
2175 conversions.append (((2, 2, 0), conv,
2176                      '''clean up version. '''))
2177
2178 def conv (str):
2179         return re.sub (r'\\apply\b', r'\\applymusic', str)
2180
2181 conversions.append (((2, 3, 1), conv,
2182                      '''\\apply -> \\applymusic'''))
2183
2184 def conv (str):
2185         if re.search ('textheight', str):
2186                 sys.stderr.write ('\n')
2187                 sys.stderr.write (NOT_SMART % "textheight")
2188                 sys.stderr.write ('\n')
2189                 sys.stderr.write (UPDATE_MANUALLY)
2190                 sys.stderr.write ('\n')
2191                 sys.stderr.write (
2192 """Page layout has been changed, using paper size and margins.
2193 textheight is no longer used.
2194 """)
2195         str = re.sub (r'\\OrchestralScoreContext', '\\Score', str)
2196         def func(m):
2197                 if m.group(1) not in ['RemoveEmptyStaff',
2198                                       'AncientRemoveEmptyStaffContext',
2199                                       'EasyNotation']:
2200                         return '\\' + m.group (1)
2201                 else:
2202                         return m.group (0)
2203
2204
2205         str = re.sub (r'\\([a-zA-Z]+)Context\b', func, str)
2206         str = re.sub ('ly:paper-lookup', 'ly:output-def-lookup', str)
2207         return str
2208
2209 conversions.append (((2, 3, 2), conv,
2210                      '''\\FooContext -> \\Foo'''))
2211
2212 def conv (str):
2213         str = re.sub (r'\\notes\b', '', str)
2214
2215         return str
2216
2217 conversions.append (((2, 3, 4), conv,
2218                      '''remove \\notes'''))
2219
2220
2221
2222 def conv (str):
2223         str = re.sub (r'lastpagefill\s*=\s*"?1"', 'raggedlastbottom = ##t', str)
2224         return str
2225
2226 conversions.append (((2, 3, 6), conv,
2227                      '''lastpagefill -> raggedlastbottom'''))
2228
2229
2230
2231 def conv (str):
2232         str = re.sub (r'\\consistsend', '\\consists', str)
2233         str = re.sub (r'\\lyricsto\s+("?[a-zA-Z]+"?)(\s*\\new Lyrics\s*)?\\lyrics',
2234                       r'\\lyricsto \1 \2', str)
2235         return str
2236
2237 conversions.append (((2, 3, 8), conv,
2238                      '''remove \\consistsend, strip \\lyrics from \\lyricsto.'''))
2239
2240 def conv (str):
2241         str = re.sub (r'neo_mensural', 'neomensural', str)
2242         str = re.sub (r'if-text-padding', 'bound-padding', str)
2243         return str
2244
2245 conversions.append (((2, 3, 9), conv,
2246                      '''neo_mensural -> neomensural, if-text-padding -> bound-padding'''))
2247
2248
2249
2250 def conv (str):
2251         str = re.sub (r'\\addlyrics', r'\\oldaddlyrics', str)
2252         str = re.sub (r'\\newlyrics', r'\\addlyrics', str)
2253         if re.search (r"\\override\s*TextSpanner", str):
2254                 sys.stderr.write ("\nWarning: TextSpanner has been split into DynamicTextSpanner and TextSpanner\n")
2255         return str
2256
2257 conversions.append (((2, 3, 10), conv,
2258                      '''\\addlyrics -> \\oldaddlyrics, \\newlyrics -> \\addlyrics'''))
2259
2260 def conv (str):
2261         str = re.sub (r'\\setMmRestFermata\s+(R[0-9.*/]*)',
2262                       r'\1^\\fermataMarkup', str)
2263         return str
2264
2265 conversions.append (((2, 3, 11), conv,
2266                      '''\\setMmRestFermata -> ^\\fermataMarkup'''))
2267
2268 def conv (str):
2269         str = re.sub (r'\\newpage', r'\\pageBreak', str)
2270         str = re.sub (r'\\scriptUp', r"""{
2271   \\override TextScript  #'direction = #1
2272   \\override Script  #'direction = #1
2273 }""", str)
2274         str = re.sub (r'\\scriptDown', r"""{
2275   \\override TextScript  #'direction = #-1
2276   \\override Script  #'direction = #-1
2277 }""", str)
2278         str = re.sub (r'\\scriptBoth', r"""{
2279   \\revert TextScript  #'direction
2280   \\revert Script  #'direction
2281 }""", str)
2282         str = re.sub ('soloADue', 'printPartCombineTexts', str)
2283         str = re.sub (r'\\applymusic\s*#notes-to-clusters',
2284                       '\\makeClusters', str)
2285
2286         str = re.sub (r'pagenumber\s*=', 'firstpagenumber = ', str)
2287         return str
2288
2289 conversions.append (((2, 3, 12), conv,
2290                      '''\\newpage -> \\pageBreak, junk \\script{up,down,both},
2291 soloADue -> printPartCombineTexts, #notes-to-clusters -> \\makeClusters
2292 '''))
2293
2294
2295 def conv (str):
2296         str = re.sub (r'\\chords\b', r'\\chordmode', str)
2297         str = re.sub (r'\\lyrics\b', r'\\lyricmode', str)
2298         str = re.sub (r'\\figures\b', r'\\figuremode', str)
2299         str = re.sub (r'\\notes\b', r'\\notemode', str)
2300         str = re.sub (r'\\drums\b', r'\\drummode', str)
2301         str = re.sub (r'\\chordmode\s*\\new ChordNames', r'\\chords', str)
2302         str = re.sub (r'\\new ChordNames\s*\\chordmode', r'\\chords', str)
2303         str = re.sub (r'\\new FiguredBass\s*\\figuremode', r'\\figures', str)
2304         str = re.sub (r'\\figuremode\s*\new FiguredBass', r'\\figures', str)
2305         str = re.sub (r'\\new DrumStaff\s*\\drummode', r'\\drums', str)
2306         str = re.sub (r'\\drummode\s*\\new DrumStaff', r'\\drums', str)
2307
2308         return str
2309
2310 conversions.append (((2, 3, 16), conv,
2311                      '''\foo -> \foomode (for chords, notes, etc.)
2312 fold \new FooContext \foomode into \foo.'''))
2313
2314 def conv (str):
2315         str = re.sub (r'(slur|stem|phrasingSlur|tie|dynamic|dots|tuplet|arpeggio|)Both', r'\1Neutral', str)
2316         str = re.sub (r"\\applymusic\s*#\(remove-tag\s*'([a-z-0-9]+)\)",
2317                       r"\\removeWithTag #'\1", str)
2318         return str
2319
2320 conversions.append (((2, 3, 17), conv,
2321                      '''\foo -> \foomode (for chords, notes, etc.)
2322 fold \new FooContext \foomode into \foo.'''))
2323
2324
2325 def conv (str):
2326         str = re.sub (r'Text_item', 'Text_interface', str)
2327         return str
2328
2329 conversions.append (((2, 3, 18),
2330                      conv,
2331                      '''Text_item -> Text_interface''' ))
2332
2333 def conv (str):
2334         str = re.sub (r'\\paper', r'\\layout', str)
2335         str = re.sub (r'\\bookpaper', r'\\paper', str)
2336         if re.search ('paper-set-staff-size', str):
2337                 sys.stderr.write ('''\nWarning: staff size should be changed at top-level
2338 with
2339
2340   #(set-global-staff-size <STAFF-HEIGHT-IN-POINT>)
2341
2342 ''')
2343
2344
2345         str = re.sub (r'#\(paper-set-staff-size', '%Use set-global-staff-size at toplevel\n% #(layout-set-staff-size', str)
2346         return str
2347
2348 conversions.append (((2, 3, 22),
2349                      conv,
2350                      '''paper -> layout
2351  bookpaper -> paper''' ))
2352
2353
2354 def conv (str):
2355         str = re.sub (r'\\context\s+([a-zA-Z]+)\s*=\s*([a-z]+)\s',
2356                       r'\\context \1 = "\2" ',
2357                       str )
2358         return str
2359
2360 conversions.append (((2, 3, 23),
2361                      conv,
2362                      '''\context Foo = NOTENAME -> \context Foo = "NOTENAME"'''))
2363
2364 def conv (str):
2365         def sub(m):
2366                 return regularize_id (m.group (1))
2367         str = re.sub (r'(maintainer_email|maintainer_web|midi_stuff|gourlay_maxmeasures)',
2368                       sub, str)
2369         return str
2370
2371 conversions.append (((2, 3, 24),
2372                      conv,
2373                      '''regularize other identifiers.'''))
2374
2375
2376 def conv (str):
2377         return str
2378
2379 conversions.append (((2, 4, 0),
2380                      conv,
2381                      ''))
2382
2383
2384 def conv (str):
2385         str = re.sub (r'\\quote\s+"?([a-zA-Z0-9]+)"?\s+([0-9.*/]+)',
2386                       r'\\quoteDuring #"\1" { \skip \2 }',
2387                       str
2388                       )
2389         return str
2390
2391 conversions.append (((2, 5, 0),
2392                      conv,
2393                      ''))
2394
2395
2396 def conv (str):
2397         str = re.sub (r'ly:import-module',
2398                       r'ly:module-copy', str)
2399         return str
2400
2401 conversions.append (((2, 5, 1),
2402                      conv,
2403                      'ly:import-module -> ly:module-copy'))
2404
2405 def conv (str):
2406         str = re.sub (r'\\(column|fill-line|dir-column|center-align|right-align|left-align|bracketed-y-column)\s*<(([^>]|<[^>]*>)*)>',
2407                       r'\\\1 {\2}', str)
2408         str = re.sub (r'\\(column|fill-line|dir-column|center-align|right-align|left-align|bracketed-y-column)\s*<(([^>]|<[^>]*>)*)>',
2409                       r'\\\1 {\2}', str)
2410         str = re.sub (r'\\(column|fill-line|dir-column|center-align|right-align|left-align|bracketed-y-column)\s*<(([^>]|<[^>]*>)*)>',
2411                       r'\\\1 {\2}', str)
2412         def get_markup (m):
2413                 s = m.group (0)
2414                 s = re.sub (r'''((\\"|})\s*){''', '\2 \\line {', s)
2415                 return s
2416         str = re.sub (r'\\markup\s*{([^}]|{[^}]*})*}', get_markup, str)
2417         return str
2418
2419 conversions.append (((2, 5, 2),
2420                      conv,
2421                      '\markup .. < .. > .. -> \markup .. { .. } ..'))
2422
2423 def conv (str):
2424         str = re.sub ('ly:find-glyph-by-name', 'ly:font-get-glyph', str)
2425         str = re.sub ('"(scripts|clefs|accidentals)-', r'"\1.', str)
2426         str = re.sub ("'hufnagel-do-fa", "'hufnagel.do.fa", str)
2427         str = re.sub ("'(vaticana|hufnagel|medicaea|petrucci|neomensural|mensural)-", r"'\1.", str)
2428         return str
2429
2430 conversions.append (((2, 5, 3),
2431                      conv,
2432                      'ly:find-glyph-by-name -> ly:font-get-glyph, remove - from glyphnames.'))
2433
2434
2435 def conv (str):
2436         str = re.sub (r"\\override\s+(Voice\.)?Slur #'dashed\s*=\s*#\d*(\.\d+)?",
2437                       r"\\slurDashed", str)
2438         return str
2439
2440 conversions.append (((2, 5, 12),
2441                      conv,
2442                      '\set Slur #\'dashed = #X -> \slurDashed'))
2443
2444 def conv (str):
2445         input_encoding = 'latin1'
2446         def func (match):
2447                 encoding = match.group (1)
2448
2449                 # FIXME: automatic recoding of other than latin1?
2450                 if encoding == 'latin1':
2451                         return match.group (2)
2452
2453                 sys.stderr.write ('\n')
2454                 sys.stderr.write (NOT_SMART % ("\\encoding: %s" % encoding))
2455                 sys.stderr.write ('\n')
2456                 sys.stderr.write (_ ("LilyPond source must be UTF-8"))
2457                 sys.stderr.write ('\n')
2458                 if encoding == 'TeX':
2459                         sys.stderr.write (_ ("Try the texstrings backend"))
2460                         sys.stderr.write ('\n')
2461                 else:
2462                         sys.stderr.write ( _("Do something like: %s") % \
2463                                            ("recode %s..utf-8 FILE" % encoding))
2464                         sys.stderr.write ('\n')
2465                 sys.stderr.write (_ ("Or save as UTF-8 in your editor"))
2466                 sys.stderr.write ('\n')
2467                 raise FatalConversionError ()
2468
2469                 return match.group (0)
2470
2471         str = re.sub (r'\\encoding\s+"?([a-zA-Z0-9]+)"?(\s+)', func, str)
2472
2473         import codecs
2474         de_ascii = codecs.getdecoder ('ascii')
2475         de_utf_8 = codecs.getdecoder ('utf_8')
2476         de_input = codecs.getdecoder (input_encoding)
2477         en_utf_8 = codecs.getencoder ('utf_8')
2478         try:
2479                 de_ascii (str)
2480         # only in python >= 2.3
2481         # except UnicodeDecodeError:
2482         except UnicodeError:
2483                 # do not re-recode UTF-8 input
2484                 try:
2485                         de_utf_8 (str)
2486                 #except UnicodeDecodeError:
2487                 except UnicodeError:
2488                         str = en_utf_8 (de_input (str)[0])[0]
2489
2490
2491
2492         str = re.sub (r"#\(ly:set-point-and-click '[a-z-]+\)", '', str)
2493         return str
2494
2495 conversions.append (((2, 5, 13),
2496                      conv,
2497                      '\\encoding: smart recode latin1..utf-8. Remove ly:point-and-click'))
2498
2499
2500 def conv (str):
2501         if re.search ("ly:stencil-set-extent!", str):
2502                 sys.stderr.write ('\n')
2503                 sys.stderr.write (NOT_SMART % "ly:stencil-set-extent!")
2504                 sys.stderr.write ('\n')
2505                 sys.stderr.write ('use (set! VAR (ly:make-stencil (ly:stencil-expr VAR) X-EXT Y-EXT))\n')
2506                 raise FatalConversionError ()
2507         if re.search ("ly:stencil-align-to!", str):
2508                 sys.stderr.write ('\n')
2509                 sys.stderr.write (NOT_SMART % "ly:stencil-align-to!")
2510                 sys.stderr.write ('\n')
2511                 sys.stderr.write ('use (set! VAR (ly:stencil-aligned-to VAR AXIS DIR))\n')
2512                 raise FatalConversionError ()
2513         return str
2514
2515 conversions.append (((2, 5, 17),
2516                      conv,
2517                      'ly:stencil-set-extent! removed'))
2518                     
2519 def conv (str):
2520         str = re.sub (r"ly:warn\b", 'ly:warning', str)
2521         return str
2522
2523 conversions.append (((2, 5, 18),
2524                      conv,
2525                      'ly:warn -> ly:warning'))
2526 def conv (str):
2527         if re.search ("(override-|revert-)auto-beam-setting", str)\
2528            or re.search ("autoBeamSettings", str):
2529                 sys.stderr.write ('\n')
2530                 sys.stderr.write (NOT_SMART % "auto beam settings")
2531                 sys.stderr.write ('\n')
2532                 sys.stderr.write ('''
2533 Auto beam settings must now specify each interesting moment in a measure
2534 explicitely; 1/4 is no longer multiplied to cover moments 1/2 and 3/4 too.
2535 ''')
2536                 sys.stderr.write (UPDATE_MANUALLY)
2537                 sys.stderr.write ('\n')
2538                 raise FatalConversionError ()
2539         return str
2540
2541 conversions.append (((2, 5, 21),
2542                      conv,
2543                      'warn about auto beam settings'))
2544                     
2545 ################################
2546 #       END OF CONVERSIONS
2547 ################################
2548
2549 def get_conversions (from_version, to_version):
2550         def version_b (v, f = from_version, t = to_version):
2551                 return version_cmp (v[0], f) > 0 and version_cmp (v[0], t) <= 0
2552         return filter (version_b, conversions)
2553
2554
2555 def latest_version ():
2556         return conversions[-1][0]
2557
2558 def do_conversion (infile, from_version, outfile, to_version):
2559         conv_list = get_conversions (from_version, to_version)
2560
2561         sys.stderr.write (_ ("Applying conversion: "))
2562         str = infile.read ()
2563         last_conversion = ()
2564         try:
2565                 for x in conv_list:
2566                         sys.stderr.write (tup_to_str (x[0]))
2567                         if x != conv_list[-1]:
2568                                 sys.stderr.write (', ')
2569                         str = x[1] (str)
2570                         last_conversion = x[0]
2571
2572         except FatalConversionError:
2573                 sys.stderr.write (_ ("%s: error while converting") \
2574                                   % program_name)
2575                 sys.stderr.write ('\n')
2576                 sys.stderr.write (_ ("Aborting"))
2577                 sys.stderr.write ('\n')
2578
2579         if last_conversion:
2580                 new_ver =  '\\version \"%s\"' % tup_to_str (last_conversion)
2581
2582                 if re.search (lilypond_version_re_str, str):
2583                         str = re.sub (lilypond_version_re_str,
2584                                       '\\%s' % new_ver, str)
2585                 elif add_version:
2586                         str = new_ver + '\n' + str
2587
2588                 sys.stderr.write ('\n')
2589                 outfile.write (str)
2590
2591         return last_conversion
2592
2593 class UnknownVersion:
2594         pass
2595
2596 def do_one_file (infile_name):
2597         sys.stderr.write (_ ("Processing `%s\'... ") % infile_name)
2598         sys.stderr.write ('\n')
2599         outfile_name = ''
2600         if __main__.edit:
2601                 outfile_name = infile_name + '.NEW'
2602         elif __main__.outfile_name:
2603                 outfile_name = __main__.outfile_name
2604
2605         if __main__.from_version:
2606                 from_version = __main__.from_version
2607         else:
2608                 guess = guess_lilypond_version (infile_name)
2609                 if not guess:
2610                         raise UnknownVersion ()
2611                 from_version = str_to_tuple (guess)
2612
2613         if __main__.to_version:
2614                 to_version = __main__.to_version
2615         else:
2616                 to_version = latest_version ()
2617
2618
2619         if infile_name:
2620                 infile = open (infile_name, 'r')
2621         else:
2622                 infile = sys.stdin
2623
2624         if outfile_name:
2625                 outfile =  open (outfile_name, 'w')
2626         else:
2627                 outfile = sys.stdout
2628
2629         touched = do_conversion (infile, from_version, outfile, to_version)
2630
2631         if infile_name:
2632                 infile.close ()
2633
2634         if outfile_name:
2635                 outfile.close ()
2636
2637         if __main__.edit and touched:
2638                 try:
2639                         os.remove(infile_name + '~')
2640                 except:
2641                         pass
2642                 os.rename (infile_name, infile_name + '~')
2643                 os.rename (infile_name + '.NEW', infile_name)
2644
2645         sys.stderr.flush ()
2646
2647 edit = 0
2648 assume_old = 0
2649 to_version = ()
2650 from_version = ()
2651 outfile_name = ''
2652 show_rules_p = 0
2653
2654 (options, files) = getopt.getopt (sys.argv[1:], 'ao:f:t:senhv',
2655                                   ['no-version', 'version', 'output',
2656                                   'show-rules', 'help', 'edit',
2657                                   'from=', 'to='])
2658
2659 for opt in options:
2660         o = opt[0]
2661         a = opt[1]
2662         if o == '--help' or o == '-h':
2663                 usage ()
2664                 sys.exit (0)
2665         elif o == '--version' or o == '-v':
2666                 print_version ()
2667                 sys.exit (0)
2668         elif o== '--from' or o=='-f':
2669                 from_version = str_to_tuple (a)
2670         elif o== '--to' or o=='-t':
2671                 to_version = str_to_tuple (a)
2672         elif o== '--edit' or o == '-e':
2673                 edit = 1
2674         elif o== '--show-rules' or o == '-s':
2675                 show_rules_p = 1
2676         elif o == '--output' or o == '-o':
2677                 outfile_name = a
2678         elif o == '--no-version' or o == '-n':
2679                 add_version = 0
2680         else:
2681                 print o
2682                 raise getopt.error
2683
2684 # should parse files[] to read \version?
2685 if show_rules_p:
2686         show_rules (sys.stdout)
2687         sys.exit (0)
2688
2689 identify ()
2690
2691 if not files:
2692         usage ()
2693         sys.exit (2)
2694
2695 for f in files:
2696         if f == '-':
2697                 f = ''
2698         elif not os.path.isfile (f):
2699                 sys.stderr.write ('\n')
2700                 sys.stderr.write (_ ("can't open file: `%s'") % f)
2701                 sys.stderr.write ('\n')
2702                 if len (files) == 1:
2703                         sys.exit (1)
2704                 continue
2705         try:
2706                 do_one_file (f)
2707         except UnknownVersion:
2708                 sys.stderr.write ('\n')
2709                 sys.stderr.write (_ ("%s: can't determine version for `%s'") \
2710                                   % (program_name, f))
2711                 sys.stderr.write ('\n')
2712                 if assume_old:
2713                         fv = from_version
2714                         from_version = (0, 0, 0)
2715                         do_one_file (f)
2716                         from_version = fv
2717                 else:
2718                         sys.stderr.write (_ ("%s: skipping: `%s'") \
2719                                           % (program_name,  f))
2720                 pass
2721
2722 sys.stderr.write ('\n')