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