X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scripts%2Fabc2ly.py;h=c58c6ef9e753b1e85b977d88da30baa52b493242;hb=35c150fac724457b125d6cdb82124b57fee05659;hp=9107b8b8665903738a68586851738831d5a5b666;hpb=7f3f0083f89d87c5ed0422858e9648fc759e98a4;p=lilypond.git diff --git a/scripts/abc2ly.py b/scripts/abc2ly.py index 9107b8b866..c58c6ef9e7 100644 --- a/scripts/abc2ly.py +++ b/scripts/abc2ly.py @@ -1,11 +1,28 @@ #!@TARGET_PYTHON@ # -*- coding: utf-8 -*- + # once upon a rainy monday afternoon. + +# This file is part of LilyPond, the GNU music typesetter. +# +# LilyPond is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# LilyPond is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with LilyPond. If not, see . + # # ... # # (not finished.) -# ABC standard v1.6: http://www.walshaw.plus.com/abc/ +# ABC standard v1.6: http://abcnotation.com/ # # Enhancements (Roy R. Rankin) # @@ -123,32 +140,45 @@ def alphabet (i): return chr (i + ord('A')) def check_clef(s): + # the number gives the base_octave + clefs = [("treble", "treble", 0), + ("treble1", "french", 0), + ("bass3", "varbaritone", 0), + ("bass", "bass", 0), + ("alto4", "tenor", 0), + ("alto2", "mezzosoprano", 0), + ("alto1", "soprano", 0), + ("alto", "alto", 0), + ("perc", "percussion", 0)] + modifier = [("-8va", "_8", -1), + ("-8", "_8", -1), + ("\+8", "^8", +1), + ("8", "_8", -1)] + if not s: return '' - if re.match('-8va', s) or re.match('treble8', s): - # treble8 is used by abctab2ps; -8va is used by barfly, - # and by my patch to abc2ps. If there's ever a standard - # about this we'll support that. - s = s[4:] - state.base_octave = -1 - voices_append("\\clef \"G_8\"\n") - elif re.match('^treble', s): - s = s[6:] - if re.match ('^-8', s): - s = s[2:] - state.base_octave = -2 - voices_append("\\clef \"G_8\"\n") - else: - state.base_octave = 0 - voices_append("\\clef treble\n") - elif re.match('^alto', s): - s = s[4:] - state.base_octave = -1 - voices_append ("\\clef alto\n" ) - elif re.match('^bass',s ): - s = s[4:] - state.base_octave = -2 - voices_append ("\\clef bass\n" ) + clef = None; + octave = 0; + for c in clefs: + m = re.match('^'+c[0], s) + if m: + (clef, octave) = (c[1], c[2]) + s = s[m.end():] + break; + if not clef: + return s + + mod = ""; + for md in modifier: + m = re.match('^'+md[0], s) + if m: + mod = md[1]; + octave += md[2]; + s = s[m.end():] + break; + + state.base_octave = octave + voices_append ("\\clef \""+clef+mod+"\"\n") return s def select_voice (name, rol): @@ -242,19 +272,17 @@ def dump_voices (outf): outf.write ("\n}") def try_parse_q(a): - global midi_specs - #assume that Q takes the form "Q:1/4=120" + #assume that Q takes the form "Q:'opt. description' 1/4=120" #There are other possibilities, but they are deprecated - if a.count ('/') == 1: - array = a.split('/') - numerator=array[0] - 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 = array[1].split ('=') - denominator=array2[0] - perminute=array2[1] - 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"]) + r = re.compile ('^(.*) *([0-9]+) */ *([0-9]+) *=* *([0-9]+)\s*') + m = r.match (a) + if m: + descr = m.group(1) # possibly empty + numerator = int(m.group (2)) + denominator = int(m.group (3)) + tempo = m.group (4) + dur = duration_to_lilypond_duration ((numerator,denominator), 1, 0) + voices_append ("\\tempo " + descr + " " + dur + "=" + tempo + "\n") else: sys.stderr.write("abc2ly: Warning, unable to parse Q specification: %s\n" % a) @@ -667,16 +695,19 @@ def try_parse_header_line (ln, state): if g == 'K': # KEY a = check_clef(a) if a: - m = re.match ('^([^ \t]*) *(.*)$', a) # seperate clef info + m = re.match ('^([^ \t]*) *([^ ]*)( *)(.*)$', a) # seperate clef info if m: # there may or may not be a space # between the key letter and the mode - if key_lookup.has_key(m.group(2)[0:3]): - key_info = m.group(1) + m.group(2)[0:3] - clef_info = m.group(2)[4:] + # convert the mode to lower-case before comparing + mode = m.group(2)[0:3].lower(); + if key_lookup.has_key(mode): + # use the full mode, not only the first three letters + key_info = m.group(1) + m.group(2).lower() + clef_info = a[m.start(4):] else: key_info = m.group(1) - clef_info = m.group(2) + clef_info = a[m.start(2):] __main__.global_key = compute_key (key_info) k = lily_key (key_info) if k: @@ -1341,7 +1372,7 @@ def get_option_parser (): 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', +''') % 'http://abcnotation.com/abc2mtex/abc.txt', add_help_option=False) p.version = "abc2ly (LilyPond) @TOPLEVEL_VERSION@" @@ -1357,7 +1388,7 @@ def get_option_parser (): 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 ('-b', '--beams', help=_ ("preserve ABC's notion of beams"), action="store_true") p.add_option_group ('', description=( _ ('Report bugs via %s')