]> git.donarmstrong.com Git - lilypond.git/blob - scripts/convert-mudela.py
release: 1.0.8
[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.2'
18
19
20
21 import os
22 import sys
23 import __main__
24 import getopt
25 from string import *
26 import regex
27 import regsub
28 import time
29 mudela_version_re_str ='\\\\version *\"\(.*\)\"'
30 mudela_version_re = regex.compile(mudela_version_re_str)
31
32 def program_id ():
33         return '%s version %s' %(program_name,  version);
34
35 def identify ():
36         sys.stderr.write (program_id () + '\n')
37
38 def gulp_file(f):
39         try:
40                 i = open(f)
41                 i.seek (0, 2)
42                 n = i.tell ()
43                 i.seek (0,0)
44         except:
45                 print 'can\'t open file: ' + f + '\n'
46                 return ''
47         s = i.read (n)
48         if len (s) <= 0:
49                 print 'gulped empty file: ' + f + '\n'
50         i.close ()
51         return s
52
53
54 def str_to_tuple (s):
55         return tuple (map (atoi, split (s,'.')))
56
57 def tup_to_str (t):
58         return join (map (lambda x: '%s' % x, list (t)), '.')
59
60 def version_cmp (t1, t2):
61         for x in [0,1,2]:
62                 if t1[x] - t2[x]:
63                         return t1[x] - t2[x]
64         return 0
65                 
66
67 def guess_mudela_version(filename):
68         s = gulp_file (filename)
69         if mudela_version_re.search(s) <> -1:
70                 return mudela_version_re.group(1)
71         else:
72                 return ''
73
74 def help ():
75         sys.stdout.write (
76                 ("Usage: %s [OPTION]... [FILE]...\n" 
77                 + "Try to convert to newer mudela-versions\n"
78                 + "Options:\n"
79                 + "  -h, --help             print this help\n"
80                 + '  -e, --edit             in place edit\n'
81                 + '  -f, --from=VERSION     start from version\n'
82                 + '  -s, --show-rules       print out all rules.\n'
83                 + '  -t, --to=VERSION       target version\n') % program_name)
84         sys.exit (0)
85
86 class FatalConversionError:
87         pass
88
89 conversions = []
90
91 def show_rules (file):
92         for x in conversions:
93                 file.write  ('%s: %s\n' % (tup_to_str (x[0]), x[2]))
94
95 ############################
96                 
97 if 1:                                   # need new a namespace
98         def conv (lines):
99                 found =0
100                 for x in lines:
101                         if regex.search ('\\\\octave', x) <> -1:
102                                 found = 1
103                                 break
104                 if found:
105                         sys.stderr.write ('\nNot smart enough to convert \\octave\n')
106                         raise FatalConversionError()
107                 return lines
108                 
109
110         conversions.append (
111                 ((0,1,19), conv, 'deprecated \\octave; can\'t convert automatically'))
112
113
114 if 1:                                   # need new a namespace
115         def conv (lines):
116                 newlines = []
117                 for x in lines:
118                         x = regsub.gsub ('\\\\textstyle\\([^;]+\\);',
119                                          '\\\\property Lyrics . textstyle = \\1', x)
120                         x = regsub.gsub ('\\\\key\\([^;]+\\);', '\\\\accidentals \\1;', x)
121                         newlines.append (x)
122                 return newlines
123                 
124
125         conversions.append (
126                 ((0,1,20), conv, 'deprecated \\textstyle, new \key syntax'))
127
128
129 if 1:                                   # need new a namespace
130         def conv (lines):
131                 newlines = []
132                 for x in lines:
133                         x = regsub.gsub ('\\\\musical_pitch',
134                                          '\\\\musicalpitch',x)
135                         x = regsub.gsub ('\\\\meter',
136                                          '\\\\time',x)
137                         newlines.append (x)
138                 return newlines
139                 
140
141         conversions.append (
142                 ((0,1,21), conv, '\\musical_pitch -> \\musicalpitch, '+
143                  '\\meter -> \\time\n'))
144
145 if 1:                                   # need new a namespace
146         def conv (lines):
147                 return lines
148
149         conversions.append (
150                 ((1,0,0), conv, '0.1.21 -> 1.0.0 '))
151
152
153 if 1:                                   # need new a namespace
154         def conv (lines):
155                 newlines = []
156                 for x in lines:
157                         x = regsub.gsub ('\\\\accidentals',
158                                          '\\\\keysignature',x)
159                         x = regsub.gsub ('specialaccidentals *= *1',
160                                          'keyoctaviation = 0',x)
161                         x = regsub.gsub ('specialaccidentals *= *0',
162                                          'keyoctaviation = 1',x)
163                         newlines.append (x)
164                 return newlines
165                 
166
167         conversions.append (
168                 ((1,0,1), conv, '\\accidentals -> \\keysignature, ' +
169                  'specialaccidentals -> keyoctaviation\n'))
170
171 if 1:
172         def conv(lines):
173                 found = 0
174                 for x in lines:
175                         if regex.search ('\\\\header', x) <> -1:
176                                 found = 1
177                                 break
178                 if found:
179                         sys.stderr.write ('\nNot smart enough to convert to new \\header format\n')
180                 return lines
181         
182         conversions.append ((1,0,2), conv, '\header { key = concat + with + operator }\n')
183
184 ############################
185
186 def get_conversions (from_version, to_version):
187         def version_b (v, f = from_version, t = to_version):
188                 return version_cmp (v[0], f) > 0 and version_cmp (v[0], t) <= 0
189         return filter (version_b, conversions)
190
191
192 def latest_version ():
193         return conversions[-1][0]
194
195 def do_conversion (infile, from_version, outfile, to_version):
196         
197         conv_list = get_conversions (from_version, to_version)
198
199         sys.stderr.write ('Applying conversions: ')
200         lines = infile.readlines();
201         last_conversion = ()
202         try:
203                 for x in conv_list:
204                         sys.stderr.write (tup_to_str (x[0])  + ', ')
205                         lines = x[1] (lines)
206                         last_conversion = x[0]
207                         
208                 sys.stderr.write ('\n')
209
210         except FatalConversionError:
211                 sys.stderr.write ('Error while converting; I won\'t convert any further')
212
213         for x in lines:
214                 if last_conversion:
215                         x = regsub.sub (mudela_version_re_str, '\\version \"%s\"' % tup_to_str (last_conversion), x)
216                 outfile.write(x)
217
218 class UnknownVersion:
219         pass
220
221 def do_one_file (infile_name):
222         outfile_name = ''
223         if __main__.edit:
224                 outfile_name = infile_name + '.NEW'
225         elif __main__.outfile_name:
226                 outfile_name = __main__.outfile_name
227
228         if __main__.from_version:
229                 from_version = __main__.from_version
230         else:
231                 guess = guess_mudela_version (infile_name)
232                 if not guess:
233                         raise UnknownVersion()
234                 from_version = str_to_tuple (guess)
235
236         if __main__.to_version:
237                 to_version = __main__.to_version
238         else:
239                 to_version = latest_version ()
240
241
242         if infile_name:
243                 infile = open (infile_name,'r')
244         else:
245                 infile = sys.stdin
246
247         if outfile_name:
248                 outfile =  open (outfile_name, 'w')
249         else:
250                 outfile = sys.stdout
251
252         
253         do_conversion (infile, from_version, outfile, to_version)
254
255         if __main__.edit:
256                 os.rename (infile_name, infile_name + '~')
257                 os.rename (infile_name + '.NEW', infile_name)
258
259
260 edit = 0
261 to_version = ()
262 from_version = ()
263 outfile_name = ''
264
265 identify ()
266 (options, files) = getopt.getopt (
267         sys.argv[1:], 'f:t:seh', ['show-rules', 'help', 'edit', 'from', 'to'])
268
269 for opt in options:
270         o = opt[0]
271         a = opt[1]
272         if o== '--help' or o == '-h':
273                 help ()
274         elif o== '--from' or o=='-f':
275                 from_version = str_to_tuple (a)
276         elif o== '--to' or o=='-t':
277                 to_version = str_to_tuple (a)
278         elif o== '--edit' or o == '-e':
279                 edit = 1
280         elif o== '--show-rules' or o == '-s':
281                 show_rules (sys.stdout)
282                 sys.exit(0)
283         else:
284                 print o
285                 raise getopt.error
286
287
288 for f in files:
289         if f == '-':
290                 f = ''
291         try:
292                 do_one_file (f)
293         except UnknownVersion:
294                 pass