lib/head_music/clef.rb in head_music-0.24.0 vs lib/head_music/clef.rb in head_music-0.24.1

- old
+ new

@@ -1,95 +1,25 @@ # frozen_string_literal: true +require 'yaml' + # A clef assigns pitches to the lines and spaces of a staff. class HeadMusic::Clef include HeadMusic::Named - CLEFS = [ - { - pitch: 'G4', line: 2, - names: %w[treble G-clef], - modern: true, - unicode: '𝄞', html_entity: '𝄞', - }, - { - pitch: 'G4', line: 1, - names: ['French', 'French violin'], - unicode: '𝄞', html_entity: '𝄞', - }, - { - pitch: 'G3', line: 2, - names: ['choral tenor', 'tenor', 'tenor G-clef'], - modern: true, - unicode: '𝄠', html_entity: '𝄠', - }, - { - pitch: 'F3', line: 3, - names: ['baritone'], - unicode: '𝄢', html_entity: '𝄢', - }, - { - pitch: 'F3', line: 4, - names: %w[bass F-clef], - modern: true, - unicode: '𝄢', html_entity: '𝄢', - }, - { - pitch: 'F3', line: 5, - names: ['sub-bass'], - unicode: '𝄢', html_entity: '𝄢', - }, - { - pitch: 'C4', line: 1, - names: ['soprano'], - unicode: '𝄡', html_entity: '𝄡', - }, - { - pitch: 'C4', line: 2, - names: ['mezzo-soprano'], - unicode: '𝄡', html_entity: '𝄡', - }, - { - pitch: 'C4', line: 3, - names: %w[alto viola counter-tenor countertenor C-clef], - modern: true, - unicode: '𝄡', html_entity: '𝄡', - }, - { - pitch: 'C4', line: 4, - names: ['tenor', 'tenor C-clef'], - modern: true, - unicode: '𝄡', html_entity: '𝄡', - }, - { - pitch: 'C4', line: 5, - names: ['baritone', 'baritone C-clef'], - unicode: '𝄡', html_entity: '𝄡', - }, - { - pitch: nil, line: 3, - names: %w[neutral percussion], - modern: true, - unicode: '𝄥', html_entity: '𝄥', - }, - ].freeze + RECORDS = YAML.load_file(File.expand_path('data/clefs.yml', __dir__)).freeze def self.get(name) get_by_name(name) end - attr_reader :pitch, :line, :musical_symbol + attr_reader :pitch, :line, :musical_symbols delegate :ascii, :html_entity, :unicode, to: :musical_symbol - def initialize(name) - @name = name.to_s - clef_data = CLEFS.detect { |clef| clef[:names].map(&:downcase).include?(name.downcase) } - @pitch = HeadMusic::Pitch.get(clef_data[:pitch]) - @line = clef_data[:line] - @modern = clef_data[:modern] - @musical_symbol = HeadMusic::MusicalSymbol.new(clef_data.slice(:ascii, :html_entity, :unicode)) + def musical_symbol + musical_symbols.first end def clef_type "#{pitch.letter_name}-clef" end @@ -113,8 +43,61 @@ def modern? @modern end def ==(other) - to_s == other.to_s + HeadMusic::Utilities::HashKey.for(self) == HeadMusic::Utilities::HashKey.for(other) + end + + def name(locale_code: Locale::DEFAULT_CODE) + I18n.translate(name_key, scope: :clefs, locale: locale_code) + end + + private_class_method :new + + private + + def initialize(name) + record = record_for_name(name) + initialize_data_from_record(record) + end + + def record_for_name(name) + name = name.to_s.strip + key = HeadMusic::Utilities::HashKey.for(name) + RECORDS.detect do |record| + name_keys = name_keys_from_record(record) + name_keys.include?(key) || name_key_translations(name_keys).include?(name) + end + end + + def name_keys_from_record(record) + ([record[:name_key]] + [record[:alias_name_keys]]).flatten.compact.uniq.map(&:to_sym) + end + + def name_key_translations(name_keys) + name_keys.map do |name_key| + I18n.config.available_locales.map do |locale_code| + I18n.translate(name_key, scope: :clefs, locale: locale_code) + end.flatten.uniq.compact + end.flatten.uniq.compact + end + + def initialize_data_from_record(record) + initialize_keys_from_record(record) + @pitch = HeadMusic::Pitch.get(record[:pitch]) + @line = record[:line] + @modern = record[:modern] + initialize_musical_symbols(record[:symbols]) + end + + def initialize_keys_from_record(record) + @name_key = record[:name_key] + @alias_name_keys = [record[:alias_name_keys]].flatten.compact + end + + def initialize_musical_symbols(list) + @musical_symbols = (list || []).map do |symbol_data| + HeadMusic::MusicalSymbol.new(symbol_data.slice(:ascii, :html_entity, :unicode)) + end end end