]> git.donarmstrong.com Git - lilypond.git/blob - buildscripts/convert-new-chords.py
* buildscripts/new-chords.py (help): add help text
[lilypond.git] / buildscripts / convert-new-chords.py
1
2 # to nwe chord syntax.  
3 import re
4 import string
5 import sys
6 import getopt
7 import os
8
9
10 def sub_chord (m):
11         str = m.group(1)
12
13         origstr =  '<%s>' % str
14         if re.search (r'\\\\', str):
15                 return origstr
16
17         if re.search (r'\\property', str):
18                 return origstr
19
20         if re.match (r'^\s*\)?\s*\\[a-zA-Z]+', str):
21                 return origstr
22
23         durs = []
24         def sub_durs (m):
25                 durs.append(m.group(2))
26                 return m.group (1)
27
28         str = re.sub ("([a-z]+[,'!? ]*)([0-9.]+)", sub_durs, str)
29         dur_str = ''
30
31         for d in durs:
32                 if dur_str == '':
33                         dur_str = d
34                 if dur_str <> d:
35                         return '<%s>' % m.group (1)
36
37         pslur_strs = ['']
38         dyns = ['']
39         slur_strs = ['']
40
41         last_str = ''
42         while last_str <> str:
43           last_str = str
44           def sub_dyn_end (m):
45                   dyns.append (' -\!')
46                   return ' ' + m.group(2)
47
48           str = re.sub (r'(\\!)\s*([a-z]+)', sub_dyn_end, str)
49           def sub_slurs(m):
50                   if '-)' not in slur_strs:
51                           slur_strs.append ( '-)')
52                   return m.group(1)
53           def sub_p_slurs(m):
54                   if '-\)' not in slur_strs:
55                           slur_strs.append ( '-\)')
56                   return m.group(1)
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 ( '-(')
62                   return m.group(1)
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 ( '-\(')
67                   return m.group(1)
68
69           str = re.sub (r"([a-z]+[,'!?0-9 ]*)\\\(", sub_begin_p_slurs, str)
70
71           def sub_dyns (m):
72                   s = m.group(0)
73                   if s == '@STARTCRESC@':
74                           slur_strs.append ("-\\<")
75                   elif s == '@STARTDECRESC@':
76                           slur_strs.append ("-\\>")
77                   elif s == r'-?\\!':
78                           slur_strs.append ('-\\!')
79                   return ''
80
81           str = re.sub (r'@STARTCRESC@', sub_dyns, str)
82           str = re.sub (r'-?\\!', sub_dyns, str)
83
84           def sub_articulations (m):
85                   a = m.group(1)
86                   if a not in slur_strs:
87                           slur_strs.append (a)
88                   return ''
89
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)
93
94           def sub_pslurs(m):
95                   slur_strs.append ( ' -\\)')
96                   return m.group(1)
97           str = re.sub (r"\\\)[ ]*([a-z]+)", sub_pslurs, str)
98
99         suffix = string.join (slur_strs, '') + string.join (pslur_strs, '') \
100                  + string.join (dyns, '')
101
102         return '@STARTCHORD@%s@ENDCHORD@%s%s' % (str , dur_str, suffix)
103
104
105
106
107 simend = '}'
108 simstart = "\n\\simultaneous {"
109 chordstart = '<'
110 chordend = '>'
111
112 old_syntax = 1
113
114 if old_syntax:
115         simend = '>'
116         simstart = "<" 
117         chordstart = '<<'
118         chordend = '>>'
119
120
121 marker_str = '%% new-chords-done %%'
122
123 def sub_chords (str):
124         if re.search (marker_str,str):
125                 return 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@-\!',
132                       str)
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)
141         return str
142
143 def articulation_substitute (str):
144         str = re.sub (r"""([^-])\[ *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
145                       r" \1 \2-[", str)
146         str = re.sub (r"""([^-])\) *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
147                       r"\1 \2-)", str)
148         str = re.sub (r"""([^-])\\! *([a-z]+[,']*[!?]?[0-9:]*\.*)""",
149                       r"\1 \2-\\!", str)
150         return str
151
152 def help ():
153         print r"""
154 new-chords.py -- update .ly files to new syntax.
155
156 Usage:
157   new-chords.py [OPTIONS] FILE(S)
158
159 Options
160
161   -e, --edit     in-place edit
162   -h, --help     this help
163
164 Description
165
166   This script converts old chord notation to new chord notation, i.e.
167
168      \< <a )b>
169
170   becomes
171
172      <<a b>> -\< -)
173
174   It will also convert slur-end, beam-start and cresc-end to postfix
175   notation, i.e.
176
177     [ \! )a
178
179   becomes
180
181     a-\!-)-[ 
182
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.
185
186 Warning
187
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
191
192      #'(italic "foo")
193
194   and Scheme function definitions may be garbled by the textual
195   substitution.
196
197 """
198
199
200 (opts, files)= getopt.getopt( sys.argv[1:], 'eh',['help','edit'])
201 edit = 0
202 for (o,a) in opts:
203         if o == '-e' or o == '--edit':
204                 edit = 1
205         if o == '-h' or o == '--help':
206                 help ()
207                 sys.exit (0)
208
209 if not files:
210         print 'Error: no input files.\n use -h for help.'
211         sys.exit(2)
212         
213
214 for a in files:
215         str = open (a).read()
216         if re.search (marker_str, str):
217                 continue
218
219         sys.stderr.write ("processing %s\n" %a)
220         
221         str = sub_chords (str)  + marker_str + '\n'
222         str = articulation_substitute (str)
223
224         if edit:
225                 open (a + '.NEW', 'w').write (str)
226                 os.rename (a, a + '~')
227                 os.rename (a + '.NEW', a)
228         else:
229                 print str
230
231
232 ##
233 ## regexes for postfix slur & beam:
234 ##
235 #PYTHON
236 ##
237 #EMACS
238 ## \([^-]\)\[ *\([a-z]+[!?]?[,']*[0-9:]*\.*\)
239 #### ->
240 ## \1 \2-[
241 ##
242 ## \([^-]\)) *\([a-z]+[!?]?[,']*[0-9:]*\.*\)
243 #### ->
244 ## \1 \2-)
245