]> git.donarmstrong.com Git - lilypond.git/blob - scripts/convert-mudela.py
release: 1.0.1
[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.stdout.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
154 ############################
155
156 def get_conversions (from_version, to_version):
157         def version_b (v, f = from_version, t = to_version):
158                 return version_cmp (v[0], f) > 0 and version_cmp (v[0], t) <= 0
159         return filter (version_b, conversions)
160
161
162 def latest_version ():
163         return conversions[-1][0]
164
165 def do_conversion (infile, from_version, outfile, to_version):
166         
167         conv_list = get_conversions (from_version, to_version)
168
169         sys.stderr.write ('Applying conversions: ')
170         lines = infile.readlines();
171         last_conversion = ()
172         try:
173                 for x in conv_list:
174                         sys.stderr.write (tup_to_str (x[0])  + ', ')
175                         lines = x[1] (lines)
176                         last_conversion = x[0]
177                         
178                 sys.stderr.write ('\n')
179
180         except FatalConversionError:
181                 sys.stderr.write ('Error while converting; I won\'t convert any further')
182
183         for x in lines:
184                 if last_conversion:
185                         x = regsub.sub (mudela_version_re_str, '\\version \"%s\"' % tup_to_str (last_conversion), x)
186                 outfile.write(x)
187
188 class UnknownVersion:
189         pass
190
191 def do_one_file (infile_name):
192         outfile_name = ''
193         if __main__.edit:
194                 outfile_name = infile_name + '.NEW'
195         elif __main__.outfile_name:
196                 outfile_name = __main__.outfile_name
197
198         if __main__.from_version:
199                 from_version = __main__.from_version
200         else:
201                 guess = guess_mudela_version (infile_name)
202                 if not guess:
203                         raise UnknownVersion()
204                 from_version = str_to_tuple (guess)
205
206         if __main__.to_version:
207                 to_version = __main__.to_version
208         else:
209                 to_version = latest_version ()
210
211
212         if infile_name:
213                 infile = open (infile_name,'r')
214         else:
215                 infile = sys.stdin
216
217         if outfile_name:
218                 outfile =  open (outfile_name, 'w')
219         else:
220                 outfile = sys.stdout
221
222         
223         do_conversion (infile, from_version, outfile, to_version)
224
225         if __main__.edit:
226                 os.rename (infile_name, infile_name + '~')
227                 os.rename (infile_name + '.NEW', infile_name)
228
229
230 edit = 0
231 to_version = ()
232 from_version = ()
233 outfile_name = ''
234
235 identify ()
236 (options, files) = getopt.getopt (
237         sys.argv[1:], 'f:t:seh', ['show-rules', 'help', 'edit', 'from', 'to'])
238
239 for opt in options:
240         o = opt[0]
241         a = opt[1]
242         if o== '--help' or o == '-h':
243                 help ()
244         elif o== '--from' or o=='-f':
245                 from_version = str_to_tuple (a)
246         elif o== '--to' or o=='-t':
247                 to_version = str_to_tuple (a)
248         elif o== '--edit' or o == '-e':
249                 edit = 1
250         elif o== '--show-rules' or o == '-s':
251                 show_rules (sys.stdout)
252                 sys.exit(0)
253         else:
254                 print o
255                 raise getopt.error
256
257
258 for f in files:
259         if f == '-':
260                 f = ''
261         try:
262                 do_one_file (f)
263         except UnknownVersion:
264                 pass