X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scripts%2Fabc2ly.py;h=9107b8b8665903738a68586851738831d5a5b666;hb=38d7d319eabc906e82fb42002678c6d42a23b6f7;hp=ba60c1cfeeb447230de77f191f2020c2e31f1576;hpb=1bcd0c6e8f193767c6b4bd21db7e4f4a229a9029;p=lilypond.git diff --git a/scripts/abc2ly.py b/scripts/abc2ly.py index ba60c1cfee..9107b8b866 100644 --- a/scripts/abc2ly.py +++ b/scripts/abc2ly.py @@ -5,7 +5,7 @@ # ... # # (not finished.) -# ABC standard v1.6: http://www.gre.ac.uk/~c.walshaw/abc2mtex/abc.txt +# ABC standard v1.6: http://www.walshaw.plus.com/abc/ # # Enhancements (Roy R. Rankin) # @@ -33,6 +33,7 @@ # %%LY now supported. # \breve and \longa supported. # M:none doesn't crash lily. +# lilypond '--' supported. # Enhancements (Guy Gascoigne-Piggford) # @@ -57,6 +58,7 @@ #TODO: # +# * coding style # * lilylib # * GNU style messages: warning:FILE:LINE: # * l10n @@ -71,22 +73,14 @@ import __main__ import getopt import sys import re -import string import os program_name = sys.argv[0] -for d in ['@lilypond_datadir@', - '@lilypond_libdir@']: - sys.path.insert (0, os.path.join (d, 'python')) - -# dynamic relocation, for GUB binaries. -bindir = os.path.abspath (os.path.split (sys.argv[0])[0]) -for p in ['share', 'lib']: - datadir = os.path.abspath (bindir + '/../%s/lilypond/current/python/' % p) - sys.path.insert (0, datadir) - +""" +@relocate-preamble@ +""" import lilylib as ly global _;_=ly._ @@ -123,7 +117,7 @@ def error (msg): sys.stderr.write (msg) if global_options.strict: sys.exit (1) - + def alphabet (i): return chr (i + ord('A')) @@ -217,12 +211,12 @@ def dump_slyrics (outf): ks.sort () for k in ks: if re.match('[1-9]', k): - m = alphabet(string.atoi(k)) + m = alphabet (int (k)) else: m = k for i in range (len(slyrics[voice_idx_dict[k]])): l= alphabet(i) - outf.write ("\nwords%sV%s = \lyricmode {" % (m, l)) + outf.write ("\nwords%sV%s = \\lyricmode {" % (m, l)) outf.write ("\n" + slyrics [voice_idx_dict[k]][i]) outf.write ("\n}") @@ -232,7 +226,7 @@ def dump_voices (outf): ks.sort () for k in ks: if re.match ('[1-9]', k): - m = alphabet(string.atoi(k)) + m = alphabet (int (k)) else: m = k outf.write ("\nvoice%s = {" % m) @@ -251,19 +245,19 @@ 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,'/') + if a.count ('/') == 1: + array = a.split('/') numerator=array[0] - if numerator != 1: + if int(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],'=') + array2 = array[1].split ('=') denominator=array2[0] perminute=array2[1] - duration=str(string.atoi(denominator)/string.atoi(numerator)) - midi_specs=string.join(["\\tempo", duration, "=", perminute]) + duration = str (int (denominator) / int (numerator)) + midi_specs = ' '.join(["\n\t\t\\context {\n\t\t \\Score tempoWholesPerMinute = #(ly:make-moment ", perminute, " ", duration, ")\n\t\t }\n"]) else: sys.stderr.write("abc2ly: Warning, unable to parse Q specification: %s\n" % a) - + def dump_score (outf): outf.write (r""" @@ -275,7 +269,7 @@ def dump_score (outf): ks.sort () for k in ks: if re.match('[1-9]', k): - m = alphabet (string.atoi(k)) + m = alphabet (int (k)) else: m = k if k == 'default' and len (voice_idx_dict) > 1: @@ -288,9 +282,9 @@ def dump_score (outf): l = ord( 'A' ) for lyrics in slyrics [voice_idx_dict[k]]: - outf.write ("\n\t\\addlyrics { \n") + outf.write ("\n\t\\addlyrics {\n") if re.match('[1-9]',k): - m = alphabet (string.atoi(k)) + m = alphabet (int (k)) else: m = k @@ -307,14 +301,14 @@ def set_default_length (s): global length_specified m = re.search ('1/([0-9]+)', s) if m: - __main__.default_len = string.atoi ( m.group (1)) + __main__.default_len = int ( m.group (1)) length_specified = 1 def set_default_len_from_time_sig (s): m = re.search ('([0-9]+)/([0-9]+)', s) if m: - n = string.atoi (m.group (1)) - d = string.atoi (m.group (2)) + n = int (m.group (1)) + d = int (m.group (2)) if (n * 1.0 )/(d * 1.0) < 0.75: __main__.default_len = 16 else: @@ -327,7 +321,7 @@ def gulp_file(f): n = i.tell () i.seek (0,0) except: - sys.stderr.write ("can't open file: `%s'\n" % f) + sys.stderr.write ("cannot open file: `%s'\n" % f) return '' s = i.read (n) if len (s) <= 0: @@ -413,7 +407,7 @@ key_lookup = { # abc to lilypond key mode names def lily_key (k): orig = "" + k # UGR - k = string.lower (k) + k = k.lower () key = k[0] #UGH k = k[1:] @@ -471,7 +465,7 @@ key_shift = { # semitone shifts for key mode names 'dorian' : -2 } def compute_key (k): - k = string.lower (k) + k = k.lower () intkey = (ord (k[0]) - ord('a') + 5) % 7 intkeyacc =0 k = k[1:] @@ -503,7 +497,7 @@ def compute_key (k): accseq = map (lambda x: (3*x + 3 ) % 7, range (1, key_count + 1)) else: error ("Huh?") - raise "Huh" + raise Exception ("Huh") key_table = [0] * 7 for a in accseq: @@ -527,7 +521,7 @@ def try_parse_tuplet_begin (str, state): dig = str[1] str = str[2:] prev_tuplet_state = state.parsing_tuplet - state.parsing_tuplet = string.atoi (dig[0]) + state.parsing_tuplet = int (dig[0]) if prev_tuplet_state: voices_append ("}") voices_append ("\\times %s {" % tup_lookup[dig]) @@ -546,7 +540,7 @@ def header_append (key, a): header [key] = s + a def wordwrap(a, v): - linelen = len (v) - string.rfind(v, '\n') + linelen = len (v) - v.rfind ('\n') if linelen + len (a) > 80: v = v + '\n' return v + a + ' ' @@ -616,7 +610,7 @@ def fix_lyric(str): def slyrics_append(a): a = re.sub ( '_', ' _ ', a) # _ to ' _ ' - a = re.sub ( '-', '- ', a) # split words with - + a = re.sub ( '([^-])-([^-])', '\\1- \\2', a) # split words with "-" unless was originally "--" a = re.sub ( '\\\\- ', '-', a) # unless \- a = re.sub ( '~', '_', a) # ~ to space('_') a = re.sub ( '\*', '_ ', a) # * to to space @@ -656,12 +650,12 @@ def try_parse_header_line (ln, state): if a == 'C': if not state.common_time: state.common_time = 1 - voices_append (" \\override Staff.TimeSignature #\'style = #'C\n") + voices_append (" \\override Staff.TimeSignature #'style = #'C\n") a = '4/4' if a == 'C|': if not state.common_time: state.common_time = 1 - voices_append ("\\override Staff.TimeSignature #\'style = #'C\n") + voices_append ("\\override Staff.TimeSignature #'style = #'C\n") a = '2/2' if not length_specified: set_default_len_from_time_sig (a) @@ -769,7 +763,7 @@ def parse_num (str): n = None if durstr: - n =string.atoi (durstr) + n = int (durstr) return (str,n) @@ -785,7 +779,7 @@ def duration_to_lilypond_duration (multiply_tup, defaultlen, dots): base = '\\breve' dots = 1 if (multiply_tup[0] / multiply_tup[1]) == 4: - base = '\longa' + base = '\\longa' return '%s%s' % ( base, '.'* dots) class Parser_state: @@ -889,6 +883,8 @@ artic_tbl = { '~' : '^"~" ', 'J' : '', # ignore slide 'R' : '', # ignore roll + 'S' : '^\\segno', + 'O' : '^\\coda', 'v' : '^\\downbow' } @@ -904,7 +900,7 @@ def try_parse_articulation (str, state): # s7m2 input doesnt care about spaces if re.match('[ \t]*\(', str): - str = string.lstrip (str) + str = str.lstrip () slur_begin =0 while str[:1] =='(' and str[1] not in DIGITS: @@ -932,9 +928,8 @@ def get_bar_acc(note, octave, state): return(UNDEF) def clear_bar_acc(state): - for k in state.in_acc.keys(): - del state.in_acc[k] - + state.in_acc = {} + # if we are parsing a beam, close it off def close_beam_state(state): @@ -965,7 +960,7 @@ def try_parse_note (str, parser_state): octave = parser_state.base_octave if str[0] in "ABCDEFG": - str = string.lower (str[0]) + str[1:] + str = str[0].lower () + str[1:] octave = octave - 1 @@ -993,7 +988,7 @@ def try_parse_note (str, parser_state): (str, num,den,current_dots) = parse_duration (str, parser_state) if re.match('[ \t]*\)', str): - str = string.lstrip (str) + str = str.lstrip () slur_end =0 while str[:1] ==')': @@ -1176,7 +1171,7 @@ def try_parse_bar (str,state): close_beam_state(state) voices_append (bs) if do_curly != '': - voices_append("} }") + voices_append("} ") do_curly = '' return str @@ -1262,14 +1257,14 @@ def try_parse_comment (str): #convention, such as most music written before 1700, or ethnic music in #non-western scales, it is necessary to be able to tell a translator that #the barlines should not affect its interpretation of the pitch. - if (string.find(str,'nobarlines') > 0): + if 'nobarlines' in str: nobarlines = 1 elif str[0:3] == '%LY': - p = string.find(str, 'voices') + p = str.find ('voices') if (p > -1): voices_append(str[p+7:]) voices_append("\n") - p = string.find(str, 'slyrics') + p = str.find ('slyrics') if (p > -1): slyrics_append(str[p+8:]) @@ -1335,7 +1330,7 @@ def identify(): sys.stderr.write ("%s from LilyPond %s\n" % (program_name, version)) authors = """ -Written by Han-Wen Nienhuys , Laura Conrad +Written by Han-Wen Nienhuys , Laura Conrad , Roy Rankin . """ @@ -1343,28 +1338,39 @@ def print_version (): print r"""abc2ly (GNU lilypond) %s""" % version def get_option_parser (): - p = ly.get_option_parser (usage='abc2ly [OPTIONS] FILE', - version="abc2ly (LilyPond) @TOPLEVEL_VERSION@", - description=_('''This program converts ABC music files (see -http://www.gre.ac.uk/~c.walshaw/abc2mtex/abc.txt) to LilyPond input.''')) - - p.add_option ('-o', '--output', metavar='FILE',help=_("set output filename to FILE"), - action='store') - p.add_option ('-s', '--strict', help=_("be strict about succes"), - action='store_true') - p.add_option ('-b', '--beams', help=_("preserve ABC's notion of beams")) - p.add_option_group ('bugs', - description='''Report bugs via http://post.gmane.org/post.php''' - '''?group=gmane.comp.gnu.lilypond.bugs\n''') - + p = ly.get_option_parser (usage=_ ("%s [OPTION]... FILE") % 'abc2ly', + description=_ ('''abc2ly converts ABC music files (see +%s) to LilyPond input. +''') % 'http://www.gre.ac.uk/~c.walshaw/abc2mtex/abc.txt', + add_help_option=False) + + p.version = "abc2ly (LilyPond) @TOPLEVEL_VERSION@" + p.add_option("--version", + action="version", + help=_ ("show version number and exit")) + + p.add_option("-h", "--help", + action="help", + help=_ ("show this help and exit")) + p.add_option ('-o', '--output', metavar='FILE', + help=_ ("write output to FILE"), + action='store') + p.add_option ('-s', '--strict', help=_ ("be strict about success"), + action='store_true') + p.add_option ('-b', '--beams', help=_ ("preserve ABC's notion of beams")) + p.add_option_group ('', + description=( + _ ('Report bugs via %s') + % 'http://post.gmane.org/post.php' + '?group=gmane.comp.gnu.lilypond.bugs') + '\n') return p -option_parser = get_option_parser() -(global_options, files) = option_parser.parse_args() +option_parser = get_option_parser () +(global_options, files) = option_parser.parse_args () -identify() +identify () header['tagline'] = 'Lily was here %s -- automatically converted from ABC' % version for f in files: