Doc-de: updates from master
[lilypond.git] / python / convertrules.py
blobf86165c477abb953ba32da9186146831e7c4a33d
1 # (setq py-indent-offset 4)
4 import string
5 import re
6 import sys
7 import lilylib
9 _ = lilylib._
12 NOT_SMART = _ ("Not smart enough to convert %s")
13 UPDATE_MANUALLY = _ ("Please refer to the manual for details, and update manually.")
14 FROM_TO = _ ( "%s has been replaced by %s")
17 class FatalConversionError:
18 pass
20 conversions = []
21 stderr_write = lilylib.stderr_write
23 def warning (str):
24 stderr_write (_ ("warning: %s") % str)
26 # Decorator to make rule syntax simpler
27 def rule (version, message):
28 """
29 version: a LilyPond version tuple like (2, 11, 50)
30 message: the message that describes the conversion.
32 This decorator adds its function together with the version and the
33 message to the global conversions list. (It doesn't need to return
34 the function as it isn't used directly anyway.)
36 A conversion rule using this decorator looks like this:
38 @rule ((1, 2, 3), "convert foo to bar")
39 def conv(str):
40 str = str.replace('foo', 'bar')
41 return str
43 """
44 def dec(f):
45 conversions.append ((version, f, message))
46 return dec
49 @rule ((0, 1, 9), _ ('\\header { key = concat + with + operator }'))
50 def conv(str):
51 if re.search ('\\\\multi', str):
52 stderr_write ('\n')
53 stderr_write (NOT_SMART % "\\multi")
54 stderr_write ('\n')
55 return str
58 @rule ((0, 1, 19), _ ('deprecated %s') % '\\octave')
59 def conv (str):
60 if re.search ('\\\\octave', str):
61 stderr_write ('\n')
62 stderr_write (NOT_SMART % "\\octave")
63 stderr_write ('\n')
64 stderr_write (UPDATE_MANUALLY)
65 stderr_write ('\n')
66 # raise FatalConversionError ()
67 return str
70 @rule ((0, 1, 20), _ ('deprecated \\textstyle, new \\key syntax'))
71 def conv (str):
72 str = re.sub ('\\\\textstyle([^;]+);',
73 '\\\\property Lyrics . textstyle = \\1', str)
74 # harmful to current .lys
75 # str = re.sub ('\\\\key([^;]+);', '\\\\accidentals \\1;', str)
76 return str
79 @rule ((0, 1, 21), '\\musical_pitch -> \\musicalpitch, \\meter -> \\time')
80 def conv (str):
81 str = re.sub ('\\\\musical_pitch', '\\\\musicalpitch',str)
82 str = re.sub ('\\\\meter', '\\\\time',str)
83 return str
86 @rule ((1, 0, 0), _ ("bump version for release"))
87 def conv (str):
88 return str
91 @rule ((1, 0, 1), '\\accidentals -> \\keysignature, specialaccidentals -> keyoctaviation')
92 def conv (str):
93 str = re.sub ('\\\\accidentals', '\\\\keysignature',str)
94 str = re.sub ('specialaccidentals *= *1', 'keyoctaviation = 0',str)
95 str = re.sub ('specialaccidentals *= *0', 'keyoctaviation = 1',str)
96 return str
99 @rule ((1, 0, 2), _ ('\\header { key = concat + with + operator }'))
100 def conv(str):
101 if re.search ('\\\\header', str):
102 stderr_write ('\n')
103 stderr_write (NOT_SMART % _ ("new \\header format"))
104 stderr_write ('\n')
105 return str
108 @rule ((1, 0, 3), '\\melodic -> \\notes')
109 def conv(str):
110 str = re.sub ('\\\\melodic([^a-zA-Z])', '\\\\notes\\1',str)
111 return str
114 @rule ((1, 0, 4), 'default_{paper,midi}')
115 def conv(str):
116 str = re.sub ('default_paper *=', '',str)
117 str = re.sub ('default_midi *=', '',str)
118 return str
121 @rule ((1, 0, 5), 'ChoireStaff -> ChoirStaff')
122 def conv(str):
123 str = re.sub ('ChoireStaff', 'ChoirStaff',str)
124 str = re.sub ('\\\\output', 'output = ',str)
125 return str
128 @rule ((1, 0, 6), 'foo = \\translator {\\type .. } ->\\translator {\\type ..; foo; }')
129 def conv(str):
130 if re.search ('[a-zA-Z]+ = *\\translator',str):
131 stderr_write ('\n')
132 stderr_write (NOT_SMART % _ ("\\translator syntax"))
133 stderr_write ('\n')
134 # raise FatalConversionError ()
135 return str
138 @rule ((1, 0, 7), '\\lyric -> \\lyrics')
139 def conv(str):
140 str = re.sub ('\\\\lyrics*', '\\\\lyrics',str)
141 return str
144 @rule ((1, 0, 10), '[2/3 ]1/1 -> \\times 2/3 ')
145 def conv(str):
146 str = re.sub ('\\\\\\[/3+', '\\\\times 2/3 { ',str)
147 str = re.sub ('\\[/3+', '\\\\times 2/3 { [',str)
148 str = re.sub ('\\\\\\[([0-9/]+)', '\\\\times \\1 {',str)
149 str = re.sub ('\\[([0-9/]+)', '\\\\times \\1 { [',str)
150 str = re.sub ('\\\\\\]([0-9/]+)', '}', str)
151 str = re.sub ('\\\\\\]', '}',str)
152 str = re.sub ('\\]([0-9/]+)', '] }', str)
153 return str
156 @rule ((1, 0, 12), 'Chord syntax stuff')
157 def conv(str):
158 return str
161 @rule ((1, 0, 13), '<a ~ b> c -> <a b> ~ c')
162 def conv(str):
163 str = re.sub ('<([^>~]+)~([^>]*)>','<\\1 \\2> ~', str)
164 return str
167 @rule ((1, 0, 14), '<[a b> <a b]>c -> [<a b> <a b>]')
168 def conv(str):
169 str = re.sub ('<\\[','[<', str)
170 str = re.sub ('\\]>','>]', str)
171 return str
174 @rule ((1, 0, 16), '\\type -> \\context, textstyle -> textStyle')
175 def conv(str):
176 str = re.sub ('\\\\type([^\n]*engraver)','\\\\TYPE\\1', str)
177 str = re.sub ('\\\\type([^\n]*performer)','\\\\TYPE\\1', str)
178 str = re.sub ('\\\\type','\\\\context', str)
179 str = re.sub ('\\\\TYPE','\\\\type', str)
180 str = re.sub ('textstyle','textStyle', str)
181 return str
184 @rule ((1, 0, 18), _ ('\\repeat NUM Music Alternative -> \\repeat FOLDSTR Music Alternative'))
185 def conv(str):
186 if re.search ('\\\\repeat',str):
187 stderr_write ('\n')
188 stderr_write (NOT_SMART % "\\repeat")
189 stderr_write ('\n')
190 # raise FatalConversionError ()
191 return str
194 @rule ((1, 0, 19), 'fontsize -> fontSize, midi_instrument -> midiInstrument, SkipBars -> skipBars')
195 def conv(str):
196 str = re.sub ('SkipBars','skipBars', str)
197 str = re.sub ('fontsize','fontSize', str)
198 str = re.sub ('midi_instrument','midiInstrument', str)
199 return str
202 @rule ((1, 0, 20), '{,tie,slur}ydirection -> {v,tieV,slurV}erticalDirection')
203 def conv(str):
204 str = re.sub ('tieydirection','tieVerticalDirection', str)
205 str = re.sub ('slurydirection','slurVerticalDirection', str)
206 str = re.sub ('ydirection','verticalDirection', str)
207 return str
210 @rule ((1, 0, 21), 'hshift -> horizontalNoteShift')
211 def conv(str):
212 str = re.sub ('hshift','horizontalNoteShift', str)
213 return str
216 @rule ((1, 1, 52), _ ('deprecate %s') % '\\grouping')
217 def conv(str):
218 str = re.sub ('\\\\grouping[^;]*;','', str)
219 return str
222 @rule ((1, 1, 55), '\\wheel -> \\coda')
223 def conv(str):
224 str = re.sub ('\\\\wheel','\\\\coda', str)
225 return str
228 @rule ((1, 1, 65), 'slurdash -> slurDash, keyoctaviation -> keyOctaviation')
229 def conv(str):
230 str = re.sub ('keyoctaviation','keyOctaviation', str)
231 str = re.sub ('slurdash','slurDash', str)
232 return str
235 @rule ((1, 1, 66), 'semi -> volta')
236 def conv(str):
237 str = re.sub ('\\\\repeat *\"?semi\"?','\\\\repeat "volta"', str)
238 return str
241 @rule ((1, 1, 67), 'beamAuto -> noAutoBeaming')
242 def conv(str):
243 str = re.sub ('\"?beamAuto\"? *= *\"?0?\"?','noAutoBeaming = "1"', str)
244 return str
247 @rule ((1, 2, 0), 'automaticMelismas -> automaticMelismata')
248 def conv(str):
249 str = re.sub ('automaticMelismas', 'automaticMelismata', str)
250 return str
253 @rule ((1, 2, 1), 'dynamicDir -> dynamicDirection')
254 def conv(str):
255 str = re.sub ('dynamicDir\\b', 'dynamicDirection', str)
256 return str
259 @rule ((1, 3, 4), '\\cadenza -> \\cadenza{On|Off}')
260 def conv(str):
261 str = re.sub ('\\\\cadenza *0 *;', '\\\\cadenzaOff', str)
262 str = re.sub ('\\\\cadenza *1 *;', '\\\\cadenzaOn', str)
263 return str
266 @rule ((1, 3, 5), 'beamAuto moment properties')
267 def conv (str):
268 str = re.sub ('"?beamAuto([^"=]+)"? *= *"([0-9]+)/([0-9]+)" *;*',
269 'beamAuto\\1 = #(make-moment \\2 \\3)',
270 str)
271 return str
274 @rule ((1, 3, 17), 'stemStyle -> flagStyle')
275 def conv (str):
276 str = re.sub ('stemStyle',
277 'flagStyle',
278 str)
279 return str
282 @rule ((1, 3, 18), 'staffLineLeading -> staffSpace')
283 def conv (str):
284 str = re.sub ('staffLineLeading',
285 'staffSpace',
286 str)
287 return str
290 @rule ((1, 3, 23), _ ('deprecate %s ') % '\\repetitions')
291 def conv(str):
292 if re.search ('\\\\repetitions',str):
293 stderr_write ('\n')
294 stderr_write (NOT_SMART % "\\repetitions")
295 stderr_write ('\n')
296 # raise FatalConversionError ()
297 return str
300 @rule ((1, 3, 35), 'textEmptyDimension -> textNonEmpty')
301 def conv (str):
302 str = re.sub ('textEmptyDimension *= *##t',
303 'textNonEmpty = ##f',
304 str)
305 str = re.sub ('textEmptyDimension *= *##f',
306 'textNonEmpty = ##t',
307 str)
308 return str
311 @rule ((1, 3, 38), '\musicalpitch { a b c } -> #\'(a b c)')
312 def conv (str):
313 str = re.sub ("([a-z]+)[ \t]*=[ \t]*\\\\musicalpitch *{([- 0-9]+)} *\n",
314 "(\\1 . (\\2))\n", str)
315 str = re.sub ("\\\\musicalpitch *{([0-9 -]+)}",
316 "\\\\musicalpitch #'(\\1)", str)
317 if re.search ('\\\\notenames',str):
318 stderr_write ('\n')
319 stderr_write (NOT_SMART % _ ("new \\notenames format"))
320 stderr_write ('\n')
321 return str
324 @rule ((1, 3, 39), '\\key A ; ->\\key a;')
325 def conv (str):
326 def replace (match):
327 return '\\key %s;' % match.group (1).lower ()
329 str = re.sub ("\\\\key ([^;]+);", replace, str)
330 return str
333 @rule ((1, 3, 41), '[:16 c4 d4 ] -> \\repeat "tremolo" 2 { c16 d16 }')
334 def conv (str):
335 if re.search ('\\[:',str):
336 stderr_write ('\n')
337 stderr_write (NOT_SMART % _ ("new tremolo format"))
338 stderr_write ('\n')
339 return str
342 @rule ((1, 3, 42), _ ('Staff_margin_engraver deprecated, use Instrument_name_engraver'))
343 def conv (str):
344 str = re.sub ('Staff_margin_engraver' , 'Instrument_name_engraver', str)
345 return str
348 @rule ((1, 3, 49), 'noteHeadStyle value: string -> symbol')
349 def conv (str):
350 str = re.sub ('note[hH]eadStyle\\s*=\\s*"?(\\w+)"?' , "noteHeadStyle = #'\\1", str)
351 return str
354 @rule ((1, 3, 58), 'noteHeadStyle value: string -> symbol')
355 def conv (str):
356 if re.search ('\\\\keysignature', str):
357 stderr_write ('\n')
358 stderr_write (NOT_SMART % '\\keysignature')
359 stderr_write ('\n')
360 return str
363 @rule ((1, 3, 59), '\key X ; -> \key X major; ')
364 def conv (str):
365 str = re.sub (r"""\\key *([a-z]+) *;""", r"""\\key \1 \major;""",str);
366 return str
369 @rule ((1, 3, 68), 'latexheaders = "\\input global" -> latexheaders = "global"')
370 def conv (str):
371 str = re.sub (r'latexheaders *= *"\\\\input ',
372 'latexheaders = "',
373 str)
374 return str
377 # TODO: lots of other syntax change should be done here as well
378 @rule ((1, 3, 92), 'basicXXXProperties -> XXX, Repeat_engraver -> Volta_engraver')
379 def conv (str):
380 str = re.sub ('basicCollisionProperties', 'NoteCollision', str)
381 str = re.sub ('basicVoltaSpannerProperties' , "VoltaBracket", str)
382 str = re.sub ('basicKeyProperties' , "KeySignature", str)
384 str = re.sub ('basicClefItemProperties' ,"Clef", str)
387 str = re.sub ('basicLocalKeyProperties' ,"Accidentals", str)
388 str = re.sub ('basicMarkProperties' ,"Accidentals", str)
389 str = re.sub ('basic([A-Za-z_]+)Properties', '\\1', str)
391 str = re.sub ('Repeat_engraver' ,'Volta_engraver', str)
392 return str
395 @rule ((1, 3, 93), _ ('change property definiton case (eg. onevoice -> oneVoice)'))
396 def conv (str):
397 # Ugh, but meaning of \stemup changed too
398 # maybe we should do \stemup -> \stemUp\slurUp\tieUp ?
399 str = re.sub ('\\\\stemup', '\\\\stemUp', str)
400 str = re.sub ('\\\\stemdown', '\\\\stemDown', str)
401 str = re.sub ('\\\\stemboth', '\\\\stemBoth', str)
403 str = re.sub ('\\\\slurup', '\\\\slurUp', str)
404 str = re.sub ('\\\\slurboth', '\\\\slurBoth', str)
405 str = re.sub ('\\\\slurdown', '\\\\slurDown', str)
406 str = re.sub ('\\\\slurdotted', '\\\\slurDotted', str)
407 str = re.sub ('\\\\slurnormal', '\\\\slurNoDots', str)
409 str = re.sub ('\\\\shiftoff', '\\\\shiftOff', str)
410 str = re.sub ('\\\\shifton', '\\\\shiftOn', str)
411 str = re.sub ('\\\\shiftonn', '\\\\shiftOnn', str)
412 str = re.sub ('\\\\shiftonnn', '\\\\shiftOnnn', str)
414 str = re.sub ('\\\\onevoice', '\\\\oneVoice', str)
415 str = re.sub ('\\\\voiceone', '\\\\voiceOne', str)
416 str = re.sub ('\\\\voicetwo', '\\\\voiceTwo', str)
417 str = re.sub ('\\\\voicethree', '\\\\voiceThree', str)
418 str = re.sub ('\\\\voicefour', '\\\\voiceFour', str)
420 # I don't know exactly when these happened...
421 # ugh, we loose context setting here...
422 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\stemUp\\\\slurUp\\\\tieUp', str)
423 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\stemDown\\\\slurDown\\\\tieDown', str)
424 str = re.sub ('\\\\property *[^ ]*verticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\\\stemBoth\\\\slurBoth\\\\tieBoth', str)
426 str = re.sub ('verticalDirection[^=]*= *#?"?(1|(\\\\up))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #1', str)
427 str = re.sub ('verticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #-1', str)
428 str = re.sub ('verticalDirection[^=]*= *#?"?(0|(\\\\center))"?', 'Stem \\\\override #\'direction = #0\nSlur \\\\override #\'direction = #0\n Tie \\\\override #\'direction = #0', str)
430 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\\\1Up', str)
431 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\\\1Down', str)
432 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)VerticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\\\\\1Both', str)
434 # (lacks capitalisation slur -> Slur)
435 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\1 \\\\override #\'direction = #1', str)
436 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?((-1)|(\\\\down))"?', '\\1 \\override #\'direction = #-1', str)
437 str = re.sub ('([a-z]+)VerticalDirection[^=]*= *#?"?(0|(\\\\center))"?', '\\1 \\\\override #\'direction = #0', str)
439 ## dynamic..
440 str = re.sub ('\\\\property *[^ .]*[.]?dynamicDirection[^=]*= *#?"?(1|(\\\\up))"?', '\\\\dynamicUp', str)
441 str = re.sub ('\\\\property *[^ .]*[.]?dyn[^=]*= *#?"?((-1)|(\\\\down))"?', '\\\\dynamicDown', str)
442 str = re.sub ('\\\\property *[^ .]*[.]?dyn[^=]*= *#?"?(0|(\\\\center))"?', '\\\\dynamicBoth', str)
444 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)Dash[^=]*= *#?"?(0|(""))"?', '\\\\\\1NoDots', str)
445 str = re.sub ('\\\\property *[^ .]*[.]?([a-z]+)Dash[^=]*= *#?"?([1-9]+)"?', '\\\\\\1Dotted', str)
447 str = re.sub ('\\\\property *[^ .]*[.]?noAutoBeaming[^=]*= *#?"?(0|(""))"?', '\\\\autoBeamOn', str)
448 str = re.sub ('\\\\property *[^ .]*[.]?noAutoBeaming[^=]*= *#?"?([1-9]+)"?', '\\\\autoBeamOff', str)
449 return str
452 @rule ((1, 3, 97), 'ChordName -> ChordNames')
453 def conv (str):
454 str = re.sub ('ChordNames*', 'ChordNames', str)
455 if re.search ('\\\\textscript "[^"]* *"[^"]*"', str):
456 stderr_write ('\n')
457 stderr_write (NOT_SMART % _ ("new \\textscript markup text"))
458 stderr_write ('\n')
460 str = re.sub ('\\textscript +("[^"]*")', '\\textscript #\\1', str)
461 return str
463 # TODO: add lots of these
465 @rule ((1, 3, 98), 'CONTEXT.textStyle -> GROB.#font-style ')
466 def conv (str):
467 str = re.sub ('\\\\property *"?Voice"? *[.] *"?textStyle"? *= *"([^"]*)"', '\\\\property Voice.TextScript \\\\set #\'font-style = #\'\\1', str)
468 str = re.sub ('\\\\property *"?Lyrics"? *[.] *"?textStyle"? *= *"([^"]*)"', '\\\\property Lyrics.LyricText \\\\set #\'font-style = #\'\\1', str)
470 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?timeSignatureStyle"? *= *"([^"]*)"', '\\\\property \\1.TimeSignature \\\\override #\'style = #\'\\2', str)
472 str = re.sub ('"?timeSignatureStyle"? *= *#?""', 'TimeSignature \\\\override #\'style = ##f', str)
474 str = re.sub ('"?timeSignatureStyle"? *= *#?"([^"]*)"', 'TimeSignature \\\\override #\'style = #\'\\1', str)
476 str = re.sub ('#\'style *= #*"([^"])"', '#\'style = #\'\\1', str)
478 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?horizontalNoteShift"? *= *"?#?([-0-9]+)"?', '\\\\property \\1.NoteColumn \\\\override #\'horizontal-shift = #\\2', str)
480 # ugh
481 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?flagStyle"? *= *""', '\\\\property \\1.Stem \\\\override #\'flag-style = ##f', str)
483 str = re.sub ('\\\\property *"?([^.]+)"? *[.] *"?flagStyle"? *= *"([^"]*)"', '\\\\property \\1.Stem \\\\override #\'flag-style = #\'\\2', str)
484 return str
487 @rule ((1, 3, 102), 'beamAutoEnd -> autoBeamSettings \\push (end * * * *)')
488 def conv (str):
489 str = re.sub ('"?beamAutoEnd_([0-9]*)"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(end 1 \\1 * *) = \\2', str)
490 str = re.sub ('"?beamAutoBegin_([0-9]*)"? *= *(#\\([^)]*\))', 'autoBeamSettings \\push #\'(begin 1 \\1 * *) = \\2', str)
491 str = re.sub ('"?beamAutoEnd"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(end * * * *) = \\1', str)
492 str = re.sub ('"?beamAutoBegin"? *= *(#\\([^)]*\\))', 'autoBeamSettings \\push #\'(begin * * * *) = \\1', str)
493 return str
496 @rule ((1, 3, 111), '\\push -> \\override, \\pop -> \\revert')
497 def conv (str):
498 str = re.sub ('\\\\push', '\\\\override', str)
499 str = re.sub ('\\\\pop', '\\\\revert', str)
500 return str
503 @rule ((1, 3, 113), 'LyricVoice -> LyricsVoice')
504 def conv (str):
505 str = re.sub ('LyricVoice', 'LyricsVoice', str)
506 # old fix
507 str = re.sub ('Chord[Nn]ames*.Chord[Nn]ames*', 'ChordNames.ChordName', str)
508 str = re.sub ('Chord[Nn]ames([ \t\n]+\\\\override)', 'ChordName\\1', str)
509 return str
512 def regularize_id (str):
513 s = ''
514 lastx = ''
515 for x in str:
516 if x == '_':
517 lastx = x
518 continue
519 elif x in string.digits:
520 x = chr(ord (x) - ord ('0') +ord ('A'))
521 elif x not in string.letters:
522 x = 'x'
523 elif x in string.lowercase and lastx == '_':
524 x = x.upper ()
525 s = s + x
526 lastx = x
527 return s
530 @rule ((1, 3, 117), _ ('identifier names: %s') % '$!foo_bar_123 -> xfooBarABC')
531 def conv (str):
532 def regularize_dollar_reference (match):
533 return regularize_id (match.group (1))
534 def regularize_assignment (match):
535 return '\n' + regularize_id (match.group (1)) + ' = '
536 str = re.sub ('\$([^\t\n ]+)', regularize_dollar_reference, str)
537 str = re.sub ('\n([^ \t\n]+)[ \t]*= *', regularize_assignment, str)
538 return str
541 @rule ((1, 3, 120), 'paper_xxx -> paperXxxx, pedalup -> pedalUp.')
542 def conv (str):
543 def regularize_paper (match):
544 return regularize_id (match.group (1))
545 str = re.sub ('(paper_[a-z]+)', regularize_paper, str)
546 str = re.sub ('sustainup', 'sustainUp', str)
547 str = re.sub ('nobreak', 'noBreak', str)
548 str = re.sub ('sustaindown', 'sustainDown', str)
549 str = re.sub ('sostenutoup', 'sostenutoUp', str)
550 str = re.sub ('sostenutodown', 'sostenutoDown', str)
551 str = re.sub ('unachorda', 'unaChorda', str)
552 str = re.sub ('trechorde', 'treChorde', str)
553 return str
556 @rule ((1, 3, 122), 'drarnChords -> chordChanges, \\musicalpitch -> \\pitch')
557 def conv (str):
558 str = re.sub ('drarnChords', 'chordChanges', str)
559 str = re.sub ('\\musicalpitch', '\\pitch', str)
560 return str
563 @rule ((1, 3, 136), 'ly-X-elt-property -> ly-X-grob-property')
564 def conv (str):
565 str = re.sub ('ly-([sg])et-elt-property', 'ly-\\1et-grob-property', str)
566 return str
569 @rule ((1, 3, 138), _ ('point-and-click argument changed to procedure.'))
570 def conv (str):
571 str = re.sub ('point-and-click +#t', 'point-and-click line-column-location', str)
572 return str
575 @rule ((1, 3, 138), 'followThread -> followVoice.')
576 def conv (str):
577 str = re.sub ('followThread', 'followVoice', str)
578 str = re.sub ('Thread.FollowThread', 'Voice.VoiceFollower', str)
579 str = re.sub ('FollowThread', 'VoiceFollower', str)
580 return str
583 @rule ((1, 3, 139), 'font-point-size -> font-design-size.')
584 def conv (str):
585 str = re.sub ('font-point-size', 'font-design-size', str)
586 return str
589 @rule ((1, 3, 141), 'xNoDots -> xSolid')
590 def conv (str):
591 str = re.sub ('([a-zA-Z]*)NoDots', '\\1Solid', str)
592 return str
595 @rule ((1, 3, 144), 'Chorda -> Corda')
596 def conv (str):
597 str = re.sub ('([Cc])hord([ea])', '\\1ord\\2', str)
598 return str
601 @rule ((1, 3, 145), 'ContextNameXxxxVerticalExtent -> XxxxVerticalExtent')
602 def conv (str):
603 str = re.sub ('([A-Za-z]+)MinimumVerticalExtent', 'MinimumV@rticalExtent', str)
604 str = re.sub ('([A-Za-z]+)ExtraVerticalExtent', 'ExtraV@rticalExtent', str)
605 str = re.sub ('([A-Za-z]+)VerticalExtent', 'VerticalExtent', str)
606 str = re.sub ('ExtraV@rticalExtent', 'ExtraVerticalExtent', str)
607 str = re.sub ('MinimumV@rticalExtent', 'MinimumVerticalExtent', str)
608 return str
611 @rule ((1, 3, 146), _('semicolons removed'))
612 def conv (str):
613 str = re.sub ('\\\\key[ \t]*;', '\\key \\default;', str)
614 str = re.sub ('\\\\mark[ \t]*;', '\\mark \\default;', str)
616 # Make sure groups of more than one ; have space before
617 # them, so that non of them gets removed by next rule
618 str = re.sub ("([^ \n\t;]);(;+)", "\\1 ;\\2", str)
620 # Only remove ; that are not after spaces, # or ;
621 # Otherwise we interfere with Scheme comments,
622 # which is badbadbad.
623 str = re.sub ("([^ \t;#]);", "\\1", str)
624 return str
627 @rule ((1, 3, 147), 'default-neutral-direction -> neutral-direction')
628 def conv (str):
629 str = re.sub ('default-neutral-direction', 'neutral-direction',str)
630 return str
633 @rule ((1, 3, 148), '"(align" -> "(axis", "(rows" -> "(columns"')
634 def conv (str):
635 str = re.sub ('\(align', '(axis', str)
636 str = re.sub ('\(rows', '(columns', str)
637 return str
640 @rule ((1, 5, 33), 'SystemStartDelimiter -> systemStartDelimiter')
641 def conv (str):
642 str = re.sub ('SystemStartDelimiter', 'systemStartDelimiter', str)
643 return str
646 @rule ((1, 5, 38), 'arithmetic... -> spacing...')
647 def conv (str):
648 str = re.sub ('arithmetic-multiplier', 'spacing-increment', str)
649 str = re.sub ('arithmetic-basicspace', 'shortest-duration-space', str)
650 return str
653 # 40 ?
654 @rule ((1, 5, 40), _ ('%s property names') % 'breakAlignOrder')
655 def conv (str):
657 def func(match):
658 break_dict = {
659 "Instrument_name": "instrument-name",
660 "Left_edge_item": "left-edge",
661 "Span_bar": "span-bar",
662 "Breathing_sign": "breathing-sign",
663 "Staff_bar": "staff-bar",
664 "Clef_item": "clef",
665 "Key_item": "key-signature",
666 "Time_signature": "time-signature",
667 "Custos": "custos"
669 props = match.group (1)
670 for (k,v) in break_dict.items():
671 props = re.sub (k, v, props)
672 return "breakAlignOrder = #'(%s)" % props
674 str = re.sub ("breakAlignOrder *= *#'\\(([a-z_\n\tA-Z ]+)\\)",
675 func, str)
676 return str
679 @rule ((1, 5, 49), 'noAutoBeaming -> autoBeaming')
680 def conv (str):
681 str = re.sub ('noAutoBeaming *= *##f', 'autoBeaming = ##t', str)
682 str = re.sub ('noAutoBeaming *= *##t', 'autoBeaming = ##f', str)
683 return str
686 @rule ((1, 5, 52), 'tuplet-X-visibility -> X-visibility')
687 def conv (str):
688 str = re.sub ('tuplet-bracket-visibility', 'bracket-visibility', str)
689 str = re.sub ('tuplet-number-visibility', 'number-visibility', str)
690 return str
693 @rule ((1, 5, 56), 'Pitch::transpose -> ly-transpose-pitch')
694 def conv (str):
695 str = re.sub ('Pitch::transpose', 'ly-transpose-pitch', str)
696 return str
699 @rule ((1, 5, 58), _ ('deprecate %s') % 'textNonEmpty')
700 def conv (str):
701 str = re.sub ('textNonEmpty *= *##t', "TextScript \\set #'no-spacing-rods = ##f", str)
702 str = re.sub ('textNonEmpty *= *##f', "TextScript \\set #'no-spacing-rods = ##t", str)
703 return str
706 @rule ((1, 5, 59), 'XxxxVerticalExtent -> xxxVerticalExtent')
707 def conv (str):
708 str = re.sub ('MinimumVerticalExtent', 'minimumV@rticalExtent', str)
709 str = re.sub ('minimumVerticalExtent', 'minimumV@rticalExtent', str)
710 str = re.sub ('ExtraVerticalExtent', 'extraV@rticalExtent', str)
711 str = re.sub ('extraVerticalExtent', 'extraV@rticalExtent', str)
712 str = re.sub ('VerticalExtent', 'verticalExtent', str)
713 str = re.sub ('extraV@rticalExtent', 'extraVerticalExtent', str)
714 str = re.sub ('minimumV@rticalExtent', 'minimumVerticalExtent', str)
715 return str
718 @rule ((1, 5, 62), 'visibility-lambda -> break-visibility')
719 def conv (str):
720 str = re.sub ('visibility-lambda', 'break-visibility', str)
721 return str
724 @rule ((1, 5, 67), _ ('automaticMelismata turned on by default'))
725 def conv (str):
726 if re.search (r'\addlyrics',str) \
727 and re.search ('automaticMelismata', str) == None:
728 stderr_write ('\n')
729 stderr_write (NOT_SMART % "automaticMelismata; turned on by default since 1.5.67.")
730 stderr_write ('\n')
731 raise FatalConversionError ()
732 return str
735 @rule ((1, 5, 68), 'ly-set-X-property -> ly-set-X-property!')
736 def conv (str):
737 str = re.sub ('ly-set-grob-property([^!])', 'ly-set-grob-property!\1', str)
738 str = re.sub ('ly-set-mus-property([^!])', 'ly-set-mus-property!\1', str)
739 return str
742 @rule ((1, 5, 71), 'extent-[XY] -> [XY]-extent')
743 def conv (str):
744 str = re.sub ('extent-X', 'X-extent', str)
745 str = re.sub ('extent-Y', 'Y-extent', str)
746 return str
749 @rule ((1, 5, 72), 'set! point-and-click -> set-point-and-click!')
750 def conv (str):
751 str = re.sub ("""#\(set! +point-and-click +line-column-location\)""",
752 """#(set-point-and-click! \'line-column)""", str)
753 str = re.sub ("""#\(set![ \t]+point-and-click +line-location\)""",
754 '#(set-point-and-click! \'line)', str)
755 str = re.sub ('#\(set! +point-and-click +#f\)',
756 '#(set-point-and-click! \'none)', str)
757 return str
760 @rule ((1, 6, 5), 'Stems: flag-style -> stroke-style; style -> flag-style')
761 def conv (str):
762 str = re.sub ('flag-style', 'stroke-style', str)
763 str = re.sub (r"""Stem([ ]+)\\override #'style""", r"""Stem \\override #'flag-style""", str);
764 str = re.sub (r"""Stem([ ]+)\\set([ ]+)#'style""", r"""Stem \\set #'flag-style""", str);
765 return str
768 def subst_req_name (match):
769 return "(make-music-by-name \'%sEvent)" % regularize_id (match.group(1))
772 @rule ((1, 7, 1), 'ly-make-music foo_bar_req -> make-music-by-name FooBarEvent')
773 def conv (str):
774 str = re.sub ('\\(ly-make-music *\"([A-Z][a-z_]+)_req\"\\)', subst_req_name, str)
775 str = re.sub ('Request_chord', 'EventChord', str)
776 return str
779 spanner_subst ={
780 "text" : 'TextSpanEvent',
781 "decrescendo" : 'DecrescendoEvent',
782 "crescendo" : 'CrescendoEvent',
783 "Sustain" : 'SustainPedalEvent',
784 "slur" : 'SlurEvent',
785 "UnaCorda" : 'UnaCordaEvent',
786 "Sostenuto" : 'SostenutoEvent',
789 def subst_ev_name (match):
790 stype = 'STOP'
791 if re.search ('start', match.group(1)):
792 stype= 'START'
793 mtype = spanner_subst[match.group(2)]
794 return "(make-span-event '%s %s)" % (mtype , stype)
796 def subst_definition_ev_name(match):
797 return ' = #%s' % subst_ev_name (match)
799 def subst_inline_ev_name (match):
800 s = subst_ev_name (match)
801 return '#(ly-export %s)' % s
803 def subst_csp_definition (match):
804 return ' = #(make-event-chord (list %s))' % subst_ev_name (match)
806 def subst_csp_inline (match):
807 return '#(ly-export (make-event-chord (list %s)))' % subst_ev_name (match)
810 @rule ((1, 7, 2), '\\spanrequest -> #(make-span-event .. ), \script -> #(make-articulation .. )')
811 def conv (str):
812 str = re.sub (r' *= *\\spanrequest *([^ ]+) *"([^"]+)"', subst_definition_ev_name, str)
813 str = re.sub (r'\\spanrequest *([^ ]+) *"([^"]+)"', subst_inline_ev_name, str)
814 str = re.sub (r' *= *\\commandspanrequest *([^ ]+) *"([^"]+)"', subst_csp_definition, str)
815 str = re.sub (r'\\commandspanrequest *([^ ]+) *"([^"]+)"', subst_csp_inline, str)
816 str = re.sub (r'ly-id ', 'ly-import ', str)
818 str = re.sub (r' *= *\\script "([^"]+)"', ' = #(make-articulation "\\1")', str)
819 str = re.sub (r'\\script "([^"]+)"', '#(ly-export (make-articulation "\\1"))', str)
820 return str
823 @rule ((1, 7, 3), 'ly- -> ly:')
824 def conv(str):
825 str = re.sub (r'\(ly-', '(ly:', str)
827 changed = [
828 r'duration\?',
829 r'font-metric\?',
830 r'molecule\?',
831 r'moment\?',
832 r'music\?',
833 r'pitch\?',
834 'make-duration',
835 'music-duration-length',
836 'duration-log',
837 'duration-dotcount',
838 'intlog2',
839 'duration-factor',
840 'transpose-key-alist',
841 'get-system',
842 'get-broken-into',
843 'get-original',
844 'set-point-and-click!',
845 'make-moment',
846 'make-pitch',
847 'pitch-octave',
848 'pitch-alteration',
849 'pitch-notename',
850 'pitch-semitones',
851 r'pitch<\?',
852 r'dir\?',
853 'music-duration-compress',
854 'set-point-and-click!'
857 origre = r'\b(%s)' % '|'.join (changed)
859 str = re.sub (origre, r'ly:\1',str)
860 str = re.sub ('set-point-and-click!', 'set-point-and-click', str)
861 return str
864 @rule ((1, 7, 4), '<< >> -> < < > >')
865 def conv(str):
866 if re.search ('new-chords-done',str):
867 return str
869 str = re.sub (r'<<', '< <', str)
870 str = re.sub (r'>>', '> >', str)
871 return str
874 @rule ((1, 7, 5), '\\transpose TO -> \\transpose FROM TO')
875 def conv(str):
876 str = re.sub (r"\\transpose", r"\\transpose c'", str)
877 str = re.sub (r"\\transpose c' *([a-z]+)'", r"\\transpose c \1", str)
878 return str
881 @rule ((1, 7, 6), 'note\\script -> note-\script')
882 def conv(str):
883 kws = ['arpeggio',
884 'sustainDown',
885 'sustainUp',
886 'f',
887 'p',
888 'pp',
889 'ppp',
890 'fp',
891 'ff',
892 'mf',
893 'mp',
894 'sfz',
897 origstr = '|'.join (kws)
898 str = re.sub (r'([^_^-])\\(%s)\b' % origstr, r'\1-\\\2', str)
899 return str
902 @rule ((1, 7, 10), "\property ChordName #'style -> #(set-chord-name-style 'style)")
903 def conv(str):
904 str = re.sub (r"\\property *ChordNames *\. *ChordName *\\(set|override) *#'style *= *#('[a-z]+)",
905 r"#(set-chord-name-style \2)", str)
906 str = re.sub (r"\\property *ChordNames *\. *ChordName *\\revert *#'style",
907 r"", str)
908 return str
911 @rule ((1, 7, 11), "transpose-pitch -> pitch-transpose")
912 def conv(str):
913 str = re.sub (r"ly:transpose-pitch", "ly:pitch-transpose", str)
914 return str
917 @rule ((1, 7, 13), "ly:XX-molecule-YY -> ly:molecule-XX-YY")
918 def conv(str):
919 str = re.sub (r"ly:get-molecule-extent", "ly:molecule-get-extent", str)
920 str = re.sub (r"ly:set-molecule-extent!", "ly:molecule-set-extent!", str)
921 str = re.sub (r"ly:add-molecule", "ly:molecule-add", str)
922 str = re.sub (r"ly:combine-molecule-at-edge", "ly:molecule-combine-at-edge", str)
923 str = re.sub (r"ly:align-to!", "ly:molecule-align-to!", str)
924 return str
927 @rule ((1, 7, 15), "linewidth = -1 -> raggedright = ##t")
928 def conv(str):
929 str = re.sub (r"linewidth *= *-[0-9.]+ *(\\mm|\\cm|\\in|\\pt)?", 'raggedright = ##t', str )
930 return str
933 @rule ((1, 7, 16), "divisiomaior -> divisioMaior")
934 def conv(str):
935 str = re.sub ("divisiomaior",
936 "divisioMaior", str)
937 str = re.sub ("divisiominima",
938 "divisioMinima", str)
939 str = re.sub ("divisiomaxima",
940 "divisioMaxima", str)
941 return str
944 @rule ((1, 7, 17), "Skip_req -> Skip_event")
945 def conv(str):
946 str = re.sub ("Skip_req_swallow_translator",
947 "Skip_event_swallow_translator", str)
948 return str
951 @rule ((1, 7, 18), "groupOpen/Close -> start/stopGroup, #'outer -> #'enclose-bounds")
952 def conv(str):
953 str = re.sub ("groupOpen",
954 "startGroup", str)
955 str = re.sub ("groupClose",
956 "stopGroup", str)
957 str = re.sub ("#'outer",
958 "#'enclose-bounds", str)
960 return str
963 @rule ((1, 7, 19), _ ("remove %s") % "GraceContext")
964 def conv(str):
965 if re.search( r'\\GraceContext', str):
966 stderr_write ('\n')
967 stderr_write (NOT_SMART % "GraceContext")
968 stderr_write (FROM_TO \
969 % ("GraceContext", "#(add-to-grace-init .. )"))
970 stderr_write ('\n')
971 stderr_write (UPDATE_MANUALLY)
972 stderr_write ('\n')
973 raise FatalConversionError ()
975 str = re.sub ('HaraKiriStaffContext', 'RemoveEmptyStaffContext', str)
976 return str
979 @rule ((1, 7, 22), "#'type -> #'style")
980 def conv(str):
981 str = re.sub (
982 r"(set|override|revert) *#'type",
983 r"\1 #'style",
984 str)
985 return str
988 @rule ((1, 7, 23), "barNonAuto -> automaticBars")
989 def conv(str):
990 str = re.sub (
991 "barNonAuto *= *##t",
992 "automaticBars = ##f",
993 str)
994 str = re.sub (
995 "barNonAuto *= *##f",
996 "automaticBars = ##t",
997 str)
998 return str
1001 @rule ((1, 7, 24), _ ("cluster syntax"))
1002 def conv(str):
1003 if re.search( r'-(start|stop)Cluster', str):
1004 stderr_write ('\n')
1005 stderr_write (NOT_SMART % _ ("cluster syntax"))
1006 stderr_write ('\n')
1007 stderr_write (UPDATE_MANUALLY)
1008 stderr_write ('\n')
1010 raise FatalConversionError ()
1011 return str
1014 @rule ((1, 7, 28), _ ("new Pedal style syntax"))
1015 def conv(str):
1016 str = re.sub (r"\\property *Staff\.(Sustain|Sostenuto|UnaCorda)Pedal *\\(override|set) *#'pedal-type *",
1017 r"\property Staff.pedal\1Style ", str)
1018 str = re.sub (r"\\property *Staff\.(Sustain|Sostenuto|UnaCorda)Pedal *\\revert *#'pedal-type", '', str)
1019 return str
1022 def sub_chord (m):
1023 str = m.group(1)
1025 origstr = '<%s>' % str
1026 if re.search (r'\\\\', str):
1027 return origstr
1029 if re.search (r'\\property', str):
1030 return origstr
1032 if re.match (r'^\s*\)?\s*\\[a-zA-Z]+', str):
1033 return origstr
1035 durs = []
1036 def sub_durs (m, durs = durs):
1037 durs.append(m.group(2))
1038 return m.group (1)
1040 str = re.sub (r"([a-z]+[,'!? ]*)([0-9]+\.*)", sub_durs, str)
1041 dur_str = ''
1043 for d in durs:
1044 if dur_str == '':
1045 dur_str = d
1046 if dur_str <> d:
1047 return '<%s>' % m.group (1)
1049 pslur_strs = ['']
1050 dyns = ['']
1051 slur_strs = ['']
1053 last_str = ''
1054 while last_str <> str:
1055 last_str = str
1057 def sub_tremolos (m, slur_strs = slur_strs):
1058 tr = m.group (2)
1059 if tr not in slur_strs:
1060 slur_strs.append (tr)
1061 return m.group (1)
1063 str = re.sub (r"([a-z]+[',!? ]*)(:[0-9]+)",
1064 sub_tremolos, str)
1066 def sub_dyn_end (m, dyns = dyns):
1067 dyns.append (' \!')
1068 return ' ' + m.group(2)
1070 str = re.sub (r'(\\!)\s*([a-z]+)', sub_dyn_end, str)
1071 def sub_slurs(m, slur_strs = slur_strs):
1072 if '-)' not in slur_strs:
1073 slur_strs.append (')')
1074 return m.group(1)
1076 def sub_p_slurs(m, slur_strs = slur_strs):
1077 if '-\)' not in slur_strs:
1078 slur_strs.append ('\)')
1079 return m.group(1)
1081 str = re.sub (r"\)[ ]*([a-z]+)", sub_slurs, str)
1082 str = re.sub (r"\\\)[ ]*([a-z]+)", sub_p_slurs, str)
1083 def sub_begin_slurs(m, slur_strs = slur_strs):
1084 if '-(' not in slur_strs:
1085 slur_strs.append ('(')
1086 return m.group(1)
1088 str = re.sub (r"([a-z]+[,'!?0-9 ]*)\(",
1089 sub_begin_slurs, str)
1090 def sub_begin_p_slurs(m, slur_strs = slur_strs):
1091 if '-\(' not in slur_strs:
1092 slur_strs.append ('\(')
1093 return m.group(1)
1095 str = re.sub (r"([a-z]+[,'!?0-9 ]*)\\\(",
1096 sub_begin_p_slurs, str)
1098 def sub_dyns (m, slur_strs = slur_strs):
1099 s = m.group(0)
1100 if s == '@STARTCRESC@':
1101 slur_strs.append ("\\<")
1102 elif s == '@STARTDECRESC@':
1103 slur_strs.append ("\\>")
1104 elif s == r'-?\\!':
1105 slur_strs.append ('\\!')
1106 return ''
1108 str = re.sub (r'@STARTCRESC@', sub_dyns, str)
1109 str = re.sub (r'-?\\!', sub_dyns, str)
1111 def sub_articulations (m, slur_strs = slur_strs):
1112 a = m.group(1)
1113 if a not in slur_strs:
1114 slur_strs.append (a)
1115 return ''
1117 str = re.sub (r"([_^-]\@ACCENT\@)", sub_articulations,
1118 str)
1119 str = re.sub (r"([_^-]\\[a-z]+)", sub_articulations,
1120 str)
1121 str = re.sub (r"([_^-][>_.+|^-])", sub_articulations,
1122 str)
1123 str = re.sub (r'([_^-]"[^"]+")', sub_articulations,
1124 str)
1126 def sub_pslurs(m, slur_strs = slur_strs):
1127 slur_strs.append (' \\)')
1128 return m.group(1)
1129 str = re.sub (r"\\\)[ ]*([a-z]+)", sub_pslurs, str)
1131 ## end of while <>
1133 suffix = ''.join (slur_strs) + ''.join (pslur_strs) \
1134 + ''.join (dyns)
1136 return '@STARTCHORD@%s@ENDCHORD@%s%s' % (str , dur_str, suffix)
1140 def sub_chords (str):
1141 simend = '>'
1142 simstart = '<'
1143 chordstart = '<<'
1144 chordend = '>>'
1145 marker_str = '%% new-chords-done %%'
1147 if re.search (marker_str,str):
1148 return str
1149 str = re.sub ('<<', '@STARTCHORD@', str)
1150 str = re.sub ('>>', '@ENDCHORD@', str)
1152 str = re.sub (r'\\<', '@STARTCRESC@', str)
1153 str = re.sub (r'\\>', '@STARTDECRESC@', str)
1154 str = re.sub (r'([_^-])>', r'\1@ACCENT@', str)
1155 str = re.sub (r'<([^<>{}]+)>', sub_chord, str)
1157 # add dash: -[, so that [<<a b>> c d] becomes
1158 # <<a b>>-[ c d]
1159 # and gets skipped by articulation_substitute
1160 str = re.sub (r'\[ *(@STARTCHORD@[^@]+@ENDCHORD@[0-9.]*)',
1161 r'\1-[', str)
1162 str = re.sub (r'\\! *(@STARTCHORD@[^@]+@ENDCHORD@[0-9.]*)',
1163 r'\1-\\!', str)
1165 str = re.sub (r'<([^?])', r'%s\1' % simstart, str)
1166 str = re.sub (r'>([^?])', r'%s\1' % simend, str)
1167 str = re.sub ('@STARTCRESC@', r'\\<', str)
1168 str = re.sub ('@STARTDECRESC@', r'\\>' ,str)
1169 str = re.sub (r'\\context *Voice *@STARTCHORD@',
1170 '@STARTCHORD@', str)
1171 str = re.sub ('@STARTCHORD@', chordstart, str)
1172 str = re.sub ('@ENDCHORD@', chordend, str)
1173 str = re.sub (r'@ACCENT@', '>', str)
1174 return str
1176 markup_start = re.compile(r"([-^_]|\\mark)\s*(#\s*'\s*)\(")
1177 musicglyph = re.compile(r"\(\s*music\b")
1178 columns = re.compile(r"\(\s*columns\b")
1179 submarkup_start = re.compile(r"\(\s*([a-zA-Z]+)")
1180 leftpar = re.compile(r"\(")
1181 rightpar = re.compile(r"\)")
1183 def text_markup (str):
1184 result = ''
1185 # Find the beginning of each markup:
1186 match = markup_start.search (str)
1187 while match:
1188 result = result + str[:match.end (1)] + " \markup"
1189 str = str[match.end( 2):]
1190 # Count matching parentheses to find the end of the
1191 # current markup:
1192 nesting_level = 0
1193 pars = re.finditer(r"[()]",str)
1194 for par in pars:
1195 if par.group () == '(':
1196 nesting_level = nesting_level + 1
1197 else:
1198 nesting_level = nesting_level - 1
1199 if nesting_level == 0:
1200 markup_end = par.end ()
1201 break
1202 # The full markup in old syntax:
1203 markup = str[:markup_end]
1204 # Modify to new syntax:
1205 markup = musicglyph.sub (r"{\\musicglyph", markup)
1206 markup = columns.sub (r"{", markup)
1207 markup = submarkup_start.sub (r"{\\\1", markup)
1208 markup = leftpar.sub ("{", markup)
1209 markup = rightpar.sub ("}", markup)
1211 result = result + markup
1212 # Find next markup
1213 str = str[markup_end:]
1214 match = markup_start.search(str)
1215 result = result + str
1216 return result
1218 def articulation_substitute (str):
1219 str = re.sub (r"""([^-])\[ *(\\?\)?[a-z]+[,']*[!?]?[0-9:]*\.*)""",
1220 r"\1 \2[", str)
1221 str = re.sub (r"""([^-])\\\) *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1222 r"\1 \2\\)", str)
1223 str = re.sub (r"""([^-\\])\) *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1224 r"\1 \2)", str)
1225 str = re.sub (r"""([^-])\\! *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
1226 r"\1 \2\\!", str)
1227 return str
1229 string_or_scheme = re.compile ('("(?:[^"\\\\]|\\\\.)*")|(#\\s*\'?\\s*\\()')
1231 # Only apply articulation_substitute () outside strings and
1232 # Scheme expressions:
1233 def smarter_articulation_subst (str):
1234 result = ''
1235 # Find the beginning of next string or Scheme expr.:
1236 match = string_or_scheme.search (str)
1237 while match:
1238 # Convert the preceding LilyPond code:
1239 previous_chunk = str[:match.start()]
1240 result = result + articulation_substitute (previous_chunk)
1241 if match.group (1): # Found a string
1242 # Copy the string to output:
1243 result = result + match.group (1)
1244 str = str[match.end(1):]
1245 else: # Found a Scheme expression. Count
1246 # matching parentheses to find its end
1247 str = str[match.start ():]
1248 nesting_level = 0
1249 pars = re.finditer(r"[()]",str)
1250 for par in pars:
1251 if par.group () == '(':
1252 nesting_level = nesting_level + 1
1253 else:
1254 nesting_level = nesting_level - 1
1255 if nesting_level == 0:
1256 scheme_end = par.end ()
1257 break
1258 # Copy the Scheme expression to output:
1259 result = result + str[:scheme_end]
1260 str = str[scheme_end:]
1261 # Find next string or Scheme expression:
1262 match = string_or_scheme.search (str)
1263 # Convert the remainder of the file
1264 result = result + articulation_substitute (str)
1265 return result
1267 def conv_relative(str):
1268 if re.search (r"\\relative", str):
1269 str= "#(ly:set-option 'old-relative)\n" + str
1271 return str
1273 @rule ((1, 9, 0), _ ("""New relative mode,
1274 Postfix articulations, new text markup syntax, new chord syntax."""))
1275 def conv (str):
1276 str = re.sub (r"#'\(\)", "@SCM_EOL@", str)
1277 str = conv_relative (str)
1278 str = sub_chords (str)
1280 str = text_markup (str)
1281 str = smarter_articulation_subst (str)
1282 str = re.sub ("@SCM_EOL@", "#'()", str)
1283 return str
1286 @rule ((1, 9, 1), _ ("Remove - before articulation"))
1287 def conv (str):
1288 if re.search ("font-style",str):
1289 stderr_write ('\n')
1290 stderr_write (NOT_SMART % "font-style")
1291 stderr_write ('\n')
1292 stderr_write (UPDATE_MANUALLY)
1293 stderr_write ('\n')
1295 raise FatalConversionError ()
1297 str = re.sub (r'-\\markup', r'@\\markup', str)
1298 str = re.sub (r'-\\', r'\\', str)
1299 str = re.sub (r'-\)', ')', str)
1300 str = re.sub (r'-\(', '(', str)
1301 str = re.sub ('-\[', '[', str)
1302 str = re.sub ('-\]', ']', str)
1303 str = re.sub ('-~', '~', str)
1304 str = re.sub (r'@\\markup', r'-\\markup', str)
1305 return str
1308 @rule ((1, 9, 2), "\\newcontext -> \\new")
1309 def conv (str):
1310 str = re.sub ('ly:set-context-property',
1311 'ly:set-context-property!', str)
1312 str = re.sub ('\\\\newcontext', '\\\\new', str)
1313 str = re.sub ('\\\\grace[\t\n ]*([^{ ]+)',
1314 r'\\grace { \1 }', str)
1315 str = re.sub ("\\\\grace[\t\n ]*{([^}]+)}",
1316 r"""\\grace {
1317 \\property Voice.Stem \\override #'stroke-style = #"grace"
1319 \\property Voice.Stem \\revert #'stroke-style }
1320 """, str)
1321 return str
1324 @rule ((1, 9, 3), (_ ("%s misspelling") % "\\acciaccatura") +
1325 ", fingerHorizontalDirection -> fingeringOrientations")
1326 def conv (str):
1327 str = re.sub ('accacciatura',
1328 'acciaccatura', str)
1330 if re.search ("context-spec-music", str):
1331 stderr_write ('\n')
1332 stderr_write (NOT_SMART % "context-spec-music")
1333 stderr_write ('\n')
1334 stderr_write (UPDATE_MANUALLY)
1335 stderr_write ('\n')
1337 raise FatalConversionError ()
1339 str = re.sub ('fingerHorizontalDirection *= *#(LEFT|-1)',
1340 "fingeringOrientations = #'(up down left)", str)
1341 str = re.sub ('fingerHorizontalDirection *= *#(RIGHT|1)',
1342 "fingeringOrientations = #'(up down right)", str)
1343 return str
1346 @rule ((1, 9, 4), _ ('Swap < > and << >>'))
1347 def conv (str):
1348 if re.search ('\\figures', str):
1349 warning (_ ("attempting automatic \\figures conversion. Check results!"));
1351 def figures_replace (m):
1352 s = m.group (1)
1353 s = re.sub ('<', '@FIGOPEN@',s)
1354 s = re.sub ('>', '@FIGCLOSE@',s)
1355 return '\\figures { %s }' % s
1357 str = re.sub (r'\\figures[ \t\n]*{([^}]+)}', figures_replace, str)
1358 str = re.sub (r'\\<', '@STARTCRESC@', str)
1359 str = re.sub (r'\\>', '@STARTDECRESC@', str)
1360 str = re.sub (r'([-^_])>', r'\1@ACCENT@', str)
1361 str = re.sub (r'<<', '@STARTCHORD@', str)
1362 str = re.sub (r'>>', '@ENDCHORD@', str)
1363 str = re.sub (r'>', '@ENDSIMUL@', str)
1364 str = re.sub (r'<', '@STARTSIMUL@', str)
1365 str = re.sub ('@STARTDECRESC@', '\\>', str)
1366 str = re.sub ('@STARTCRESC@', '\\<', str)
1367 str = re.sub ('@ACCENT@', '>', str)
1368 str = re.sub ('@ENDCHORD@', '>', str)
1369 str = re.sub ('@STARTCHORD@', '<', str)
1370 str = re.sub ('@STARTSIMUL@', '<<', str)
1371 str = re.sub ('@ENDSIMUL@', '>>', str)
1372 str = re.sub ('@FIGOPEN@', '<', str)
1373 str = re.sub ('@FIGCLOSE@', '>', str)
1374 return str
1377 @rule ((1, 9, 5), 'HaraKiriVerticalGroup -> RemoveEmptyVerticalGroup')
1378 def conv (str):
1379 str = re.sub ('HaraKiriVerticalGroup', 'RemoveEmptyVerticalGroup', str)
1380 return str
1383 @rule ((1, 9, 6), _ ('deprecate %s') % 'ly:get-font')
1384 def conv (str):
1385 if re.search ("ly:get-font", str) :
1386 stderr_write ('\n')
1387 stderr_write (NOT_SMART % "(ly:-get-font")
1388 stderr_write ('\n')
1389 stderr_write (FROM_TO \
1390 % ("(ly:paper-get-font (ly:grob-get-paper foo) .. )",
1391 "(ly:paper-get-font (ly:grob-get-paper foo) .. )"))
1392 stderr_write (UPDATE_MANUALLY)
1393 stderr_write ('\n')
1394 raise FatalConversionError ()
1396 if re.search ("\\pitch *#", str) :
1397 stderr_write ('\n')
1398 stderr_write (NOT_SMART % "\\pitch")
1399 stderr_write ('\n')
1400 stderr_write (_ ("Use Scheme code to construct arbitrary note events."))
1401 stderr_write ('\n')
1403 raise FatalConversionError ()
1404 return str
1407 @rule ((1, 9, 7), _ ('''use symbolic constants for alterations,
1408 remove \\outputproperty, move ly:verbose into ly:get-option'''))
1409 def conv (str):
1410 def sub_alteration (m):
1411 alt = m.group (3)
1412 alt = {
1413 '-1': 'FLAT',
1414 '-2': 'DOUBLE-FLAT',
1415 '0': 'NATURAL',
1416 '1': 'SHARP',
1417 '2': 'DOUBLE-SHARP',
1418 }[alt]
1420 return '(ly:make-pitch %s %s %s)' % (m.group(1), m.group (2),
1421 alt)
1423 str =re.sub ("\\(ly:make-pitch *([0-9-]+) *([0-9-]+) *([0-9-]+) *\\)",
1424 sub_alteration, str)
1427 str = re.sub ("ly:verbose", "ly:get-option 'verbose", str)
1429 m= re.search ("\\\\outputproperty #([^#]+)[\t\n ]*#'([^ ]+)", str)
1430 if m:
1431 stderr_write (_ (\
1432 r"""\outputproperty found,
1433 Please hand-edit, using
1435 \applyoutput #(outputproperty-compatibility %s '%s <GROB PROPERTY VALUE>)
1437 as a substitution text.""") % (m.group (1), m.group (2)) )
1438 raise FatalConversionError ()
1440 if re.search ("ly:(make-pitch|pitch-alteration)", str) \
1441 or re.search ("keySignature", str):
1442 stderr_write ('\n')
1443 stderr_write (NOT_SMART % "pitches")
1444 stderr_write ('\n')
1445 stderr_write (
1446 _ ("""The alteration field of Scheme pitches was multiplied by 2
1447 to support quarter tone accidentals. You must update the following constructs manually:
1449 * calls of ly:make-pitch and ly:pitch-alteration
1450 * keySignature settings made with \property
1451 """))
1452 raise FatalConversionError ()
1453 return str
1456 @rule ((1, 9, 8), "dash-length -> dash-fraction")
1457 def conv (str):
1458 if re.search ("dash-length",str):
1459 stderr_write ('\n')
1460 stderr_write (NOT_SMART % "dash-length")
1461 stderr_write ('\n')
1462 stderr_write (FROM_TO % ("dash-length", "dash-fraction"))
1463 stderr_write ('\n')
1464 stderr_write (UPDATE_MANUALLY)
1465 stderr_write ('\n')
1466 raise FatalConversionError ()
1467 return str
1470 @rule ((2, 1, 1), "font-relative-size -> font-size")
1471 def conv (str):
1472 def func(match):
1473 return "#'font-size = #%d" % (2*int (match.group (1)))
1475 str =re.sub (r"#'font-relative-size\s*=\s*#\+?([0-9-]+)", func, str)
1476 str =re.sub (r"#'font-family\s*=\s*#'ancient",
1477 r"#'font-family = #'music", str)
1478 return str
1481 @rule ((2, 1, 2), "ly:get-music-length -> ly:music-length")
1482 def conv (str):
1483 str =re.sub (r"ly:get-music-length", "ly:music-length", str)
1484 return str
1487 @rule ((2, 1, 3), "stanza -> instrument")
1488 def conv (str):
1489 str =re.sub (r"\.\s+stz=", ". instr ", str)
1490 return str
1493 @rule ((2, 1, 4), _ ("removal of automaticMelismata; use melismaBusyProperties instead."))
1494 def conv (str):
1495 def func (match):
1496 c = match.group (1)
1497 b = match.group (2)
1499 if b == 't':
1500 if c == 'Score':
1501 return ''
1502 else:
1503 return r" \property %s.melismaBusyProperties \unset" % c
1504 elif b == 'f':
1505 return r"\property %s.melismaBusyProperties = #'(melismaBusy)" % c
1507 str = re.sub (r"\\property ([a-zA-Z]+)\s*\.\s*automaticMelismata\s*=\s*##([ft])", func, str)
1508 return str
1511 @rule ((2, 1, 7), "\\translator Staff -> \\change Staff")
1512 def conv (str):
1513 str =re.sub (r"\\translator\s+([a-zA-Z]+)", r"\\change \1", str)
1514 return str
1517 @rule ((2, 1, 10), "\\newaddlyrics -> \\lyricsto")
1518 def conv (str):
1519 str =re.sub (r"\\newaddlyrics", r"\\lyricsto", str)
1520 return str
1523 @rule ((2, 1, 11), """\\include "paper16.ly" -> #(set-staff-size 16)
1524 \\note #3 #1 #1 -> \\note #"8." #1
1525 """)
1526 def conv (str):
1527 str = re.sub (r'\\include\s*"paper([0-9]+)(-init)?.ly"',
1528 r"#(set-staff-size \1)", str)
1530 def sub_note (match):
1531 dur = ''
1532 log = int (match.group (1))
1533 dots = int (match.group (2))
1535 if log >= 0:
1536 dur = '%d' % (1 << log)
1537 else:
1538 dur = { -1 : 'breve',
1539 -2 : 'longa',
1540 -3 : 'maxima'}[log]
1542 dur += ('.' * dots)
1544 return r'\note #"%s" #%s' % (dur, match.group (3))
1546 str = re.sub (r'\\note\s+#([0-9-]+)\s+#([0-9]+)\s+#([0-9.-]+)',
1547 sub_note, str)
1548 return str
1551 @rule ((2, 1, 12), "OttavaSpanner -> OttavaBracket")
1552 def conv (str):
1553 str = re.sub (r"OttavaSpanner", r"OttavaBracket", str)
1554 return str
1557 @rule ((2, 1, 13), "set-staff-size -> set-global-staff-size")
1558 def conv (str):
1559 str = re.sub (r"\(set-staff-size ", r"(set-global-staff-size ", str)
1560 return str
1563 @rule ((2, 1, 14), "style = dotted -> dash-fraction = 0")
1564 def conv (str):
1565 str = re.sub (r"#'style\s*=\s*#'dotted-line",
1566 r"#'dash-fraction = #0.0 ", str)
1567 return str
1570 @rule ((2, 1, 15), "LyricsVoice . instr(ument) -> vocalName")
1571 def conv (str):
1572 str = re.sub (r'LyricsVoice\s*\.\s*instrument\s*=\s*("[^"]*")',
1573 r'LyricsVoice . vocalName = \1', str)
1575 str = re.sub (r'LyricsVoice\s*\.\s*instr\s*=\s*("[^"]*")',
1576 r'LyricsVoice . vocNam = \1', str)
1577 return str
1580 @rule ((2, 1, 16), '\\musicglyph #"accidentals-NUM" -> \\sharp/flat/etc.')
1581 def conv (str):
1582 def sub_acc (m):
1583 d = {
1584 '4': 'doublesharp',
1585 '3': 'threeqsharp',
1586 '2': 'sharp',
1587 '1': 'semisharp',
1588 '0': 'natural',
1589 '-1': 'semiflat',
1590 '-2': 'flat',
1591 '-3': 'threeqflat',
1592 '-4': 'doubleflat'}
1593 return '\\%s' % d[m.group (1)]
1595 str = re.sub (r'\\musicglyph\s*#"accidentals-([0-9-]+)"',
1596 sub_acc, str)
1597 return str
1600 @rule ((2, 1, 17), _ ("\\partcombine syntax change to \\newpartcombine"))
1601 def conv (str):
1603 if re.search (r'\\partcombine', str):
1604 stderr_write ('\n')
1605 stderr_write (NOT_SMART % "\\partcombine")
1606 stderr_write ('\n')
1607 stderr_write (UPDATE_MANUALLY)
1608 stderr_write ('\n')
1609 raise FatalConversionError ()
1611 # this rule doesn't really work,
1612 # too lazy to figure out why.
1613 str = re.sub (r'\\context\s+Voice\s*=\s*one\s*\\partcombine\s+Voice\s*\\context\s+Thread\s*=\s*one(.*)\s*'
1614 + r'\\context\s+Thread\s*=\s*two',
1615 '\\\\newpartcombine\n\\1\n', str)
1616 return str
1619 @rule ((2, 1, 18), """\\newpartcombine -> \\partcombine,
1620 \\autochange Staff -> \\autochange
1621 """)
1622 def conv (str):
1623 str = re.sub (r'\\newpartcombine', r'\\partcombine', str)
1624 str = re.sub (r'\\autochange\s+Staff', r'\\autochange ', str)
1625 return str
1628 @rule ((2, 1, 19), _ ("""Drum notation changes, Removing \\chordmodifiers, \\notenames.
1629 Harmonic notes. Thread context removed. Lyrics context removed."""))
1630 def conv (str):
1631 if re.search ('include "drumpitch', str):
1632 stderr_write (_ ("Drums found. Enclose drum notes in \\drummode"))
1634 str = re.sub (r'\\include "drumpitch-init.ly"','', str)
1636 str = re.sub (r'\\pitchnames ','pitchnames = ', str)
1637 str = re.sub (r'\\chordmodifiers ','chordmodifiers = ', str)
1638 str = re.sub (r'\bdrums\b\s*=','drumContents = ', str)
1639 str = re.sub (r'\\drums\b','\\drumContents ', str)
1642 if re.search ('drums->paper', str):
1643 stderr_write (_ ("\n%s found. Check file manually!\n") % _("Drum notation"))
1645 str = re.sub (r"""\\apply\s+#\(drums->paper\s+'([a-z]+)\)""",
1646 r"""\property DrumStaff.drumStyleTable = #\1-style""",
1647 str)
1649 if re.search ('Thread', str):
1650 stderr_write (_ ("\n%s found. Check file manually!\n") % "Thread");
1652 str = re.sub (r"""(\\once\s*)?\\property\s+Thread\s*\.\s*NoteHead\s*"""
1653 + r"""\\(set|override)\s*#'style\s*=\s*#'harmonic"""
1654 + r"""\s+([a-z]+[,'=]*)([0-9]*\.*)"""
1655 ,r"""<\3\\harmonic>\4""", str)
1657 str = re.sub (r"""\\new Thread""", """\context Voice""", str)
1658 str = re.sub (r"""Thread""", """Voice""", str)
1660 if re.search ('\bLyrics\b', str):
1661 stderr_write (_ ("\n%s found. Check file manually!\n") % "Lyrics");
1663 str = re.sub (r"""LyricsVoice""", r"""L@ricsVoice""", str)
1664 str = re.sub (r"""\bLyrics\b""", r"""LyricsVoice""", str)
1665 str = re.sub (r"""LyricsContext""", r"""LyricsVoiceContext""", str)
1666 str = re.sub (r"""L@ricsVoice""", r"""LyricsVoice""",str)
1667 return str
1670 @rule ((2, 1, 20), "nonevent-skip -> skip-music")
1671 def conv (str):
1672 str = re.sub (r'nonevent-skip', 'skip-music', str)
1673 return str
1676 @rule ((2, 1, 21), """molecule-callback -> print-function,
1677 brew_molecule -> print
1678 brew-new-markup-molecule -> Text_item::print
1679 LyricsVoice -> Lyrics
1680 tupletInvisible -> TupletBracket \set #'transparent
1682 """ % (_ ("remove %s") % "Grob::preset_extent"))
1683 def conv (str):
1684 str = re.sub (r'molecule-callback', 'print-function', str)
1685 str = re.sub (r'brew_molecule', 'print', str)
1686 str = re.sub (r'brew-new-markup-molecule', 'Text_item::print', str)
1687 str = re.sub (r'LyricsVoice', 'Lyrics', str)
1688 str = re.sub (r'tupletInvisible',
1689 r"TupletBracket \\set #'transparent", str)
1690 # str = re.sub (r'molecule', 'collage', str)
1691 #molecule -> collage
1692 str = re.sub (r"\\property\s+[a-zA-Z]+\s*\.\s*[a-zA-Z]+\s*"
1693 + r"\\set\s*#'X-extent-callback\s*=\s*#Grob::preset_extent",
1694 "", str)
1695 return str
1698 @rule ((2, 1, 22), """%s
1699 \\set A.B = #C , \\unset A.B
1700 \\override A.B #C = #D, \\revert A.B #C
1702 """ % _ ("new syntax for property settings:"))
1703 def conv (str):
1704 str = re.sub (r'(\\property[^=]+)=\s*([-0-9]+)',
1705 r'\1= #\2', str)
1706 str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\=]+)\s*\\(set|override)',
1707 r"\\overrid@ \1.\2 ", str)
1708 str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\= ]+)\s*=\s*',
1709 r'\\s@t \1.\2 = ', str)
1710 str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\= ]+)\s*\\unset',
1711 r'\\uns@t \1.\2 ', str)
1712 str = re.sub (r'\\property\s+([^. ]+)\s*\.\s*([^\\= ]+)\s*\\revert'
1713 + r"\s*#'([-a-z0-9_]+)",
1714 r"\\rev@rt \1.\2 #'\3", str)
1715 str = re.sub (r'Voice\.', '', str)
1716 str = re.sub (r'Lyrics\.', '', str)
1717 str = re.sub (r'ChordNames\.', '', str)
1719 str = re.sub ('rev@rt', 'revert',str)
1720 str = re.sub ('s@t', 'set',str)
1721 str = re.sub ('overrid@', 'override',str)
1723 str = re.sub ('molecule', 'stencil', str)
1724 str = re.sub ('Molecule', 'Stencil', str)
1725 return str
1728 @rule ((2, 1, 23), _ ("Property setting syntax in \\translator{ }"))
1729 def conv (str):
1730 def subst_in_trans (match):
1731 s = match.group (0)
1732 s = re.sub (r'\s([a-zA-Z]+)\s*\\override',
1733 r' \\override \1', s)
1734 s = re.sub (r'\s([a-zA-Z]+)\s*\\set',
1735 r' \\override \1', s)
1736 s = re.sub (r'\s([a-zA-Z]+)\s*\\revert',
1737 r' \\revert \1', s)
1738 return s
1739 str = re.sub (r'\\(translator|with)\s*{[^}]+}', subst_in_trans, str)
1741 def sub_abs (m):
1743 context = m.group ('context')
1744 d = m.groupdict ()
1745 if context:
1746 context = " '%s" % context[:-1] # -1: remove .
1747 else:
1748 context = ''
1750 d['context'] = context
1752 return r"""#(override-auto-beam-setting %(prop)s %(num)s %(den)s%(context)s)""" % d
1754 str = re.sub (r"""\\override\s*(?P<context>[a-zA-Z]+\s*\.\s*)?autoBeamSettings"""
1755 +r"""\s*#(?P<prop>[^=]+)\s*=\s*#\(ly:make-moment\s+(?P<num>\d+)\s+(?P<den>\d)\s*\)""",
1756 sub_abs, str)
1757 return str
1760 @rule ((2, 1, 24), "music-list? -> ly:music-list?")
1761 def conv (str):
1762 str = re.sub (r'music-list\?', 'ly:music-list?', str)
1763 str = re.sub (r'\|\s*~', '~ |', str)
1764 return str
1767 @rule ((2, 1, 25), _ ("Scheme grob function renaming"))
1768 def conv (str):
1769 str = re.sub (r'ly:get-spanner-bound', 'ly:spanner-get-bound', str)
1770 str = re.sub (r'ly:get-extent', 'ly:grob-extent', str)
1771 str = re.sub (r'ly:get-system', 'ly:grob-system', str)
1772 str = re.sub (r'ly:get-original', 'ly:grob-original', str)
1773 str = re.sub (r'ly:get-parent', 'ly:grob-parent', str)
1774 str = re.sub (r'ly:get-broken-into', 'ly:spanner-broken-into', str)
1775 str = re.sub (r'Melisma_engraver', 'Melisma_translator', str)
1776 if re.search ("ly:get-paper-variable", str):
1777 stderr_write ('\n')
1778 stderr_write (NOT_SMART % "ly:paper-get-variable")
1779 stderr_write ('\n')
1780 stderr_write (_ ('use %s') % '(ly:paper-lookup (ly:grob-paper ))')
1781 stderr_write ('\n')
1782 raise FatalConversionError ()
1784 str = re.sub (r'\\defaultAccidentals', "#(set-accidental-style 'default)", str)
1785 str = re.sub (r'\\voiceAccidentals', "#(set-accidental-style 'voice)", str)
1786 str = re.sub (r'\\modernAccidentals', "#(set-accidental-style 'modern)", str)
1787 str = re.sub (r'\\modernCautionaries', "#(set-accidental-style 'modern-cautionary)", str)
1788 str = re.sub (r'\\modernVoiceAccidental', "#(set-accidental-style 'modern-voice)", str)
1789 str = re.sub (r'\\modernVoiceCautionaries', "#(set-accidental-style 'modern-voice-cautionary)", str)
1790 str = re.sub (r'\\pianoAccidentals', "#(set-accidental-style 'piano)", str)
1791 str = re.sub (r'\\pianoCautionaries', "#(set-accidental-style 'piano-cautionary)", str)
1792 str = re.sub (r'\\forgetAccidentals', "#(set-accidental-style 'forget)", str)
1793 str = re.sub (r'\\noResetKey', "#(set-accidental-style 'no-reset)", str)
1794 return str
1797 @rule ((2, 1, 26), _ ("More Scheme function renaming"))
1798 def conv (str):
1799 str = re.sub ('ly:set-grob-property!', 'ly:grob-set-property!',str)
1800 str = re.sub ('ly:set-mus-property!', 'ly:music-set-property!',str)
1801 str = re.sub ('ly:set-context-property!', 'ly:context-set-property!', str)
1802 str = re.sub ('ly:get-grob-property', 'ly:grob-property',str)
1803 str = re.sub ('ly:get-mus-property', 'ly:music-property',str)
1804 str = re.sub ('ly:get-context-property', 'ly:context-property',str)
1805 return str
1808 @rule ((2, 1, 27), "property transposing -> tuning")
1809 def conv (str):
1810 def subst (m):
1811 g = int (m.group (2))
1812 o = g / 12
1813 g -= o * 12
1814 if g < 0:
1815 g += 12
1816 o -= 1
1819 lower_pitches = filter (lambda x : x <= g, [0, 2, 4, 5, 7, 9, 11, 12])
1820 s = len (lower_pitches) -1
1821 a = g - lower_pitches [-1]
1824 print s , lower_pitches, g, a, s
1825 str = 'cdefgab' [s]
1826 str += ['eses', 'es', '', 'is', 'isis'][a + 2]
1827 if o < 0:
1828 str += ',' * (-o - 1)
1829 elif o >= 0:
1830 str += "'" * (o + 1)
1832 return '\\transposition %s ' % str
1835 str = re.sub (r"\\set ([A-Za-z]+\s*\.\s*)?transposing\s*=\s*#([-0-9]+)",
1836 subst, str)
1837 return str
1840 @rule ((2, 1, 28), """make-music-by-name -> make-music,
1841 new syntax for setting \\arpeggioBracket""")
1842 def conv (str):
1843 str = re.sub (r'make-music-by-name', 'make-music', str)
1844 str = re.sub (r"\\override\s+.*Arpeggio\s+#.print-function\s+=\s+\\arpeggioBracket", r"\\arpeggioBracket", str)
1845 return str
1848 @rule ((2, 1, 29), '\\center -> \\center-align, \\translator -> \\context')
1849 def conv (str):
1850 str = re.sub (r'\\center([^-])', '\\center-align\\1', str)
1851 str = re.sub (r'\\translator', '\\context', str)
1852 return str
1855 @rule ((2, 1, 30), '''\\threeq{flat,sharp} -> \\sesqui{flat,sharp}
1856 ly:get-mutable-properties -> ly:mutable-music-properties
1857 centralCPosition -> middleCPosition
1858 ly:unset-context-property -> ly:context-unset-property
1859 ly:translator-find -> ly:context-find
1860 ly:get-stencil-extent -> ly:stencil-extent
1861 ''')
1862 def conv (str):
1863 str = re.sub (r'\\threeq(flat|sharp)', r'\\sesqui\1', str)
1864 str = re.sub (r'ly:stencil-get-extent',
1865 'ly:stencil-extent', str)
1866 str = re.sub (r'ly:translator-find',
1867 'ly:context-find', str)
1868 str = re.sub ('ly:unset-context-property','ly:context-unset-property',
1869 str)
1871 str = re.sub (r'ly:get-mutable-properties',
1872 'ly:mutable-music-properties',str)
1873 str = re.sub (r'centralCPosition',
1874 'middleCPosition',str)
1875 return str
1878 @rule ((2, 1, 31), 'remove \\alias Timing')
1879 def conv (str):
1880 str = re.sub (r'\\alias\s*"?Timing"?', '', str)
1881 return str
1884 @rule ((2, 1, 33), 'breakAlignOrder -> break-align-orders.')
1885 def conv (str):
1886 str = re.sub (r"(\\set\s+)?(?P<context>(Score\.)?)breakAlignOrder\s*=\s*#'(?P<list>[^\)]+)",
1887 r"\n\\override \g<context>BreakAlignment #'break-align-orders = "
1888 + "#(make-vector 3 '\g<list>)", str)
1889 return str
1892 @rule ((2, 1, 34), 'set-paper-size -> set-default-paper-size.')
1893 def conv (str):
1894 str = re.sub (r"\(set-paper-size",
1895 "(set-default-paper-size",str)
1896 return str
1899 @rule ((2, 1, 36), 'ly:mutable-music-properties -> ly:music-mutable-properties')
1900 def conv (str):
1901 str = re.sub (r"ly:mutable-music-properties",
1902 "ly:music-mutable-properties", str)
1903 return str
1906 @rule ((2, 2, 0), _ ("bump version for release"))
1907 def conv (str):
1908 return str
1911 @rule ((2, 3, 1), '\\apply -> \\applymusic')
1912 def conv (str):
1913 return re.sub (r'\\apply\b', r'\\applymusic', str)
1916 @rule ((2, 3, 2), '\\FooContext -> \\Foo')
1917 def conv (str):
1918 if re.search ('textheight', str):
1919 stderr_write ('\n')
1920 stderr_write (NOT_SMART % "textheight")
1921 stderr_write ('\n')
1922 stderr_write (UPDATE_MANUALLY)
1923 stderr_write ('\n')
1924 stderr_write (
1925 _ ("""Page layout has been changed, using paper size and margins.
1926 textheight is no longer used.
1927 """))
1928 str = re.sub (r'\\OrchestralScoreContext', '\\Score', str)
1929 def func(m):
1930 if m.group(1) not in ['RemoveEmptyStaff',
1931 'AncientRemoveEmptyStaffContext',
1932 'EasyNotation']:
1933 return '\\' + m.group (1)
1934 else:
1935 return m.group (0)
1938 str = re.sub (r'\\([a-zA-Z]+)Context\b', func, str)
1939 str = re.sub ('ly:paper-lookup', 'ly:output-def-lookup', str)
1940 return str
1943 @rule ((2, 3, 4), _ ('remove %s') % '\\notes')
1944 def conv (str):
1945 str = re.sub (r'\\notes\b', '', str)
1946 return str
1949 @rule ((2, 3, 6), 'lastpagefill -> raggedlastbottom')
1950 def conv (str):
1951 str = re.sub (r'lastpagefill\s*=\s*"?1"', 'raggedlastbottom = ##t', str)
1952 return str
1955 @rule ((2, 3, 8), 'remove \\consistsend, strip \\lyrics from \\lyricsto.')
1956 def conv (str):
1957 str = re.sub (r'\\consistsend', '\\consists', str)
1958 str = re.sub (r'\\lyricsto\s+("?[a-zA-Z]+"?)(\s*\\new Lyrics\s*)?\\lyrics',
1959 r'\\lyricsto \1 \2', str)
1960 return str
1963 @rule ((2, 3, 9), 'neo_mensural -> neomensural, if-text-padding -> bound-padding')
1964 def conv (str):
1965 str = re.sub (r'neo_mensural', 'neomensural', str)
1966 str = re.sub (r'if-text-padding', 'bound-padding', str)
1967 return str
1970 @rule ((2, 3, 10), '\\addlyrics -> \\oldaddlyrics, \\newlyrics -> \\addlyrics')
1971 def conv (str):
1972 str = re.sub (r'\\addlyrics', r'\\oldaddlyrics', str)
1973 str = re.sub (r'\\newlyrics', r'\\addlyrics', str)
1974 if re.search (r"\\override\s*TextSpanner", str):
1975 stderr_write ("\nWarning: TextSpanner has been split into DynamicTextSpanner and TextSpanner\n")
1976 return str
1979 @rule ((2, 3, 11), '\\setMmRestFermata -> ^\\fermataMarkup')
1980 def conv (str):
1981 str = re.sub (r'\\setMmRestFermata\s+(R[0-9.*/]*)',
1982 r'\1^\\fermataMarkup', str)
1983 return str
1986 @rule ((2, 3, 12), '''\\newpage -> \\pageBreak, junk \\script{up,down,both},
1987 soloADue -> printPartCombineTexts, #notes-to-clusters -> \\makeClusters
1988 ''')
1989 def conv (str):
1990 str = re.sub (r'\\newpage', r'\\pageBreak', str)
1991 str = re.sub (r'\\scriptUp', r"""{
1992 \\override TextScript #'direction = #1
1993 \\override Script #'direction = #1
1994 }""", str)
1995 str = re.sub (r'\\scriptDown', r"""{
1996 \\override TextScript #'direction = #-1
1997 \\override Script #'direction = #-1
1998 }""", str)
1999 str = re.sub (r'\\scriptBoth', r"""{
2000 \\revert TextScript #'direction
2001 \\revert Script #'direction
2002 }""", str)
2003 str = re.sub ('soloADue', 'printPartCombineTexts', str)
2004 str = re.sub (r'\\applymusic\s*#notes-to-clusters',
2005 '\\makeClusters', str)
2007 str = re.sub (r'pagenumber\s*=', 'firstpagenumber = ', str)
2008 return str
2011 @rule ((2, 3, 16), _ ('''\\foo -> \\foomode (for chords, notes, etc.)
2012 fold \\new FooContext \\foomode into \\foo.'''))
2013 def conv (str):
2014 str = re.sub (r'\\chords\b', r'\\chordmode', str)
2015 str = re.sub (r'\\lyrics\b', r'\\lyricmode', str)
2016 str = re.sub (r'\\figures\b', r'\\figuremode', str)
2017 str = re.sub (r'\\notes\b', r'\\notemode', str)
2018 str = re.sub (r'\\drums\b', r'\\drummode', str)
2019 str = re.sub (r'\\chordmode\s*\\new ChordNames', r'\\chords', str)
2020 str = re.sub (r'\\new ChordNames\s*\\chordmode', r'\\chords', str)
2021 str = re.sub (r'\\new FiguredBass\s*\\figuremode', r'\\figures', str)
2022 str = re.sub (r'\\figuremode\s*\new FiguredBass', r'\\figures', str)
2023 str = re.sub (r'\\new DrumStaff\s*\\drummode', r'\\drums', str)
2024 str = re.sub (r'\\drummode\s*\\new DrumStaff', r'\\drums', str)
2026 return str
2029 @rule ((2, 3, 17), '''slurBoth -> slurNeutral, stemBoth -> stemNeutral, etc.
2030 \\applymusic #(remove-tag 'foo) -> \\removeWithTag 'foo''')
2031 def conv (str):
2032 str = re.sub (r'(slur|stem|phrasingSlur|tie|dynamic|dots|tuplet|arpeggio|)Both', r'\1Neutral', str)
2033 str = re.sub (r"\\applymusic\s*#\(remove-tag\s*'([a-z-0-9]+)\)",
2034 r"\\removeWithTag #'\1", str)
2035 return str
2038 @rule ((2, 3, 18), 'Text_item -> Text_interface')
2039 def conv (str):
2040 str = re.sub (r'Text_item', 'Text_interface', str)
2041 return str
2044 @rule ((2, 3, 22), 'paper -> layout, bookpaper -> paper')
2045 def conv (str):
2046 str = re.sub (r'\\paper', r'\\layout', str)
2047 str = re.sub (r'\\bookpaper', r'\\paper', str)
2048 if re.search ('paper-set-staff-size', str):
2049 warning (_ ('''staff size should be changed at top-level
2050 with
2052 #(set-global-staff-size <STAFF-HEIGHT-IN-POINT>)
2054 '''))
2057 str = re.sub (r'#\(paper-set-staff-size', '%Use set-global-staff-size at toplevel\n% #(layout-set-staff-size', str)
2058 return str
2061 @rule ((2, 3, 23), r'\context Foo = NOTENAME -> \context Foo = "NOTENAME"')
2062 def conv (str):
2063 str = re.sub (r'\\context\s+([a-zA-Z]+)\s*=\s*([a-z]+)\s',
2064 r'\\context \1 = "\2" ',
2065 str )
2066 return str
2069 @rule ((2, 3, 24), _ ('''regularize other identifiers'''))
2070 def conv (str):
2071 def sub(m):
2072 return regularize_id (m.group (1))
2073 str = re.sub (r'(maintainer_email|maintainer_web|midi_stuff|gourlay_maxmeasures)',
2074 sub, str)
2075 return str
2078 @rule ((2, 3, 25), 'petrucci_c1 -> petrucci-c1, 1style -> single-digit')
2079 def conv (str):
2080 str = re.sub ('petrucci_c1', 'petrucci-c1', str)
2081 str = re.sub ('1style', 'single-digit', str)
2082 return str
2085 @rule ((2, 4, 0), _ ("bump version for release"))
2086 def conv (str):
2087 return str
2090 @rule ((2, 5, 0), '\\quote -> \\quoteDuring')
2091 def conv (str):
2092 str = re.sub (r'\\quote\s+"?([a-zA-Z0-9]+)"?\s+([0-9.*/]+)',
2093 r'\\quoteDuring #"\1" { \skip \2 }',
2094 str)
2095 return str
2098 @rule ((2, 5, 1), 'ly:import-module -> ly:module-copy')
2099 def conv (str):
2100 str = re.sub (r'ly:import-module',
2101 r'ly:module-copy', str)
2102 return str
2105 @rule ((2, 5, 2), '\markup .. < .. > .. -> \markup .. { .. } ..')
2106 def conv (str):
2107 str = re.sub (r'\\(column|fill-line|dir-column|center-align|right-align|left-align|bracketed-y-column)\s*<(([^>]|<[^>]*>)*)>',
2108 r'\\\1 {\2}', str)
2109 str = re.sub (r'\\(column|fill-line|dir-column|center-align|right-align|left-align|bracketed-y-column)\s*<(([^>]|<[^>]*>)*)>',
2110 r'\\\1 {\2}', str)
2111 str = re.sub (r'\\(column|fill-line|dir-column|center-align|right-align|left-align|bracketed-y-column)\s*<(([^>]|<[^>]*>)*)>',
2112 r'\\\1 {\2}', str)
2113 def get_markup (m):
2114 s = m.group (0)
2115 s = re.sub (r'''((\\"|})\s*){''', '\2 \\line {', s)
2116 return s
2117 str = re.sub (r'\\markup\s*{([^}]|{[^}]*})*}', get_markup, str)
2118 return str
2121 @rule ((2, 5, 3), 'ly:find-glyph-by-name -> ly:font-get-glyph, remove - from glyphnames.')
2122 def conv (str):
2123 str = re.sub ('ly:find-glyph-by-name', 'ly:font-get-glyph', str)
2124 str = re.sub ('"(scripts|clefs|accidentals)-', r'"\1.', str)
2125 str = re.sub ("'hufnagel-do-fa", "'hufnagel.do.fa", str)
2126 str = re.sub ("'(vaticana|hufnagel|medicaea|petrucci|neomensural|mensural)-", r"'\1.", str)
2127 return str
2130 @rule ((2, 5, 12), '\set Slur #\'dashed = #X -> \slurDashed')
2131 def conv (str):
2132 str = re.sub (r"\\override\s+(Voice\.)?Slur #'dashed\s*=\s*#\d*(\.\d+)?",
2133 r"\\slurDashed", str)
2134 return str
2137 @rule ((2, 5, 13), _ ('\\encoding: smart recode latin1..utf-8. Remove ly:point-and-click'))
2138 def conv (str):
2139 input_encoding = 'latin1'
2140 def func (match):
2141 encoding = match.group (1)
2143 # FIXME: automatic recoding of other than latin1?
2144 if encoding == 'latin1':
2145 return match.group (2)
2147 stderr_write ('\n')
2148 stderr_write (NOT_SMART % ("\\encoding: %s" % encoding))
2149 stderr_write ('\n')
2150 stderr_write (_ ("LilyPond source must be UTF-8"))
2151 stderr_write ('\n')
2152 if encoding == 'TeX':
2153 stderr_write (_ ("Try the texstrings backend"))
2154 stderr_write ('\n')
2155 else:
2156 stderr_write ( _("Do something like: %s") % \
2157 ("recode %s..utf-8 FILE" % encoding))
2158 stderr_write ('\n')
2159 stderr_write (_ ("Or save as UTF-8 in your editor"))
2160 stderr_write ('\n')
2161 raise FatalConversionError ()
2163 return match.group (0)
2165 str = re.sub (r'\\encoding\s+"?([a-zA-Z0-9]+)"?(\s+)', func, str)
2167 import codecs
2168 de_ascii = codecs.getdecoder ('ascii')
2169 de_utf_8 = codecs.getdecoder ('utf_8')
2170 de_input = codecs.getdecoder (input_encoding)
2171 en_utf_8 = codecs.getencoder ('utf_8')
2172 try:
2173 de_ascii (str)
2174 # only in python >= 2.3
2175 # except UnicodeDecodeError:
2176 except UnicodeError:
2177 # do not re-recode UTF-8 input
2178 try:
2179 de_utf_8 (str)
2180 #except UnicodeDecodeError:
2181 except UnicodeError:
2182 str = en_utf_8 (de_input (str)[0])[0]
2186 str = re.sub (r"#\(ly:set-point-and-click '[a-z-]+\)", '', str)
2187 return str
2190 @rule ((2, 5, 17), _ ('remove %s') % 'ly:stencil-set-extent!')
2191 def conv (str):
2192 if re.search ("ly:stencil-set-extent!", str):
2193 stderr_write ('\n')
2194 stderr_write (NOT_SMART % "ly:stencil-set-extent!")
2195 stderr_write ('\n')
2196 stderr_write ('use (set! VAR (ly:make-stencil (ly:stencil-expr VAR) X-EXT Y-EXT))\n')
2197 raise FatalConversionError ()
2198 if re.search ("ly:stencil-align-to!", str):
2199 stderr_write ('\n')
2200 stderr_write (NOT_SMART % "ly:stencil-align-to!")
2201 stderr_write ('\n')
2202 stderr_write ('use (set! VAR (ly:stencil-aligned-to VAR AXIS DIR))\n')
2203 raise FatalConversionError ()
2204 return str
2207 @rule ((2, 5, 18), 'ly:warn -> ly:warning')
2208 def conv (str):
2209 str = re.sub (r"ly:warn\b", 'ly:warning', str)
2210 return str
2213 @rule ((2, 5, 21), _ ('warn about auto beam settings'))
2214 def conv (str):
2215 if re.search ("(override-|revert-)auto-beam-setting", str)\
2216 or re.search ("autoBeamSettings", str):
2217 stderr_write ('\n')
2218 stderr_write (NOT_SMART % _ ("auto beam settings"))
2219 stderr_write ('\n')
2220 stderr_write (_ ('''
2221 Auto beam settings must now specify each interesting moment in a measure
2222 explicitely; 1/4 is no longer multiplied to cover moments 1/2 and 3/4 too.
2223 '''))
2224 stderr_write (UPDATE_MANUALLY)
2225 stderr_write ('\n')
2226 raise FatalConversionError ()
2227 return str
2230 @rule ((2, 5, 25), 'unfoldrepeats -> unfoldRepeats, compressmusic -> compressMusic')
2231 def conv (str):
2232 str = re.sub (r"unfoldrepeats", 'unfoldRepeats', str)
2233 str = re.sub (r"compressmusic", 'compressMusic', str)
2234 return str
2237 @rule ((2, 6, 0), _ ("bump version for release"))
2238 def conv (str):
2239 return str
2242 @rule ((2, 7, 0), 'ly:get-default-font -> ly:grob-default-font')
2243 def conv (str):
2244 return re.sub('ly:get-default-font', 'ly:grob-default-font', str)
2247 @rule ((2, 7, 1), '''ly:parser-define -> ly:parser-define!
2248 excentricity -> eccentricity
2249 Timing_engraver -> Timing_translator + Default_bar_line_engraver
2250 ''')
2251 def conv (str):
2252 str = re.sub('ly:parser-define', 'ly:parser-define!', str)
2253 str = re.sub('excentricity', 'eccentricity', str)
2254 str = re.sub(r'\\(consists|remove) *"?Timing_engraver"?',
2255 r'\\\1 "Timing_translator" \\\1 "Default_bar_line_engraver"',
2256 str)
2257 return str
2260 @rule ((2, 7, 2), 'ly:X-moment -> ly:moment-X')
2261 def conv (str):
2262 str = re.sub('ly:(add|mul|mod|div)-moment', r'ly:moment-\1', str)
2263 return str
2266 @rule ((2, 7, 4), 'keyAccidentalOrder -> keyAlterationOrder')
2267 def conv (str):
2268 str = re.sub('keyAccidentalOrder', 'keyAlterationOrder', str)
2269 return str
2272 @rule ((2, 7, 6), '''Performer_group_performer -> Performer_group, Engraver_group_engraver -> Engraver_group,
2273 inside-slur -> avoid-slur''')
2274 def conv (str):
2275 str = re.sub('Performer_group_performer', 'Performer_group', str)
2276 str = re.sub('Engraver_group_engraver', 'Engraver_group', str)
2277 str = re.sub (r"#'inside-slur\s*=\s*##t *",
2278 r"#'avoid-slur = #'inside ", str)
2279 str = re.sub (r"#'inside-slur\s*=\s*##f *",
2280 r"#'avoid-slur = #'around ", str)
2281 str = re.sub (r"#'inside-slur",
2282 r"#'avoid-slur", str)
2283 return str
2286 @rule ((2, 7, 10), '\\applyxxx -> \\applyXxx')
2287 def conv (str):
2288 str = re.sub(r'\\applyoutput', r'\\applyOutput', str)
2289 str = re.sub(r'\\applycontext', r'\\applyContext', str)
2290 str = re.sub(r'\\applymusic', r'\\applyMusic', str)
2291 str = re.sub(r'ly:grob-suicide', 'ly:grob-suicide!', str)
2292 return str
2295 @rule ((2, 7, 11), '"tabloid" -> "11x17"')
2296 def conv (str):
2297 str = re.sub(r'\"tabloid\"', '"11x17"', str)
2298 return str
2301 @rule ((2, 7, 12), 'outputProperty -> overrideProperty')
2302 def conv (str):
2303 str = re.sub(r'outputProperty' , 'overrideProperty', str)
2304 return str
2307 @rule ((2, 7, 13), 'layout engine refactoring [FIXME]')
2308 def conv (str):
2309 def subber (match):
2310 newkey = {'spacing-procedure': 'springs-and-rods',
2311 'after-line-breaking-callback' : 'after-line-breaking',
2312 'before-line-breaking-callback' : 'before-line-breaking',
2313 'print-function' : 'stencil'} [match.group(3)]
2314 what = match.group (1)
2315 grob = match.group (2)
2317 if what == 'revert':
2318 return "revert %s #'callbacks %% %s\n" % (grob, newkey)
2319 elif what == 'override':
2320 return "override %s #'callbacks #'%s" % (grob, newkey)
2321 else:
2322 raise 'urg'
2323 return ''
2325 str = re.sub(r"(override|revert)\s*([a-zA-Z.]+)\s*#'(spacing-procedure|after-line-breaking-callback"
2326 + r"|before-line-breaking-callback|print-function)",
2327 subber, str)
2329 if re.search ('bar-size-procedure', str):
2330 stderr_write (NOT_SMART % "bar-size-procedure")
2331 if re.search ('space-function', str):
2332 stderr_write (NOT_SMART % "space-function")
2333 if re.search ('verticalAlignmentChildCallback', str):
2334 stderr_write (_ ('verticalAlignmentChildCallback has been deprecated'))
2335 return str
2338 @rule ((2, 7, 14), _ ('Remove callbacks property, deprecate XY-extent-callback.'))
2339 def conv (str):
2340 str = re.sub (r"\\override +([A-Z.a-z]+) #'callbacks",
2341 r"\\override \1", str)
2342 str = re.sub (r"\\revert ([A-Z.a-z]+) #'callbacks % ([a-zA-Z]+)",
2343 r"\\revert \1 #'\2", str)
2344 str = re.sub (r"([XY]-extent)-callback", r'\1', str)
2345 str = re.sub (r"RemoveEmptyVerticalGroup", "VerticalAxisGroup", str)
2346 str = re.sub (r"\\set ([a-zA-Z]*\.?)minimumVerticalExtent",
2347 r"\\override \1VerticalAxisGroup #'minimum-Y-extent",
2348 str)
2349 str = re.sub (r"minimumVerticalExtent",
2350 r"\\override VerticalAxisGroup #'minimum-Y-extent",
2351 str)
2352 str = re.sub (r"\\set ([a-zA-Z]*\.?)extraVerticalExtent",
2353 r"\\override \1VerticalAxisGroup #'extra-Y-extent", str)
2354 str = re.sub (r"\\set ([a-zA-Z]*\.?)verticalExtent",
2355 r"\\override \1VerticalAxisGroup #'Y-extent", str)
2356 return str
2359 @rule ((2, 7, 15), _ ('Use grob closures iso. XY-offset-callbacks.'))
2360 def conv (str):
2361 if re.search ('[XY]-offset-callbacks', str):
2362 stderr_write (NOT_SMART % "[XY]-offset-callbacks")
2363 if re.search ('position-callbacks', str):
2364 stderr_write (NOT_SMART % "position-callbacks")
2365 return str
2368 @rule ((2, 7, 22), r"\tag #'(a b) -> \tag #'a \tag #'b")
2369 def conv (str):
2370 def sub_syms (m):
2371 syms = m.group (1).split ()
2372 tags = ["\\tag #'%s" % s for s in syms]
2373 return ' '.join (tags)
2375 str = re.sub (r"\\tag #'\(([^)]+)\)", sub_syms, str)
2376 return str
2379 @rule ((2, 7, 24), _ ('deprecate %s') % 'number-visibility')
2380 def conv (str):
2381 str = re.sub (r"#'number-visibility",
2382 "#'number-visibility % number-visibility is deprecated. Tune the TupletNumber instead\n",
2383 str)
2384 return str
2387 @rule ((2, 7, 28), "ly:spanner-get-bound -> ly:spanner-bound")
2388 def conv (str):
2389 str = re.sub (r"ly:spanner-get-bound", "ly:spanner-bound", str)
2390 return str
2393 @rule ((2, 7, 29), "override Stem #'beamed-* -> #'details #'beamed-*")
2394 def conv (str):
2395 for a in ['beamed-lengths', 'beamed-minimum-free-lengths',
2396 'lengths',
2397 'beamed-extreme-minimum-free-lengths']:
2398 str = re.sub (r"\\override\s+Stem\s+#'%s" % a,
2399 r"\\override Stem #'details #'%s" % a,
2400 str)
2401 return str
2404 @rule ((2, 7, 30), "\\epsfile")
2405 def conv (str):
2406 str = re.sub (r'\\epsfile *#"', r'\\epsfile #X #10 #"', str)
2407 return str
2410 @rule ((2, 7, 31), "Foo_bar::bla_bla -> ly:foo-bar::bla-bla")
2411 def conv (str):
2412 def sub_cxx_id (m):
2413 str = m.group(1)
2414 return 'ly:' + str.lower ().replace ('_','-')
2416 str = re.sub (r'([A-Z][a-z_0-9]+::[a-z_0-9]+)',
2417 sub_cxx_id, str)
2418 return str
2421 @rule ((2, 7, 32), _ ("foobar -> foo-bar for \paper, \layout"))
2422 def conv (str):
2423 identifier_subs = [
2424 ('inputencoding', 'input-encoding'),
2425 ('printpagenumber', 'print-page-number'),
2426 ('outputscale', 'output-scale'),
2427 ('betweensystemspace', 'between-system-space'),
2428 ('betweensystempadding', 'between-system-padding'),
2429 ('pagetopspace', 'page-top-space'),
2430 ('raggedlastbottom', 'ragged-last-bottom'),
2431 ('raggedright', 'ragged-right'),
2432 ('raggedlast', 'ragged-last'),
2433 ('raggedbottom', 'ragged-bottom'),
2434 ('aftertitlespace', 'after-title-space'),
2435 ('beforetitlespace', 'before-title-space'),
2436 ('betweentitlespace', 'between-title-space'),
2437 ('topmargin', 'top-margin'),
2438 ('bottommargin', 'bottom-margin'),
2439 ('headsep', 'head-separation'),
2440 ('footsep', 'foot-separation'),
2441 ('rightmargin', 'right-margin'),
2442 ('leftmargin', 'left-margin'),
2443 ('printfirstpagenumber', 'print-first-page-number'),
2444 ('firstpagenumber', 'first-page-number'),
2445 ('hsize', 'paper-width'),
2446 ('vsize', 'paper-height'),
2447 ('horizontalshift', 'horizontal-shift'),
2448 ('staffspace', 'staff-space'),
2449 ('linethickness', 'line-thickness'),
2450 ('ledgerlinethickness', 'ledger-line-thickness'),
2451 ('blotdiameter', 'blot-diameter'),
2452 ('staffheight', 'staff-height'),
2453 ('linewidth', 'line-width'),
2454 ('annotatespacing', 'annotate-spacing')
2457 for (a,b) in identifier_subs:
2458 ### for C++:
2459 ## str = re.sub ('"%s"' % a, '"%s"' b, str)
2461 str = re.sub (a, b, str)
2462 return str
2465 @rule ((2, 7, 32), "debug-beam-quanting -> debug-beam-scoring")
2466 def conv (str):
2467 str = re.sub ('debug-beam-quanting', 'debug-beam-scoring', str)
2468 return str
2471 @rule ((2, 7, 36), "def-(music-function|markup-command) -> define-(music-function|markup-command)")
2472 def conv (str):
2473 str = re.sub ('def-music-function', 'define-music-function', str)
2474 str = re.sub ('def-markup-command', 'define-markup-command', str)
2475 return str
2478 @rule ((2, 7, 40), "rehearsalMarkAlignSymbol/barNumberAlignSymbol -> break-align-symbol")
2479 def conv (str):
2480 str = re.sub (r'\\set\s+Score\s*\.\s*barNumberAlignSymbol\s*=',
2481 r"\\override Score.BarNumber #'break-align-symbol = ", str)
2482 str = re.sub (r'\\set\s*Score\s*\.\s*rehearsalMarkAlignSymbol\s*=',
2483 r"\\override Score.RehearsalMark #'break-align-symbol = ", str)
2484 return str
2487 @rule ((2, 9, 4), "(page-)penalty -> (page-)break-penalty")
2488 def conv (str):
2489 str = re.sub ('page-penalty', 'page-break-penalty', str)
2490 str = re.sub ('([^-])penalty', '\1break-penalty', str)
2491 return str
2494 @rule ((2, 9, 6), "\\context Foo \\applyOutput #bla -> \\applyOutput #'Foo #bla ")
2495 def conv (str):
2496 str = re.sub (r'\\context\s+\"?([a-zA-Z]+)\"?\s*\\applyOutput', r"\\applyOutput #'\1", str)
2497 return str
2500 @rule ((2, 9, 9), "annotatefoo -> annotate-foo")
2501 def conv (str):
2502 str = re.sub ('annotatepage', 'annotate-page', str)
2503 str = re.sub ('annotateheaders', 'annotate-headers', str)
2504 str = re.sub ('annotatesystems', 'annotate-systems', str)
2505 return str
2508 @rule ((2, 9, 11), "\\set tupletNumberFormatFunction -> \\override #'text = ")
2509 def conv (str):
2510 str = re.sub (r"""(\\set\s)?(?P<context>[a-zA-Z]*.?)tupletNumberFormatFunction\s*=\s*#denominator-tuplet-formatter""",
2511 r"""\\override \g<context>TupletNumber #'text = #tuplet-number::calc-denominator-text""", str)
2513 str = re.sub (r"""(\\set\s+)?(?P<context>[a-zA-Z]*.?)tupletNumberFormatFunction\s*=\s*#fraction-tuplet-formatter""",
2514 r"""\\override \g<context>TupletNumber #'text = #tuplet-number::calc-fraction-text""", str)
2516 if re.search ('tupletNumberFormatFunction', str):
2517 stderr_write ("\n")
2518 stderr_write ("tupletNumberFormatFunction has been removed. Use #'text property on TupletNumber")
2519 stderr_write ("\n")
2520 return str
2523 @rule ((2, 9, 13), "instrument -> instrumentName, instr -> shortInstrumentName, vocNam -> shortVocalName")
2524 def conv (str):
2525 str = re.sub ('vocNam', 'shortVocalName', str)
2526 str = re.sub (r'\.instr\s*=', r'.shortInstrumentName =', str)
2527 str = re.sub (r'\.instrument\s*=', r'.instrumentName =', str)
2528 return str
2531 @rule ((2, 9, 16), _ ("deprecate \\tempo in \\midi"))
2532 def conv (str):
2534 def sub_tempo (m):
2535 dur = int (m.group (1))
2536 dots = len (m.group (2))
2537 count = int (m.group (3))
2539 log2 = 0
2540 while dur > 1 :
2541 dur /= 2
2542 log2 += 1
2544 den = (1 << dots) * (1 << log2)
2545 num = ((1 << (dots+1)) - 1)
2547 return """
2548 \midi {
2549 \context {
2550 \Score
2551 tempoWholesPerMinute = #(ly:make-moment %d %d)
2555 """ % (num*count, den)
2557 str = re.sub (r'\\midi\s*{\s*\\tempo ([0-9]+)\s*([.]*)\s*=\s*([0-9]+)\s*}', sub_tempo, str)
2558 return str
2561 @rule ((2, 9, 19), "printfirst-page-number -> print-first-page-number")
2562 def conv (str):
2563 str = re.sub ('printfirst-page-number', 'print-first-page-number', str)
2564 return str
2567 @rule ((2, 10, 0), _ ("bump version for release"))
2568 def conv (str):
2569 return str
2572 @rule ((2, 11, 2), "ly:clone-parser -> ly:parser-clone")
2573 def conv (str):
2574 return re.sub ('ly:clone-parser',
2575 'ly:parser-clone', str)
2578 @rule ((2, 11, 5), _ ("deprecate cautionary-style. Use AccidentalCautionary properties"))
2579 def conv (str):
2580 str = re.sub ("Accidental\s*#'cautionary-style\s*=\s*#'smaller",
2581 "AccidentalCautionary #'font-size = #-2", str)
2582 str = re.sub ("Accidental\s*#'cautionary-style\s*=\s*#'parentheses",
2583 "AccidentalCautionary #'parenthesized = ##t", str)
2584 str = re.sub ("([A-Za-z]+)\s*#'cautionary-style\s*=\s*#'parentheses",
2585 r"\1 #'parenthesized = ##t", str)
2586 str = re.sub ("([A-Za-z]+)\s*#'cautionary-style\s*=\s*#'smaller",
2587 r"\1 #'font-size = #-2", str)
2588 return str
2591 @rule ((2, 11, 6), _ ("Rename accidental glyphs, use glyph-name-alist."))
2592 def conv (str):
2594 def sub_acc_name (m):
2595 idx = int (m.group (1).replace ('M','-'))
2597 return ["accidentals.doublesharp",
2598 "accidentals.sharp.slashslash.stemstemstem",
2599 "accidentals.sharp",
2600 "accidentals.sharp.slashslash.stem",
2601 "accidentals.natural",
2602 "accidentals.mirroredflat",
2603 "accidentals.flat",
2604 "accidentals.mirroredflat.flat",
2605 "accidentals.flatflat"][4-idx]
2607 str = re.sub (r"accidentals[.](M?[-0-9]+)",
2608 sub_acc_name, str)
2609 str = re.sub (r"(KeySignature|Accidental[A-Za-z]*)\s*#'style\s*=\s*#'([a-z]+)",
2610 r"\1 #'glyph-name-alist = #alteration-\2-glyph-name-alist", str)
2611 ## FIXME: standard vs default, alteration-FOO vs FOO-alteration
2612 str = str.replace ('alteration-default-glyph-name-alist',
2613 'standard-alteration-glyph-name-alist')
2614 return str
2617 @rule ((2, 11, 10), """allowBeamBreak -> Beam #'breakable = ##t
2618 addquote -> addQuote
2619 """)
2620 def conv (str):
2621 str = re.sub (r'(\\set\s+)?([A-Z][a-zA-Z]+\s*\.\s*)allowBeamBreak',
2622 r"\override \2Beam #'breakable", str)
2623 str = re.sub (r'(\\set\s+)?allowBeamBreak',
2624 r"\override Beam #'breakable", str)
2625 str = re.sub (r'addquote', 'addQuote', str)
2626 if re.search ("Span_dynamic_performer", str):
2627 stderr_write ("Span_dynamic_performer has been merged into Dynamic_performer")
2629 return str
2632 @rule ((2, 11, 11), "layout-set-staff-size -> layout-set-absolute-staff-size")
2633 def conv (str):
2634 str = re.sub (r'\(layout-set-staff-size \(\*\s*([0-9.]+)\s*(pt|mm|cm)\)\)',
2635 r'(layout-set-absolute-staff-size (* \1 \2))', str)
2636 return str
2639 @rule ((2, 11, 13), "#'arrow = ##t -> #'bound-details #'right #'arrow = ##t")
2640 def conv (str):
2641 str = re.sub (r"\\override\s*([a-zA-Z.]+)\s*#'arrow\s*=\s*##t",
2642 r"\\override \1 #'bound-details #'right #'arrow = ##t",
2643 str)
2645 if re.search ('edge-text', str):
2646 stderr_write (NOT_SMART % _ ("edge-text settings for TextSpanner."))
2647 stderr_write (_ ("Use\n\n%s") %
2648 "\t\\override TextSpanner #'bound-details #'right #'text = <right-text>\n"
2649 "\t\\override TextSpanner #'bound-details #'left #'text = <left-text>\n")
2650 return str
2653 @rule ((2, 11, 15), "#'edge-height -> #'bound-details #'right/left #'text = ...")
2654 def conv (str):
2655 def sub_edge_height (m):
2656 s = ''
2657 for (var, h) in [('left', m.group (3)),
2658 ('right', m.group (4))]:
2660 if h and float (h):
2661 once = m.group(1)
2662 if not once:
2663 once = ''
2665 s += (r"%s \override %s #'bound-details #'%s #'text = \markup { \draw-line #'(0 . %s) }"
2666 % (once, m.group (2), var, h))
2668 s += '\n'
2670 return s
2673 str = re.sub (r"(\\once)?\s*\\override\s*([a-zA-Z.]+)\s*#'edge-height\s*=\s*#'\(([0-9.-]+)\s+[.]\s+([0-9.-]+)\)",
2674 sub_edge_height, str)
2675 return str
2678 @rule ((2, 11, 23), "#'break-align-symbol -> #'break-align-symbols")
2679 def conv (str):
2680 str = re.sub (r"\\override\s*([a-zA-Z.]+)\s*#'break-align-symbol\s*=\s*#'([a-z-]+)",
2681 r"\\override \1 #'break-align-symbols = #'(\2)", str)
2682 return str
2685 @rule ((2, 11, 35), """scripts.caesura -> scripts.caesura.curved.
2686 """ + _ ("Use #'style not #'dash-fraction to select solid/dashed lines."))
2687 def conv (str):
2688 str = re.sub (r"scripts\.caesura",
2689 r"scripts.caesura.curved", str)
2691 if re.search ('dash-fraction', str):
2692 stderr_write (NOT_SMART % _ ("all settings related to dashed lines.\n"))
2693 stderr_write (_ ("Use \\override ... #'style = #'line for solid lines and\n"))
2694 stderr_write (_ ("\t\\override ... #'style = #'dashed-line for dashed lines."))
2695 return str
2698 @rule ((2, 11, 38), """\\setEasyHeads -> \\easyHeadsOn, \\fatText -> \\textLengthOn,
2699 \\emptyText -> \\textLengthOff""")
2700 def conv (str):
2701 str = re.sub (r"setEasyHeads", r"easyHeadsOn", str)
2702 str = re.sub (r"fatText", r"textLengthOn", str)
2703 str = re.sub (r"emptyText", r"textLengthOff", str)
2704 return str
2707 @rule ((2, 11, 46), "\\set hairpinToBarline -> \\override Hairpin #'to-barline")
2708 def conv (str):
2709 str = re.sub (r"\\set\s+([a-zA-Z]+)\s*.\s*hairpinToBarline\s*=\s*##([tf]+)",
2710 r"\\override \1.Hairpin #'to-barline = ##\2", str)
2711 str = re.sub (r"\\set\s+hairpinToBarline\s*=\s*##([tf]+)",
2712 r"\\override Hairpin #'to-barline = ##\1", str)
2713 str = re.sub (r"\\unset\s+([a-zA-Z]+)\s*.\s*hairpinToBarline",
2714 r"\\revert \1.Hairpin #'to-barline", str)
2715 str = re.sub (r"\\unset\s+hairpinToBarline",
2716 r"\\revert Hairpin #'to-barline", str)
2717 str = re.sub (r"hairpinToBarline\s*=\s*##([tf]+)",
2718 r"\\override Hairpin #'to-barline = ##\1", str)
2719 str = re.sub (r"\\set (de|)crescendoSpanner = #'dashed-line",
2720 r"\\set \1crescendoSpanner = #'text", str)
2721 return str
2724 @rule ((2, 11, 48), "\\compressMusic -> \\scaleDurations")
2725 def conv (str):
2726 str = re.sub (r"compressMusic", r"scaleDurations", str)
2727 return str
2730 @rule ((2, 11, 50), _ ("metronomeMarkFormatter uses text markup as second argument,\n\
2731 fret diagram properties moved to fret-diagram-details."))
2732 def conv (str):
2733 ## warning 1/2: metronomeMarkFormatter uses text markup as second argument
2734 if re.search ('metronomeMarkFormatter', str):
2735 stderr_write (NOT_SMART % _ ("metronomeMarkFormatter got an additional text argument.\n"))
2736 stderr_write (_ ("The function assigned to Score.metronomeMarkFunction now uses the signature\n%s") %
2737 "\t(format-metronome-markup text dur count context)\n")
2739 ## warning 2/2: fret diagram properties moved to fret-diagram-details
2740 fret_props = ['barre-type',
2741 'dot-color',
2742 'dot-radius',
2743 'finger-code',
2744 'fret-count',
2745 'label-dir',
2746 'number-type',
2747 'string-count',
2748 'xo-font-magnification',
2749 'mute-string',
2750 'open-string',
2751 'orientation']
2752 for prop in fret_props:
2753 if re.search (prop, str):
2754 stderr_write (NOT_SMART %
2755 prop + " in fret-diagram properties. Use fret-diagram-details.")
2756 stderr_write ('\n')
2757 return str
2759 @rule ((2, 11, 51), "\\octave -> \\octaveCheck, \\arpeggioUp -> \\arpeggioArrowUp,\n\
2760 \\arpeggioDown -> \\arpeggioArrowDown, \\arpeggioNeutral -> \\arpeggioNormal,\n\
2761 \\setTextCresc -> \\crescTextCresc, \\setTextDecresc -> \\dimTextDecresc,\n\
2762 \\setTextDecr -> \\dimTextDecr, \\setTextDim -> \\dimTextDim,\n\
2763 \\setHairpinCresc -> \\crescHairpin, \\setHairpinDecresc -> \\dimHairpin,\n\
2764 \\sustainUp -> \\sustainOff, \\sustainDown -> \\sustainOn\n\
2765 \\sostenutoDown -> \\sostenutoOn, \\sostenutoUp -> \\sostenutoOff")
2766 def conv (str):
2767 str = re.sub (r"\\octave", r"\\octaveCheck", str)
2768 str = re.sub (r"arpeggioUp", r"arpeggioArrowUp", str)
2769 str = re.sub (r"arpeggioDown", r"arpeggioArrowDown", str)
2770 str = re.sub (r"arpeggioNeutral", r"arpeggioNormal", str)
2771 str = re.sub (r"setTextCresc", r"crescTextCresc", str)
2772 str = re.sub (r"setTextDecresc", r"dimTextDecresc", str)
2773 str = re.sub (r"setTextDecr", r"dimTextDecr", str)
2774 str = re.sub (r"setTextDim", r"dimTextDim", str)
2775 str = re.sub (r"setHairpinCresc", r"crescHairpin", str)
2776 str = re.sub (r"setHairpinDecresc", r"dimHairpin", str)
2777 str = re.sub (r"sustainUp", r"sustainOff", str)
2778 str = re.sub (r"sustainDown", r"sustainOn", str)
2779 str = re.sub (r"sostenutoDown", r"sostenutoOn", str)
2780 str = re.sub (r"sostenutoUp", r"sostenutoOff", str)
2781 return str
2783 @rule ((2, 11, 52), "\\setHairpinDim -> \\dimHairpin")
2784 def conv (str):
2785 str = str.replace ("setHairpinDim", "dimHairpin")
2786 return str
2788 @rule ((2, 11, 53), "infinite-spacing-height -> extra-spacing-height")
2789 def conv (str):
2790 str = re.sub (r"infinite-spacing-height\s+=\s+##t", r"extra-spacing-height = #'(-inf.0 . +inf.0)", str)
2791 str = re.sub (r"infinite-spacing-height\s+=\s+##f", r"extra-spacing-height = #'(0 . 0)", str)
2792 return str
2794 @rule ((2, 11, 55), "#(set-octavation oct) -> \\ottava #oct,\n\
2795 \\put-adjacent markup axis dir markup -> \\put-adjacent axis dir markup markup")
2796 def conv (str):
2797 str = re.sub (r"#\(set-octavation (-*[0-9]+)\)", r"\\ottava #\1", str)
2798 if re.search ('put-adjacent', str):
2799 stderr_write (NOT_SMART % _ ("\\put-adjacent argument order.\n"))
2800 stderr_write (_ ("Axis and direction now come before markups:\n"))
2801 stderr_write (_ ("\\put-adjacent axis dir markup markup."))
2802 return str
2804 @rule ((2, 11, 57), "\\center-align -> \\center-column, \\hcenter -> \\center-align")
2805 def conv (str):
2806 str = re.sub (r"([\\:]+)center-align", r"\1center-column", str)
2807 str = re.sub (r"hcenter(\s+)", r"center-align\1", str)
2808 return str
2810 @rule ((2, 11, 60), "printallheaders -> print-all-headers")
2811 def conv (str):
2812 str = re.sub (r"printallheaders", r"print-all-headers", str)
2813 return str
2815 @rule ((2, 11, 61), "gregorian-init.ly -> gregorian.ly")
2816 def conv (str):
2817 str = re.sub (r'\\include(\s+)"gregorian-init.ly"', r'\\include\1"gregorian.ly"', str)
2818 return str
2820 @rule ((2, 11, 62), "makam-init.ly -> makam.ly, \\bigger -> \\larger")
2821 def conv (str):
2822 str = re.sub (r'\\include(\s+)"makam-init.ly"', r'\\include\1"makam.ly"', str)
2823 str = re.sub (r"\\bigger", r"\\larger", str)
2824 return str
2826 @rule ((2, 11, 64), "systemSeparatorMarkup -> system-separator-markup,\n\
2827 InnerStaffGroup -> StaffGroup, InnerChoirStaff -> ChoirStaff")
2828 def conv (str):
2829 str = re.sub (r'systemSeparatorMarkup', r'system-separator-markup', str)
2830 if re.search (r'\\InnerStaffGroup', str):
2831 stderr_write ("\n")
2832 stderr_write (NOT_SMART % _("re-definition of InnerStaffGroup.\n"))
2833 stderr_write (FROM_TO % ("InnerStaffGroup", "StaffGroup.\n"))
2834 stderr_write (UPDATE_MANUALLY)
2835 raise FatalConversionError ()
2836 if re.search (r'\\InnerChoirStaff', str):
2837 stderr_write ("\n")
2838 stderr_write (NOT_SMART % _("re-definition of InnerChoirStaff.\n"))
2839 stderr_write (FROM_TO % ("InnerChoirStaff", "ChoirStaff.\n"))
2840 stderr_write (UPDATE_MANUALLY)
2841 raise FatalConversionError ()
2842 else:
2843 str = re.sub ('InnerStaffGroup', 'StaffGroup', str)
2844 str = re.sub ('InnerChoirStaff', 'ChoirStaff', str)
2845 return str
2847 @rule ((2, 11, 66), "Syntax changes for \\addChordShape and \\chord-shape")
2848 def conv(str):
2849 if re.search(r'\\addChordShape', str):
2850 stderr_write ("\n")
2851 stderr_write (NOT_SMART % _("stringTuning must be added to \
2852 addChordShape call.\n"))
2853 stderr_write (UPDATE_MANUALLY)
2854 raise FatalConversionError ()
2855 if re.search (r'\\chord-shape', str):
2856 stderr_write ("\n")
2857 stderr_write (NOT_SMART % _("stringTuning must be added to \
2858 chord-shape call.\n"))
2859 stderr_write (UPDATE_MANUALLY)
2860 raise FatalConversionError ()
2861 return str
2863 # Guidelines to write rules (please keep this at the end of this file)
2865 # - keep at most one rule per version; if several conversions should be done,
2866 # concatenate them into a single "conv" function;
2868 # - enclose strings to be localized with `_(' and `)';
2870 # - write rule for bumping major stable version with
2872 # _ ("bump version for release")
2874 # as exact description.