(system): remove errorlog files.
[lilypond.git] / scripts / convert-ly.py
blob2f14ad226d277779143f76b22d13502271169bb1
1 #!@PYTHON@
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--2003 Han-Wen Nienhuys <hanwen@cs.uu.nl>
8 # Jan Nieuwenhuizen <janneke@gnu.org>
11 # TODO
12 # use -f and -t for -s output
14 # NEWS
15 # 0.2
16 # - rewrite in python
18 program_name = 'convert-ly'
19 version = '@TOPLEVEL_VERSION@'
21 import os
22 import sys
23 import __main__
24 import getopt
25 import string
26 import re
27 import time
29 # Did we ever have \mudela-version? I doubt it.
30 # lilypond_version_re_str = '\\\\version *\"(.*)\"'
31 lilypond_version_re_str = '\\\\(mudela-)?version *\"(.*)\"'
32 lilypond_version_re = re.compile (lilypond_version_re_str)
33 add_version = 1
36 def program_id ():
37 return '%s (GNU LilyPond) %s' %(program_name, version);
39 def identify ():
40 sys.stderr.write (program_id () + '\n')
42 def usage ():
43 sys.stdout.write (
44 r"""Usage: %s [OPTIONS]... [FILE]...
45 Try to convert to newer lilypond-versions. The version number of the
46 input is guessed by default from \version directive.
48 Options:
49 -h, --help print this help
50 -e, --edit edit in place
51 -f, --from=VERSION start from version; overrides \version found in file
52 -s, --show-rules print all rules
53 -t, --to=VERSION show target version
54 -n, --no-version don't add new version stamp
55 --version print program version
57 Report bugs to bugs-gnu-music@gnu.org.
59 """ % program_name)
62 sys.exit (0)
64 def print_version ():
66 sys.stdout.write (r"""%s
68 This is free software. It is covered by the GNU General Public
69 License, and you are welcome to change it and/or distribute copies of
70 it under certain conditions. invoke as `%s --warranty' for more
71 information.
73 """ % (program_id() , program_name))
75 def gulp_file(f):
76 try:
77 i = open(f)
78 i.seek (0, 2)
79 n = i.tell ()
80 i.seek (0,0)
81 except:
82 print 'can\'t open file: ' + f + '\n'
83 return ''
84 s = i.read (n)
85 if len (s) <= 0:
86 print 'gulped empty file: ' + f + '\n'
87 i.close ()
88 return s
90 def str_to_tuple (s):
91 return tuple (map (string.atoi, string.split (s,'.')))
93 def tup_to_str (t):
94 return string.join (map (lambda x: '%s' % x, list (t)), '.')
96 def version_cmp (t1, t2):
97 for x in [0,1,2]:
98 if t1[x] - t2[x]:
99 return t1[x] - t2[x]
100 return 0
102 def guess_lilypond_version (filename):
103 s = gulp_file (filename)
104 m = lilypond_version_re.search (s)
105 if m:
106 return m.group (2)
107 else:
108 return ''
110 class FatalConversionError:
111 pass
113 conversions = []
115 def show_rules (file):
116 for x in conversions:
117 file.write ('%s: %s\n' % (tup_to_str (x[0]), x[2]))
119 ############################
121 if 1:
122 def conv(str):
123 if re.search ('\\\\multi', str):
124 sys.stderr.write ('\nNot smart enough to convert \\multi')
125 return str
127 conversions.append (((0,1,9), conv, '\\header { key = concat + with + operator }'))
129 if 1: # need new a namespace
130 def conv (str):
131 if re.search ('\\\\octave', str):
132 sys.stderr.write ('\nNot smart enough to convert \\octave')
133 # raise FatalConversionError()
135 return str
137 conversions.append ((
138 ((0,1,19), conv, 'deprecated \\octave; can\'t convert automatically')))
141 if 1: # need new a namespace
142 def conv (str):
143 str = re.sub ('\\\\textstyle([^;]+);',
144 '\\\\property Lyrics . textstyle = \\1', str)
145 # harmful to current .lys
146 # str = re.sub ('\\\\key([^;]+);', '\\\\accidentals \\1;', str)
148 return str
150 conversions.append ((
151 ((0,1,20), conv, 'deprecated \\textstyle, new \key syntax')))
154 if 1:
155 def conv (str):
156 str = re.sub ('\\\\musical_pitch', '\\\\musicalpitch',str)
157 str = re.sub ('\\\\meter', '\\\\time',str)
159 return str
161 conversions.append ((
162 ((0,1,21), conv, '\\musical_pitch -> \\musicalpitch, '+
163 '\\meter -> \\time')))
165 if 1:
166 def conv (str):
167 return str
169 conversions.append ((
170 ((1,0,0), conv, '0.1.21 -> 1.0.0 ')))
173 if 1:
174 def conv (str):
175 str = re.sub ('\\\\accidentals', '\\\\keysignature',str)
176 str = re.sub ('specialaccidentals *= *1', 'keyoctaviation = 0',str)
177 str = re.sub ('specialaccidentals *= *0', 'keyoctaviation = 1',str)
179 return str
181 conversions.append ((
182 ((1,0,1), conv, '\\accidentals -> \\keysignature, ' +
183 'specialaccidentals -> keyoctaviation')))
185 if 1:
186 def conv(str):
187 if re.search ('\\\\header', str):
188 sys.stderr.write ('\nNot smart enough to convert to new \\header format')
189 return str
191 conversions.append (((1,0,2), conv, '\\header { key = concat + with + operator }'))
193 if 1:
194 def conv(str):
195 str = re.sub ('\\\\melodic([^a-zA-Z])', '\\\\notes\\1',str)
196 return str
198 conversions.append (((1,0,3), conv, '\\melodic -> \\notes'))
200 if 1:
201 def conv(str):
202 str = re.sub ('default_paper *=', '',str)
203 str = re.sub ('default_midi *=', '',str)
204 return str
206 conversions.append (((1,0,4), conv, 'default_{paper,midi}'))
208 if 1:
209 def conv(str):
210 str = re.sub ('ChoireStaff', 'ChoirStaff',str)
211 str = re.sub ('\\\\output', 'output = ',str)
213 return str
215 conversions.append (((1,0,5), conv, 'ChoireStaff -> ChoirStaff'))
217 if 1:
218 def conv(str):
219 if re.search ('[a-zA-Z]+ = *\\translator',str):
220 sys.stderr.write ('\nNot smart enough to change \\translator syntax')
221 # raise FatalConversionError()
222 return str
224 conversions.append (((1,0,6), conv, 'foo = \\translator {\\type .. } ->\\translator {\\type ..; foo; }'))
227 if 1:
228 def conv(str):
229 str = re.sub ('\\\\lyrics*', '\\\\lyrics',str)
231 return str
233 conversions.append (((1,0,7), conv, '\\lyric -> \\lyrics'))
235 if 1:
236 def conv(str):
237 str = re.sub ('\\\\\\[/3+', '\\\\times 2/3 { ',str)
238 str = re.sub ('\\[/3+', '\\\\times 2/3 { [',str)
239 str = re.sub ('\\\\\\[([0-9/]+)', '\\\\times \\1 {',str)
240 str = re.sub ('\\[([0-9/]+)', '\\\\times \\1 { [',str)
241 str = re.sub ('\\\\\\]([0-9/]+)', '}', str)
242 str = re.sub ('\\\\\\]', '}',str)
243 str = re.sub ('\\]([0-9/]+)', '] }', str)
244 return str
246 conversions.append (((1,0,10), conv, '[2/3 ]1/1 -> \\times 2/3 '))
248 if 1:
249 def conv(str):
250 return str
251 conversions.append (((1,0,12), conv, 'Chord syntax stuff'))
254 if 1:
255 def conv(str):
258 str = re.sub ('<([^>~]+)~([^>]*)>','<\\1 \\2> ~', str)
260 return str
262 conversions.append (((1,0,13), conv, '<a ~ b> c -> <a b> ~ c'))
264 if 1:
265 def conv(str):
266 str = re.sub ('<\\[','[<', str)
267 str = re.sub ('\\]>','>]', str)
269 return str
271 conversions.append (((1,0,14), conv, '<[a b> <a b]>c -> [<a b> <a b>]'))
274 if 1:
275 def conv(str):
276 str = re.sub ('\\\\type([^\n]*engraver)','\\\\TYPE\\1', str)
277 str = re.sub ('\\\\type([^\n]*performer)','\\\\TYPE\\1', str)
278 str = re.sub ('\\\\type','\\\\context', str)
279 str = re.sub ('\\\\TYPE','\\\\type', str)
280 str = re.sub ('textstyle','textStyle', str)
282 return str
284 conversions.append (((1,0,16), conv, '\\type -> \\context, textstyle -> textStyle'))
287 if 1:
288 def conv(str):
289 if re.search ('\\\\repeat',str):
290 sys.stderr.write ('\nNot smart enough to convert \\repeat')
291 # raise FatalConversionError()
292 return str
294 conversions.append (((1,0,18), conv,
295 '\\repeat NUM Music Alternative -> \\repeat FOLDSTR Music Alternative'))
297 if 1:
298 def conv(str):
299 str = re.sub ('SkipBars','skipBars', str)
300 str = re.sub ('fontsize','fontSize', str)
301 str = re.sub ('midi_instrument','midiInstrument', str)
303 return str
305 conversions.append (((1,0,19), conv,
306 'fontsize -> fontSize, midi_instrument -> midiInstrument, SkipBars -> skipBars'))
309 if 1:
310 def conv(str):
311 str = re.sub ('tieydirection','tieVerticalDirection', str)
312 str = re.sub ('slurydirection','slurVerticalDirection', str)
313 str = re.sub ('ydirection','verticalDirection', str)
315 return str
317 conversions.append (((1,0,20), conv,
318 '{,tie,slur}ydirection -> {v,tieV,slurV}erticalDirection'))
321 if 1:
322 def conv(str):
323 str = re.sub ('hshift','horizontalNoteShift', str)
325 return str
327 conversions.append (((1,0,21), conv,
328 'hshift -> horizontalNoteShift'))
331 if 1:
332 def conv(str):
333 str = re.sub ('\\\\grouping[^;]*;','', str)
335 return str
337 conversions.append (((1,1,52), conv,
338 'deprecate \\grouping'))
341 if 1:
342 def conv(str):
343 str = re.sub ('\\\\wheel','\\\\coda', str)
345 return str
347 conversions.append (((1,1,55), conv,
348 '\\wheel -> \\coda'))
350 if 1:
351 def conv(str):
352 str = re.sub ('keyoctaviation','keyOctaviation', str)
353 str = re.sub ('slurdash','slurDash', str)
355 return str
357 conversions.append (((1,1,65), conv,
358 'slurdash -> slurDash, keyoctaviation -> keyOctaviation'))
360 if 1:
361 def conv(str):
362 str = re.sub ('\\\\repeat *\"?semi\"?','\\\\repeat "volta"', str)
364 return str
366 conversions.append (((1,1,66), conv,
367 'semi -> volta'))
370 if 1:
371 def conv(str):
372 str = re.sub ('\"?beamAuto\"? *= *\"?0?\"?','noAutoBeaming = "1"', str)
374 return str
376 conversions.append (((1,1,67), conv,
377 'beamAuto -> noAutoBeaming'))
379 if 1:
380 def conv(str):
381 str = re.sub ('automaticMelismas', 'automaticMelismata', str)
383 return str
385 conversions.append (((1,2,0), conv,
386 'automaticMelismas -> automaticMelismata'))
388 if 1:
389 def conv(str):
390 str = re.sub ('dynamicDir\\b', 'dynamicDirection', str)
392 return str
394 conversions.append (((1,2,1), conv,
395 'dynamicDir -> dynamicDirection'))
397 if 1:
398 def conv(str):
399 str = re.sub ('\\\\cadenza *0 *;', '\\\\cadenzaOff', str)
400 str = re.sub ('\\\\cadenza *1 *;', '\\\\cadenzaOn', str)
402 return str
404 conversions.append (((1,3,4), conv,
405 '\\cadenza -> \cadenza{On|Off}'))
407 if 1:
408 def conv (str):
409 str = re.sub ('"?beamAuto([^"=]+)"? *= *"([0-9]+)/([0-9]+)" *;*',
410 'beamAuto\\1 = #(make-moment \\2 \\3)',
411 str)
412 return str
414 conversions.append (((1,3,5), conv, 'beamAuto moment properties'))
416 if 1:
417 def conv (str):
418 str = re.sub ('stemStyle',
419 'flagStyle',
420 str)
421 return str
423 conversions.append (((1,3,17), conv, 'stemStyle -> flagStyle'))
425 if 1:
426 def conv (str):
427 str = re.sub ('staffLineLeading',
428 'staffSpace',
429 str)
430 return str
432 conversions.append (((1,3,18), conv, 'staffLineLeading -> staffSpace'))
435 if 1:
436 def conv(str):
437 if re.search ('\\\\repetitions',str):
438 sys.stderr.write ('\nNot smart enough to convert \\repetitions')
439 # raise FatalConversionError()
440 return str
442 conversions.append (((1,3,23), conv,
443 '\\\\repetitions feature dropped'))
446 if 1:
447 def conv (str):
448 str = re.sub ('textEmptyDimension *= *##t',
449 'textNonEmpty = ##f',
450 str)
451 str = re.sub ('textEmptyDimension *= *##f',
452 'textNonEmpty = ##t',
453 str)
454 return str
456 conversions.append (((1,3,35), conv, 'textEmptyDimension -> textNonEmpty'))
458 if 1:
459 def conv (str):
460 str = re.sub ("([a-z]+)[ \t]*=[ \t]*\\\\musicalpitch *{([- 0-9]+)} *\n",
461 "(\\1 . (\\2))\n", str)
462 str = re.sub ("\\\\musicalpitch *{([0-9 -]+)}",
463 "\\\\musicalpitch #'(\\1)", str)
464 if re.search ('\\\\notenames',str):
465 sys.stderr.write ('\nNot smart enough to convert to new \\notenames format')
466 return str
468 conversions.append (((1,3,38), conv, '\musicalpitch { a b c } -> #\'(a b c)'))
470 if 1:
471 def conv (str):
472 def replace (match):
473 return '\\key %s;' % string.lower (match.group (1))
475 str = re.sub ("\\\\key ([^;]+);", replace, str)
476 return str
478 conversions.append (((1,3,39), conv, '\\key A ; ->\\key a;'))
480 if 1:
481 def conv (str):
482 if re.search ('\\[:',str):
483 sys.stderr.write ('\nNot smart enough to convert to new tremolo format')
484 return str
486 conversions.append (((1,3,41), conv,
487 '[:16 c4 d4 ] -> \\repeat "tremolo" 2 { c16 d16 }'))
489 if 1:
490 def conv (str):
491 str = re.sub ('Staff_margin_engraver' , 'Instrument_name_engraver', str)
492 return str
494 conversions.append (((1,3,42), conv,
495 'Staff_margin_engraver deprecated, use Instrument_name_engraver'))
497 if 1:
498 def conv (str):
499 str = re.sub ('note[hH]eadStyle\\s*=\\s*"?(\\w+)"?' , "noteHeadStyle = #'\\1", str)
500 return str
502 conversions.append (((1,3,49), conv,
503 'noteHeadStyle value: string -> symbol'))
505 if 1:
506 def conv (str):
507 if re.search ('\\\\keysignature', str):
508 sys.stderr.write ('\nNot smart enough to convert to new tremolo format')
509 return str
512 conversions.append (((1,3,58), conv,
513 'noteHeadStyle value: string -> symbol'))
515 if 1:
516 def conv (str):
517 str = re.sub (r"""\\key *([a-z]+) *;""", r"""\\key \1 \major;""",str);
518 return str
519 conversions.append (((1,3,59), conv,
520 '\key X ; -> \key X major; '))
522 if 1:
523 def conv (str):
524 str = re.sub (r'latexheaders *= *"\\\\input ',
525 'latexheaders = "',
526 str)
527 return str
528 conversions.append (((1,3,68), conv, 'latexheaders = "\\input global" -> latexheaders = "global"'))
533 # TODO: lots of other syntax change should be done here as well
534 if 1:
535 def conv (str):
536 str = re.sub ('basicCollisionProperties', 'NoteCollision', str)
537 str = re.sub ('basicVoltaSpannerProperties' , "VoltaBracket", str)
538 str = re.sub ('basicKeyProperties' , "KeySignature", str)
540 str = re.sub ('basicClefItemProperties' ,"Clef", str)
543 str = re.sub ('basicLocalKeyProperties' ,"Accidentals", str)
544 str = re.sub ('basicMarkProperties' ,"Accidentals", str)
545 str = re.sub ('basic([A-Za-z_]+)Properties', '\\1', str)
547 str = re.sub ('Repeat_engraver' ,'Volta_engraver', str)
548 return str
550 conversions.append (((1,3,92), conv, 'basicXXXProperties -> XXX, Repeat_engraver -> Volta_engraver'))
552 if 1:
553 def conv (str):
554 # Ugh, but meaning of \stemup changed too
555 # maybe we should do \stemup -> \stemUp\slurUp\tieUp ?
556 str = re.sub ('\\\\stemup', '\\\\stemUp', str)
557 str = re.sub ('\\\\stemdown', '\\\\stemDown', str)
558 str = re.sub ('\\\\stemboth', '\\\\stemBoth', str)
560 str = re.sub ('\\\\slurup', '\\\\slurUp', str)
561 str = re.sub ('\\\\slurboth', '\\\\slurBoth', str)
562 str = re.sub ('\\\\slurdown', '\\\\slurDown', str)
563 str = re.sub ('\\\\slurdotted', '\\\\slurDotted', str)
564 str = re.sub ('\\\\slurnormal', '\\\\slurNoDots', str)
566 str = re.sub ('\\\\shiftoff', '\\\\shiftOff', str)
567 str = re.sub ('\\\\shifton', '\\\\shiftOn', str)
568 str = re.sub ('\\\\shiftonn', '\\\\shiftOnn', str)
569 str = re.sub ('\\\\shiftonnn', '\\\\shiftOnnn', str)
571 str = re.sub ('\\\\onevoice', '\\\\oneVoice', str)
572 str = re.sub ('\\\\voiceone', '\\\\voiceOne', str)
573 str = re.sub ('\\\\voicetwo', '\\\\voiceTwo', str)
574 str = re.sub ('\\\\voicethree', '\\\\voiceThree', str)
575 str = re.sub ('\\\\voicefour', '\\\\voiceFour', str)
577 # I don't know exactly when these happened...
578 # ugh, we loose context setting here...
579 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\stemUp\\\\slurUp\\\\tieUp', str)
580 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\stemDown\\\\slurDown\\\\tieDown', str)
581 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\\\stemBoth\\\\slurBoth\\\\tieBoth', str)
583 str = re.sub ('verticalDirection[^=]*= *#?"?(1|(\\\\up))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #1', str)
584 str = re.sub ('verticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #-1', str)
585 str = re.sub ('verticalDirection[^=]*= *#?"?(0|(\\\\center))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #0', str)
587 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\\\1Up', str)
588 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\\\1Down', str)
589 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\\\\\1Both', str)
591 # (lacks capitalisation slur -> Slur)
592 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\1 \\\\override #\'direction = #1', str)
593 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\1 \\override #\'direction = #-1', str)
594 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\1 \\\\override #\'direction = #0', str)
596 ## dynamic..
597 str = re.sub ('\\\\property *[^ .]*[.]?dynamicDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\dynamicUp', str)
598 str = re.sub ('\\\\property *[^ .]*[.]?dyn[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\dynamicDown', str)
599 str = re.sub ('\\\\property *[^ .]*[.]?dyn[^=]*= *#?"?(0|(\\\\center))"?', '\\\\dynamicBoth', str)
601 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)Dash[^=]*= *#?"?(0|(""))"?', '\\\\\\1NoDots', str)
602 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)Dash[^=]*= *#?"?([1-9]+)"?', '\\\\\\1Dotted', str)
604 str = re.sub ('\\\\property *[^ .]*[.]?noAutoBeaming[^=]*= *#?"?(0|(""))"?', '\\\\autoBeamOn', str)
605 str = re.sub ('\\\\property *[^ .]*[.]?noAutoBeaming[^=]*= *#?"?([1-9]+)"?', '\\\\autoBeamOff', str)
609 return str
611 conversions.append (((1,3,93), conv,
612 'property definiton case (eg. onevoice -> oneVoice)'))
615 if 1:
616 def conv (str):
617 str = re.sub ('ChordNames*', 'ChordNames', str)
618 if re.search ('\\\\textscript "[^"]* *"[^"]*"', str):
619 sys.stderr.write ('\nNot smart enough to convert to new \\textscript markup text')
621 str = re.sub ('\\textscript +("[^"]*")', '\\textscript #\\1', str)
623 return str
625 conversions.append (((1,3,97), conv, 'ChordName -> ChordNames'))
628 # TODO: add lots of these
630 if 1:
631 def conv (str):
632 str = re.sub ('\\\\property *"?Voice"? *[.] *"?textStyle"? *= *"([^"]*)"', '\\\\property Voice.TextScript \\\\set #\'font-style = #\'\\1', str)
633 str = re.sub ('\\\\property *"?Lyrics"? *[.] *"?textStyle"? *= *"([^"]*)"', '\\\\property Lyrics.LyricText \\\\set #\'font-style = #\'\\1', str)
635 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?timeSignatureStyle"? *= *"([^"]*)"', '\\\\property \\1.TimeSignature \\\\override #\'style = #\'\\2', str)
637 str = re.sub ('"?timeSignatureStyle"? *= *#?""', 'TimeSignature \\\\override #\'style = ##f', str)
639 str = re.sub ('"?timeSignatureStyle"? *= *#?"([^"]*)"', 'TimeSignature \\\\override #\'style = #\'\\1', str)
641 str = re.sub ('#\'style *= #*"([^"])"', '#\'style = #\'\\1', str)
643 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?horizontalNoteShift"? *= *"?#?([-0-9]+)"?', '\\\\property \\1.NoteColumn \\\\override #\'horizontal-shift = #\\2', str)
645 # ugh
646 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?flagStyle"? *= *""', '\\\\property \\1.Stem \\\\override #\'flag-style = ##f', str)
648 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?flagStyle"? *= *"([^"]*)"', '\\\\property \\1.Stem \\\\override #\'flag-style = #\'\\2', str)
649 return str
651 conversions.append (((1,3,98), conv, 'CONTEXT.textStyle -> GROB.#font-style '))
653 if 1:
654 def conv (str):
655 str = re.sub ('"?beamAutoEnd_([0-9]*)"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(end 1 \\1 * *) = \\2', str)
656 str = re.sub ('"?beamAutoBegin_([0-9]*)"? *= *(#\\([^)]*\))', 'autoBeamSettings \\push #\'(begin 1 \\1 * *) = \\2', str)
657 str = re.sub ('"?beamAutoEnd"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(end * * * *) = \\1', str)
658 str = re.sub ('"?beamAutoBegin"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(begin * * * *) = \\1', str)
661 return str
663 conversions.append (((1,3,102), conv, 'beamAutoEnd -> autoBeamSettings \\push (end * * * *)'))
666 if 1:
667 def conv (str):
668 str = re.sub ('\\\\push', '\\\\override', str)
669 str = re.sub ('\\\\pop', '\\\\revert', str)
671 return str
673 conversions.append (((1,3,111), conv, '\\push -> \\override, \\pop -> \\revert'))
675 if 1:
676 def conv (str):
677 str = re.sub ('LyricVoice', 'LyricsVoice', str)
678 # old fix
679 str = re.sub ('Chord[Nn]ames*.Chord[Nn]ames*', 'ChordNames.ChordName', str)
680 str = re.sub ('Chord[Nn]ames([ \t\n]+\\\\override)', 'ChordName\\1', str)
681 return str
683 conversions.append (((1,3,113), conv, 'LyricVoice -> LyricsVoice'))
685 def regularize_id (str):
686 s = ''
687 lastx = ''
688 for x in str:
689 if x == '_':
690 lastx = x
691 continue
692 elif x in string.digits:
693 x = chr(ord (x) - ord ('0') +ord ('A'))
694 elif x not in string.letters:
695 x = 'x'
696 elif x in string.lowercase and lastx == '_':
697 x = string.upper (x)
698 s = s + x
699 lastx = x
700 return s
702 if 1:
703 def conv (str):
705 def regularize_dollar_reference (match):
706 return regularize_id (match.group (1))
707 def regularize_assignment (match):
708 return '\n' + regularize_id (match.group (1)) + ' = '
709 str = re.sub ('\$([^\t\n ]+)', regularize_dollar_reference, str)
710 str = re.sub ('\n([^ \t\n]+)[ \t]*= *', regularize_assignment, str)
711 return str
713 conversions.append (((1,3,117), conv, 'identifier names: $!foo_bar_123 -> xfooBarABC'))
716 if 1:
717 def conv (str):
718 def regularize_paper (match):
719 return regularize_id (match.group (1))
721 str = re.sub ('(paper_[a-z]+)', regularize_paper, str)
722 str = re.sub ('sustainup', 'sustainUp', str)
723 str = re.sub ('nobreak', 'noBreak', str)
724 str = re.sub ('sustaindown', 'sustainDown', str)
725 str = re.sub ('sostenutoup', 'sostenutoUp', str)
726 str = re.sub ('sostenutodown', 'sostenutoDown', str)
727 str = re.sub ('unachorda', 'unaChorda', str)
728 str = re.sub ('trechorde', 'treChorde', str)
730 return str
732 conversions.append (((1,3,120), conv, 'paper_xxx -> paperXxxx, pedalup -> pedalUp.'))
734 if 1:
735 def conv (str):
736 str = re.sub ('drarnChords', 'chordChanges', str)
737 str = re.sub ('\\musicalpitch', '\\pitch', str)
738 return str
740 conversions.append (((1,3,122), conv, 'drarnChords -> chordChanges, \\musicalpitch -> \\pitch'))
742 if 1:
743 def conv (str):
744 str = re.sub ('ly-([sg])et-elt-property', 'ly-\\1et-grob-property', str)
745 return str
747 conversions.append (((1,3,136), conv, 'ly-X-elt-property -> ly-X-grob-property'))
749 if 1:
750 def conv (str):
751 str = re.sub ('point-and-click +#t', 'point-and-click line-column-location', str)
752 return str
754 conversions.append (((1,3,138), conv, 'point-and-click argument changed to procedure.'))
756 if 1:
757 def conv (str):
758 str = re.sub ('followThread', 'followVoice', str)
759 str = re.sub ('Thread.FollowThread', 'Voice.VoiceFollower', str)
760 str = re.sub ('FollowThread', 'VoiceFollower', str)
761 return str
763 conversions.append (((1,3,138), conv, 'followThread -> followVoice.'))
765 if 1:
766 def conv (str):
767 str = re.sub ('font-point-size', 'font-design-size', str)
768 return str
770 conversions.append (((1,3,139), conv, 'font-point-size -> font-design-size.'))
772 if 1:
773 def conv (str):
774 str = re.sub ('([a-zA-Z]*)NoDots', '\\1Solid', str)
775 return str
777 conversions.append (((1,3,141), conv, 'xNoDots -> xSolid'))
779 if 1:
780 def conv (str):
781 str = re.sub ('([Cc])hord([ea])', '\\1ord\\2', str)
782 return str
784 conversions.append (((1,3,144), conv, 'Chorda -> Corda'))
787 if 1:
788 def conv (str):
789 str = re.sub ('([A-Za-z]+)MinimumVerticalExtent', 'MinimumV@rticalExtent', str)
790 str = re.sub ('([A-Za-z]+)ExtraVerticalExtent', 'ExtraV@rticalExtent', str)
791 str = re.sub ('([A-Za-z]+)VerticalExtent', 'VerticalExtent', str)
792 str = re.sub ('ExtraV@rticalExtent', 'ExtraVerticalExtent', str)
793 str = re.sub ('MinimumV@rticalExtent', 'MinimumVerticalExtent', str)
794 return str
796 conversions.append (((1,3,145), conv,
797 'ContextNameXxxxVerticalExtent -> XxxxVerticalExtent'))
799 if 1:
800 def conv (str):
801 str = re.sub ('\\\\key[ \t]*;', '\\key \\default;', str)
802 str = re.sub ('\\\\mark[ \t]*;', '\\mark \\default;', str)
804 # Make sure groups of more than one ; have space before
805 # them, so that non of them gets removed by next rule
806 str = re.sub ("([^ \n\t;]);(;+)", "\\1 ;\\2", str)
808 # Only remove ; that are not after spaces, # or ;
809 # Otherwise we interfere with Scheme comments,
810 # which is badbadbad.
811 str = re.sub ("([^ \t;#]);", "\\1", str)
813 return str
814 conversions.append (((1,3,146), conv, 'semicolons removed'))
816 if 1:
817 def conv (str):
818 str = re.sub ('default-neutral-direction', 'neutral-direction',str)
819 return str
820 conversions.append (((1,3,147), conv, 'default-neutral-direction -> neutral-direction'))
822 if 1:
823 def conv (str):
824 str = re.sub ('\(align', '(axis', str)
825 str = re.sub ('\(rows', '(columns', str)
826 return str
827 conversions.append (((1,3,148), conv, '"(align" -> "(axis", "(rows" -> "(columns"'))
830 if 1:
831 def conv (str):
832 str = re.sub ('SystemStartDelimiter', 'systemStartDelimiter', str)
833 return str
834 conversions.append (((1,5,33), conv, 'SystemStartDelimiter -> systemStartDelimiter'))
836 if 1:
837 def conv (str):
838 str = re.sub ('arithmetic-multiplier', 'spacing-increment', str)
839 str = re.sub ('arithmetic-basicspace', 'shortest-duration-space', str)
840 return str
842 conversions.append (((1,5,38), conv, 'SystemStartDelimiter -> systemStartDelimiter'))
845 if 1:
846 def conv (str):
848 def func(match):
849 break_dict = {
850 "Instrument_name": "instrument-name",
851 "Left_edge_item": "left-edge",
852 "Span_bar": "span-bar",
853 "Breathing_sign": "breathing-sign",
854 "Staff_bar": "staff-bar",
855 "Clef_item": "clef",
856 "Key_item": "key-signature",
857 "Time_signature": "time-signature",
858 "Custos": "custos"
860 props = match.group (1)
861 for (k,v) in break_dict.items():
862 props = re.sub (k, v, props)
863 return "breakAlignOrder = #'(%s)" % props
865 str = re.sub ("breakAlignOrder *= *#'\\(([a-z_\n\tA-Z ]+)\\)",
866 func, str)
867 return str
869 # 40 ?
870 conversions.append (((1,5,40), conv, 'breakAlignOrder property names'))
873 if 1:
874 def conv (str):
875 str = re.sub ('noAutoBeaming *= *##f', 'autoBeaming = ##t', str)
876 str = re.sub ('noAutoBeaming *= *##t', 'autoBeaming = ##f', str)
877 return str
879 conversions.append (((1,5,49), conv, 'noAutoBeaming -> autoBeaming'))
881 if 1:
882 def conv (str):
883 str = re.sub ('tuplet-bracket-visibility', 'bracket-visibility', str)
884 str = re.sub ('tuplet-number-visibility', 'number-visibility', str)
885 return str
887 conversions.append (((1,5,52), conv, 'tuplet-X-visibility -> X-visibility'))
889 if 1:
890 def conv (str):
891 str = re.sub ('Pitch::transpose', 'ly-transpose-pitch', str)
893 return str
895 conversions.append (((1,5,56), conv, 'Pitch::transpose -> ly-transpose-pitch'))
897 if 1:
898 def conv (str):
899 str = re.sub ('textNonEmpty *= *##t', "TextScript \\set #'no-spacing-rods = ##f", str)
900 str = re.sub ('textNonEmpty *= *##f', "TextScript \\set #'no-spacing-rods = ##t", str)
901 return str
903 conversions.append (((1,5,58), conv, 'deprecate textNonEmpty'))
906 if 1:
907 def conv (str):
908 str = re.sub ('MinimumVerticalExtent', 'minimumV@rticalExtent', str)
909 str = re.sub ('minimumVerticalExtent', 'minimumV@rticalExtent', str)
910 str = re.sub ('ExtraVerticalExtent', 'extraV@rticalExtent', str)
911 str = re.sub ('extraVerticalExtent', 'extraV@rticalExtent', str)
912 str = re.sub ('VerticalExtent', 'verticalExtent', str)
913 str = re.sub ('extraV@rticalExtent', 'extraVerticalExtent', str)
914 str = re.sub ('minimumV@rticalExtent', 'minimumVerticalExtent', str)
915 return str
917 conversions.append (((1,5,59), conv,
918 'XxxxVerticalExtent -> xxxVerticalExtent'))
920 if 1:
921 def conv (str):
922 str = re.sub ('visibility-lambda', 'break-visibility', str)
923 return str
925 conversions.append (((1,5,62), conv,
926 'visibility-lambda -> break-visibility'))
929 if 1:
930 def conv (str):
931 if re.search (r'\addlyrics',str) \
932 and re.search ('automaticMelismata', str) == None:
933 sys.stderr.write ('automaticMelismata is turned on by default since 1.5.67. Please fix this by hand.')
934 raise FatalConversionError()
935 return str
937 conversions.append (((1,5,67), conv,
938 'automaticMelismata turned on by default'))
940 if 1:
941 def conv (str):
942 str = re.sub ('ly-set-grob-property([^!])', 'ly-set-grob-property!\1', str)
943 str = re.sub ('ly-set-mus-property([^!])', 'ly-set-mus-property!\1', str)
944 return str
946 conversions.append (((1,5,68), conv, 'ly-set-X-property -> ly-set-X-property!'))
948 if 1:
949 def conv (str):
950 str = re.sub ('extent-X', 'X-extent', str)
951 str = re.sub ('extent-Y', 'Y-extent', str)
952 return str
954 conversions.append (((1,5,71), conv, 'extent-[XY] -> [XY]-extent'))
957 if 1:
958 def conv (str):
959 str = re.sub ("""#\(set! +point-and-click +line-column-location\)""",
960 """#(set-point-and-click! \'line-column)""", str)
961 str = re.sub ("""#\(set![ \t]+point-and-click +line-location\)""",
962 '#(set-point-and-click! \'line)', str)
963 str = re.sub ('#\(set! +point-and-click +#f\)',
964 '#(set-point-and-click! \'none)', str)
965 return str
967 conversions.append (((1,5,72), conv, 'set! point-and-click -> set-point-and-click!'))
970 if 1:
971 def conv (str):
972 str = re.sub ('flag-style', 'stroke-style', str)
973 str = re.sub (r"""Stem([ ]+)\\override #'style""", r"""Stem \\override #'flag-style""", str);
974 str = re.sub (r"""Stem([ ]+)\\set([ ]+)#'style""", r"""Stem \\set #'flag-style""", str);
975 return str
977 conversions.append (((1,6,5), conv, 'Stems: flag-style -> stroke-style; style -> flag-style'))
980 if 1:
981 def subst_req_name (match):
982 return "(make-music-by-name \'%sEvent)" % regularize_id (match.group(1))
984 def conv (str):
985 str = re.sub ('\\(ly-make-music *\"([A-Z][a-z_]+)_req\"\\)', subst_req_name, str)
986 str = re.sub ('Request_chord', 'EventChord', str)
987 return str
989 conversions.append (((1,7,1), conv, 'ly-make-music foo_bar_req -> make-music-by-name FooBarEvent'))
992 if 1:
993 spanner_subst ={
994 "text" : 'TextSpanEvent',
995 "decrescendo" : 'DecrescendoEvent',
996 "crescendo" : 'CrescendoEvent',
997 "Sustain" : 'SustainPedalEvent',
998 "slur" : 'SlurEvent',
999 "UnaCorda" : 'UnaCordaEvent',
1000 "Sostenuto" : 'SostenutoEvent',
1002 def subst_ev_name (match):
1003 stype = 'STOP'
1004 if re.search ('start', match.group(1)):
1005 stype= 'START'
1007 mtype = spanner_subst[match.group(2)]
1008 return "(make-span-event '%s %s)" % (mtype , stype)
1010 def subst_definition_ev_name(match):
1011 return ' = #%s' % subst_ev_name (match)
1012 def subst_inline_ev_name (match):
1013 s = subst_ev_name (match)
1014 return '#(ly-export %s)' % s
1015 def subst_csp_definition (match):
1016 return ' = #(make-event-chord (list %s))' % subst_ev_name (match)
1017 def subst_csp_inline (match):
1018 return '#(ly-export (make-event-chord (list %s)))' % subst_ev_name (match)
1020 def conv (str):
1021 str = re.sub (r' *= *\\spanrequest *([^ ]+) *"([^"]+)"', subst_definition_ev_name, str)
1022 str = re.sub (r'\\spanrequest *([^ ]+) *"([^"]+)"', subst_inline_ev_name, str)
1023 str = re.sub (r' *= *\\commandspanrequest *([^ ]+) *"([^"]+)"', subst_csp_definition, str)
1024 str = re.sub (r'\\commandspanrequest *([^ ]+) *"([^"]+)"', subst_csp_inline, str)
1025 str = re.sub (r'ly-id ', 'ly-import ', str)
1027 str = re.sub (r' *= *\\script "([^"]+)"', ' = #(make-articulation "\\1")', str)
1028 str = re.sub (r'\\script "([^"]+)"', '#(ly-export (make-articulation "\\1"))', str)
1029 return str
1031 conversions.append (((1,7,2), conv, '\\spanrequest -> #(make-span-event .. ), \script -> #(make-articulation .. )'))
1033 if 1:
1034 def conv(str):
1035 str = re.sub (r'\(ly-', '(ly:', str)
1037 changed = [
1038 r'duration\?',
1039 r'font-metric\?',
1040 r'molecule\?',
1041 r'moment\?',
1042 r'music\?',
1043 r'pitch\?',
1044 'make-duration',
1045 'music-duration-length',
1046 'duration-log',
1047 'duration-dotcount',
1048 'intlog2',
1049 'duration-factor',
1050 'transpose-key-alist',
1051 'get-system',
1052 'get-broken-into',
1053 'get-original',
1054 'set-point-and-click!',
1055 'make-moment',
1056 'make-pitch',
1057 'pitch-octave',
1058 'pitch-alteration',
1059 'pitch-notename',
1060 'pitch-semitones',
1061 r'pitch<\?',
1062 r'dir\?',
1063 'music-duration-compress',
1064 'set-point-and-click!'
1067 origre = r'\b(%s)' % string.join (changed, '|')
1069 str = re.sub (origre, r'ly:\1',str)
1070 str = re.sub ('set-point-and-click!', 'set-point-and-click', str)
1072 return str
1074 conversions.append (((1,7,3), conv, 'ly- -> ly:'))
1076 if 1:
1077 def conv(str):
1078 if re.search ('new-chords-done',str):
1079 return str
1081 str = re.sub (r'<<', '< <', str)
1082 str = re.sub (r'>>', '> >', str)
1083 return str
1085 conversions.append (((1,7,4), conv, '<< >> -> < < > >'))
1087 if 1:
1088 def conv(str):
1089 str = re.sub (r"\\transpose", r"\\transpose c'", str)
1090 str = re.sub (r"\\transpose c' *([a-z]+)'", r"\\transpose c \1", str)
1091 return str
1092 conversions.append (((1,7,5), conv, '\\transpose TO -> \\transpose FROM TO'))
1094 if 1:
1095 def conv(str):
1096 kws = ['arpeggio',
1097 'sustainDown',
1098 'sustainUp',
1099 'f',
1100 'p',
1101 'pp',
1102 'ppp',
1103 'fp',
1104 'ff',
1105 'mf',
1106 'mp',
1107 'sfz',
1110 origstr = string.join (kws, '|')
1111 str = re.sub (r'([^_^-])\\(%s)\b' % origstr, r'\1-\\\2', str)
1112 return str
1113 conversions.append (((1,7,6), conv, 'note\\script -> note-\script'))
1116 if 1:
1117 def conv(str):
1118 str = re.sub (r"\\property *ChordNames *\. *ChordName *\\(set|override) *#'style *= *#('[a-z]+)",
1119 r"#(set-chord-name-style \2)", str)
1120 str = re.sub (r"\\property *ChordNames *\. *ChordName *\\revert *#'style",
1121 r"", str)
1122 return str
1123 conversions.append (((1,7,10), conv, "\property ChordName #'style -> #(set-chord-name-style 'style)"))
1127 if 1:
1128 def conv(str):
1129 str = re.sub (r"ly:transpose-pitch", "ly:pitch-transpose", str)
1131 return str
1132 conversions.append (((1,7,11), conv, "transpose-pitch -> pitch-transpose"))
1134 if 1:
1135 def conv(str):
1136 str = re.sub (r"ly:get-molecule-extent", "ly:molecule-get-extent", str)
1137 str = re.sub (r"ly:set-molecule-extent!", "ly:molecule-set-extent!", str)
1138 str = re.sub (r"ly:add-molecule", "ly:molecule-add", str)
1139 str = re.sub (r"ly:combine-molecule-at-edge", "ly:molecule-combine-at-edge", str)
1140 str = re.sub (r"ly:align-to!", "ly:molecule-align-to!", str)
1142 return str
1144 conversions.append (((1,7,13), conv, "ly:XX-molecule-YY -> ly:molecule-XX-YY"))
1146 if 1:
1147 def conv(str):
1148 str = re.sub (r"linewidth *= *-[0-9.]+ *(\\mm|\\cm|\\in|\\pt)?", 'raggedright = ##t', str )
1149 return str
1151 conversions.append (((1,7,15), conv, "linewidth = -1 -> raggedright = ##t"))
1153 if 1:
1154 def conv(str):
1155 str = re.sub ("divisiomaior",
1156 "divisioMaior", str)
1157 str = re.sub ("divisiominima",
1158 "divisioMinima", str)
1159 str = re.sub ("divisiomaxima",
1160 "divisioMaxima", str)
1161 return str
1163 conversions.append (((1,7,16), conv, "divisiomaior -> divisioMaior"))
1165 if 1:
1166 def conv(str):
1167 str = re.sub ("Skip_req_swallow_translator",
1168 "Skip_event_swallow_translator", str)
1169 return str
1171 conversions.append (((1,7,17), conv, "Skip_req -> Skip_event"))
1173 if 1:
1174 def conv(str):
1175 str = re.sub ("groupOpen",
1176 "startGroup", str)
1177 str = re.sub ("groupClose",
1178 "stopGroup", str)
1179 str = re.sub ("#'outer",
1180 "#'enclose-bounds", str)
1182 return str
1184 conversions.append (((1,7,18), conv,
1185 """groupOpen/Close -> start/stopGroup,
1186 #'outer -> #'enclose-bounds
1187 """))
1189 if 1:
1190 def conv(str):
1191 if re.search( r'\\GraceContext', str):
1192 sys.stderr.write ("GraceContext has been removed")
1193 sys.stderr.write ("please use #(add-to-grace-init .. )")
1194 raise FatalConversionError()
1196 str = re.sub ('HaraKiriStaffContext', 'RemoveEmptyStaffContext', str)
1197 return str
1199 conversions.append (((1,7,19), conv,"remove GraceContext"))
1203 if 1:
1204 def conv(str):
1205 str = re.sub (
1206 r"(set|override|revert) *#'type",
1207 r"\1 #'style",
1208 str)
1209 return str
1211 conversions.append (((1,7,22), conv,"#'type -> #'style"))
1213 if 1:
1214 def conv(str):
1215 str = re.sub (
1216 "barNonAuto *= *##t",
1217 "automaticBars = ##f",
1218 str)
1219 str = re.sub (
1220 "barNonAuto *= *##f",
1221 "automaticBars = ##t",
1222 str)
1223 return str
1225 conversions.append (((1,7,23), conv,"barNonAuto -> automaticBars"))
1228 if 1:
1229 def conv(str):
1230 if re.search( r'-(start|stop)Cluster', str):
1231 sys.stderr.write ("""Cluster syntax has been changed.
1232 Please refer to the manual for details, and convert manually.
1233 """)
1235 raise FatalConversionError()
1237 return str
1239 conversions.append (((1,7,24), conv,"cluster syntax"))
1241 if 1:
1242 def conv(str):
1243 str = re.sub (r"\\property *Staff\.(Sustain|Sostenuto|UnaCorda)Pedal *\\(override|set) *#'pedal-type *",
1244 r"\property Staff.pedal\1Style ", str)
1245 str = re.sub (r"\\property *Staff\.(Sustain|Sostenuto|UnaCorda)Pedal *\\revert *#'pedal-type", '', str)
1246 return str
1248 conversions.append (((1,7,28), conv,"new Pedal style syntax"))
1252 if 1:
1254 def sub_chord (m):
1255 str = m.group(1)
1257 origstr = '<%s>' % str
1258 if re.search (r'\\\\', str):
1259 return origstr
1261 if re.search (r'\\property', str):
1262 return origstr
1264 if re.match (r'^\s*\)?\s*\\[a-zA-Z]+', str):
1265 return origstr
1267 durs = []
1268 def sub_durs (m):
1269 durs.append(m.group(2))
1270 return m.group (1)
1272 str = re.sub ("([a-z]+[,'!? ]*)([0-9.]+)", sub_durs, str)
1273 dur_str = ''
1275 for d in durs:
1276 if dur_str == '':
1277 dur_str = d
1278 if dur_str <> d:
1279 return '<%s>' % m.group (1)
1281 pslur_strs = ['']
1282 dyns = ['']
1283 slur_strs = ['']
1285 last_str = ''
1286 while last_str <> str:
1287 last_str = str
1288 def sub_dyn_end (m):
1289 dyns.append (' \!')
1290 return ' ' + m.group(2)
1292 str = re.sub (r'(\\!)\s*([a-z]+)', sub_dyn_end, str)
1293 def sub_slurs(m):
1294 if '-)' not in slur_strs:
1295 slur_strs.append ( ')')
1296 return m.group(1)
1297 def sub_p_slurs(m):
1298 if '-\)' not in slur_strs:
1299 slur_strs.append ( '\)')
1300 return m.group(1)
1301 str = re.sub (r"\)[ ]*([a-z]+)", sub_slurs, str)
1302 str = re.sub (r"\\\)[ ]*([a-z]+)", sub_p_slurs, str)
1303 def sub_begin_slurs(m):
1304 if '-(' not in slur_strs:
1305 slur_strs.append ( '(')
1306 return m.group(1)
1307 str = re.sub (r"([a-z]+[,'!?0-9 ]*)\(", sub_begin_slurs, str)
1308 def sub_begin_p_slurs(m):
1309 if '-\(' not in slur_strs:
1310 slur_strs.append ( '\(')
1311 return m.group(1)
1313 str = re.sub (r"([a-z]+[,'!?0-9 ]*)\\\(", sub_begin_p_slurs, str)
1315 def sub_dyns (m):
1316 s = m.group(0)
1317 if s == '@STARTCRESC@':
1318 slur_strs.append ("\\<")
1319 elif s == '@STARTDECRESC@':
1320 slur_strs.append ("\\>")
1321 elif s == r'-?\\!':
1322 slur_strs.append ('\\!')
1323 return ''
1325 str = re.sub (r'@STARTCRESC@', sub_dyns, str)
1326 str = re.sub (r'-?\\!', sub_dyns, str)
1328 def sub_articulations (m):
1329 a = m.group(1)
1330 if a not in slur_strs:
1331 slur_strs.append (a)
1332 return ''
1334 str = re.sub (r"([_^-]\@ACCENT\@)", sub_articulations, str)
1335 str = re.sub (r"([_^-]\\[a-z]+)", sub_articulations, str)
1336 str = re.sub (r"([_^-][>_.+|^-])", sub_articulations, str)
1338 def sub_pslurs(m):
1339 slur_strs.append ( ' \\)')
1340 return m.group(1)
1341 str = re.sub (r"\\\)[ ]*([a-z]+)", sub_pslurs, str)
1343 suffix = string.join (slur_strs, '') + string.join (pslur_strs, '') \
1344 + string.join (dyns, '')
1346 return '@STARTCHORD@%s@ENDCHORD@%s%s' % (str , dur_str, suffix)
1352 def sub_chords (str):
1353 simend = '>'
1354 simstart = "<"
1355 chordstart = '<<'
1356 chordend = '>>'
1357 marker_str = '%% new-chords-done %%'
1359 if re.search (marker_str,str):
1360 return str
1361 str= re.sub (r'\\<', '@STARTCRESC@', str)
1362 str= re.sub (r'\\>', '@STARTDECRESC@', str)
1363 str= re.sub (r'([_^-])>', r'\1@ACCENT@', str)
1364 str = re.sub ('<([^<>{}]+)>', sub_chord, str)
1366 str = re.sub (r'\[ *(@STARTCHORD@[^@]+@ENDCHORD@[0-9.]*)',
1367 r'\1[',
1368 str)
1369 str = re.sub (r'\\! *(@STARTCHORD@[^@]+@ENDCHORD@[0-9.]*)',
1370 r'\1\\!',
1371 str)
1372 str = re.sub ('<([^?])', r'%s\1' % simstart, str)
1373 str = re.sub ('>([^?])', r'%s\1' % simend, str)
1374 str = re.sub ('@STARTCRESC@', r'\\<', str)
1375 str = re.sub ('@STARTDECRESC@', r'\\>' ,str)
1376 str = re.sub (r'\\context *Voice *@STARTCHORD@', '@STARTCHORD@', str)
1377 str = re.sub ('@STARTCHORD@', chordstart, str)
1378 str = re.sub ('@ENDCHORD@', chordend, str)
1379 str = re.sub (r'@ACCENT@', '>', str)
1380 return str
1382 def articulation_substitute (str):
1383 str = re.sub (r"""([^-])\[ *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1384 r" \1 \2[", str)
1385 str = re.sub (r"""([^-])\) *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1386 r"\1 \2)", str)
1387 str = re.sub (r"""([^-])\\! *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1388 r"\1 \2\\!", str)
1389 return str
1391 def conv_relative(str):
1392 if re.search (r"\\relative", str):
1393 str= "#(ly:set-option 'old-relative)\n" + str
1395 return str
1397 def conv (str):
1398 str = conv_relative (str)
1399 str = sub_chords (str)
1401 str = articulation_substitute (str)
1403 return str
1405 conversions.append (((1,9,0), conv, """New relative mode,
1406 Postfix articulations, new chord syntax."""))
1408 if 1:
1409 def conv (str):
1410 if re.search ("font-style",str):
1411 sys.stderr.write ("font-style is deprecated. Please remove.")
1412 raise FatalConversionError()
1414 str = re.sub (r'-\\markup', r'@\\markup', str)
1415 str = re.sub (r'-\\', r'\\', str)
1416 str = re.sub (r'-\)', ')', str)
1417 str = re.sub (r'-\(', '(', str)
1418 str = re.sub ('-\[', '[', str)
1419 str = re.sub ('-\]', ']', str)
1420 str = re.sub ('-~', '~', str)
1421 str = re.sub (r'@\\markup', r'-\\markup', str)
1422 return str
1424 conversions.append (((1,9,1), conv, """Remove - before articulation"""))
1425 if 1:
1426 def conv (str):
1427 str = re.sub ('ly:set-context-property',
1428 'ly:set-context-property!', str)
1429 str = re.sub ('\\\\newcontext', '\\\\new', str)
1430 str = re.sub ('\\\\grace[\t\n ]*([^{ ]+)',
1431 r'\\grace { \1 }', str)
1432 str = re.sub ("\\\\grace[\t\n ]*{([^}]+)}",
1433 r"""\\grace {
1434 \\property Voice.Stem \\override #'stroke-style = #"grace"
1436 \\property Voice.Stem \\revert #'stroke-style }
1437 """, str)
1439 return str
1441 conversions.append (((1,9,2), conv, """\newcontext -> \new"""))
1443 if 1:
1444 def conv (str):
1445 str = re.sub ('accacciatura',
1446 'acciaccatura', str)
1447 return str
1449 conversions.append (((1,9,3), conv, """\acciaccatura misspelling"""))
1451 ################################
1452 # END OF CONVERSIONS
1453 ################################
1455 def get_conversions (from_version, to_version):
1456 def version_b (v, f = from_version, t = to_version):
1457 return version_cmp (v[0], f) > 0 and version_cmp (v[0], t) <= 0
1458 return filter (version_b, conversions)
1461 def latest_version ():
1462 return conversions[-1][0]
1464 def do_conversion (infile, from_version, outfile, to_version):
1465 conv_list = get_conversions (from_version, to_version)
1467 sys.stderr.write ('Applying conversions: ')
1468 str = infile.read ()
1469 last_conversion = ()
1470 try:
1471 for x in conv_list:
1472 sys.stderr.write (tup_to_str (x[0]) + ', ')
1473 str = x[1] (str)
1474 last_conversion = x[0]
1476 except FatalConversionError:
1477 sys.stderr.write ('Error while converting; I won\'t convert any further')
1479 if last_conversion:
1480 sys.stderr.write ('\n')
1481 new_ver = '\\version \"%s\"' % tup_to_str (last_conversion)
1483 if re.search (lilypond_version_re_str, str):
1484 str = re.sub (lilypond_version_re_str,'\\'+new_ver , str)
1485 elif add_version:
1486 str = new_ver + '\n' + str
1488 outfile.write(str)
1490 return last_conversion
1492 class UnknownVersion:
1493 pass
1495 def do_one_file (infile_name):
1496 sys.stderr.write ('Processing `%s\' ... '% infile_name)
1497 outfile_name = ''
1498 if __main__.edit:
1499 outfile_name = infile_name + '.NEW'
1500 elif __main__.outfile_name:
1501 outfile_name = __main__.outfile_name
1503 if __main__.from_version:
1504 from_version = __main__.from_version
1505 else:
1506 guess = guess_lilypond_version (infile_name)
1507 if not guess:
1508 raise UnknownVersion()
1509 from_version = str_to_tuple (guess)
1511 if __main__.to_version:
1512 to_version = __main__.to_version
1513 else:
1514 to_version = latest_version ()
1517 if infile_name:
1518 infile = open (infile_name,'r')
1519 else:
1520 infile = sys.stdin
1522 if outfile_name:
1523 outfile = open (outfile_name, 'w')
1524 else:
1525 outfile = sys.stdout
1527 touched = do_conversion (infile, from_version, outfile, to_version)
1529 if infile_name:
1530 infile.close ()
1532 if outfile_name:
1533 outfile.close ()
1535 if __main__.edit and touched:
1536 try:
1537 os.remove(infile_name + '~')
1538 except:
1539 pass
1540 os.rename (infile_name, infile_name + '~')
1541 os.rename (infile_name + '.NEW', infile_name)
1543 sys.stderr.write ('\n')
1544 sys.stderr.flush ()
1546 edit = 0
1547 assume_old = 0
1548 to_version = ()
1549 from_version = ()
1550 outfile_name = ''
1552 (options, files) = getopt.getopt (
1553 sys.argv[1:], 'ao:f:t:senh', ['no-version', 'version', 'output', 'show-rules', 'help', 'edit', 'from=', 'to='])
1555 for opt in options:
1556 o = opt[0]
1557 a = opt[1]
1558 if o== '--help' or o == '-h':
1559 usage ()
1560 sys.exit (0)
1561 if o == '--version' or o == '-v':
1562 print_version ()
1563 sys.exit (0)
1564 elif o== '--from' or o=='-f':
1565 from_version = str_to_tuple (a)
1566 elif o== '--to' or o=='-t':
1567 to_version = str_to_tuple (a)
1568 elif o== '--edit' or o == '-e':
1569 edit = 1
1570 elif o== '--show-rules' or o == '-s':
1571 show_rules (sys.stdout)
1572 sys.exit(0)
1573 elif o == '--output' or o == '-o':
1574 outfile_name = a
1575 elif o == '--no-version' or o == '-n':
1576 add_version = 0
1577 else:
1578 print o
1579 raise getopt.error
1581 identify ()
1582 for f in files:
1583 if f == '-':
1584 f = ''
1585 if not os.path.isfile (f):
1586 continue
1587 try:
1588 do_one_file (f)
1589 except UnknownVersion:
1590 sys.stderr.write ('\n')
1591 sys.stderr.write ("%s: can't determine version for `%s'" % (program_name, f))
1592 sys.stderr.write ('\n')
1593 if assume_old:
1594 fv = from_version
1595 from_version = (0,0,0)
1596 do_one_file (f)
1597 from_version = fv
1598 else:
1599 sys.stderr.write ("%s: skipping: `%s' " % (program_name, f))
1600 pass
1602 sys.stderr.write ('\n')