X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=scripts%2Fabc2ly.py;h=77d47d7dcdbd453f41d3fa47d9f784e752ff13d7;hb=743385b5b963ebece3924b4e84f89ebba36678f8;hp=be84071e9f817c0d679afb15c95ff716827b5964;hpb=c7555d70732969277c5e906285ec04e5b561c38e;p=lilypond.git
diff --git a/scripts/abc2ly.py b/scripts/abc2ly.py
index be84071e9f..77d47d7dcd 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)
#
@@ -62,12 +79,12 @@
# * lilylib
# * GNU style messages: warning:FILE:LINE:
# * l10n
-#
+#
# Convert to new chord styles.
#
# UNDEF -> None
#
-
+
import __main__
import getopt
@@ -87,7 +104,7 @@ global _;_=ly._
version = '@TOPLEVEL_VERSION@'
if version == '@' + 'TOPLEVEL_VERSION' + '@':
- version = '(unknown version)' # uGUHGUHGHGUGH
+ version = '(unknown version)' # uGUHGUHGHGUGH
UNDEF = 255
state = UNDEF
@@ -121,34 +138,47 @@ def error (msg):
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):
@@ -174,7 +204,7 @@ def select_voice (name, rol):
value = re.sub ('\\\\','\\\\\\\\', value)
## < 2.2
voices_append ("\\set Staff.instrument = %s\n" % value )
-
+
__main__.part_names = 1
elif keyword == "sname" or keyword == "snm":
voices_append ("\\set Staff.instr = %s\n" % value )
@@ -186,24 +216,24 @@ def dump_header (outf,hdr):
ks = hdr.keys ()
ks.sort ()
for k in ks:
- hdr[k] = re.sub('"', '\\"', hdr[k])
+ hdr[k] = re.sub('"', '\\"', hdr[k])
outf.write ('\t%s = "%s"\n'% (k,hdr[k]))
outf.write ('}')
def dump_lyrics (outf):
if (len(lyrics)):
- outf.write("\n\\score\n{\n \\lyrics\n <<\n")
+ outf.write("\n\\markup \\column {\n")
for i in range (len (lyrics)):
- outf.write ( lyrics [i])
+ outf.write (lyrics [i])
outf.write ("\n")
- outf.write(" >>\n \\layout{}\n}\n")
+ outf.write("}\n")
def dump_default_bar (outf):
"""
Nowadays abc2ly outputs explicits barlines (?)
"""
## < 2.2
- outf.write ("\n\\set Score.defaultBarType = \"empty\"\n")
+ outf.write ("\n\\set Score.defaultBarType = \"\"\n")
def dump_slyrics (outf):
@@ -216,7 +246,7 @@ def dump_slyrics (outf):
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}")
@@ -242,21 +272,27 @@ 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)
+ # Parsing of numeric tempi, as these are fairly
+ # common. The spec says the number is a "beat" so using
+ # a quarter note as the standard time
+ numericQ = re.compile ('[0-9]+')
+ m = numericQ.match (a)
+ if m:
+ voices_append ("\\tempo 4=" + m.group(0))
+ else:
+ sys.stderr.write("abc2ly: Warning, unable to parse Q specification: %s\n" % a)
def dump_score (outf):
outf.write (r"""
@@ -274,7 +310,7 @@ def dump_score (outf):
m = k
if k == 'default' and len (voice_idx_dict) > 1:
break
- outf.write ("\n\t\\context Staff=\"%s\"\n\t{\n" %k )
+ outf.write ("\n\t\\context Staff=\"%s\"\n\t{\n" %k )
if k != 'default':
outf.write ("\t \\voicedefault\n")
outf.write ("\t \\voice%s " % m)
@@ -282,7 +318,7 @@ 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 (int (k))
else:
@@ -332,17 +368,17 @@ def gulp_file(f):
# pitch manipulation. Tuples are (name, alteration).
# 0 is (central) C. Alteration -1 is a flat, Alteration +1 is a sharp
-# pitch in semitones.
+# pitch in semitones.
def semitone_pitch (tup):
p =0
t = tup[0]
p = p + 12 * (t / 7)
t = t % 7
-
+
if t > 2:
p = p- 1
-
+
p = p + t* 2 + tup[1]
return p
@@ -351,7 +387,7 @@ def fifth_above_pitch (tup):
difference = 7 - (semitone_pitch ((n,a)) - semitone_pitch (tup))
a = a + difference
-
+
return (n,a)
def sharp_keys ():
@@ -385,26 +421,28 @@ def quart_above_pitch (tup):
difference = 5 - (semitone_pitch ((n,a)) - semitone_pitch (tup))
a = a + difference
-
+
return (n,a)
key_lookup = { # abc to lilypond key mode names
'm' : 'minor',
'min' : 'minor',
'maj' : 'major',
- 'major' : 'major',
+ 'major' : 'major',
'phr' : 'phrygian',
'ion' : 'ionian',
'loc' : 'locrian',
'aeo' : 'aeolian',
'mix' : 'mixolydian',
- 'mixolydian' : 'mixolydian',
+ 'mixolydian' : 'mixolydian',
'lyd' : 'lydian',
'dor' : 'dorian',
- 'dorian' : 'dorian'
+ 'dorian' : 'dorian'
}
def lily_key (k):
+ if k == 'none':
+ return
orig = "" + k
# UGR
k = k.lower ()
@@ -448,28 +486,28 @@ key_shift = { # semitone shifts for key mode names
'min' : 3,
'minor' : 3,
'maj' : 0,
- 'major' : 0,
+ 'major' : 0,
'phr' : -4,
'phrygian' : -4,
'ion' : 0,
'ionian' : 0,
'loc' : 1,
- 'locrian' : 1,
+ 'locrian' : 1,
'aeo' : 3,
'aeolian' : 3,
'mix' : 5,
- 'mixolydian' : 5,
+ 'mixolydian' : 5,
'lyd' : -5,
- 'lydian' : -5,
+ 'lydian' : -5,
'dor' : -2,
- 'dorian' : -2
+ 'dorian' : -2
}
def compute_key (k):
k = k.lower ()
intkey = (ord (k[0]) - ord('a') + 5) % 7
intkeyacc =0
k = k[1:]
-
+
if k and k[0] == 'b':
intkeyacc = -1
k = k[1:]
@@ -480,7 +518,7 @@ def compute_key (k):
if k and key_shift.has_key(k):
(intkey, intkeyacc) = shift_key(intkey, intkeyacc, key_shift[k])
keytup = (intkey, intkeyacc)
-
+
sharp_key_seq = sharp_keys ()
flat_key_seq = flat_keys ()
@@ -498,7 +536,7 @@ def compute_key (k):
else:
error ("Huh?")
raise Exception ("Huh")
-
+
key_table = [0] * 7
for a in accseq:
key_table[a] = key_table[a] + accsign
@@ -523,7 +561,7 @@ def try_parse_tuplet_begin (str, state):
prev_tuplet_state = state.parsing_tuplet
state.parsing_tuplet = int (dig[0])
if prev_tuplet_state:
- voices_append ("}")
+ voices_append ("}")
voices_append ("\\times %s {" % tup_lookup[dig])
return str
@@ -532,7 +570,7 @@ def try_parse_group_end (str, state):
str = str[1:]
close_beam_state(state)
return str
-
+
def header_append (key, a):
s = ''
if header.has_key (key):
@@ -583,11 +621,11 @@ def repeat_prepend():
if not using_old:
repeat_state[current_voice_idx] = 't'
-
+
def lyrics_append(a):
a = re.sub ('#', '\\#', a) # latex does not like naked #'s
a = re.sub ('"', '\\"', a) # latex does not like naked "'s
- a = '\t{ "' + a + '" }\n'
+ a = ' \\line { "' + a + '" }\n'
stuff_append (lyrics, current_lyric_idx, a)
# break lyrics to words and put "'s around words containing numbers and '"'s
@@ -610,7 +648,7 @@ def fix_lyric(str):
def slyrics_append(a):
a = re.sub ( '_', ' _ ', a) # _ to ' _ '
- a = re.sub ( '([^-])-([^-])', '\\1- \\2', a) # split words with "-" unless was originally "--"
+ 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
@@ -650,12 +688,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)
@@ -667,16 +705,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) # separate 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:
@@ -709,7 +750,7 @@ def try_parse_header_line (ln, state):
header ['subtitle'] = a
if g == 'L': # Default note length
set_default_length (ln)
- if g == 'V': # Voice
+ if g == 'V': # Voice
voice = re.sub (' .*$', '', a)
rest = re.sub ('^[^ \t]* *', '', a)
if state.next_bar:
@@ -738,7 +779,7 @@ def pitch_to_lilypond_name (name, acc, bar_acc, key):
s = 'es'
elif acc == 1:
s = 'is'
-
+
if name > 4:
name = name -7
return(chr (name + ord('c')) + s)
@@ -779,7 +820,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:
@@ -797,7 +838,7 @@ class Parser_state:
-# return (str, num,den,dots)
+# return (str, num,den,dots)
def parse_duration (str, parser_state):
num = 0
den = parser_state.next_den
@@ -818,7 +859,7 @@ def parse_duration (str, parser_state):
den = den * d
den = den * default_len
-
+
current_dots = parser_state.next_dots
parser_state.next_dots = 0
if re.match ('[ \t]*[<>]', str):
@@ -828,7 +869,7 @@ def parse_duration (str, parser_state):
str = str [1:]
current_dots = current_dots + 1
parser_state.next_den = parser_state.next_den * 2
-
+
while str[0] == '<':
str = str [1:]
den = den * 2
@@ -844,7 +885,7 @@ def parse_duration (str, parser_state):
num = num / multiplier
den = den / f
current_dots = current_dots + d
-
+
return (str, num,den,current_dots)
@@ -887,7 +928,7 @@ artic_tbl = {
'O' : '^\\coda',
'v' : '^\\downbow'
}
-
+
def try_parse_articulation (str, state):
while str and artic_tbl.has_key(str[:1]):
state.next_articulation = state.next_articulation + artic_tbl[str[:1]]
@@ -896,9 +937,9 @@ def try_parse_articulation (str, state):
str = str[1:]
-
-
- # s7m2 input doesnt care about spaces
+
+
+ # s7m2 input doesn't care about spaces
if re.match('[ \t]*\(', str):
str = str.lstrip ()
@@ -909,7 +950,7 @@ def try_parse_articulation (str, state):
str = str[1:]
return str
-
+
#
# remember accidental for rest of bar
#
@@ -928,8 +969,7 @@ def get_bar_acc(note, octave, state):
return(UNDEF)
def clear_bar_acc(state):
- for k in state.in_acc:
- del state.in_acc[k]
+ state.in_acc = {}
# if we are parsing a beam, close it off
@@ -938,7 +978,7 @@ def close_beam_state(state):
state.parsing_beam = 0
voices_append_back( ']' )
-
+
# WAT IS ABC EEN ONTZETTENDE PROGRAMMEERPOEP !
def try_parse_note (str, parser_state):
mud = ''
@@ -972,7 +1012,7 @@ def try_parse_note (str, parser_state):
else:
return str # failed; not a note!
-
+
__main__.lyric_idx = -1
if parser_state.next_bar:
@@ -990,13 +1030,13 @@ def try_parse_note (str, parser_state):
if re.match('[ \t]*\)', str):
str = str.lstrip ()
-
+
slur_end =0
while str[:1] ==')':
slur_end = slur_end + 1
str = str[1:]
-
+
bar_acc = get_bar_acc(notename, octave, parser_state)
pit = pitch_to_lilypond_name(notename, acc, bar_acc, global_key[notename])
oct = octave_to_lilypond_quotes (octave)
@@ -1007,7 +1047,7 @@ def try_parse_note (str, parser_state):
voices_append ("%s%s%s%s" %
(pit, oct, mod,
duration_to_lilypond_duration ((num,den), default_len, current_dots)))
-
+
set_bar_acc(notename, octave, acc, parser_state)
if parser_state.next_articulation:
articulation = articulation + parser_state.next_articulation
@@ -1015,22 +1055,23 @@ def try_parse_note (str, parser_state):
voices_append (articulation)
- if parser_state.parsing_tuplet:
- parser_state.parsing_tuplet = parser_state.parsing_tuplet - 1
- if not parser_state.parsing_tuplet:
- voices_append ("}")
if slur_begin:
voices_append ('-(' * slur_begin )
if slur_end:
voices_append ('-)' *slur_end )
+ if parser_state.parsing_tuplet:
+ parser_state.parsing_tuplet = parser_state.parsing_tuplet - 1
+ if not parser_state.parsing_tuplet:
+ voices_append ("}")
+
if global_options.beams and \
str[0] in '^=_ABCDEFGabcdefg' and \
not parser_state.parsing_beam and \
not parser_state.parsing_tuplet:
parser_state.parsing_beam = 1
voices_append_back( '[' )
-
+
return str
def junk_space (str,state):
@@ -1053,7 +1094,7 @@ def try_parse_guitar_chord (str, state):
while str and str[0] != '"':
gc = gc + str[0]
str = str[1:]
-
+
if str:
str = str[1:]
gc = re.sub('#', '\\#', gc) # escape '#'s
@@ -1064,7 +1105,7 @@ def try_parse_guitar_chord (str, state):
def try_parse_escape (str):
if not str or str [0] != '\\':
return str
-
+
str = str[1:]
if str[:1] =='K':
key_table = compute_key ()
@@ -1083,12 +1124,12 @@ old_bar_dict = {
'|]' : '|.',
'||' : '||',
'[|' : '||',
-':|' : ':|',
+':|' : ':|.',
'|:' : '|:',
-'::' : ':|:',
+'::' : ':|.|:',
'|1' : '|',
'|2' : '|',
-':|2' : ':|',
+':|2' : ':|.',
'|' : '|'
}
bar_dict = {
@@ -1161,12 +1202,12 @@ def try_parse_bar (str,state):
str = str[1:]
clear_bar_acc(state)
close_beam_state(state)
-
+
if bs <> None or state.next_bar != '':
if state.parsing_tuplet:
state.parsing_tuplet =0
voices_append ('} ')
-
+
if bs <> None:
clear_bar_acc(state)
close_beam_state(state)
@@ -1222,7 +1263,7 @@ def try_parse_chord_delims (str, state):
end = end + 1
str = str[1:]
-
+
voices_append ("\\spanrequest \\stop \"slur\"" * end)
voices_append (ch)
return str
@@ -1257,7 +1298,7 @@ def try_parse_comment (str):
#Since ABC is frequently used for music in styles that do not use this
#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.
+#the barlines should not affect its interpretation of the pitch.
if 'nobarlines' in str:
nobarlines = 1
elif str[0:3] == '%LY':
@@ -1268,8 +1309,8 @@ def try_parse_comment (str):
p = str.find ('slyrics')
if (p > -1):
slyrics_append(str[p+8:])
-
-#write other kinds of appending if we ever need them.
+
+#write other kinds of appending if we ever need them.
return str
lineno = 0
@@ -1282,10 +1323,11 @@ def parse_file (fn):
select_voice('default', '')
global lineno
lineno = 0
- sys.stderr.write ("Line ... ")
- sys.stderr.flush ()
+ if not global_options.quiet:
+ sys.stderr.write ("Line ... ")
+ sys.stderr.flush ()
__main__.state = state_list[current_voice_idx]
-
+
for ln in ls:
lineno = lineno + 1
@@ -1300,7 +1342,8 @@ def parse_file (fn):
ln = m.group (1)
orig_ln = ln
-
+
+ ln = junk_space (ln, state)
ln = try_parse_header_line (ln, state)
# Try nibbling characters off until the line doesn't change.
@@ -1324,11 +1367,12 @@ def parse_file (fn):
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')
+ sys.stderr.write (' ' * len (left) + ln + '\n')
def identify():
- sys.stderr.write ("%s from LilyPond %s\n" % (program_name, version))
+ if not global_options.quiet:
+ sys.stderr.write ("%s from LilyPond %s\n" % (program_name, version))
authors = """
Written by Han-Wen Nienhuys , Laura Conrad
@@ -1342,27 +1386,33 @@ 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@"
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 ("-o", "--output", metavar='FILE',
+ action="store",
+ help=_ ("write output to FILE"))
+ p.add_option ("-s", "--strict",
+ action="store_true",
+ help=_ ("be strict about success"))
+ p.add_option ('-b', '--beams',
+ action="store_true",
+ help=_ ("preserve ABC's notion of beams"))
+ p.add_option ('-q', '--quiet',
+ action="store_true",
+ help=_ ("suppress progress messages"))
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
@@ -1377,12 +1427,14 @@ for f in files:
if f == '-':
f = ''
- sys.stderr.write ('Parsing `%s\'...\n' % f)
+ if not global_options.quiet:
+ sys.stderr.write ('Parsing `%s\'...\n' % f)
parse_file (f)
if not global_options.output:
global_options.output = os.path.basename (os.path.splitext (f)[0]) + ".ly"
- sys.stderr.write ('lilypond output to: `%s\'...' % global_options.output)
+ if not global_options.quiet:
+ sys.stderr.write ('lilypond output to: `%s\'...' % global_options.output)
outf = open (global_options.output, 'w')
# don't substitute @VERSION@. We want this to reflect
@@ -1395,5 +1447,5 @@ for f in files:
dump_voices (outf)
dump_score (outf)
dump_lyrics (outf)
- sys.stderr.write ('\n')
-
+ if not global_options.quiet:
+ sys.stderr.write ('\n')