Class: HeadMusic::Notation::LilyPond::KeyReader
- Inherits:
-
Object
- Object
- HeadMusic::Notation::LilyPond::KeyReader
- Defined in:
- lib/head_music/notation/lily_pond/key_reader.rb
Overview
Converts the pitch and mode tokens of a \key command into a key signature.
Constant Summary collapse
- TONIC_FRAGMENTS_BY_SEMITONES =
{0 => "", 1 => "#", -1 => "b"}.freeze
Instance Attribute Summary collapse
-
#mode_token ⇒ Object
readonly
private
Returns the value of attribute mode_token.
-
#pitch_token ⇒ Object
readonly
private
Returns the value of attribute pitch_token.
Class Method Summary collapse
-
.key_signature(pitch_token, mode_token) ⇒ Object
-
.scale_types_by_mode_command ⇒ Object
The inverse of the writer’s table, keyed by the mode command’s name without its backslash.
Instance Method Summary collapse
-
#ensure_bare_pitch ⇒ Object
private
-
#error(message, token) ⇒ Object
private
-
#initialize(pitch_token, mode_token) ⇒ KeyReader
constructor
A new instance of KeyReader.
-
#key_signature ⇒ Object
-
#scale_type ⇒ Object
private
-
#tonic ⇒ Object
private
Constructor Details
#initialize(pitch_token, mode_token) ⇒ KeyReader
Returns a new instance of KeyReader.
20 21 22 23 |
# File 'lib/head_music/notation/lily_pond/key_reader.rb', line 20 def initialize(pitch_token, mode_token) @pitch_token = pitch_token @mode_token = mode_token end |
Instance Attribute Details
#mode_token ⇒ Object (readonly, private)
Returns the value of attribute mode_token.
32 33 34 |
# File 'lib/head_music/notation/lily_pond/key_reader.rb', line 32 def mode_token @mode_token end |
#pitch_token ⇒ Object (readonly, private)
Returns the value of attribute pitch_token.
32 33 34 |
# File 'lib/head_music/notation/lily_pond/key_reader.rb', line 32 def pitch_token @pitch_token end |
Class Method Details
.key_signature(pitch_token, mode_token) ⇒ Object
16 17 18 |
# File 'lib/head_music/notation/lily_pond/key_reader.rb', line 16 def self.key_signature(pitch_token, mode_token) new(pitch_token, mode_token).key_signature end |
.scale_types_by_mode_command ⇒ Object
The inverse of the writer’s table, keyed by the mode command’s name without its backslash. Built lazily because the reader loads before the writer.
10 11 12 13 14 |
# File 'lib/head_music/notation/lily_pond/key_reader.rb', line 10 def self.scale_types_by_mode_command @scale_types_by_mode_command ||= KeyMapper::MODE_COMMANDS_BY_SCALE_TYPE .to_h { |scale_type, command| [command.delete_prefix("\\"), scale_type] } .freeze end |
Instance Method Details
#ensure_bare_pitch ⇒ Object (private)
34 35 36 37 38 39 |
# File 'lib/head_music/notation/lily_pond/key_reader.rb', line 34 def return unless pitch_token.nil? || pitch_token.type != :note || pitch_token.octave_marks || pitch_token.duration || pitch_token.multiplier raise error("\\key expects a pitch and a mode", pitch_token || mode_token) end |
#error(message, token) ⇒ Object (private)
59 60 61 |
# File 'lib/head_music/notation/lily_pond/key_reader.rb', line 59 def error(, token) ParseError.new(, line_number: token&.line, column: token&.column, snippet: token&.lexeme) end |
#key_signature ⇒ Object
25 26 27 28 |
# File 'lib/head_music/notation/lily_pond/key_reader.rb', line 25 def key_signature HeadMusic::Rudiment::KeySignature.get("#{tonic} #{scale_type}") end |
#scale_type ⇒ Object (private)
49 50 51 52 53 54 55 56 57 |
# File 'lib/head_music/notation/lily_pond/key_reader.rb', line 49 def scale_type unless mode_token&.type == :command raise error("\\key expects a pitch and a mode", mode_token || pitch_token) end self.class.scale_types_by_mode_command.fetch(mode_token.lexeme) do raise error(%(Unrecognized mode "\\#{mode_token.lexeme}" in \\key command), mode_token) end end |
#tonic ⇒ Object (private)
41 42 43 44 45 46 47 |
# File 'lib/head_music/notation/lily_pond/key_reader.rb', line 41 def tonic semitones = PitchReader.alterations_by_suffix.fetch(pitch_token.suffix.to_s) fragment = TONIC_FRAGMENTS_BY_SEMITONES.fetch(semitones) do raise error(%(Cannot build a key signature on the double-altered tonic "#{pitch_token.lexeme}"), pitch_token) end "#{pitch_token.letter.upcase}#{fragment}" end |