#!@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 <http://www.gnu.org/licenses/>.
+
#
# ...
#
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):
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}")
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)
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 (int (k))
else:
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)
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:
base = '\\breve'
dots = 1
if (multiply_tup[0] / multiply_tup[1]) == 4:
- base = '\longa'
+ base = '\\longa'
return '%s%s' % ( base, '.'* dots)
class Parser_state:
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')
- + ''' http://post.gmane.org/post.php'''
- '''?group=gmane.comp.gnu.lilypond.bugs\n'''))
+ description=(
+ _ ('Report bugs via %s')
+ % 'http://post.gmane.org/post.php'
+ '?group=gmane.comp.gnu.lilypond.bugs') + '\n')
return p