From: Reinhold Kainhofer Date: Mon, 12 Apr 2010 17:39:39 +0000 (+0200) Subject: MusicXML: Implement staff-lines setting (i.e. # of lines of a staff) X-Git-Tag: release/2.13.18-1~15^2~31 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=c6cd21e48b0d05be84c54293c6a1e99a51c46dfd;p=lilypond.git MusicXML: Implement staff-lines setting (i.e. # of lines of a staff) -) Add possible context modifications to staves -) convert a global staff-lines attribute to a contex mod inside \with -) Convert a staff-lines attribute midway through the part as \stopStaff \override ... \startStaff -) Add regtest for all these cases --- diff --git a/input/regression/musicxml/14a-StaffDetails-LineChanges.xml b/input/regression/musicxml/14a-StaffDetails-LineChanges.xml new file mode 100644 index 0000000000..e297d5c884 --- /dev/null +++ b/input/regression/musicxml/14a-StaffDetails-LineChanges.xml @@ -0,0 +1,154 @@ + + + + + + The number of staff lines can be + modified by using the staff-lines child of the staff-details attribute. + This can happen globally (the first staff has one line globally) or + during the part at the beginning of a measure and even inside a measure + (the second part has 5 lines initially, 4 at the beginning of the + second measure, and 3 starting in the middle of the third + measure). + + + + + bracket + yes + + + Part 1 + + + Part 2 + + + + + + + + 1 + + 0 + major + + + 1 + + + + + D + 5 + + 4 + 1 + whole + + + + + + + D + 5 + + 4 + 1 + whole + + + + + + + D + 5 + + 4 + 1 + whole + + + + + + + + 1 + + 0 + major + + + 5 + + + + + G + 4 + + 4 + 1 + whole + + + + + + + 4 + + + + + G + 4 + + 2 + 1 + half + + + + G + 4 + + 2 + 1 + half + + + + + + + G + 4 + + 2 + 1 + half + + + + 2 + + + + + G + 4 + + 2 + 1 + half + + + + + diff --git a/python/musicexp.py b/python/musicexp.py index b49ee658af..1c9f3effb1 100644 --- a/python/musicexp.py +++ b/python/musicexp.py @@ -1598,6 +1598,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 +1748,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,27 +1765,38 @@ 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": "f", + "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 (self, printer): @@ -1805,7 +1827,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): diff --git a/scripts/musicxml2ly.py b/scripts/musicxml2ly.py index b0f8284d86..318020d8b5 100644 --- a/scripts/musicxml2ly.py +++ b/scripts/musicxml2ly.py @@ -401,6 +401,8 @@ def staff_attributes_to_lily_staff (mxl_attr): if staff_lines: lines = string.atoi (staff_lines.get_text ()) + # TODO: Handle other staff attributes like staff-space, etc. + staff = None if clef_sign == "percussion" and lines == 1: staff = musicexp.RhythmicStaff () @@ -412,8 +414,11 @@ def staff_attributes_to_lily_staff (mxl_attr): staff.string_tunings = staff_attributes_to_string_tunings (attributes) # staff.tablature_format = ??? else: - # TODO: Handle case with lines <> 5! staff = musicexp.Staff () + # TODO: Handle case with lines <> 5! + if (lines != 5): + staff.add_context_modification ("\\override StaffSymbol #'line-count = #%s" % lines) + return staff @@ -926,6 +931,22 @@ def musicxml_transpose_to_lily (attributes): transposition.pitch = musicexp.Pitch ().transposed (shift) return transposition +def musicxml_staff_details_to_lily (attributes): + details = attributes.get_maybe_exist_named_child ('staff-details') + if not details: + return None + + ## TODO: Handle staff-type, staff-lines, staff-tuning, capo, staff-size + ret = [] + + stafflines = details.get_maybe_exist_named_child ('staff-lines') + if stafflines: + lines = string.atoi (stafflines.get_text ()); + lines_event = musicexp.StaffLinesEvent (lines); + ret.append (lines_event); + + return ret; + def musicxml_attributes_to_lily (attrs): elts = [] @@ -934,12 +955,16 @@ def musicxml_attributes_to_lily (attrs): 'time': musicxml_time_to_lily, 'key': musicxml_key_to_lily, 'transpose': musicxml_transpose_to_lily, + 'staff-details': musicxml_staff_details_to_lily, } for (k, func) in attr_dispatch.items (): children = attrs.get_named_children (k) if children: ev = func (attrs) - if ev: + if isinstance (ev, list): + for e in ev: + elts.append (e) + elif ev: elts.append (ev) return elts