Class: HeadMusic::Notation::MusicXML::AttributesWriter
- Inherits:
-
Object
- Object
- HeadMusic::Notation::MusicXML::AttributesWriter
- Includes:
- XmlText
- Defined in:
- lib/head_music/notation/music_xml/attributes_writer.rb
Overview
Renders a measure's
Instance Attribute Summary collapse
-
#plan ⇒ Object
readonly
private
Returns the value of attribute plan.
Instance Method Summary collapse
- #clef_element_lines(clef, number) ⇒ Object private
- #clef_for(part, staff) ⇒ Object private
-
#clef_lines(part) ⇒ Object
private
An authored clef wins; the selector is the fallback for a part whose staves were never authored.
- #diatonic_steps(semitones) ⇒ Object private
- #escape(text) ⇒ Object included from XmlText private
- #first_measure_lines(part) ⇒ Object private
-
#initialize(plan) ⇒ AttributesWriter
constructor
A new instance of AttributesWriter.
- #instrument_change_transpose_lines(part, bar_number) ⇒ Object private
- #key_lines(key) ⇒ Object private
- #lines(part, bar_number) ⇒ Object
-
#staves_lines(part) ⇒ Object
private
is omitted for the single-staff part, where it would be noise. - #time_lines(meter) ⇒ Object private
-
#transpose_lines(instrument) ⇒ Object
private
states sounding = written + transpose, the same convention the instrument catalog states its sounding_transposition in.
Constructor Details
#initialize(plan) ⇒ AttributesWriter
Returns a new instance of AttributesWriter.
16 17 18 |
# File 'lib/head_music/notation/music_xml/attributes_writer.rb', line 16 def initialize(plan) @plan = plan end |
Instance Attribute Details
#plan ⇒ Object (readonly, private)
Returns the value of attribute plan.
39 40 41 |
# File 'lib/head_music/notation/music_xml/attributes_writer.rb', line 39 def plan @plan end |
Instance Method Details
#clef_element_lines(clef, number) ⇒ Object (private)
123 124 125 126 127 128 129 130 |
# File 'lib/head_music/notation/music_xml/attributes_writer.rb', line 123 def clef_element_lines(clef, number) [ "#{INDENT * 4}<clef#{number}>", "#{INDENT * 5}<sign>#{clef.pitch.letter_name}</sign>", "#{INDENT * 5}<line>#{clef.line}</line>", "#{INDENT * 4}</clef>" ] end |
#clef_for(part, staff) ⇒ Object (private)
119 120 121 |
# File 'lib/head_music/notation/music_xml/attributes_writer.rb', line 119 def clef_for(part, staff) staff.clef_at(.first) || HeadMusic::Notation::ClefSelector.for(part.voices.first) end |
#clef_lines(part) ⇒ Object (private)
An authored clef wins; the selector is the fallback for a part whose staves were never authored. It reads a voice's pitch range, which is why the fallback lives here, where a voice is in scope, rather than on the staff.
111 112 113 114 115 116 117 |
# File 'lib/head_music/notation/music_xml/attributes_writer.rb', line 111 def clef_lines(part) staves = part.staff_system.staves staves.each_with_index.flat_map do |staff, index| number = (staves.length > 1) ? %( number="#{index + 1}") : "" clef_element_lines(clef_for(part, staff), number) end end |
#diatonic_steps(semitones) ⇒ Object (private)
80 81 82 |
# File 'lib/head_music/notation/music_xml/attributes_writer.rb', line 80 def diatonic_steps(semitones) HeadMusic::Content::Layout::Transposition.for_semitones(semitones).diatonic_steps end |
#escape(text) ⇒ Object (private) Originally defined in module XmlText
#first_measure_lines(part) ⇒ Object (private)
41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/head_music/notation/music_xml/attributes_writer.rb', line 41 def first_measure_lines(part) [ "#{INDENT * 3}<attributes>", "#{INDENT * 4}<divisions>#{divisions}</divisions>", *key_lines(first_measure_key(part)), *time_lines(first_measure_meter), *staves_lines(part), *clef_lines(part), *transpose_lines(part.instrument_at(.first)), "#{INDENT * 3}</attributes>" ] end |
#instrument_change_transpose_lines(part, bar_number) ⇒ Object (private)
54 55 56 57 58 |
# File 'lib/head_music/notation/music_xml/attributes_writer.rb', line 54 def instrument_change_transpose_lines(part, ) return [] unless part.instrument_changes.key?() transpose_lines(part.instrument_at()) end |
#key_lines(key) ⇒ Object (private)
90 91 92 93 94 95 96 97 |
# File 'lib/head_music/notation/music_xml/attributes_writer.rb', line 90 def key_lines(key) [ "#{INDENT * 4}<key>", "#{INDENT * 5}<fifths>#{key[:fifths]}</fifths>", key[:mode] && "#{INDENT * 5}<mode>#{key[:mode]}</mode>", "#{INDENT * 4}</key>" ].compact end |
#lines(part, bar_number) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/head_music/notation/music_xml/attributes_writer.rb', line 20 def lines(part, ) return first_measure_lines(part) if == .first key = measure_key_changes(part)[] meter = measure_time_changes[] transpose = instrument_change_transpose_lines(part, ) return [] unless key || meter || transpose.any? [ "#{INDENT * 3}<attributes>", *(key ? key_lines(key) : []), *(meter ? time_lines(meter) : []), *transpose, "#{INDENT * 3}</attributes>" ] end |
#staves_lines(part) ⇒ Object (private)
85 86 87 88 |
# File 'lib/head_music/notation/music_xml/attributes_writer.rb', line 85 def staves_lines(part) count = part.staff_system.length (count > 1) ? ["#{INDENT * 4}<staves>#{count}</staves>"] : [] end |
#time_lines(meter) ⇒ Object (private)
99 100 101 102 103 104 105 106 |
# File 'lib/head_music/notation/music_xml/attributes_writer.rb', line 99 def time_lines(meter) [ "#{INDENT * 4}<time>", "#{INDENT * 5}<beats>#{meter.top_number}</beats>", "#{INDENT * 5}<beat-type>#{meter.bottom_number}</beat-type>", "#{INDENT * 4}</time>" ] end |
#transpose_lines(instrument) ⇒ Object (private)
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/head_music/notation/music_xml/attributes_writer.rb', line 63 def transpose_lines(instrument) return [] unless transposed? semitones = instrument&.sounding_transposition.to_i return [] if semitones.zero? sign = semitones.negative? ? -1 : 1 octaves, chromatic = semitones.abs.divmod(12) [ "#{INDENT * 4}<transpose>", "#{INDENT * 5}<diatonic>#{diatonic_steps(sign * chromatic)}</diatonic>", "#{INDENT * 5}<chromatic>#{sign * chromatic}</chromatic>", (octaves.zero? ? nil : "#{INDENT * 5}<octave-change>#{sign * octaves}</octave-change>"), "#{INDENT * 4}</transpose>" ].compact end |