]> git.donarmstrong.com Git - lilypond.git/blobdiff - python/musicexp.py
Issue 4799: Let musicxml2py generate current override/revert syntax
[lilypond.git] / python / musicexp.py
index 68318678de073ea8ae5fec845dd6f8794793b94d..f6b47c3c93582af7471c13da23b38e7eec70ae1d 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):
@@ -250,6 +258,10 @@ def pitch_italiano (pitch):
 def pitch_catalan (pitch):
     return pitch_italiano (pitch)
 
+def pitch_francais (pitch):
+    str = pitch_generic (pitch, ['do', 'ré', 'mi', 'fa', 'sol', 'la', 'si'], ['b', 'sb', 'sd', 'd'])
+    return str
+
 def pitch_espanol (pitch):
     str = pitch_generic (pitch, ['do', 're', 'mi', 'fa', 'sol', 'la', 'si'], ['b', None, None, 's'])
     return str
@@ -267,8 +279,10 @@ def set_pitch_language (language):
         "norsk": pitch_norsk,
         "svenska": pitch_svenska,
         "italiano": pitch_italiano,
+        "français": pitch_francais,
         "catalan": pitch_catalan,
         "espanol": pitch_espanol,
+        "español": pitch_espanol,
         "vlaams": pitch_vlaams}
     pitch_generating_function = function_dict.get (language, pitch_general)
 
@@ -477,11 +491,11 @@ class TimeScaledMusic (MusicWrapper):
 
     def print_ly (self, func):
         if self.display_bracket == None:
-            func ("\\once \\override TupletBracket #'stencil = ##f")
+            func ("\\once \\omit TupletBracket")
             func.newline ()
         elif self.display_bracket == "curved":
-            warning (_ ("Tuplet brackets of curved shape are not correctly implemented"))
-            func ("\\once \\override TupletBracket #'stencil = #ly:slur::print")
+            ly.warning (_ ("Tuplet brackets of curved shape are not correctly implemented"))
+            func ("\\once \\override TupletBracket.stencil = #ly:slur::print")
             func.newline ()
 
         base_number_function = {None: "#f",
@@ -505,12 +519,12 @@ class TimeScaledMusic (MusicWrapper):
         if self.display_type == "actual" and self.normal_type:
             # Obtain the note duration in scheme-mode, i.e. \longa as \\longa
             base_duration = self.normal_type.ly_expression (None, True)
-            func ("\\once \\override TupletNumber #'text = #(tuplet-number::append-note-wrapper %s \"%s\")" %
+            func ("\\once \\override TupletNumber.text = #(tuplet-number::append-note-wrapper %s \"%s\")" %
                 (base_number_function, base_duration))
             func.newline ()
         elif self.display_type == "both": # TODO: Implement this using actual_type and normal_type!
             if self.display_number == None:
-                func ("\\once \\override TupletNumber #'stencil = ##f")
+                func ("\\once \\omit TupletNumber")
                 func.newline ()
             elif self.display_number == "both":
                 den_duration = self.normal_type.ly_expression (None, True)
@@ -520,20 +534,20 @@ class TimeScaledMusic (MusicWrapper):
                 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:
             if self.display_number == None:
-                func ("\\once \\override TupletNumber #'stencil = ##f")
+                func ("\\once \\omit TupletNumber")
                 func.newline ()
             elif self.display_number == "both":
-                func ("\\once \\override TupletNumber #'text = #%s" % base_number_function)
+                func ("\\once \\override TupletNumber.text = #%s" % base_number_function)
                 func.newline ()
 
         func ('\\times %d/%d ' %
@@ -666,7 +680,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 +689,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 {')
@@ -845,7 +859,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 +1021,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
@@ -1036,7 +1050,7 @@ class GlissandoEvent (SpanEvent):
                 "wavy"   : "zigzag"
             }. get (self.line_type, None)
             if style:
-                printer.dump ("\\once \\override Glissando #'style = #'%s" % style)
+                printer.dump ("\\once \\override Glissando.style = #'%s" % style)
     def ly_expression (self):
         return {-1: '\\glissando',
             1:''}.get (self.span_direction, '')
@@ -1243,12 +1257,12 @@ class NotestyleEvent (Event):
         self.filled = None
     def pre_chord_ly (self):
         if self.style:
-            return "\\once \\override NoteHead #'style = #%s" % self.style
+            return "\\once \\override NoteHead.style = #%s" % self.style
         else:
             return ''
     def pre_note_ly (self, is_chord_element):
         if self.style and is_chord_element:
-            return "\\tweak #'style #%s" % self.style
+            return "\\tweak style #%s" % self.style
         else:
             return ''
     def ly_expression (self):
@@ -1465,7 +1479,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)
@@ -1481,7 +1495,7 @@ class KeySignatureChange (Music):
         elif self.non_standard_alterations:
             alterations = [self.format_non_standard_alteration (a) for
                                         a in self.non_standard_alterations]
-            return "\\set Staff.keySignature = #`(%s)" % string.join (alterations, " ")
+            return "\\set Staff.keyAlterations = #`(%s)" % string.join (alterations, " ")
         else:
             return ''
 
@@ -1507,7 +1521,7 @@ class TimeSignatureChange (Music):
             if self.style == "common":
                 st = "\\defaultTimeSignature"
             elif (self.style != "'()"):
-                st = "\\once \\override Staff.TimeSignature #'style = #%s " % self.style
+                st = "\\once \\override Staff.TimeSignature.style = #%s " % self.style
             elif (self.style != "'()") or is_common_signature:
                 st = "\\numericTimeSignature"
 
@@ -1604,9 +1618,9 @@ class StaffLinesEvent (Music):
         self.lines = lines
     def ly_expression (self):
         if (self.lines > 0):
-          return "\\stopStaff \\override Staff.StaffSymbol #'line-count = #%s \\startStaff" % self.lines
+          return "\\stopStaff \\override Staff.StaffSymbol.line-count = #%s \\startStaff" % self.lines
         else:
-          return "\\stopStaff \\revert Staff.StaffSymbol #'line-count \\startStaff"
+          return "\\stopStaff \\revert Staff.StaffSymbol.line-count \\startStaff"
 
 class TempoMark (Music):
     def __init__ (self):
@@ -1783,9 +1797,9 @@ class StaffGroup:
         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")
+            printer.dump ("\\hide SpanBar")
         brack = {"brace": "SystemStartBrace",
-                 "none": "f",
+                 "none": "SystemStartBar",
                  "line": "SystemStartSquare"}.get (self.symbol, None)
         if brack:
             printer.dump ("systemStartDelimiter = #'%s" % brack)
@@ -1799,7 +1813,18 @@ class StaffGroup:
                 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)
@@ -1840,12 +1865,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:
@@ -1922,6 +1941,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: