]> git.donarmstrong.com Git - lilypond.git/blobdiff - scripts/abc2ly.py
release: 1.5.18
[lilypond.git] / scripts / abc2ly.py
index ed92da172a209791c823199c3283332c0a4fd273..6428e0f1054aa4fb6ff2cbc6062da1b4a01c10fd 100644 (file)
@@ -67,6 +67,7 @@ import os
 
 UNDEF = 255
 state = UNDEF
+strict = 0
 voice_idx_dict = {}
 header = {}
 header['footnotes'] = ''
@@ -87,7 +88,14 @@ names = ["One", "Two", "Three"]
 DIGITS='0123456789'
 alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ"  
 HSPACE=' \t'
+midi_specs = ''
 
+
+def error (msg):
+       sys.stderr.write (msg)
+       if strict:
+               sys.exit (1)
+       
        
 def check_clef(s):
       if not s:
@@ -174,9 +182,13 @@ def dump_slyrics (outf):
        ks = voice_idx_dict.keys()
        ks.sort ()
        for k in ks:
+               if re.match('[1-9]', k):
+                       m = alphabet[string.atoi(k)]
+               else:
+                       m = k
                for i in range (len(slyrics[voice_idx_dict[k]])):
                        l=alphabet[i]
-                       outf.write ("\nwords%sV%s = \\lyrics  {" % (k, l))
+                       outf.write ("\nwords%sV%s = \\lyrics  {" % (m, l))
                        outf.write ("\n" + slyrics [voice_idx_dict[k]][i])
                        outf.write ("\n}")
 
@@ -185,7 +197,11 @@ def dump_voices (outf):
        ks = voice_idx_dict.keys()
        ks.sort ()
        for k in ks:
-               outf.write ("\nvoice%s = \\notes {" % k)
+               if re.match ('[1-9]', k):
+                       m = alphabet[string.atoi(k)]
+               else:
+                       m = k
+               outf.write ("\nvoice%s = \\notes {" % m)
                dump_default_bar(outf)
                if repeat_state[voice_idx_dict[k]]:
                        outf.write("\n\\repeat volta 2 {")
@@ -197,6 +213,23 @@ def dump_voices (outf):
                                outf.write("}")
                outf.write ("\n}")
 
+def try_parse_q(a):
+       global midi_specs
+       #assume that Q takes the form "Q:1/4=120"
+       #There are other possibilities, but they are deprecated
+       if string.count(a, '/') == 1:
+               array=string.split(a,'/')
+               numerator=array[0]
+               if numerator != 1:
+                       sys.stderr.write("abc2ly: Warning, unable to translate a Q specification with a numerator of %s: %s\n" % (numerator, a))
+               array2=string.split(array[1],'=')
+               denominator=array2[0]
+               perminute=array2[1]
+               duration=str(string.atof(denominator)/string.atoi(numerator))
+               midi_specs=string.join(["\\tempo", duration, "=", perminute])
+       else:
+               sys.stderr.write("abc2ly: Warning, unable to parse Q specification: %s\n" % a)
+        
 def dump_score (outf):
        outf.write (r"""\score{
         \notes <
@@ -205,6 +238,10 @@ def dump_score (outf):
        ks  = voice_idx_dict.keys ();
        ks.sort ()
        for k in  ks:
+               if re.match('[1-9]', k):
+                       m = alphabet[string.atoi(k)]
+               else:
+                       m = k
                if k == 'default' and len (voice_idx_dict) > 1:
                        break
                if len ( slyrics [voice_idx_dict[k]] ):
@@ -212,22 +249,26 @@ def dump_score (outf):
                outf.write ("\n\t\\context Staff=\"%s\"\n\t{\n" %k ) 
                if k != 'default':
                        outf.write ("\t    \\voicedefault\n")
-               outf.write ("\t    \\voice%s " % k)
+               outf.write ("\t    \\voice%s " % m)
                outf.write ("\n\t}\n")
                if len ( slyrics [voice_idx_dict[k]] ):
                        outf.write ("\n\t\\context Lyrics=\"%s\" \n\t<\t" % k)
+                       if re.match('[1-9]',k):
+                               m = alphabet[string.atoi(k)]
+                       else:
+                               m = k
                        for i in range (len(slyrics[voice_idx_dict[k]])):
                                l=alphabet[i]
-                               outf.write("\n\t  { \\words%sV%s }" % ( k, l) )
+                               outf.write("\n\t  { \\words%sV%s }" % ( m, l) )
                        outf.write ( "\n\t>\n" )
        outf.write ("\n    >")
        outf.write ("\n\t\\paper {\n")
        if part_names:
                outf.write ("\t    \\translator \n\t    {\n")
                outf.write ("\t\t\\StaffContext\n")
-               outf.write ("\t\t\\consists Staff_margin_engraver\n")
+#              outf.write ("\t\t\\consists Staff_margin_engraver\n")
                outf.write ("\t    }\n")
-       outf.write ("\t}\n\t\\midi {}\n}\n")
+       outf.write ("\t}\n\t\\midi {%s}\n}\n" % midi_specs)
 
 
 
@@ -424,6 +465,7 @@ def compute_key (k):
                key_count = flat_key_seq.index (keytup)
                accseq = map (lambda x: (3*x + 3 ) % 7, range (1, key_count + 1))
        else:
+               error ("Huh?")
                raise "Huh"
        
        key_table = [0] * 7
@@ -615,7 +657,8 @@ def try_parse_header_line (ln, state):
                        lyrics_append(a)
                if g == 'w':    # vocals
                        slyrics_append (a)
-
+               if g == 'Q':    #tempo
+                       try_parse_q (a)
                return ''
        return ln
 
@@ -1192,8 +1235,7 @@ def parse_file (fn):
                        ln = junk_space (ln)
 
                if ln:
-                       msg = "%s: %d: Huh?  Don't understand\n" % (fn, lineno)
-                       sys.stderr.write (msg)
+                       error ("%s: %d: Huh?  Don't understand\n" % (fn, lineno))
                        left = orig_ln[0:-len (ln)]
                        sys.stderr.write (left + '\n')
                        sys.stderr.write (' ' *  len (left) + ln + '\n')        
@@ -1212,7 +1254,8 @@ Options:
   -h, --help          this help
   -o, --output=FILE   set output filename to FILE
   -v, --version       version information
-
+  -s, --strict        be strict about succes.
+  
 This program converts ABC music files (see
 http://www.gre.ac.uk/~c.walshaw/abc2mtex/abc.txt) To LilyPond input.
 """
@@ -1222,7 +1265,7 @@ def print_version ():
 
 
 
-(options, files) = getopt.getopt (sys.argv[1:], 'vo:h', ['help','version', 'output='])
+(options, files) = getopt.getopt (sys.argv[1:], 'vo:hs', ['help','version', 'output=', 'strict'])
 out_filename = ''
 
 for opt in options:
@@ -1231,11 +1274,12 @@ for opt in options:
        if o== '--help' or o == '-h':
                help ()
                sys.exit (0)
-       if o == '--version' or o == '-v':
+       elif o == '--version' or o == '-v':
                print_version ()
                sys.exit(0)
-               
-       if o == '--output' or o == '-o':
+       elif o == '--strict' or o == '-s':
+               strict = 1
+       elif o == '--output' or o == '-o':
                out_filename = a
        else:
                print o