]> git.donarmstrong.com Git - lilypond.git/blobdiff - python/musicexp.py
Restrict lilypond-book mingw32 subprocess workaround to Python versions < 2.6
[lilypond.git] / python / musicexp.py
index 1303af2655145bd3ee7714288d1baeabf1bf7280..ea2525d866e4085e3adb90de929a7ebd91ac4f53 100644 (file)
@@ -13,16 +13,13 @@ 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):
         rx = re.compile (r'[\n\r]+')
         strings = rx.split (retstring)
-        retstring = "\\markup { \\column { "
+        retstring = "\\markup { \\center-column { "
         for s in strings:
             retstring += "\\line {\"" + s + "\"} "
         retstring += "} }"
@@ -201,6 +198,17 @@ class Duration:
 
         return base * dot_fact * self.factor
 
+# implement the midi command line option '-m' and '--midi'
+# if TRUE add midi-block to .ly file (see below)
+def set_create_midi (option):
+    global midi_option
+    midi_option = option
+
+def get_create_midi ():
+    try:
+        return midi_option
+    except:
+        return False
 
 # Implement the different note names for the various languages
 def pitch_generic (pitch, notenames, accidentals):
@@ -213,12 +221,12 @@ def pitch_generic (pitch, notenames, accidentals):
     # Handle remaining fraction to pitch.alteration (for microtones)
     if (halftones != pitch.alteration):
         if None in accidentals[1:3]:
-            warning (_ ("Language does not support microtones contained in the piece"))
+            ly.warning (_ ("Language does not support microtones contained in the piece"))
         else:
             try:
                 str += {-0.5: accidentals[1], 0.5: accidentals[2]}[pitch.alteration-halftones]
             except KeyError:
-                warning (_ ("Language does not support microtones contained in the piece"))
+                ly.warning (_ ("Language does not support microtones contained in the piece"))
     return str
 
 def pitch_general (pitch):
@@ -480,7 +488,7 @@ class TimeScaledMusic (MusicWrapper):
             func ("\\once \\override TupletBracket #'stencil = ##f")
             func.newline ()
         elif self.display_bracket == "curved":
-            warning (_ ("Tuplet brackets of curved shape are not correctly implemented"))
+            ly.warning (_ ("Tuplet brackets of curved shape are not correctly implemented"))
             func ("\\once \\override TupletBracket #'stencil = #ly:slur::print")
             func.newline ()
 
@@ -666,7 +674,7 @@ class RepeatedMusic:
             self.music = SequentialMusic ()
             self.music.elements = music
         else:
-            warning (_ ("unable to set the music %(music)s for the repeat %(repeat)s") % \
+            ly.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)
@@ -675,7 +683,7 @@ class RepeatedMusic:
         if self.music:
             self.music.print_ly (printer)
         else:
-            warning (_ ("encountered repeat without body"))
+            ly.warning (_ ("encountered repeat without body"))
             printer.dump ('{}')
         if self.endings:
             printer.dump ('\\alternative {')
@@ -749,7 +757,7 @@ class Paper:
         self.print_length_field (printer, "paper-width", self.page_width)
         self.print_length_field (printer, "paper-height", self.page_height)
         self.print_length_field (printer, "top-margin", self.top_margin)
-        self.print_length_field (printer, "botton-margin", self.bottom_margin)
+        self.print_length_field (printer, "bottom-margin", self.bottom_margin)
         self.print_length_field (printer, "left-margin", self.left_margin)
         # TODO: maybe set line-width instead of right-margin?
         self.print_length_field (printer, "right-margin", self.right_margin)
@@ -845,7 +853,7 @@ class ChordEvent (NestedMusic):
             # don't print newlines after the { and } braces
             self.grace_elements.print_ly (printer, False)
         elif self.grace_elements: # no self.elements!
-            warning (_ ("Grace note with no following music: %s") % self.grace_elements)
+            ly.warning (_ ("Grace note with no following music: %s") % self.grace_elements)
             if self.grace_type:
                 printer ('\\%s' % self.grace_type)
             else:
@@ -1007,7 +1015,7 @@ class OctaveShiftEvent (SpanEvent):
         try:
             value = {8: 1, 15: 2}[self.size]
         except KeyError:
-            warning (_ ("Invalid octave shift size found: %s. Using no shift.") % self.size)
+            ly.warning (_ ("Invalid octave shift size found: %s. Using no shift.") % self.size)
             value = 0
         # negative values go up!
         value *= -1*self.span_type
@@ -1465,7 +1473,7 @@ class KeySignatureChange (Music):
         try:
             accidental = alter_dict[a[1]]
         except KeyError:
-            warning (_ ("Unable to convert alteration %s to a lilypond expression") % a[1])
+            ly.warning (_ ("Unable to convert alteration %s to a lilypond expression") % a[1])
             return ''
         if len (a) == 2:
             return "( %s . %s )" % (a[0], accidental)
@@ -1587,6 +1595,26 @@ class StaffChange (Music):
         else:
             return ''
 
+class SetEvent (Music):
+    def __init__ (self, contextprop, value):
+        Music.__init__ (self)
+        self.context_prop = contextprop
+        self.value = value
+    def ly_expression (self):
+        if self.value:
+            return "\\set %s = %s" % (self.context_prop, self.value)
+        else:
+            return ''
+
+class StaffLinesEvent (Music):
+    def __init__ (self, lines):
+        Music.__init__ (self)
+        self.lines = lines
+    def ly_expression (self):
+        if (self.lines > 0):
+          return "\\stopStaff \\override Staff.StaffSymbol #'line-count = #%s \\startStaff" % self.lines
+        else:
+          return "\\stopStaff \\revert Staff.StaffSymbol #'line-count \\startStaff"
 
 class TempoMark (Music):
     def __init__ (self):
@@ -1728,6 +1756,7 @@ class StaffGroup:
         self.spanbar = None
         self.children = []
         self.is_group = True
+        self.context_modifications = []
         # part_information is a list with entries of the form
         #     [staffid, voicelist]
         # where voicelist is a list with entries of the form
@@ -1744,30 +1773,52 @@ class StaffGroup:
             for c in self.children:
                 c.set_part_information (part_name, staves_info)
 
+    def add_context_modification (self, modification):
+        self.context_modifications.append (modification)
+
     def print_ly_contents (self, printer):
         for c in self.children:
             if c:
                 c.print_ly (printer)
-    def print_ly_overrides (self, printer):
+    def needs_with (self):
         needs_with = False
         needs_with |= self.spanbar == "no"
         needs_with |= self.instrument_name != None
         needs_with |= self.short_instrument_name != None
         needs_with |= (self.symbol != None) and (self.symbol != "bracket")
+        return needs_with
+    def print_ly_context_mods (self, printer):
+        if self.instrument_name or self.short_instrument_name:
+            printer.dump ("\\consists \"Instrument_name_engraver\"")
+        if self.spanbar == "no":
+            printer.dump ("\\override SpanBar #'transparent = ##t")
+        brack = {"brace": "SystemStartBrace",
+                 "none": "SystemStartBar",
+                 "line": "SystemStartSquare"}.get (self.symbol, None)
+        if brack:
+            printer.dump ("systemStartDelimiter = #'%s" % brack)
+
+    def print_ly_overrides (self, printer):
+        needs_with = self.needs_with () | (len (self.context_modifications) > 0);
         if needs_with:
             printer.dump ("\\with {")
-            if self.instrument_name or self.short_instrument_name:
-                printer.dump ("\\consists \"Instrument_name_engraver\"")
-            if self.spanbar == "no":
-                printer.dump ("\\override SpanBar #'transparent = ##t")
-            brack = {"brace": "SystemStartBrace",
-                     "none": "f",
-                     "line": "SystemStartSquare"}.get (self.symbol, None)
-            if brack:
-                printer.dump ("systemStartDelimiter = #'%s" % brack)
+            self.print_ly_context_mods (printer)
+            for m in self.context_modifications:
+                printer.dump (m)
             printer.dump ("}")
 
+    def print_ly_chords (self,printer):
+        try:
+            for [staff_id, voices] in self.part_information:
+                for [v, lyrics, figuredbass, chordnames] in voices:
+                    if chordnames:
+                        printer ('\context ChordNames = "%s" \\%s' % (chordnames, chordnames))
+                        printer.newline ()
+        except TypeError:
+            return
+
     def print_ly (self, printer):
+        self.print_ly_chords (printer)
         if self.stafftype:
             printer.dump ("\\new %s" % self.stafftype)
         self.print_ly_overrides (printer)
@@ -1795,7 +1846,9 @@ class Staff (StaffGroup):
         self.voice_command = "Voice"
         self.substafftype = None
 
-    def print_ly_overrides (self, printer):
+    def needs_with (self):
+        return False
+    def print_ly_context_mods (self, printer):
         pass
 
     def print_ly_contents (self, printer):
@@ -1806,12 +1859,6 @@ class Staff (StaffGroup):
             sub_staff_type = self.stafftype
 
         for [staff_id, voices] in self.part_information:
-            # Chord names need to come before the staff itself!
-            for [v, lyrics, figuredbass, chordnames] in voices:
-                if chordnames:
-                    printer ('\context ChordNames = "%s" \\%s' % (chordnames, chordnames))
-
-            # now comes the real staff definition:
             if staff_id:
                 printer ('\\context %s = "%s" << ' % (sub_staff_type, staff_id))
             else:
@@ -1851,9 +1898,9 @@ class TabStaff (Staff):
         if self.string_tunings or self.tablature_format:
             printer.dump ("\\with {")
             if self.string_tunings:
-                printer.dump ("stringTunings = #'(")
+                printer.dump ("stringTunings = #`(")
                 for i in self.string_tunings:
-                    printer.dump ("%s" % i.semitones ())
+                    printer.dump (",%s" % i.lisp_expression ())
                 printer.dump (")")
             if self.tablature_format:
                 printer.dump ("tablatureFormat = #%s" % self.tablature_format)
@@ -1888,6 +1935,7 @@ class Score:
           self.contents.set_part_information (part_id, staves_info)
 
     def print_ly (self, printer):
+        self.create_midi = get_create_midi ()
         printer.dump ("\\score {");
         printer.newline ()
         if self.contents: