]> git.donarmstrong.com Git - lilypond.git/blob - scripts/convert-mudela.py
a51f700c675e7f28656fa1afc94fc07a7eda2303
[lilypond.git] / scripts / convert-mudela.py
1 #!@PYTHON@
2
3 # convert-mudela.py -- convertor for mudela versions
4
5 # source file of the GNU LilyPond music typesetter
6
7 # (c) 1998 
8
9 # TODO
10 #   use -f and -t for -s output
11
12 # NEWS
13 # 0.2
14 #  - rewrite in python
15
16 program_name = 'convert-mudela'
17 version = '0.3'
18
19
20 import os
21 import sys
22 import __main__
23 import getopt
24 from string import *
25 import regex
26 import regsub
27 import time
28 mudela_version_re_str ='\\\\version *\"\(.*\)\"'
29 mudela_version_re = regex.compile(mudela_version_re_str)
30
31 def program_id ():
32         return '%s version %s' %(program_name,  version);
33
34 def identify ():
35         sys.stderr.write (program_id () + '\n')
36
37 def gulp_file(f):
38         try:
39                 i = open(f)
40                 i.seek (0, 2)
41                 n = i.tell ()
42                 i.seek (0,0)
43         except:
44                 print 'can\'t open file: ' + f + '\n'
45                 return ''
46         s = i.read (n)
47         if len (s) <= 0:
48                 print 'gulped empty file: ' + f + '\n'
49         i.close ()
50         return s
51
52
53 def str_to_tuple (s):
54         return tuple (map (atoi, split (s,'.')))
55
56 def tup_to_str (t):
57         return join (map (lambda x: '%s' % x, list (t)), '.')
58
59 def version_cmp (t1, t2):
60         for x in [0,1,2]:
61                 if t1[x] - t2[x]:
62                         return t1[x] - t2[x]
63         return 0
64                 
65
66 def guess_mudela_version(filename):
67         s = gulp_file (filename)
68         if mudela_version_re.search(s) <> -1:
69                 return mudela_version_re.group(1)
70         else:
71                 return ''
72
73 def help ():
74         sys.stdout.write (
75                 ("Usage: %s [OPTION]... [FILE]...\n" 
76                 + "Try to convert to newer mudela-versions\n"
77                 + "Options:\n"
78                 + "  -h, --help             print this help\n"
79                 + '  -e, --edit             in place edit\n'
80                 + '  -f, --from=VERSION     start from version\n'
81                 + '  -s, --show-rules       print out all rules.\n'
82                 + '  -t, --to=VERSION       target version\n') % program_name)
83         sys.exit (0)
84
85 class FatalConversionError:
86         pass
87
88 conversions = []
89
90 def show_rules (file):
91         for x in conversions:
92                 file.write  ('%s: %s\n' % (tup_to_str (x[0]), x[2]))
93
94 ############################
95                 
96 if 1:                                   # need new a namespace
97         def conv (lines):
98                 found =0
99                 for x in lines:
100                         if regex.search ('\\\\octave', x) <> -1:
101                                 found = 1
102                                 break
103                 if found:
104                         sys.stderr.write ('\nNot smart enough to convert \\octave')
105                         raise FatalConversionError()
106                 return lines
107                 
108
109         conversions.append (
110                 ((0,1,19), conv, 'deprecated \\octave; can\'t convert automatically'))
111
112
113 if 1:                                   # need new a namespace
114         def conv (lines):
115                 newlines = []
116                 for x in lines:
117                         x = regsub.gsub ('\\\\textstyle\\([^;]+\\);',
118                                          '\\\\property Lyrics . textstyle = \\1', x)
119                         x = regsub.gsub ('\\\\key\\([^;]+\\);', '\\\\accidentals \\1;', x)
120                         newlines.append (x)
121                 return newlines
122                 
123
124         conversions.append (
125                 ((0,1,20), conv, 'deprecated \\textstyle, new \key syntax'))
126
127
128 if 1:                                   # need new a namespace
129         def conv (lines):
130                 newlines = []
131                 for x in lines:
132                         x = regsub.gsub ('\\\\musical_pitch',
133                                          '\\\\musicalpitch',x)
134                         x = regsub.gsub ('\\\\meter',
135                                          '\\\\time',x)
136                         newlines.append (x)
137                 return newlines
138                 
139
140         conversions.append (
141                 ((0,1,21), conv, '\\musical_pitch -> \\musicalpitch, '+
142                  '\\meter -> \\time'))
143
144 if 1:                                   # need new a namespace
145         def conv (lines):
146                 return lines
147
148         conversions.append (
149                 ((1,0,0), conv, '0.1.21 -> 1.0.0 '))
150
151
152 if 1:                                   # need new a namespace
153         def conv (lines):
154                 newlines = []
155                 for x in lines:
156                         x = regsub.gsub ('\\\\accidentals',
157                                          '\\\\keysignature',x)
158                         x = regsub.gsub ('specialaccidentals *= *1',
159                                          'keyoctaviation = 0',x)
160                         x = regsub.gsub ('specialaccidentals *= *0',
161                                          'keyoctaviation = 1',x)
162                         newlines.append (x)
163                 return newlines
164                 
165
166         conversions.append (
167                 ((1,0,1), conv, '\\accidentals -> \\keysignature, ' +
168                  'specialaccidentals -> keyoctaviation'))
169
170 if 1:
171         def conv(lines):
172                 found = 0
173                 for x in lines:
174                         if regex.search ('\\\\header', x) <> -1:
175                                 found = 1
176                                 break
177                 if found:
178                         sys.stderr.write ('\nNot smart enough to convert to new \\header format')
179                 return lines
180         
181         conversions.append ((1,0,2), conv, '\\header { key = concat + with + operator }')
182
183 if 1:
184         def conv(lines):
185                 newlines =[]
186                 for x in lines:
187                         x =  regsub.gsub ('\\\\melodic', '\\\\notes',x)
188                         newlines.append (x)
189                 return newlines
190         
191         conversions.append ((1,0,3), conv, '\\melodic -> \\notes')
192
193 if 1:
194         def conv(lines):
195                 newlines =[]
196                 for x in lines:
197                         x =  regsub.gsub ('default_paper *=', '',x)
198                         x =  regsub.gsub ('default_midi *=', '',x)                      
199                         newlines.append (x)
200                 return newlines
201         
202         conversions.append ((1,0,4), conv, 'default_{paper,midi}')
203
204 if 1:
205         def conv(lines):
206                 newlines =[]
207                 for x in lines:
208                         x =  regsub.gsub ('ChoireStaff', 'ChoirStaff',x)
209                         x =  regsub.gsub ('\\output', 'output = ',x)
210                         newlines.append (x)
211                 return newlines
212         
213         conversions.append ((1,0,5), conv, 'ChoireStaff -> ChoirStaff')
214
215 if 1:
216         def conv(lines):
217                 newlines =[]
218                 found = 0
219                 for x in lines:
220                         found = regex.search ('[a-zA-Z]+ = *\\translator',x) <> -1
221                         newlines.append (x)
222                         if found: break
223                 if found:
224                         sys.stderr.write ('\nNot smart enough to \\translator syntax')
225                         raise FatalConversionError()
226                 return newlines
227         
228         conversions.append ((1,0,6), conv, 'foo = \\translator {\\type .. } ->\\translator {\\type ..; foo; }')
229
230
231 if 1:
232         def conv(lines):
233                 newlines =[]
234                 for x in lines:
235                         x =  regsub.gsub ('\\\\lyric', '\\\\lyrics',x)
236                         newlines.append (x)
237                 return newlines
238         
239         conversions.append ((1,0,7), conv, '\\lyric -> \\lyrics')
240
241
242 ############################
243         
244
245 def get_conversions (from_version, to_version):
246         def version_b (v, f = from_version, t = to_version):
247                 return version_cmp (v[0], f) > 0 and version_cmp (v[0], t) <= 0
248         return filter (version_b, conversions)
249
250
251 def latest_version ():
252         return conversions[-1][0]
253
254 def do_conversion (infile, from_version, outfile, to_version):
255         
256         conv_list = get_conversions (from_version, to_version)
257
258         sys.stderr.write ('Applying conversions: ')
259         lines = infile.readlines();
260         last_conversion = ()
261         try:
262                 for x in conv_list:
263                         sys.stderr.write (tup_to_str (x[0])  + ', ')
264                         lines = x[1] (lines)
265                         last_conversion = x[0]
266                         
267
268         except FatalConversionError:
269                 sys.stderr.write ('Error while converting; I won\'t convert any further')
270
271         for x in lines:
272                 if last_conversion:
273                         x = regsub.sub (mudela_version_re_str, '\\version \"%s\"' % tup_to_str (last_conversion), x)
274                 outfile.write(x)
275
276 class UnknownVersion:
277         pass
278
279 def do_one_file (infile_name):
280         sys.stderr.write ('Processing `%s\' ... '% infile_name)
281         outfile_name = ''
282         if __main__.edit:
283                 outfile_name = infile_name + '.NEW'
284         elif __main__.outfile_name:
285                 outfile_name = __main__.outfile_name
286
287         if __main__.from_version:
288                 from_version = __main__.from_version
289         else:
290                 guess = guess_mudela_version (infile_name)
291                 if not guess:
292                         raise UnknownVersion()
293                 from_version = str_to_tuple (guess)
294
295         if __main__.to_version:
296                 to_version = __main__.to_version
297         else:
298                 to_version = latest_version ()
299
300
301         if infile_name:
302                 infile = open (infile_name,'r')
303         else:
304                 infile = sys.stdin
305
306         if outfile_name:
307                 outfile =  open (outfile_name, 'w')
308         else:
309                 outfile = sys.stdout
310
311         
312         do_conversion (infile, from_version, outfile, to_version)
313
314         if infile_name:
315                 infile.close ()
316
317         if outfile_name:
318                 outfile.close ()
319
320         if __main__.edit:
321                 os.rename (infile_name, infile_name + '~')
322                 os.rename (infile_name + '.NEW', infile_name)
323
324         sys.stderr.write ('\n')
325
326 edit = 0
327 to_version = ()
328 from_version = ()
329 outfile_name = ''
330
331 identify ()
332 (options, files) = getopt.getopt (
333         sys.argv[1:], 'f:t:seh', ['show-rules', 'help', 'edit', 'from', 'to'])
334
335 for opt in options:
336         o = opt[0]
337         a = opt[1]
338         if o== '--help' or o == '-h':
339                 help ()
340         elif o== '--from' or o=='-f':
341                 from_version = str_to_tuple (a)
342         elif o== '--to' or o=='-t':
343                 to_version = str_to_tuple (a)
344         elif o== '--edit' or o == '-e':
345                 edit = 1
346         elif o== '--show-rules' or o == '-s':
347                 show_rules (sys.stdout)
348                 sys.exit(0)
349         else:
350                 print o
351                 raise getopt.error
352
353
354 for f in files:
355         if f == '-':
356                 f = ''
357         try:
358                 do_one_file (f)
359         except UnknownVersion:
360                 pass