]> git.donarmstrong.com Git - lilypond.git/blob - scripts/abc-2-ly.py
f1e5dd9ab799a8aedae817078a4d20884e7e416b
[lilypond.git] / scripts / abc-2-ly.py
1 #!@PYTHON@
2
3 # once upon a rainy monday afternoon.
4 #
5 #   ...
6 #
7 # (not finished.)
8
9
10 name = 'abc-to-ly'
11 version = '0.1'
12
13 import getopt
14 import sys
15 import re
16 import string
17 header = {}
18 global_voice_stuff = []
19 default_len = 4
20
21
22 def dump_header (hdr):
23         print '\\header {'
24         for k in hdr.keys ():
25                 print '%s = "%s";\n'% (k,hdr[k])
26         print '};'
27
28 def set_default_length (s):
29         m =  re.match ('1/(.*)$', s)
30         if m:
31                 default_len = string.atoi ( m.group (1))
32
33 def parse_timesig (s):
34         m =  re.match ('^M: *(.*)$', s)
35         if m:
36                 print '\meter %s; ' % m.group (1)
37
38 def parse_key (s):
39         m =  re.match ('^K: *(.*)$', s)
40         if m:
41                 print '\key %s; ' % m.group (1)
42         
43 def gulp_file(f):
44         try:
45                 i = open(f)
46                 i.seek (0, 2)
47                 n = i.tell ()
48                 i.seek (0,0)
49         except:
50                 print 'can\'t open file: ' + f + '\n'
51                 return ''
52         s = i.read (n)
53         if len (s) <= 0:
54                 print 'gulped empty file: ' + f + '\n'
55         i.close ()
56         return s
57
58
59 def try_parse_header_line (ln):
60         m = re.match ('^(.): *(.*)$', ln)
61
62         if m:
63                 g =m.group (1)
64                 a = m.group (2)
65                 if g == 'T':
66                         header['title'] =  a
67                 if g == 'M':
68                         global_voice_stuff.append ('\\time %s;' % a)
69                 if g == 'K':
70                         global_voice_stuff.append ('\\key %s;' % a)
71                 if g == 'O': 
72                         header ['origin'] = a
73                 if g == 'X': 
74                         header ['crossRefNumber'] = a
75
76                 if g == 'A':
77                         header ['area'] = a
78                 if g == 'H':
79                         header ['history'] = a
80                 if g == 'B':
81                         header ['book'] = a
82                 if g == 'S':
83                         header ['subtitle'] = a
84                 if g == 'L':
85                         set_default_length (ln)
86         
87
88         return m
89
90
91 # WAT IS ABC EEN ONTZETTENDE PROGRAMMEERPOEP  !
92
93 def try_parse_note (str):
94         mud = ''
95
96         slur_begin =0
97         if str[0] == '(':
98                 slur_begin = 1
99                 str = str[1:]
100
101         acc = None
102         if str[0] in '^=_':
103                 c = str[0]
104                 str = str[1:]
105                 if c == '^':
106                         acc = 1
107                 if c == '=':
108                         acc = 0
109                 if c == '_':
110                         acc = -1
111
112         octave = 0;
113         if str[0] in "ABCDEFG":
114                 str = string.lower (str[0]) + str[1:]
115                 octave = -1
116
117
118         notename = 0
119         if str[0] in "abcdefg":
120                 notename = ord(str[0]) - ord('a')
121                 str = str[1:]
122         else:
123                 return str              # failed; not a note!
124
125         while str[0] == ',':
126                  octave = octave - 1
127                  str = str[1:]
128         while str[0] == '\'':
129                  octave = octave + 1
130                  str = str[1:]
131         divide =0
132         if str[0] == '/':
133                 divide =1
134                 str = str[1:]
135         durstr = ''
136         while str[0] in "1234567890":
137                 durstr = durstr + str[0]
138                 str = str[1:]
139
140         duration_mult = 1
141         if durstr:
142                 duration_mult = string.atoi (durstr)
143
144         
145         slur_end =0
146         if str[0] == ')':
147                 slur_begin = 1
148                 str = str[1:]
149
150
151         return str
152
153 def junk_space (str):
154         while str and str[0] in '\t\n ':
155                 str = str[1:]
156
157         return str
158
159 def try_parse_bar (str):
160         if str[0] == '|':
161                 str = str[1:]
162         return str
163         
164 def try_parse_body_line (ln):
165         prev_ln = ''
166         while ln and  ln != prev_ln:
167                 prev_ln = ln
168                 ln = try_parse_note  (ln)
169                 ln = try_parse_bar (ln)
170                 ln = junk_space (ln)
171         if ln:
172                 print 'Huh %s' % ln
173                 
174
175 def parse_file (fn):
176         f = open (fn)
177         ls = f.readlines ()
178
179         head = 1
180         for l in ls:
181                 if re.match ('^[\t ]*(%.*)?$', l):
182                         continue
183                 
184                 if head:
185                         m = try_parse_header_line (l)
186                         if not m:
187                                 head = 0
188
189                 if not head:
190                         m = try_parse_body_line (l)
191
192
193 def identify():
194         print '%s %s' % (name, version)
195
196 def help ():
197         print r"""
198 This is a disfunctional ABC to mudela convertor.  It only gulps input, and
199 says huh when confused.  Does not do chords.  Go ahead and fix me.
200
201 -h, --help   this help.
202 """
203
204 identify()
205 (options, files) = getopt.getopt (sys.argv[1:], 'h', ['help'])
206
207 for opt in options:
208         o = opt[0]
209         a = opt[1]
210         if o== '--help' or o == '-h':
211                 help ()
212         else:
213                 print o
214                 raise getopt.error
215
216
217 for f in files:
218         if f == '-':
219                 f = ''
220         
221         parse_file (f)
222         dump_header (header)
223         print global_voice_stuff, 1
224