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