13 origstr = '<%s>' % str
14 if re.search (r'\\\\', str):
17 if re.search (r'\\property', str):
20 if re.match (r'^\s*\)?\s*\\[a-zA-Z]+', str):
25 durs.append(m.group(2))
28 str = re.sub ("([a-z]+[,'!? ]*)([0-9.]+)", sub_durs, str)
35 return '<%s>' % m.group (1)
42 while last_str <> str:
46 return ' ' + m.group(2)
48 str = re.sub (r'(\\!)\s*([a-z]+)', sub_dyn_end, str)
50 if '-)' not in slur_strs:
51 slur_strs.append ( '-)')
54 if '-\)' not in slur_strs:
55 slur_strs.append ( '-\)')
57 str = re.sub (r"\)[ ]*([a-z]+)", sub_slurs, str)
58 str = re.sub (r"\\\)[ ]*([a-z]+)", sub_p_slurs, str)
59 def sub_begin_slurs(m):
60 if '-(' not in slur_strs:
61 slur_strs.append ( '-(')
63 str = re.sub (r"([a-z]+[,'!?0-9 ]*)\(", sub_begin_slurs, str)
64 def sub_begin_p_slurs(m):
65 if '-\(' not in slur_strs:
66 slur_strs.append ( '-\(')
69 str = re.sub (r"([a-z]+[,'!?0-9 ]*)\\\(", sub_begin_p_slurs, str)
73 if s == '@STARTCRESC@':
74 slur_strs.append ("-\\<")
75 elif s == '@STARTDECRESC@':
76 slur_strs.append ("-\\>")
78 slur_strs.append ('-\\!')
81 str = re.sub (r'@STARTCRESC@', sub_dyns, str)
82 str = re.sub (r'-?\\!', sub_dyns, str)
84 def sub_articulations (m):
86 if a not in slur_strs:
90 str = re.sub (r"([_^-]\@ACCENT\@)", sub_articulations, str)
91 str = re.sub (r"([_^-]\\[a-z]+)", sub_articulations, str)
92 str = re.sub (r"([_^-][>_.+|^-])", sub_articulations, str)
95 slur_strs.append ( ' -\\)')
97 str = re.sub (r"\\\)[ ]*([a-z]+)", sub_pslurs, str)
99 suffix = string.join (slur_strs, '') + string.join (pslur_strs, '') \
100 + string.join (dyns, '')
102 return '@STARTCHORD@%s@ENDCHORD@%s%s' % (str , dur_str, suffix)
108 simstart = "\n\\simultaneous {"
121 marker_str = '%% new-chords-done %%'
123 def sub_chords (str):
124 if re.search (marker_str,str):
126 str= re.sub (r'\\<', '@STARTCRESC@', str)
127 str= re.sub (r'\\>', '@STARTDECRESC@', str)
128 str= re.sub (r'([_^-])>', r'\1@ACCENT@', str)
129 str = re.sub ('<([^<>{}]+)>', sub_chord, str)
130 str = re.sub (r'\\! *@STARTCHORD@([^@]+)@ENDCHORD@',
131 r'@STARTCHORD@\1@ENDCHORD@-\!',
133 str = re.sub ('<([^?])', r'%s\1' % simstart, str)
134 str = re.sub ('>([^?])', r'%s\1' % simend, str)
135 str = re.sub ('@STARTCRESC@', r'\\<', str)
136 str = re.sub ('@STARTDECRESC@', r'\\>' ,str)
137 str = re.sub (r'\\context *Voice *@STARTCHORD@', '@STARTCHORD@', str)
138 str = re.sub ('@STARTCHORD@', chordstart, str)
139 str = re.sub ('@ENDCHORD@', chordend, str)
140 str = re.sub (r'@ACCENT@', '>', str)
143 def articulation_substitute (str):
144 str = re.sub (r"""([^-])\[ *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
146 str = re.sub (r"""([^-])\) *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
148 str = re.sub (r"""([^-])\\! *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
154 new-chords.py -- update .ly files to new syntax.
157 new-chords.py [OPTIONS] FILE(S)
161 -e, --edit in-place edit
166 This script converts old chord notation to new chord notation, i.e.
174 It will also convert slur-end, beam-start and cresc-end to postfix
183 By default, the script will print the result on stdout. Use with -e
184 if you are confident that it does the right thing.
188 This conversion does not convert all files correctly. It is
189 recommended to verify the output of the new file manually.
190 In particular, files with extensive Scheme code (markups, like
194 and Scheme function definitions may be garbled by the textual
200 (opts, files)= getopt.getopt( sys.argv[1:], 'eh',['help','edit'])
203 if o == '-e' or o == '--edit':
205 if o == '-h' or o == '--help':
210 print 'Error: no input files.\n use -h for help.'
215 str = open (a).read()
216 if re.search (marker_str, str):
219 sys.stderr.write ("processing %s\n" %a)
221 str = sub_chords (str) + marker_str + '\n'
222 str = articulation_substitute (str)
225 open (a + '.NEW', 'w').write (str)
226 os.rename (a, a + '~')
227 os.rename (a + '.NEW', a)
233 ## regexes for postfix slur & beam:
238 ## \([^-]\)\[ *\([a-z]+[!?]?[,']*[0-9:]*\.*\)
242 ## \([^-]\)) *\([a-z]+[!?]?[,']*[0-9:]*\.*\)