return None
class SequentialMusic (NestedMusic):
- def print_ly (self, printer):
+ def get_last_event_chord (self):
+ value = None
+ at = len( self.elements ) - 1
+ while (at >= 0 and
+ not isinstance (self.elements[at], EventChord) and
+ not isinstance (self.elements[at], BarCheck)):
+ at -= 1
+
+ if (at >= 0 and isinstance (self.elements[at], EventChord)):
+ value = self.elements[at]
+ return value
+
+ def print_ly (self, printer, newline = True):
printer ('{')
if self.comment:
self.print_comment (printer)
- printer.newline()
+ if newline:
+ printer.newline()
for e in self.elements:
e.print_ly (printer)
printer ('}')
- printer.newline()
+ if newline:
+ printer.newline()
def lisp_sub_expression (self, pred):
name = self.name()
class EventChord (NestedMusic):
def __init__ (self):
NestedMusic.__init__ (self)
- self.grace_elements = []
+ self.grace_elements = None
+ self.grace_type = None
def append_grace (self, element):
if element:
+ if not self.grace_elements:
+ self.grace_elements = SequentialMusic ()
self.grace_elements.append (element)
def get_length (self):
not isinstance (e, RhythmicEvent)]
if self.grace_elements and self.elements:
- printer ('\grace {')
- for g in self.grace_elements:
- g.print_ly (printer)
- printer ('}')
+ if self.grace_type:
+ printer ('\\%s' % self.grace_type)
+ else:
+ printer ('\\grace')
+ # don't print newlines after the { and } braces
+ self.grace_elements.print_ly (printer, False)
if rest_events:
rest_events[0].print_ly (printer)
if not ev_chord:
ev_chord = musicexp.EventChord()
voice_builder.add_music (ev_chord, n._duration)
- # When a note/chord has grace notes (duration==0), the duration of the
- # event chord is not yet known, but the event chord was already added
- # 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 n.get_maybe_exist_typed_child (musicxml.Grace):
- ev_chord.append_grace (main_event)
+
+ grace = n.get_maybe_exist_typed_child (musicxml.Grace)
+ if grace:
+ grace_chord = None
+ if n.get_maybe_exist_typed_child (musicxml.Chord) and ev_chord.grace_elements:
+ grace_chord = ev_chord.grace_elements.get_last_event_chord ()
+ if not grace_chord:
+ grace_chord = musicexp.EventChord ()
+ ev_chord.append_grace (grace_chord)
+ if hasattr (grace, 'slash'):
+ # TODO: use grace_type = "appoggiatura" for slurred grace notes
+ if grace.slash == "yes":
+ ev_chord.grace_type = "acciaccatura"
+ elif grace.slash == "no":
+ ev_chord.grace_type = "grace"
+ # now that we have inserted the chord into the grace music, insert
+ # everything into that chord instead of the ev_chord
+ ev_chord = grace_chord
+ ev_chord.append (main_event)
else:
ev_chord.append (main_event)
+ # When a note/chord has grace notes (duration==0), the duration of the
+ # event chord is not yet known, but the event chord was already added
+ # 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)
notations = n.get_maybe_exist_typed_child (musicxml.Notations)
tuplet_event = None