]> git.donarmstrong.com Git - lilypond.git/blobdiff - python/musicexp.py
Merge branch 'master' of ssh+git://hanwen@git.sv.gnu.org/srv/git/lilypond
[lilypond.git] / python / musicexp.py
index 7aa45b1a9949edf57d88acbf0c59158175dc9aec..b266830d0726bd32e43b884e5ae1e6e2f795836a 100644 (file)
@@ -2,6 +2,9 @@ import inspect
 import sys
 import string
 import re
+import lilylib
+
+_ = lilylib._
 
 from rational import Rational
 
@@ -9,6 +12,10 @@ from rational import Rational
 previous_pitch = None
 relative_pitches = False
 
+def warning (str):
+    ly.stderr_write ((_ ("warning: %s") % str) + "\n")
+
+
 def escape_instrument_string (input_string):
     retstring = string.replace (input_string, "\"", "\\\"")
     if re.match ('.*[\r\n]+.*', retstring):
@@ -567,7 +574,8 @@ class RepeatedMusic:
             self.music = SequentialMusic ()
             self.music.elements = music
         else:
-            sys.stderr.write ("WARNING: Unable to set the music %s for the repeat %s" % (music, self))
+            warning (_ ("unable to set the music %(music)s for the repeat %(repeat)s" % \
+                            {'music':music, 'repeat':self}))
     def add_ending (self, music):
         self.endings.append (music)
     def print_ly (self, printer):
@@ -575,7 +583,7 @@ class RepeatedMusic:
         if self.music:
             self.music.print_ly (printer)
         else:
-            sys.stderr.write ("WARNING: Encountered repeat without body\n")
+            warning (_ ("encountered repeat without body"))
             printer.dump ('{}')
         if self.endings:
             printer.dump ('\\alternative {')
@@ -697,6 +705,10 @@ class ChordEvent (NestedMusic):
                 printer ('\\grace')
             # don't print newlines after the { and } braces
             self.grace_elements.print_ly (printer, False)
+        # Print all overrides and other settings needed by the 
+        # articulations/ornaments before the note
+        for e in other_events:
+            e.print_before_note (printer)
 
         if rest_events:
             rest_events[0].print_ly (printer)
@@ -719,6 +731,9 @@ class ChordEvent (NestedMusic):
         for e in other_events:
             e.print_ly (printer)
 
+        for e in other_events:
+            e.print_after_note (printer)
+
         self.print_comment (printer)
             
 class Partial (Music):
@@ -755,6 +770,19 @@ class BarLine (Music):
         return " | "
 
 class Event(Music):
+    def __init__ (self):
+        # strings to print before the note to which an event is attached.
+        # Ignored for notes etc.
+        self.before_note = None
+        self.after_note = None
+   # print something before the note to which an event is attached, e.g. overrides
+    def print_before_note (self, printer):
+        if self.before_note:
+            printer.dump (self.before_note)
+   # print something after the note to which an event is attached, e.g. resetting
+    def print_after_note (self, printer):
+        if self.after_note:
+            printer.dump (self.after_note)
     pass
 
 class SpanEvent (Event):
@@ -772,24 +800,23 @@ class SpanEvent (Event):
         self.span_type = type
 
 class SlurEvent (SpanEvent):
+    def print_before_note (self, printer):
+        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', 
+                  'dashed' : '\\slurSolid'}.get (self.line_type, '')
+        if command and self.span_direction == -1:
+            printer.dump (command)
     def ly_expression (self):
-        before = ''
-        after = ''
-        # TODO: setting dashed/dotted line style does not work, because that
-        #       command needs to be written before the note, not when the
-        #       event is observed after the note!
-        #before = {'dotted': '\\slurDotted', 
-        #          'dashed' : '\\slurDashed'}.get (self.line_type, '')
-        #if before:
-            #after = '\\slurSolid'
-
-        return {-1: before + '(' + after,
-            1:')'}.get (self.span_direction, '')
+        return {-1: '(', 1:')'}.get (self.span_direction, '')
 
 class BeamEvent (SpanEvent):
     def ly_expression (self):
-        return {-1: '[',
-            1:']'}.get (self.span_direction, '')
+        return {-1: '[', 1:']'}.get (self.span_direction, '')
 
 class PedalEvent (SpanEvent):
     def ly_expression (self):
@@ -836,24 +863,37 @@ class TrillSpanEvent (SpanEvent):
             1:'\\stopTrillSpan'}.get (self.span_direction, '')
 
 class GlissandoEvent (SpanEvent):
+    def print_before_note (self, printer):
+        if self.span_direction == -1:
+            style= {
+                "dashed" : "dashed-line",
+                "dotted" : "dotted-line",
+                "wavy"   : "zigzag" 
+            }. get (self.line_type, None)
+            if style:
+                printer.dump ("\once \override Glissando #'style = #'%s" % style)
     def ly_expression (self):
-        style = ''
-        # TODO: wavy-line glissandos don't work, becasue the style has to be
-        #       set before the note, at the \glissando it's already too late!
-        #if self.line_type == 'wavy':
-            #style = "\once\override Glissando #'style = #'zigzag"
-        # In lilypond, glissando is NOT a spanner, unlike MusicXML.
-        return {-1: style + '\\glissando',
+        return {-1: '\\glissando',
             1:''}.get (self.span_direction, '')
 
 class ArpeggioEvent(Event):
     def __init__ (self):
         Event.__init__ (self)
         self.direction = 0
+        self.non_arpeggiate = False
     def wait_for_note (self):
         return True
+    def print_before_note (self, printer):
+        if self.non_arpeggiate:
+            printer.dump ("\\arpeggioBracket")
+        else:
+          dir = { -1: "\\arpeggioDown", 1: "\\arpeggioUp" }.get (self.direction, '')
+          if dir:
+              printer.dump (dir)
+    def print_after_note (self, printer):
+        if self.non_arpeggiate or self.direction:
+            printer.dump ("\\arpeggioNeutral")
     def ly_expression (self):
-        # TODO: Use self.direction for up/down arpeggios
         return ('\\arpeggio')
 
 
@@ -883,6 +923,7 @@ class HairpinEvent (SpanEvent):
 
 class DynamicsEvent (Event):
     def __init__ (self):
+        Event.__init__ (self)
         self.type = None
     def wait_for_note (self):
         return True
@@ -898,6 +939,7 @@ class DynamicsEvent (Event):
 
 class MarkEvent (Event):
     def __init__ (self, text="\\default"):
+        Event.__init__ (self)
         self.mark = text
     def wait_for_note (self):
         return False
@@ -919,6 +961,7 @@ class MusicGlyphMarkEvent (MarkEvent):
 
 class TextEvent (Event):
     def __init__ (self):
+        Event.__init__ (self)
         self.Text = None
         self.force_direction = None
         self.markup = ''
@@ -936,6 +979,7 @@ class TextEvent (Event):
 
 class ArticulationEvent (Event):
     def __init__ (self):
+        Event.__init__ (self)
         self.type = None
         self.force_direction = None
     def wait_for_note (self):