Class: HeadMusic::Notation::MusicXML::NoteWriter
- Inherits:
-
Object
- Object
- HeadMusic::Notation::MusicXML::NoteWriter
- Includes:
- XmlText, PlacementValidation
- Defined in:
- lib/head_music/notation/music_xml/note_writer.rb
Overview
Serializes the
A placement becomes one
Instance Attribute Summary collapse
-
#lyric_writer ⇒ Object
readonly
private
Returns the value of attribute lyric_writer.
-
#plan ⇒ Object
readonly
private
Returns the value of attribute plan.
Instance Method Summary collapse
-
#beam_lines(beams) ⇒ Object
private
-
#element_lines(placement, component, pitch: nil, chord: false, beams: []) ⇒ Object
private
A chord note carries
as its first child, before , marking it as sounding with the preceding note; the lead note (and every single note and rest) omits it, so this path stays byte-identical for those. -
#ensure_pitched_sounds(placement) ⇒ Object
included
from PlacementValidation
private
-
#escape(text) ⇒ Object
included
from XmlText
private
-
#initialize(plan) ⇒ NoteWriter
constructor
A new instance of NoteWriter.
-
#lines(placement) ⇒ Object
-
#notation_lines(placement, component) ⇒ Object
private
-
#note_slots(placement) ⇒ Object
private
A rest emits one empty slot; a sounded placement emits its pitches low to high, so the lowest note leads and the rest carry
. -
#pitch_lines(pitch) ⇒ Object
private
-
#render_error_class ⇒ Object
private
-
#tie_lines(placement, component) ⇒ Object
private
Rests take no tie elements; the links of a rest’s tied chain render as consecutive independent rests.
Constructor Details
#initialize(plan) ⇒ NoteWriter
Returns a new instance of NoteWriter.
14 15 16 17 |
# File 'lib/head_music/notation/music_xml/note_writer.rb', line 14 def initialize(plan) @plan = plan @lyric_writer = LyricWriter.new end |
Instance Attribute Details
#lyric_writer ⇒ Object (readonly, private)
Returns the value of attribute lyric_writer.
34 35 36 |
# File 'lib/head_music/notation/music_xml/note_writer.rb', line 34 def lyric_writer @lyric_writer end |
#plan ⇒ Object (readonly, private)
Returns the value of attribute plan.
34 35 36 |
# File 'lib/head_music/notation/music_xml/note_writer.rb', line 34 def plan @plan end |
Instance Method Details
#beam_lines(beams) ⇒ Object (private)
68 69 70 |
# File 'lib/head_music/notation/music_xml/note_writer.rb', line 68 def beam_lines(beams) beams.map { |beam| %(#{INDENT * 4}<beam number="#{beam.number}">#{beam.type}</beam>) } end |
#element_lines(placement, component, pitch: nil, chord: false, beams: []) ⇒ Object (private)
A chord note carries
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/head_music/notation/music_xml/note_writer.rb', line 52 def element_lines(placement, component, pitch: nil, chord: false, beams: []) [ "#{INDENT * 3}<note>", *(chord ? ["#{INDENT * 4}<chord/>"] : []), *(pitch ? pitch_lines(pitch) : ["#{INDENT * 4}<rest/>"]), "#{INDENT * 4}<duration>#{component.duration}</duration>", *tie_lines(placement, component), "#{INDENT * 4}<type>#{component.type}</type>", *Array.new(component.dots) { "#{INDENT * 4}<dot/>" }, *beam_lines(beams), *notation_lines(placement, component), *lyric_writer.lines(placement, component, chord: chord), "#{INDENT * 3}</note>" ] end |
#ensure_pitched_sounds(placement) ⇒ Object (private) Originally defined in module PlacementValidation
#escape(text) ⇒ Object (private) Originally defined in module XmlText
#lines(placement) ⇒ Object
19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/head_music/notation/music_xml/note_writer.rb', line 19 def lines(placement) ensure_pitched_sounds(placement) components_by_placement[placement].each_with_index.flat_map do |component, component_index| beams = beam_annotations[[placement, component_index]] || [] note_slots(placement).each_with_index.flat_map do |pitch, index| element_lines( placement, component, pitch: pitch, chord: index.positive?, beams: index.zero? ? beams : [] ) end end end |
#notation_lines(placement, component) ⇒ Object (private)
94 95 96 97 98 99 100 101 102 103 |
# File 'lib/head_music/notation/music_xml/note_writer.rb', line 94 def notation_lines(placement, component) return [] if placement.rest? || (!component.tie_start && !component.tie_stop) [ "#{INDENT * 4}<notations>", component.tie_stop ? %(#{INDENT * 5}<tied type="stop"/>) : nil, component.tie_start ? %(#{INDENT * 5}<tied type="start"/>) : nil, "#{INDENT * 4}</notations>" ].compact end |
#note_slots(placement) ⇒ Object (private)
A rest emits one empty slot; a sounded placement emits its pitches low to
high, so the lowest note leads and the rest carry
41 42 43 |
# File 'lib/head_music/notation/music_xml/note_writer.rb', line 41 def note_slots(placement) placement.rest? ? [nil] : placement.pitches.sort end |
#pitch_lines(pitch) ⇒ Object (private)
72 73 74 75 76 77 78 79 80 81 |
# File 'lib/head_music/notation/music_xml/note_writer.rb', line 72 def pitch_lines(pitch) attributes = PitchWriter.attributes(pitch) [ "#{INDENT * 4}<pitch>", "#{INDENT * 5}<step>#{attributes[:step]}</step>", attributes[:alter] && "#{INDENT * 5}<alter>#{attributes[:alter]}</alter>", "#{INDENT * 5}<octave>#{attributes[:octave]}</octave>", "#{INDENT * 4}</pitch>" ].compact end |
#render_error_class ⇒ Object (private)
45 46 47 |
# File 'lib/head_music/notation/music_xml/note_writer.rb', line 45 def render_error_class RenderError end |
#tie_lines(placement, component) ⇒ Object (private)
Rests take no tie elements; the links of a rest’s tied chain render as consecutive independent rests.
85 86 87 88 89 90 91 92 |
# File 'lib/head_music/notation/music_xml/note_writer.rb', line 85 def tie_lines(placement, component) return [] if placement.rest? [ component.tie_stop ? %(#{INDENT * 4}<tie type="stop"/>) : nil, component.tie_start ? %(#{INDENT * 4}<tie type="start"/>) : nil ].compact end |