* input/regression/hairpin-dashed.ly: new file.
[lilypond.git] / scripts / convert-ly.py
blobbc6b6dcb2bfddbc7d65e9e38baec2f7bda720120
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_tremolos (m):
1289 tr = m.group (2)
1290 if tr not in slur_strs:
1291 slur_strs.append (tr)
1292 return m.group (1)
1294 str = re.sub (r"([a-z]+[',!? ]*)(:[0-9]+)", sub_tremolos, str)
1296 def sub_dyn_end (m):
1297 dyns.append (' \!')
1298 return ' ' + m.group(2)
1300 str = re.sub (r'(\\!)\s*([a-z]+)', sub_dyn_end, str)
1301 def sub_slurs(m):
1302 if '-)' not in slur_strs:
1303 slur_strs.append ( ')')
1304 return m.group(1)
1305 def sub_p_slurs(m):
1306 if '-\)' not in slur_strs:
1307 slur_strs.append ( '\)')
1308 return m.group(1)
1309 str = re.sub (r"\)[ ]*([a-z]+)", sub_slurs, str)
1310 str = re.sub (r"\\\)[ ]*([a-z]+)", sub_p_slurs, str)
1311 def sub_begin_slurs(m):
1312 if '-(' not in slur_strs:
1313 slur_strs.append ( '(')
1314 return m.group(1)
1315 str = re.sub (r"([a-z]+[,'!?0-9 ]*)\(", sub_begin_slurs, str)
1316 def sub_begin_p_slurs(m):
1317 if '-\(' not in slur_strs:
1318 slur_strs.append ( '\(')
1319 return m.group(1)
1321 str = re.sub (r"([a-z]+[,'!?0-9 ]*)\\\(", sub_begin_p_slurs, str)
1323 def sub_dyns (m):
1324 s = m.group(0)
1325 if s == '@STARTCRESC@':
1326 slur_strs.append ("\\<")
1327 elif s == '@STARTDECRESC@':
1328 slur_strs.append ("\\>")
1329 elif s == r'-?\\!':
1330 slur_strs.append ('\\!')
1331 return ''
1333 str = re.sub (r'@STARTCRESC@', sub_dyns, str)
1334 str = re.sub (r'-?\\!', sub_dyns, str)
1336 def sub_articulations (m):
1337 a = m.group(1)
1338 if a not in slur_strs:
1339 slur_strs.append (a)
1340 return ''
1342 str = re.sub (r"([_^-]\@ACCENT\@)", sub_articulations, str)
1343 str = re.sub (r"([_^-]\\[a-z]+)", sub_articulations, str)
1344 str = re.sub (r"([_^-][>_.+|^-])", sub_articulations, str)
1346 def sub_pslurs(m):
1347 slur_strs.append ( ' \\)')
1348 return m.group(1)
1349 str = re.sub (r"\\\)[ ]*([a-z]+)", sub_pslurs, str)
1351 suffix = string.join (slur_strs, '') + string.join (pslur_strs, '') \
1352 + string.join (dyns, '')
1354 return '@STARTCHORD@%s@ENDCHORD@%s%s' % (str , dur_str, suffix)
1360 def sub_chords (str):
1361 simend = '>'
1362 simstart = "<"
1363 chordstart = '<<'
1364 chordend = '>>'
1365 marker_str = '%% new-chords-done %%'
1367 if re.search (marker_str,str):
1368 return str
1369 str= re.sub (r'\\<', '@STARTCRESC@', str)
1370 str= re.sub (r'\\>', '@STARTDECRESC@', str)
1371 str= re.sub (r'([_^-])>', r'\1@ACCENT@', str)
1372 str = re.sub ('<([^<>{}]+)>', sub_chord, str)
1374 str = re.sub (r'\[ *(@STARTCHORD@[^@]+@ENDCHORD@[0-9.]*)',
1375 r'\1[',
1376 str)
1377 str = re.sub (r'\\! *(@STARTCHORD@[^@]+@ENDCHORD@[0-9.]*)',
1378 r'\1\\!',
1379 str)
1380 str = re.sub ('<([^?])', r'%s\1' % simstart, str)
1381 str = re.sub ('>([^?])', r'%s\1' % simend, str)
1382 str = re.sub ('@STARTCRESC@', r'\\<', str)
1383 str = re.sub ('@STARTDECRESC@', r'\\>' ,str)
1384 str = re.sub (r'\\context *Voice *@STARTCHORD@', '@STARTCHORD@', str)
1385 str = re.sub ('@STARTCHORD@', chordstart, str)
1386 str = re.sub ('@ENDCHORD@', chordend, str)
1387 str = re.sub (r'@ACCENT@', '>', str)
1388 return str
1390 def articulation_substitute (str):
1391 str = re.sub (r"""([^-])\[ *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1392 r" \1 \2[", str)
1393 str = re.sub (r"""([^-])\) *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1394 r"\1 \2)", str)
1395 str = re.sub (r"""([^-])\\! *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1396 r"\1 \2\\!", str)
1397 return str
1399 def conv_relative(str):
1400 if re.search (r"\\relative", str):
1401 str= "#(ly:set-option 'old-relative)\n" + str
1403 return str
1405 def conv (str):
1406 str = conv_relative (str)
1407 str = sub_chords (str)
1409 str = articulation_substitute (str)
1411 return str
1413 conversions.append (((1,9,0), conv, """New relative mode,
1414 Postfix articulations, new chord syntax."""))
1416 if 1:
1417 def conv (str):
1418 if re.search ("font-style",str):
1419 sys.stderr.write ("font-style is deprecated. Please remove.")
1420 raise FatalConversionError()
1422 str = re.sub (r'-\\markup', r'@\\markup', str)
1423 str = re.sub (r'-\\', r'\\', str)
1424 str = re.sub (r'-\)', ')', str)
1425 str = re.sub (r'-\(', '(', str)
1426 str = re.sub ('-\[', '[', str)
1427 str = re.sub ('-\]', ']', str)
1428 str = re.sub ('-~', '~', str)
1429 str = re.sub (r'@\\markup', r'-\\markup', str)
1430 return str
1432 conversions.append (((1,9,1), conv, """Remove - before articulation"""))
1433 if 1:
1434 def conv (str):
1435 str = re.sub ('ly:set-context-property',
1436 'ly:set-context-property!', str)
1437 str = re.sub ('\\\\newcontext', '\\\\new', str)
1438 str = re.sub ('\\\\grace[\t\n ]*([^{ ]+)',
1439 r'\\grace { \1 }', str)
1440 str = re.sub ("\\\\grace[\t\n ]*{([^}]+)}",
1441 r"""\\grace {
1442 \\property Voice.Stem \\override #'stroke-style = #"grace"
1444 \\property Voice.Stem \\revert #'stroke-style }
1445 """, str)
1447 return str
1449 conversions.append (((1,9,2), conv, """\newcontext -> \new"""))
1451 if 1:
1452 def conv (str):
1453 str = re.sub ('accacciatura',
1454 'acciaccatura', str)
1456 if re.search ("context-spec-music", str):
1457 sys.stderr.write ("context-spec-music takes a symbol for the context now. Update by hand.")
1459 raise FatalConversionError()
1461 str = re.sub ('fingerHorizontalDirection *= *#(LEFT|-1)',
1462 "fingeringOrientations = #'(up down left)", str)
1463 str = re.sub ('fingerHorizontalDirection *= *#(RIGHT|1)',
1464 "fingeringOrientations = #'(up down right)", str)
1466 return str
1468 conversions.append (((1,9,3), conv,
1469 """\acciaccatura misspelling, fingerHorizontalDirection -> fingeringOrientations"""))
1472 def conv (str):
1473 if re.search ('\\figures', str):
1474 sys.stderr.write ("Warning: attempting automatic \\figures conversion. Check results!");
1477 def figures_replace (m):
1478 s = m.group (1)
1479 s = re.sub ('<', '@FIGOPEN@',s)
1480 s = re.sub ('>', '@FIGCLOSE@',s)
1481 return '\\figures { %s }' % s
1483 str = re.sub (r'\\figures[ \t\n]*{([^}]+)}', figures_replace, str)
1484 str = re.sub (r'\\<', '@STARTCRESC@', str)
1485 str = re.sub (r'\\>', '@STARTDECRESC@', str)
1486 str = re.sub (r'([-^_])>', r'\1@ACCENT@', str)
1487 str = re.sub (r'<<', '@STARTCHORD@', str)
1488 str = re.sub (r'>>', '@ENDCHORD@', str)
1489 str = re.sub (r'>', '@ENDSIMUL@', str)
1490 str = re.sub (r'<', '@STARTSIMUL@', str)
1491 str = re.sub ('@STARTDECRESC@', '\\>', str)
1492 str = re.sub ('@STARTCRESC@', '\\<', str)
1493 str = re.sub ('@ACCENT@', '>', str)
1494 str = re.sub ('@ENDCHORD@', '>', str)
1495 str = re.sub ('@STARTCHORD@', '<', str)
1496 str = re.sub ('@STARTSIMUL@', '<<', str)
1497 str = re.sub ('@ENDSIMUL@', '>>', str)
1498 str = re.sub ('@FIGOPEN@', '<', str)
1499 str = re.sub ('@FIGCLOSE@', '>', str)
1501 return str
1503 conversions.append (((1,9,4), conv, 'Swap < > and << >>'))
1506 def conv (str):
1507 str = re.sub ('HaraKiriVerticalGroup', 'RemoveEmptyVerticalGroup', str)
1509 return str
1511 conversions.append (((1,9,5), conv, 'HaraKiriVerticalGroup -> RemoveEmptyVerticalGroup'))
1513 def conv (str):
1514 if re.search ("ly:get-font", str) :
1515 sys.stderr.write (r"(ly:get-font foo ..) has been replaced by" + \
1516 " (ly:paper-get-font (ly:grob-get-paper foo) .. ).\n" +\
1517 "please update manually.")
1519 raise FatalConversionError()
1521 if re.search ("\\pitch *#", str) :
1522 sys.stderr.write (r"\\pitch has been deprecated. " +\
1523 " Use Scheme code to construct arbitrary note events.")
1525 raise FatalConversionError()
1527 return str
1530 conversions.append (((1,9,6), conv, 'ly:get-font deprecated.'))
1532 def conv (str):
1533 def sub_alteration (m):
1534 alt = m.group (3)
1535 alt = {
1536 '-1': 'FLAT',
1537 '-2': 'DOUBLE-FLAT',
1538 '0': 'NATURAL',
1539 '1': 'SHARP',
1540 '2': 'DOUBLE-SHARP',
1541 }[alt]
1543 return '(ly:make-pitch %s %s %s)' % (m.group(1), m.group (2), alt)
1545 str =re.sub ("\\(ly:make-pitch *([0-9-]+) *([0-9-]+) *([0-9-]+) *\\)", sub_alteration, str)
1548 str = re.sub ("ly:verbose", "ly:get-option 'verbose", str)
1550 m= re.search ("\\\\outputproperty #([^#]+)[\t\n ]*#'([^ ]+)", str)
1551 if m:
1552 sys.stderr.write (\
1553 r"""\outputproperty found,
1554 Please hand-edit, using
1556 \applyoutput #(outputproperty-compatibility %s '%s <GROB PROPERTY VALUE>)
1558 as a substitution text.""" % (m.group (1), m.group (2)) )
1559 raise FatalConversionError ()
1561 if re.search ("ly:(make-pitch|pitch-alteration)", str) \
1562 or re.search ("keySignature", str):
1563 sys.stderr.write (
1564 """The alteration field of Scheme pitches was multiplied by 2
1565 to support quarter tone accidentals. You have to edit the following constructs by hand:
1567 * calls of ly:make-pitch and ly:pitch-alteration
1568 * keySignature settings made with \property
1569 """)
1570 raise FatalConversionError ()
1572 return str
1573 conversions.append (((1,9,7), conv,
1574 '''use symbolic constants for alterations,
1575 remove \\outputproperty, move ly:verbose into ly:get-option'''))
1578 def conv (str):
1579 if re.search ("dash-length",str):
1580 sys.stderr.write ("""dash-length has been removed. Use dash-fraction instead.""")
1581 raise FatalConversionError()
1582 return str
1584 conversions.append (((1,9,8), conv, """dash-length -> dash-fraction""")
1586 ################################
1587 # END OF CONVERSIONS
1588 ################################
1590 def get_conversions (from_version, to_version):
1591 def version_b (v, f = from_version, t = to_version):
1592 return version_cmp (v[0], f) > 0 and version_cmp (v[0], t) <= 0
1593 return filter (version_b, conversions)
1596 def latest_version ():
1597 return conversions[-1][0]
1599 def do_conversion (infile, from_version, outfile, to_version):
1600 conv_list = get_conversions (from_version, to_version)
1602 sys.stderr.write ('Applying conversions: ')
1603 str = infile.read ()
1604 last_conversion = ()
1605 try:
1606 for x in conv_list:
1607 sys.stderr.write (tup_to_str (x[0]) + ', ')
1608 str = x[1] (str)
1609 last_conversion = x[0]
1611 except FatalConversionError:
1612 sys.stderr.write ('Error while converting; I won\'t convert any further')
1614 if last_conversion:
1615 sys.stderr.write ('\n')
1616 new_ver = '\\version \"%s\"' % tup_to_str (last_conversion)
1618 if re.search (lilypond_version_re_str, str):
1619 str = re.sub (lilypond_version_re_str,'\\'+new_ver , str)
1620 elif add_version:
1621 str = new_ver + '\n' + str
1623 outfile.write(str)
1625 return last_conversion
1627 class UnknownVersion:
1628 pass
1630 def do_one_file (infile_name):
1631 sys.stderr.write ('Processing `%s\' ... '% infile_name)
1632 outfile_name = ''
1633 if __main__.edit:
1634 outfile_name = infile_name + '.NEW'
1635 elif __main__.outfile_name:
1636 outfile_name = __main__.outfile_name
1638 if __main__.from_version:
1639 from_version = __main__.from_version
1640 else:
1641 guess = guess_lilypond_version (infile_name)
1642 if not guess:
1643 raise UnknownVersion()
1644 from_version = str_to_tuple (guess)
1646 if __main__.to_version:
1647 to_version = __main__.to_version
1648 else:
1649 to_version = latest_version ()
1652 if infile_name:
1653 infile = open (infile_name,'r')
1654 else:
1655 infile = sys.stdin
1657 if outfile_name:
1658 outfile = open (outfile_name, 'w')
1659 else:
1660 outfile = sys.stdout
1662 touched = do_conversion (infile, from_version, outfile, to_version)
1664 if infile_name:
1665 infile.close ()
1667 if outfile_name:
1668 outfile.close ()
1670 if __main__.edit and touched:
1671 try:
1672 os.remove(infile_name + '~')
1673 except:
1674 pass
1675 os.rename (infile_name, infile_name + '~')
1676 os.rename (infile_name + '.NEW', infile_name)
1678 sys.stderr.write ('\n')
1679 sys.stderr.flush ()
1681 edit = 0
1682 assume_old = 0
1683 to_version = ()
1684 from_version = ()
1685 outfile_name = ''
1687 (options, files) = getopt.getopt (
1688 sys.argv[1:], 'ao:f:t:senh', ['no-version', 'version', 'output', 'show-rules', 'help', 'edit', 'from=', 'to='])
1690 for opt in options:
1691 o = opt[0]
1692 a = opt[1]
1693 if o== '--help' or o == '-h':
1694 usage ()
1695 sys.exit (0)
1696 if o == '--version' or o == '-v':
1697 print_version ()
1698 sys.exit (0)
1699 elif o== '--from' or o=='-f':
1700 from_version = str_to_tuple (a)
1701 elif o== '--to' or o=='-t':
1702 to_version = str_to_tuple (a)
1703 elif o== '--edit' or o == '-e':
1704 edit = 1
1705 elif o== '--show-rules' or o == '-s':
1706 show_rules (sys.stdout)
1707 sys.exit(0)
1708 elif o == '--output' or o == '-o':
1709 outfile_name = a
1710 elif o == '--no-version' or o == '-n':
1711 add_version = 0
1712 else:
1713 print o
1714 raise getopt.error
1716 identify ()
1717 for f in files:
1718 if f == '-':
1719 f = ''
1720 if not os.path.isfile (f):
1721 continue
1722 try:
1723 do_one_file (f)
1724 except UnknownVersion:
1725 sys.stderr.write ('\n')
1726 sys.stderr.write ("%s: can't determine version for `%s'" % (program_name, f))
1727 sys.stderr.write ('\n')
1728 if assume_old:
1729 fv = from_version
1730 from_version = (0,0,0)
1731 do_one_file (f)
1732 from_version = fv
1733 else:
1734 sys.stderr.write ("%s: skipping: `%s' " % (program_name, f))
1735 pass
1737 sys.stderr.write ('\n')