]> git.donarmstrong.com Git - lilypond.git/blob - scripts/convert-mudela.py
6481c5b77b5876abb058a40aec6e9f6a7b561403
[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\n')
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\n'))
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\n'))
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\n')
179                 return lines
180         
181         conversions.append ((1,0,2), conv, '\header { key = concat + with + operator }\n')
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\n')
192 if 1:
193         def conv(lines):
194                 newlines =[]
195                 for x in lines:
196                         x =  regsub.gsub ('default_paper *=', '',x)
197                         x =  regsub.gsub ('default_midi *=', '',x)                      
198                         newlines.append (x)
199                 return newlines
200         
201         conversions.append ((1,0,4), conv, 'default_{paper,midi}\n')
202
203 if 1:
204         def conv(lines):
205                 newlines =[]
206                 for x in lines:
207                         x =  regsub.gsub ('ChoireStaff', 'ChoirStaff',x)
208                         x =  regsub.gsub ('\\output', 'output = ',x)
209                         newlines.append (x)
210                 return newlines
211         
212         conversions.append ((1,0,5), conv, 'ChoireStaff -> ChoirStaff\n')
213
214 if 1:
215         def conv(lines):
216                 newlines =[]
217                 found = 0
218                 for x in lines:
219                         found = regex.search ('[a-zA-Z]+ = *\\translator',x) <> -1
220                         newlines.append (x)
221                         if found: break
222                 if found:
223                         sys.stderr.write ('\nNot smart enough to \\translator syntax\n')
224                         raise FatalConversionError()
225                 return newlines
226         
227         conversions.append ((1,0,6), conv, 'foo = \\translator {\type .. } ->\translator {\type ..; foo; }\n')
228 ############################
229
230 def get_conversions (from_version, to_version):
231         def version_b (v, f = from_version, t = to_version):
232                 return version_cmp (v[0], f) > 0 and version_cmp (v[0], t) <= 0
233         return filter (version_b, conversions)
234
235
236 def latest_version ():
237         return conversions[-1][0]
238
239 def do_conversion (infile, from_version, outfile, to_version):
240         
241         conv_list = get_conversions (from_version, to_version)
242
243         sys.stderr.write ('Applying conversions: ')
244         lines = infile.readlines();
245         last_conversion = ()
246         try:
247                 for x in conv_list:
248                         sys.stderr.write (tup_to_str (x[0])  + ', ')
249                         lines = x[1] (lines)
250                         last_conversion = x[0]
251                         
252
253         except FatalConversionError:
254                 sys.stderr.write ('Error while converting; I won\'t convert any further')
255
256         for x in lines:
257                 if last_conversion:
258                         x = regsub.sub (mudela_version_re_str, '\\version \"%s\"' % tup_to_str (last_conversion), x)
259                 outfile.write(x)
260
261 class UnknownVersion:
262         pass
263
264 def do_one_file (infile_name):
265         sys.stderr.write ('Processing `%s\' ... '% infile_name)
266         outfile_name = ''
267         if __main__.edit:
268                 outfile_name = infile_name + '.NEW'
269         elif __main__.outfile_name:
270                 outfile_name = __main__.outfile_name
271
272         if __main__.from_version:
273                 from_version = __main__.from_version
274         else:
275                 guess = guess_mudela_version (infile_name)
276                 if not guess:
277                         raise UnknownVersion()
278                 from_version = str_to_tuple (guess)
279
280         if __main__.to_version:
281                 to_version = __main__.to_version
282         else:
283                 to_version = latest_version ()
284
285
286         if infile_name:
287                 infile = open (infile_name,'r')
288         else:
289                 infile = sys.stdin
290
291         if outfile_name:
292                 outfile =  open (outfile_name, 'w')
293         else:
294                 outfile = sys.stdout
295
296         
297         do_conversion (infile, from_version, outfile, to_version)
298
299         if infile_name:
300                 infile.close ()
301
302         if outfile_name:
303                 outfile.close ()
304
305         if __main__.edit:
306                 os.rename (infile_name, infile_name + '~')
307                 os.rename (infile_name + '.NEW', infile_name)
308
309         sys.stderr.write ('\n')
310
311 edit = 0
312 to_version = ()
313 from_version = ()
314 outfile_name = ''
315
316 identify ()
317 (options, files) = getopt.getopt (
318         sys.argv[1:], 'f:t:seh', ['show-rules', 'help', 'edit', 'from', 'to'])
319
320 for opt in options:
321         o = opt[0]
322         a = opt[1]
323         if o== '--help' or o == '-h':
324                 help ()
325         elif o== '--from' or o=='-f':
326                 from_version = str_to_tuple (a)
327         elif o== '--to' or o=='-t':
328                 to_version = str_to_tuple (a)
329         elif o== '--edit' or o == '-e':
330                 edit = 1
331         elif o== '--show-rules' or o == '-s':
332                 show_rules (sys.stdout)
333                 sys.exit(0)
334         else:
335                 print o
336                 raise getopt.error
337
338
339 for f in files:
340         if f == '-':
341                 f = ''
342         try:
343                 do_one_file (f)
344         except UnknownVersion:
345                 pass