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