X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=python%2Fmusicexp.py;h=f6b47c3c93582af7471c13da23b38e7eec70ae1d;hb=14bd7e660f59c1ce1373424a877a70ec576a93d3;hp=b49ee658af6bb2aedf34894e7bb81214a6c6f9e0;hpb=899823d9d23688ae24bd8b9efccf3ac7d0a86f9e;p=lilypond.git diff --git a/python/musicexp.py b/python/musicexp.py index b49ee658af..f6b47c3c93 100644 --- a/python/musicexp.py +++ b/python/musicexp.py @@ -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 {') @@ -749,7 +763,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 +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" @@ -1598,6 +1612,16 @@ class SetEvent (Music): 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): Music.__init__ (self) @@ -1738,6 +1762,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 @@ -1754,30 +1779,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 ("\\hide SpanBar") + 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) @@ -1805,7 +1852,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): @@ -1816,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: @@ -1861,9 +1904,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) @@ -1898,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: