Class: HeadMusic::Rudiment::RhythmicValue::Parser
- Inherits:
-
Object
- Object
- HeadMusic::Rudiment::RhythmicValue::Parser
- Defined in:
- lib/head_music/rudiment/rhythmic_value/parser.rb
Constant Summary collapse
- RhythmicUnit =
HeadMusic::Rudiment::RhythmicUnit
- RhythmicValue =
HeadMusic::Rudiment::RhythmicValue
- PATTERN =
/((double|triple)\W?)?(dotted)?.?(#{HeadMusic::Rudiment::RhythmicUnit::PATTERN})/- SHORTHAND_PATTERN =
For stuff like the “q.” in “q. = 108”
/\A(#{HeadMusic::Rudiment::RhythmicUnit::Parser::TEMPO_SHORTHAND_PATTERN})(\.*)?\z/i
Instance Attribute Summary collapse
-
#identifier ⇒ Object
readonly
Returns the value of attribute identifier.
-
#rhythmic_value ⇒ Object
readonly
Returns the value of attribute rhythmic_value.
Class Method Summary collapse
-
.parse(identifier) ⇒ Object
Parse a rhythmic value identifier and return a RhythmicValue object Returns nil if the identifier cannot be parsed.
Instance Method Summary collapse
-
#dots_from_word(matched_string) ⇒ Object
private
-
#from_direct_unit ⇒ Object
private
Try RhythmicUnit::Parser directly (handles fractions, decimals, British names, etc.).
-
#from_dotted_unit ⇒ Object
private
Parse with dots extracted for formats like “1/4.” (-> “1/4” with 1 dot), skipping identifiers that look like a decimal number.
-
#from_shorthand ⇒ Object
private
Check for shorthand patterns like “q.” first to avoid infinite recursion.
-
#from_word_pattern ⇒ Object
private
Check the word pattern for things like “dotted quarter”.
-
#initialize(identifier) ⇒ Parser
constructor
A new instance of Parser.
-
#parse_components ⇒ Object
private
Constructor Details
#initialize(identifier) ⇒ Parser
Returns a new instance of Parser.
19 20 21 22 |
# File 'lib/head_music/rudiment/rhythmic_value/parser.rb', line 19 def initialize(identifier) @identifier = identifier.to_s.strip parse_components end |
Instance Attribute Details
#identifier ⇒ Object (readonly)
Returns the value of attribute identifier.
2 3 4 |
# File 'lib/head_music/rudiment/rhythmic_value/parser.rb', line 2 def identifier @identifier end |
#rhythmic_value ⇒ Object (readonly)
Returns the value of attribute rhythmic_value.
2 3 4 |
# File 'lib/head_music/rudiment/rhythmic_value/parser.rb', line 2 def rhythmic_value @rhythmic_value end |
Class Method Details
.parse(identifier) ⇒ Object
Parse a rhythmic value identifier and return a RhythmicValue object Returns nil if the identifier cannot be parsed
14 15 16 17 |
# File 'lib/head_music/rudiment/rhythmic_value/parser.rb', line 14 def self.parse(identifier) return nil if identifier.nil? new(identifier).rhythmic_value end |
Instance Method Details
#dots_from_word(matched_string) ⇒ Object (private)
78 79 80 81 82 83 |
# File 'lib/head_music/rudiment/rhythmic_value/parser.rb', line 78 def dots_from_word(matched_string) return 3 if matched_string.include?("triple") return 2 if matched_string.include?("double") matched_string.include?("dotted") ? 1 : 0 end |
#from_direct_unit ⇒ Object (private)
Try RhythmicUnit::Parser directly (handles fractions, decimals, British names, etc.)
47 48 49 50 51 52 |
# File 'lib/head_music/rudiment/rhythmic_value/parser.rb', line 47 def from_direct_unit parser = RhythmicUnit::Parser.new(identifier) return nil unless parser.american_name RhythmicValue.new(parser.american_name, dots: 0) end |
#from_dotted_unit ⇒ Object (private)
Parse with dots extracted for formats like “1/4.” (-> “1/4” with 1 dot), skipping identifiers that look like a decimal number.
56 57 58 59 60 61 62 63 64 |
# File 'lib/head_music/rudiment/rhythmic_value/parser.rb', line 56 def from_dotted_unit return nil if identifier.match?(/^\d+\.\d+$/) dots = identifier.scan(".").count parser = RhythmicUnit::Parser.new(identifier.delete(".").strip) return nil unless parser.american_name RhythmicValue.new(parser.american_name, dots: dots) end |
#from_shorthand ⇒ Object (private)
Check for shorthand patterns like “q.” first to avoid infinite recursion
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/head_music/rudiment/rhythmic_value/parser.rb', line 35 def from_shorthand match = identifier.match(SHORTHAND_PATTERN) return nil unless match && match[1] unit_name = RhythmicUnit::Parser.parse(match[1].to_s.strip) return nil unless unit_name dots = match[2] ? match[2].strip.length : 0 RhythmicValue.new(unit_name, dots: dots) end |
#from_word_pattern ⇒ Object (private)
Check the word pattern for things like “dotted quarter”
67 68 69 70 71 72 73 74 75 76 |
# File 'lib/head_music/rudiment/rhythmic_value/parser.rb', line 67 def from_word_pattern match = identifier.match(PATTERN) return nil unless match matched_string = match[0].to_s.strip unit = RhythmicUnit.get(matched_string.gsub(/^\W*(double|triple)?\W*(dotted)?\W*/, "")) return nil unless unit RhythmicValue.new(unit, dots: dots_from_word(matched_string)) end |
#parse_components ⇒ Object (private)
26 27 28 29 30 31 32 |
# File 'lib/head_music/rudiment/rhythmic_value/parser.rb', line 26 def parse_components @rhythmic_value = from_shorthand || from_direct_unit || from_dotted_unit || from_word_pattern end |