Class: HeadMusic::Rudiment::RhythmicValue::Parser

Inherits:
Object
  • Object
show all
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

Class Method Summary collapse

Instance Method Summary collapse

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

#identifierObject (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_valueObject (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_unitObject (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_unitObject (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_shorthandObject (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_patternObject (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_componentsObject (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