Class: HeadMusic::Notation::LilyPond::MeterReader

Inherits:
Object
  • Object
show all
Defined in:
lib/head_music/notation/lily_pond/meter_reader.rb

Overview

Converts the argument of a \time command into a meter.

The signature is validated textually before Meter.get sees it: the rudiment memoizes whatever it is handed, and a zero numerator makes position arithmetic loop forever.

Constant Summary collapse

SIGNATURE_PATTERN =
%r{\A(\d+)/(\d+)\z}
MAX_DENOMINATOR =
256

Class Method Summary collapse

Class Method Details

.meter(token) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/head_music/notation/lily_pond/meter_reader.rb', line 12

def self.meter(token)
  match = token&.type == :number && SIGNATURE_PATTERN.match(token.lexeme)
  top = match && match[1].to_i
  bottom = match && match[2].to_i
  unless match && top.positive? && valid_denominator?(bottom)
    raise ParseError.new(
      %(Invalid \\time signature "#{token&.lexeme}"),
      line_number: token&.line, column: token&.column, snippet: token&.lexeme
    )
  end

  HeadMusic::Rudiment::Meter.get("#{top}/#{bottom}")
end

.valid_denominator?(bottom) ⇒ Boolean (private)

Returns:

  • (Boolean)


26
27
28
# File 'lib/head_music/notation/lily_pond/meter_reader.rb', line 26

def self.valid_denominator?(bottom)
  bottom.positive? && bottom <= MAX_DENOMINATOR && (bottom & (bottom - 1)).zero?
end