"""A class that takes care of formatting (eg.: indenting) a
Music expression as a .ly file.
-
+
"""
-
+
def __init__ (self):
self._line = ''
self._indent = 4
def set_file (self, file):
self._file = file
-
+
def dump_version (self):
self.newline ()
self.print_verbatim ('\\version "@TOPLEVEL_VERSION@"')
self.newline ()
-
+
def get_indent (self):
return self._nesting * self._indent
-
+
def override (self):
last = self._output_state_stack[-1]
self._output_state_stack.append (last.copy())
-
+
def add_factor (self, factor):
self.override()
self._output_state_stack[-1].factor *= factor
def unformatted_output (self, str):
# don't indent on \< and indent only once on <<
- self._nesting += ( str.count ('<')
- - str.count ('\<') - str.count ('<<')
+ self._nesting += ( str.count ('<')
+ - str.count ('\<') - str.count ('<<')
+ str.count ('{') )
self._nesting -= ( str.count ('>') - str.count ('\>') - str.count ('>>')
- str.count ('->') - str.count ('_>')
- str.count ('^>')
+ str.count ('}') )
self.print_verbatim (str)
-
+
def print_duration_string (self, str):
if self._last_duration == str:
return
-
+
self.unformatted_output (str)
-
+
def add_word (self, str):
if (len (str) + 1 + len (self._line) > self._line_len):
self.newline()
self._line += ' '
self.unformatted_output (str)
self._skipspace = False
-
+
def newline (self):
self._file.write (self._line + '\n')
self._line = ' ' * self._indent * self._nesting
def skipspace (self):
self._skipspace = True
-
+
def __call__(self, arg):
self.dump (arg)
-
+
def dump (self, str):
if self._skipspace:
self._skipspace = False
self.duration_log = 0
self.dots = 0
self.factor = Rational (1)
-
+
def lisp_expression (self):
return '(ly:make-duration %d %d %d %d)' % (self.duration_log,
self.dots,
str += '*%d' % factor.numerator ()
return str
-
+
def print_ly (self, outputter):
str = self.ly_expression (self.factor / outputter.duration_factor ())
outputter.print_duration_string (str)
-
+
def __repr__(self):
return self.ly_expression()
-
+
def copy (self):
d = Duration ()
d.dots = self.dots
self.step = 0
self.octave = 0
self._force_absolute_pitch = False
-
+
def __repr__(self):
return self.ly_expression()
c.step += interval.step
c.octave += interval.octave
c.normalize ()
-
+
target_st = self.semitones() + interval.semitones()
c.alteration += target_st - c.semitones()
return c
p = Pitch ()
p.alteration = self.alteration
p.step = self.step
- p.octave = self.octave
+ p.octave = self.octave
return p
def steps (self):
def semitones (self):
return self.octave * 12 + [0,2,4,5,7,9,11][self.step] + self.alteration
-
- def ly_step_expression (self):
+
+ def ly_step_expression (self):
return pitch_generating_function (self)
def absolute_pitch (self):
str += self.absolute_pitch ()
return str
-
+
def print_ly (self, outputter):
outputter (self.ly_expression())
-
+
class Music:
def __init__ (self):
self.parent = None
self.start = Rational (0)
self.comment = ''
self.identifier = None
-
+
def get_length(self):
return Rational (0)
-
+
def get_properties (self):
return ''
-
+
def has_children (self):
return False
-
+
def get_index (self):
if self.parent:
return self.parent.elements.index (self)
return None
def name (self):
return self.__class__.__name__
-
+
def lisp_expression (self):
name = self.name()
props = self.get_properties ()
-
+
return "(make-music '%s %s)" % (name, props)
def set_start (self, start):
if not text:
return
-
+
if text == '\n':
printer.newline ()
return
-
+
lines = string.split (text, '\n')
for l in lines:
if l:
printer.unformatted_output ('% ' + l)
printer.newline ()
-
+
def print_with_identifier (self, printer):
- if self.identifier:
+ if self.identifier:
printer ("\\%s" % self.identifier)
else:
self.print_ly (printer)
previous_pitch = self.basepitch
if not previous_pitch:
previous_pitch = Pitch ()
- func ('\\relative %s%s' % (pitch_generating_function (previous_pitch),
+ func ('\\relative %s%s' % (pitch_generating_function (previous_pitch),
previous_pitch.absolute_pitch ()))
MusicWrapper.print_ly (self, func)
relative_pitches = prev_relative_pitches
func ("\\once \\override TupletBracket #'stencil = #ly:slur::print")
func.newline ()
- base_number_function = {None: "#f",
- "actual": "tuplet-number::calc-denominator-text",
+ base_number_function = {None: "#f",
+ "actual": "tuplet-number::calc-denominator-text",
"both": "tuplet-number::calc-fraction-text"}.get (self.display_number, None)
# If we have non-standard numerator/denominator, use our custom function
if self.display_number == "actual" and self.display_denominator:
else:
num_duration = den_duration
if (self.display_denominator or self.display_numerator):
- func ("\\once \\override TupletNumber #'text = #(tuplet-number::non-default-fraction-with-notes %s \"%s\" %s \"%s\")" %
+ func ("\\once \\override TupletNumber #'text = #(tuplet-number::non-default-fraction-with-notes %s \"%s\" %s \"%s\")" %
(self.display_denominator, den_duration,
self.display_numerator, num_duration))
func.newline ()
else:
- func ("\\once \\override TupletNumber #'text = #(tuplet-number::fraction-with-notes \"%s\" \"%s\")" %
+ func ("\\once \\override TupletNumber #'text = #(tuplet-number::fraction-with-notes \"%s\" \"%s\")" %
(den_duration, num_duration))
func.newline ()
else:
def append (self, what):
if what:
self.elements.append (what)
-
+
def has_children (self):
return self.elements
assert elt.parent == None
assert succ == None or succ in self.elements
-
+
idx = 0
if succ:
idx = self.elements.index (succ)
self.elements.insert (idx, elt)
elt.parent = self
-
+
def get_properties (self):
return ("'elements (list %s)"
% string.join (map (lambda x: x.lisp_expression(),
def delete_element (self, element):
assert element in self.elements
-
+
self.elements.remove (element)
element.parent = None
-
+
def set_start (self, start):
self.start = start
for e in self.elements:
r = Music.find_first (self, predicate)
if r:
return r
-
+
for e in self.elements:
r = e.find_first (predicate)
if r:
return r
return None
-
+
class SequentialMusic (NestedMusic):
def get_last_event_chord (self):
value = None
printer ('}')
if newline:
printer.newline()
-
+
def lisp_sub_expression (self, pred):
name = self.name()
props = self.get_subset_properties (pred)
-
+
return "(make-music '%s %s)" % (name, props)
-
+
def set_start (self, start):
for e in self.elements:
e.set_start (start)
rest_events = [e for e in self.elements if
isinstance (e, RhythmicEvent)
and not isinstance (e, NoteEvent)]
-
+
other_events = [e for e in self.elements if
not isinstance (e, RhythmicEvent)]
self.grace_elements.print_ly (printer, False)
printer ('{}')
- # Print all overrides and other settings needed by the
+ # Print all overrides and other settings needed by the
# articulations/ornaments before the note
for e in other_events:
e.print_before_note (printer)
duration.print_ly (printer)
else:
pass
-
+
for e in other_events:
e.print_ly (printer)
self.after_grace_elements.print_ly (printer, False)
self.print_comment (printer)
-
+
class Partial (Music):
def __init__ (self):
Music.__init__ (self)
Music.__init__ (self)
self.bar_number = 0
self.type = None
-
+
def print_ly (self, printer):
bar_symbol = { 'regular': "|", 'dotted': ":", 'dashed': "dashed",
'heavy': "|", 'light-light': "||", 'light-heavy': "|.",
class SlurEvent (SpanEvent):
def print_before_note (self, printer):
- command = {'dotted': '\\slurDotted',
+ command = {'dotted': '\\slurDotted',
'dashed' : '\\slurDashed'}.get (self.line_type, '')
if command and self.span_direction == -1:
printer.dump (command)
def print_after_note (self, printer):
# reset non-solid slur types!
- command = {'dotted': '\\slurSolid',
+ command = {'dotted': '\\slurSolid',
'dashed' : '\\slurSolid'}.get (self.line_type, '')
if command and self.span_direction == -1:
printer.dump (command)
value = ''
if dir:
value = '\ottava #%s' % dir
- return {
+ return {
-1: value,
1: '\ottava #0'}.get (self.span_direction, '')
style= {
"dashed" : "dashed-line",
"dotted" : "dotted-line",
- "wavy" : "zigzag"
+ "wavy" : "zigzag"
}. get (self.line_type, None)
if style:
printer.dump ("\once \override Glissando #'style = #'%s" % style)
return '\!'
else:
return {1: '\<', -1: '\>'}.get (self.span_type, '')
-
+
def ly_expression (self):
return self.hairpin_to_ly ()
-
+
def print_ly (self, printer):
val = self.hairpin_to_ly ()
if val:
self.step = 0
def __repr__(self):
return self.ly_expression()
- def ly_expression (self):
+ def ly_expression (self):
return pitch_generating_function (self)
class ChordModification:
def get_length (self):
return self.duration.get_length()
-
+
def get_properties (self):
return ("'duration %s"
% self.duration.lisp_expression ())
-
+
class RestEvent (RhythmicEvent):
def __init__ (self):
RhythmicEvent.__init__ (self)
return res + "%s%s\\rest" % (self.pitch.ly_expression (), self.duration.ly_expression ())
else:
return 'r%s' % self.duration.ly_expression ()
-
+
def print_ly (self, printer):
for ev in self.associated_events:
ev.print_ly (printer)
class SkipEvent (RhythmicEvent):
def ly_expression (self):
- return 's%s' % self.duration.ly_expression ()
+ return 's%s' % self.duration.ly_expression ()
class NoteEvent(RhythmicEvent):
def __init__ (self):
def get_properties (self):
str = RhythmicEvent.get_properties (self)
-
+
if self.pitch:
str += self.pitch.lisp_expression ()
elif self.drum_type:
str += "'drum-type '%s" % self.drum_type
return str
-
+
def pitch_mods (self):
excl_question = ''
if self.cautionary:
def ly_expression (self):
st = ''
- # Print out the style if we have ome, but the '() should only be
- # forced for 2/2 or 4/4, since in all other cases we'll get numeric
+ # Print out the style if we have ome, but the '() should only be
+ # forced for 2/2 or 4/4, since in all other cases we'll get numeric
# signatures anyway despite the default 'C signature style!
is_common_signature = self.fractions in ([2,2], [4,4], [4,2])
if self.style:
return st + "\\compoundMeter #'%s" % self.format_fraction (self.fractions)
else:
return st + ''
-
+
class ClefChange (Music):
def __init__ (self):
Music.__init__ (self)
"C": ("clefs.C", 0, 0),
"F": ("clefs.F", 2, 6),
}
-
+
def lisp_expression (self):
try:
(glyph, pos, c0) = self.clef_dict[self.type]
return False
def duration_to_markup (self, dur):
if dur:
- # Generate the markup to print the note, use scheme mode for
+ # Generate the markup to print the note, use scheme mode for
# ly_expression to get longa and not \longa (which causes an error)
return "\\general-align #Y #DOWN \\smaller \\note #\"%s\" #UP" % dur.ly_expression(None, True)
else:
printer.dump ("<<")
printer.newline ()
if self.stafftype and self.instrument_name:
- printer.dump ("\\set %s.instrumentName = %s" % (self.stafftype,
+ printer.dump ("\\set %s.instrumentName = %s" % (self.stafftype,
escape_instrument_string (self.instrument_name)))
printer.newline ()
if self.stafftype and self.short_instrument_name:
class RhythmicStaff (Staff):
def __init__ (self, command = "RhythmicStaff"):
Staff.__init__ (self, command)
-
+
class Score:
def __init__ (self):
self.contents = None
def set_contents (self, contents):
self.contents = contents
-
+
def set_part_information (self, part_id, staves_info):
if self.contents:
self.contents.set_part_information (part_id, staves_info)
down = Pitch ()
down.step = -4
down.normalize ()
-
-
+
+
print bflat.semitones()
print bflat.transposed (fifth), bflat.transposed (fifth).transposed (fifth)
print bflat.transposed (fifth).transposed (fifth).transposed (fifth)
m.append (make_note ())
m.append (make_note ())
-
+
t = TimeScaledMusic ()
t.numerator = 2
t.denominator = 3
m.append (make_tup ())
m.append (make_tup ())
m.append (make_tup ())
-
+
printer = Output_printer()
m.print_ly (printer)
printer.newline ()
-
+
def test_expr ():
m = SequentialMusic()
- l = 2
+ l = 2
evc = ChordEvent()
n = NoteEvent()
n.duration.duration_log = l
evc = ChordEvent()
n = NoteEvent()
n.duration.duration_log = l
- n.pitch.step = 2
+ n.pitch.step = 2
evc.insert_around (None, n, 0)
m.insert_around (None, evc, 0)
n = KeySignatureChange()
n.tonic=tonic.copy()
n.scale = [0, 0, -2, 0, 0,-2,-2]
-
+
evc.insert_around (None, n, 0)
m.insert_around (None, evc, 0)
test_printer ()
raise 'bla'
test_pitch()
-
+
expr = test_expr()
expr.set_start (Rational (0))
print expr.ly_expression()
def sub(x, start=start, stop=stop):
ok = x.start >= start and x.start +x.get_length() <= stop
return ok
-
+
print expr.lisp_sub_expression(sub)
conversion_settings = Conversion_Settings ()
# Use a global variable to store the setting needed inside a \layout block.
-# whenever we need to change a setting or add/remove an engraver, we can access
+# whenever we need to change a setting or add/remove an engraver, we can access
# this layout and add the corresponding settings
layout_information = musicexp.Layout ()
needed_additional_definitions = []
additional_definitions = {
- "tuplet-note-wrapper": """ % a formatter function, which is simply a wrapper around an existing
+ "tuplet-note-wrapper": """ % a formatter function, which is simply a wrapper around an existing
% tuplet formatter function. It takes the value returned by the given
- % function and appends a note of given length.
+ % function and appends a note of given length.
#(define-public ((tuplet-number::append-note-wrapper function note) grob)
(let* ((txt (if function (function grob) #f)))
- (if txt
+ (if txt
(markup txt #:fontsize -5 #:note note UP)
(markup #:fontsize -5 #:note note UP)
)
)""",
"tuplet-non-default-denominator": """#(define ((tuplet-number::non-default-tuplet-denominator-text denominator) grob)
- (number->string (if denominator
- denominator
+ (number->string (if denominator
+ denominator
(ly:event-property (event-cause grob) 'denominator))))
""",
(join-markups (cons (car remaining) (cons m markups)) (cdr remaining))
markups))))
-% Use a centered-column inside a left-column, because the centered column
-% moves its reference point to the center, which the left-column undoes.
+% Use a centered-column inside a left-column, because the centered column
+% moves its reference point to the center, which the left-column undoes.
% The center-column also aligns its contented centered, which is not undone...
#(define-public (format-time-fraction time-sig-fraction)
(let* ((revargs (reverse (map number->string time-sig-fraction)))
(den (car revargs))
(nums (reverse (cdr revargs))))
(make-override-markup '(baseline-skip . 0)
- (make-number-markup
+ (make-number-markup
(make-left-column-markup (list
(make-center-column-markup (list
(make-line-markup (insert-markups nums "+"))
(let* ((sigs (map format-time-fraction time-sig)))
(make-override-markup '(baseline-skip . 0)
(make-number-markup
- (make-line-markup
+ (make-line-markup
(insert-markups sigs (make-vcenter-markup "+")))))))
#(define-public (format-compound-time time-sig)
set_if_exists ('title', work.get_work_title ())
set_if_exists ('worknumber', work.get_work_number ())
set_if_exists ('opus', work.get_opus ())
-
+
identifications = tree.get_named_children ('identification')
for ids in identifications:
set_if_exists ('copyright', ids.get_rights ())
set_if_exists ('arranger', ids.get_arranger ())
set_if_exists ('editor', ids.get_editor ())
set_if_exists ('poet', ids.get_poet ())
-
+
set_if_exists ('tagline', ids.get_encoding_software ())
set_if_exists ('encodingsoftware', ids.get_encoding_software ())
set_if_exists ('encodingdate', ids.get_encoding_date ())
set_if_exists ('encoder', ids.get_encoding_person ())
set_if_exists ('encodingdescription', ids.get_encoding_description ())
-
+
set_if_exists ('texidoc', ids.get_file_description ());
# Finally, apply the required compatibility modes
- # Some applications created wrong MusicXML files, so we need to
+ # Some applications created wrong MusicXML files, so we need to
# apply some compatibility mode, e.g. ignoring some features/tags
# in those files
software = ids.get_encoding_software_list ()
score = musicexp.Score ()
structure = musicexp.StaffGroup (None)
score.set_contents (structure)
-
+
if not part_list:
return structure
d = musicexp.Duration ()
d.duration_log = dur[0]
d.dots = dur[1]
- # Grace notes by specification have duration 0, so no time modification
+ # Grace notes by specification have duration 0, so no time modification
# factor is possible. It even messes up the output with *0/1
if not mxl_note.get_maybe_exist_typed_child (musicxml.Grace):
d.factor = mxl_note._duration / d.get_length ()
return music_list
-# Extract the settings for tuplets from the <notations><tuplet> and the
+# Extract the settings for tuplets from the <notations><tuplet> and the
# <time-modification> elements of the note:
def musicxml_tuplet_to_lily (tuplet_elt, time_modification):
tsm = musicexp.TimeScaledMusic ()
MUSIC_LIST demarcated by EVENTS_LIST in TimeScaledMusic objects.
"""
-
+
indices = []
brackets = {}
change = musicexp.ClefChange ()
(change.type, change.position, change.octave) = attributes.get_clef_information ()
return change
-
+
def musicxml_time_to_lily (attributes):
sig = attributes.get_time_signature ()
if not sig:
# TODO: Handle senza-misura measures
# TODO: Handle hidden time signatures (print-object="no")
- # TODO: What shall we do if the symbol clashes with the sig? e.g. "cut"
+ # TODO: What shall we do if the symbol clashes with the sig? e.g. "cut"
# with 3/8 or "single-number" with (2+3)/8 or 3/8+2/4?
return change
def musicxml_key_to_lily (attributes):
- key_sig = attributes.get_key_signature ()
+ key_sig = attributes.get_key_signature ()
if not key_sig or not (isinstance (key_sig, list) or isinstance (key_sig, tuple)):
error_message (_ ("Unable to extract key signature!"))
return None
-
+
change = musicexp.KeySignatureChange()
-
+
if len (key_sig) == 2 and not isinstance (key_sig[0], list):
# standard key signature, (fifths, mode)
(fifths, mode) = key_sig
chromatic_shift = string.atoi (transpose.get_named_child ('chromatic').get_text ())
chromatic_shift_normalized = chromatic_shift % 12;
(shift.step, shift.alteration) = [
- (0,0), (0,1), (1,0), (2,-1), (2,0),
- (3,0), (3,1), (4,0), (5,-1), (5,0),
+ (0,0), (0,1), (1,0), (2,-1), (2,0),
+ (3,0), (3,1), (4,0), (5,-1), (5,0),
(6,-1), (6,0)][chromatic_shift_normalized];
-
+
shift.octave += (chromatic_shift - chromatic_shift_normalized) / 12
diatonic = transpose.get_maybe_exist_named_child ('diatonic')
ev = func (attrs)
if ev:
elts.append (ev)
-
+
return elts
-
+
def musicxml_print_to_lily (el):
# TODO: Implement other print attributes
# <!ELEMENT print (page-layout?, system-layout?, staff-layout*,
- # measure-layout?, measure-numbering?, part-name-display?,
+ # measure-layout?, measure-numbering?, part-name-display?,
# part-abbreviation-display?)>
# <!ATTLIST print
# staff-spacing %tenths; #IMPLIED
# new-system %yes-no; #IMPLIED
# new-page %yes-no-number; #IMPLIED
# blank-page NMTOKEN #IMPLIED
- # page-number CDATA #IMPLIED
+ # page-number CDATA #IMPLIED
# >
elts = []
if (hasattr (el, "new-system") and conversion_settings.convert_page_layout):
def musicxml_spanner_to_lily_event (mxl_event):
ev = None
-
+
name = mxl_event.get_name()
func = spanner_event_dict.get (name)
if func:
def musicxml_dynamics_to_lily_event (dynentry):
dynamics_available = (
- "ppppp", "pppp", "ppp", "pp", "p", "mp", "mf",
+ "ppppp", "pppp", "ppp", "pp", "p", "mp", "mf",
"f", "ff", "fff", "ffff", "fp", "sf", "sff", "sp", "spp", "sfz", "rfz" )
dynamicsname = dynentry.get_name ()
if dynamicsname == "other-dynamics":
"""
middle = mxl_event.get_maybe_exist_named_child ('accordion-middle')
if middle:
- # By default, use one dot (when no or invalid content is given). The
+ # By default, use one dot (when no or invalid content is given). The
# MusicXML spec is quiet about this case...
txt = 1
try:
index = -1
index = next_non_hash_index (children, index)
- if isinstance (children[index], musicxml.BeatUnit):
+ if isinstance (children[index], musicxml.BeatUnit):
# first form of metronome-mark, using unit and beats/min or other unit
ev = musicexp.TempoMark ()
if hasattr (mxl_event, 'parentheses'):
if hasattr (n, 'placement') and options.convert_directions:
dir = musicxml_direction_to_indicator (n.placement)
dirtype_children = []
- # TODO: The direction-type is used for grouping (e.g. dynamics with text),
+ # TODO: The direction-type is used for grouping (e.g. dynamics with text),
# so we can't simply flatten them out!
for dt in n.get_typed_children (musicxml.DirType):
dirtype_children += dt.get_all_children ()
# TODO: LilyPond does not support inversions, does it?
# Mail from Carl Sorensen on lilypond-devel, June 11, 2008:
- # 4. LilyPond supports the first inversion in the form of added
- # bass notes. So the first inversion of C major would be c:/g.
- # To get the second inversion of C major, you would need to do
- # e:6-3-^5 or e:m6-^5. However, both of these techniques
- # require you to know the chord and calculate either the fifth
- # pitch (for the first inversion) or the third pitch (for the
+ # 4. LilyPond supports the first inversion in the form of added
+ # bass notes. So the first inversion of C major would be c:/g.
+ # To get the second inversion of C major, you would need to do
+ # e:6-3-^5 or e:m6-^5. However, both of these techniques
+ # require you to know the chord and calculate either the fifth
+ # pitch (for the first inversion) or the third pitch (for the
# second inversion) so they may not be helpful for musicxml2ly.
inversion_count = string.atoi (inversion.get_text ())
if inversion_count == 1:
d.step = deg.get_value ()
d.alteration = deg.get_alter ()
ev.add_modification (d)
- #TODO: convert the user-symbols attribute:
+ #TODO: convert the user-symbols attribute:
#major: a triangle, like Unicode 25B3
#minor: -, like Unicode 002D
#augmented: +, like Unicode 002B
def musicxml_figured_bass_note_to_lily (n):
res = musicexp.FiguredBassNote ()
- suffix_dict = { 'sharp' : "+",
- 'flat' : "-",
- 'natural' : "!",
- 'double-sharp' : "++",
- 'flat-flat' : "--",
- 'sharp-sharp' : "++",
+ suffix_dict = { 'sharp' : "+",
+ 'flat' : "-",
+ 'natural' : "!",
+ 'double-sharp' : "++",
+ 'flat-flat' : "--",
+ 'sharp-sharp' : "++",
'slash' : "/" }
prefix = n.get_maybe_exist_named_child ('prefix')
if prefix:
if suffix:
res.set_suffix (suffix_dict.get (suffix.get_text (), ""))
if n.get_maybe_exist_named_child ('extend'):
- # TODO: Implement extender lines (unfortunately, in lilypond you have
+ # TODO: Implement extender lines (unfortunately, in lilypond you have
# to use \set useBassFigureExtenders = ##t, which turns them on
# globally, while MusicXML has a property for each note...
# I'm not sure there is a proper way to implement this cleanly
acc = n.get_maybe_exist_named_child ('accidental')
if acc:
- # let's not force accs everywhere.
+ # let's not force accs everywhere.
event.cautionary = acc.editorial
elif n.get_maybe_exist_typed_child (musicxml.Unpitched):
unpitched = n.get_maybe_exist_typed_child (musicxml.Unpitched)
event = musicexp.NoteEvent ()
event.pitch = musicxml_unpitched_to_lily (unpitched)
-
+
elif n.get_maybe_exist_typed_child (musicxml.Rest):
# rests can have display-octave and display-step, which are
# treated like an ordinary note pitch
self.end_moment = self.begin_moment + duration
def current_duration (self):
return self.end_moment - self.begin_moment
-
+
def add_music (self, music, duration, relevant = True):
assert isinstance (music, musicexp.Music)
if self.pending_multibar > Rational (0):
self.elements.append (music)
self.begin_moment = self.end_moment
self.set_duration (duration)
-
+
# Insert all pending dynamics right after the note/rest:
if isinstance (music, musicexp.ChordEvent) and self.pending_dynamics:
for d in self.pending_dynamics:
# Insert only if we don't have a barline already
# TODO: Implement proper merging of default barline and custom bar line
has_relevant = self.has_relevant_elements
- if (not (self.elements) or
- not (isinstance (self.elements[-1], musicexp.BarLine)) or
+ if (not (self.elements) or
+ not (isinstance (self.elements[-1], musicexp.BarLine)) or
(self.pending_multibar > Rational (0))):
self.add_music (barline, Rational (0))
self.has_relevant_elements = has_relevant or relevant
def jumpto (self, moment):
current_end = self.end_moment + self.pending_multibar
diff = moment - current_end
-
+
if diff < Rational (0):
- error_message (_ ('Negative skip %s (from position %s to %s)') %
+ error_message (_ ('Negative skip %s (from position %s to %s)') %
(diff, current_end, moment))
diff = Rational (0)
duration_factor = 1
duration_log = {1: 0, 2: 1, 4:2, 8:3, 16:4, 32:5, 64:6, 128:7, 256:8, 512:9}.get (diff.denominator (), -1)
duration_dots = 0
- # TODO: Use the time signature for skips, too. Problem: The skip
+ # TODO: Use the time signature for skips, too. Problem: The skip
# might not start at a measure boundary!
if duration_log > 0: # denominator is a power of 2...
if diff.numerator () == 3:
self.jumpto (starting_at)
value = None
return value
-
+
def correct_negative_skip (self, goto):
self.end_moment = goto
self.begin_moment = goto
lyrics = {}
return_value = VoiceData ()
return_value.voicedata = voice
-
+
# First pitch needed for relative mode (if selected in command-line options)
first_pitch = None
ignore_lyrics = False
current_staff = None
-
+
pending_figured_bass = []
pending_chordnames = []
if not n.__class__.__name__ == 'Note':
n.message (_ ('unexpected %s; expected %s or %s or %s') % (n, 'Note', 'Attributes', 'Barline'))
continue
-
+
main_event = musicxml_note_to_lily_main_event (n)
if main_event and not first_pitch:
first_pitch = main_event.pitch
modes_found['drummode'] = True
ev_chord = voice_builder.last_event_chord (n._when)
- if not ev_chord:
+ if not ev_chord:
ev_chord = musicexp.ChordEvent()
voice_builder.add_music (ev_chord, n._duration)
grace_chord = None
# after-graces and other graces use different lists; Depending on
- # whether we have a chord or not, obtain either a new ChordEvent or
+ # whether we have a chord or not, obtain either a new ChordEvent or
# the previous one to create a chord
if is_after_grace:
if ev_chord.after_grace_elements and n.get_maybe_exist_typed_child (musicxml.Chord):
# with duration 0. The following correct this when we hit the real note!
if voice_builder.current_duration () == 0 and n._duration > 0:
voice_builder.set_duration (n._duration)
-
+
# if we have a figured bass, set its voice builder to the correct position
# and insert the pending figures
if pending_figured_bass:
fb.duration = ev_chord.get_duration ()
figured_bass_builder.add_music (fb, dur)
pending_figured_bass = []
-
+
if pending_chordnames:
try:
chordnames_builder.jumpto (n._when)
span_events = []
# The <notation> element can have the following children (+ means implemented, ~ partially, - not):
- # +tied | +slur | +tuplet | glissando | slide |
+ # +tied | +slur | +tuplet | glissando | slide |
# ornaments | technical | articulations | dynamics |
- # +fermata | arpeggiate | non-arpeggiate |
+ # +fermata | arpeggiate | non-arpeggiate |
# accidental-mark | other-notation
for notations in notations_children:
for tuplet_event in notations.get_tuplets():
fermatas = notations.get_named_children ('fermata')
for a in fermatas:
ev = musicxml_fermata_to_lily_event (a)
- if ev:
+ if ev:
ev_chord.append (ev)
arpeggiate = notations.get_named_children ('arpeggiate')
# Articulations can contain the following child elements:
# accent | strong-accent | staccato | tenuto |
# detached-legato | staccatissimo | spiccato |
- # scoop | plop | doit | falloff | breath-mark |
+ # scoop | plop | doit | falloff | breath-mark |
# caesura | stress | unstress
# Technical can contain the following child elements:
# up-bow | down-bow | harmonic | open-string |
# toe | fingernails | other-technical
# Ornaments can contain the following child elements:
# trill-mark | turn | delayed-turn | inverted-turn |
- # shake | wavy-line | mordent | inverted-mordent |
+ # shake | wavy-line | mordent | inverted-mordent |
# schleifer | tremolo | other-ornament, accidental-mark
ornaments = notations.get_named_children ('ornaments')
ornaments += notations.get_named_children ('articulations')
mxl_beams = [b for b in n.get_named_children ('beam')
if (b.get_type () in ('begin', 'end')
- and b.is_primary ())]
+ and b.is_primary ())]
if mxl_beams and not conversion_settings.ignore_beaming:
beam_ev = musicxml_spanner_to_lily_event (mxl_beams[0])
if beam_ev:
## force trailing mm rests to be written out.
voice_builder.add_music (musicexp.ChordEvent (), Rational (0))
-
+
ly_voice = group_tuplets (voice_builder.elements, tuplet_events)
ly_voice = group_repeats (ly_voice)
## \key <pitch> barfs in drummode.
ly_voice = [e for e in ly_voice
if not isinstance(e, musicexp.KeySignatureChange)]
-
+
seq_music.elements = ly_voice
for k in lyrics.keys ():
return_value.lyrics_dict[k] = musicexp.Lyrics ()
return_value.lyrics_dict[k].lyrics_syllables = lyrics[k]
-
-
+
+
if len (modes_found) > 1:
error_message (_ ('cannot simultaneously have more than one mode: %s') % modes_found.keys ())
-
+
if options.relative:
v = musicexp.RelativeMusic ()
v.element = seq_music
v.element = seq_music
v.mode = mode
return_value.ly_voice = v
-
+
# create \figuremode { figured bass elements }
if figured_bass_builder.has_relevant_elements:
fbass_music = musicexp.SequentialMusic ()
v.mode = 'figuremode'
v.element = fbass_music
return_value.figured_bass = v
-
+
# create \chordmode { chords }
if chordnames_builder.has_relevant_elements:
cname_music = musicexp.SequentialMusic ()
v.mode = 'chordmode'
v.element = cname_music
return_value.chordnames = v
-
+
return return_value
def musicxml_id_to_lily (id):
digits = ['Zero', 'One', 'Two', 'Three', 'Four', 'Five',
'Six', 'Seven', 'Eight', 'Nine', 'Ten']
-
+
for digit in digits:
d = digits.index (digit)
id = re.sub ('%d' % d, digit, id)
action = "store",
help = _ ("use a different language file 'LANG.ly' and corresponding pitch names, e.g. 'deutsch' for deutsch.ly"))
- p.add_option ('--nd', '--no-articulation-directions',
+ p.add_option ('--nd', '--no-articulation-directions',
action = "store_false",
default = True,
dest = "convert_directions",
help = _ ("do not convert directions (^, _ or -) for articulations, dynamics, etc."))
- p.add_option ('--nrp', '--no-rest-positions',
+ p.add_option ('--nrp', '--no-rest-positions',
action = "store_false",
default = True,
dest = "convert_rest_positions",
help = _ ("do not convert exact vertical positions of rests"))
- p.add_option ('--npl', '--no-page-layout',
+ p.add_option ('--npl', '--no-page-layout',
action = "store_false",
default = True,
dest = "convert_page_layout",
help = _ ("do not convert the exact page layout and breaks"))
- p.add_option ('--no-beaming',
+ p.add_option ('--no-beaming',
action = "store_false",
default = True,
dest = "convert_beaming",
def music_xml_voice_name_to_lily_name (part_id, name):
str = "Part%sVoice%s" % (part_id, name)
- return musicxml_id_to_lily (str)
+ return musicxml_id_to_lily (str)
def music_xml_lyrics_name_to_lily_name (part_id, name, lyricsnr):
str = "Part%sVoice%sLyrics%s" % (part_id, name, lyricsnr)
- return musicxml_id_to_lily (str)
+ return musicxml_id_to_lily (str)
def music_xml_figuredbass_name_to_lily_name (part_id, voicename):
str = "Part%sVoice%sFiguredBass" % (part_id, voicename)
- return musicxml_id_to_lily (str)
+ return musicxml_id_to_lily (str)
def music_xml_chordnames_name_to_lily_name (part_id, voicename):
str = "Part%sVoice%sChords" % (part_id, voicename)
- return musicxml_id_to_lily (str)
+ return musicxml_id_to_lily (str)
def print_voice_definitions (printer, part_list, voices):
for part in part_list:
def uniq_list (l):
return dict ([(elt,1) for elt in l]).keys ()
-# format the information about the staff in the form
+# format the information about the staff in the form
# [staffid,
# [
# [voiceid1, [lyricsid11, lyricsid12,...], figuredbassid1],
staves = uniq_list (staves)
staves.sort ()
for s in staves:
- thisstaff_raw_voices = [(voice_name, voice.lyrics_order, voice.figured_bass, voice.chordnames)
+ thisstaff_raw_voices = [(voice_name, voice.lyrics_order, voice.figured_bass, voice.chordnames)
for (voice_name, voice) in nv_dict.items ()
if voice.voicedata._start_staff == s]
staves_info.append (format_staff_info (part_id, s, thisstaff_raw_voices))
else:
- thisstaff_raw_voices = [(voice_name, voice.lyrics_order, voice.figured_bass, voice.chordnames)
+ thisstaff_raw_voices = [(voice_name, voice.lyrics_order, voice.figured_bass, voice.chordnames)
for (voice_name, voice) in nv_dict.items ()]
staves_info.append (format_staff_info (part_id, None, thisstaff_raw_voices))
score_structure.set_part_information (part_id, staves_info)
printer.newline ()
printer.newline ()
-# Read in the tree from the given I/O object (either file or string) and
+# Read in the tree from the given I/O object (either file or string) and
# demarshall it using the classes from the musicxml.py file
def read_xml (io_object, use_lxml):
if use_lxml:
update_layout_information ()
if not options.output_name:
- options.output_name = os.path.basename (filename)
+ options.output_name = os.path.basename (filename)
options.output_name = os.path.splitext (options.output_name)[0]
elif re.match (".*\.ly", options.output_name):
options.output_name = os.path.splitext (options.output_name)[0]
if layout_information:
layout_information.print_ly (printer)
print_voice_definitions (printer, part_list, voices)
-
+
printer.newline ()
printer.dump ("% The score definition")
printer.newline ()