Sha256: 7d4383da6ac10aa66b8fdf399df1d66079798eafbb48b46fa85571c5ff598f73

Contents?: true

Size: 1.93 KB

Versions: 1

Compression:

Stored size: 1.93 KB

Contents

class HeadMusic::Sign
  include Comparable

  attr_reader :identifier, :name, :ascii, :unicode, :html_entity, :cents

  def self.all
    @all ||= [
      new(identifier: :sharp, name: 'sharp', ascii: '#', unicode: '♯', html_entity: '♯', cents: 100),
      new(identifier: :flat, name: 'flat', ascii: 'b', unicode: "♭", html_entity: '♭', cents: -100),
      new(identifier: :natural, name: 'natural', ascii: '', unicode: '♮', html_entity: '♮', cents: 0),
      new(identifier: :double_sharp, name: 'double sharp', ascii: '##', unicode: '𝄪', html_entity: '𝄪', cents: 200),
      new(identifier: :double_flat, name: 'double flat', ascii: 'bb', unicode: '𝄫', html_entity: '𝄫', cents: -200),
    ]
  end

  def self.symbols
    @sign_symbols ||= all.map { |sign| [sign.ascii, sign.unicode] }.flatten.reject { |s| s.nil? || s.empty? }
  end

  def self.matcher
    @matcher ||= Regexp.new symbols.join('|')
  end

  def self.symbol?(candidate)
    /^(#{matcher})$/.match?(candidate)
  end

  def self.get(identifier)
    return identifier if identifier.is_a?(HeadMusic::Sign)
    all.detect do |sign|
      sign.representions.include?(identifier)
    end
  end

  def self.by(key, value)
    all.detect do |sign|
      if %i[cents semitones].include?(key.to_sym)
        sign.send(key) == value
      end
    end
  end

  def representions
    [identifier, identifier.to_s, name, ascii, unicode, html_entity].reject { |representation| representation.to_s.strip == '' }
  end

  def semitones
    cents / 100.0
  end

  def to_s
    unicode
  end

  def <=>(other)
    other = HeadMusic::Sign.get(other)
    self.cents <=> other.cents
  end

  private

  def initialize(attributes)
    @identifier = attributes[:identifier]
    @name = attributes[:name]
    @ascii = attributes[:ascii]
    @unicode = attributes[:unicode]
    @html_entity = attributes[:html_entity]
    @cents = attributes[:cents]
  end

  private_class_method :new
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
head_music-0.17.0 lib/head_music/sign.rb