Class: HeadMusic::Instruments::ScoreOrder
- Inherits:
-
Object
- Object
- HeadMusic::Instruments::ScoreOrder
- Includes:
- Named
- Defined in:
- lib/head_music/instruments/score_order.rb
Constant Summary collapse
- SCORE_ORDERS =
YAML.load_file(File.("score_orders.yml", __dir__)).freeze
- DEFAULT_ENSEMBLE_TYPE_KEY =
:orchestral
Instance Attribute Summary collapse
-
#alias_name_keys ⇒ Object
included
from Named
readonly
Returns the value of attribute alias_name_keys.
-
#ensemble_type_key ⇒ Object
readonly
Returns the value of attribute ensemble_type_key.
-
#name_key ⇒ Object
included
from Named
readonly
Returns the value of attribute name_key.
-
#sections ⇒ Object
readonly
Returns the value of attribute sections.
Class Method Summary collapse
-
.get(ensemble_type) ⇒ Object
Factory method to get a ScoreOrder instance for a specific ensemble type.
-
.in_band_order(instruments) ⇒ Object
Convenience method to order instruments in concert band order.
-
.in_orchestral_order(instruments) ⇒ Object
Convenience method to order instruments in orchestral order.
Instance Method Summary collapse
-
#build_ordering_index ⇒ Object
private
Builds an index mapping instrument names to their position in the order.
- #ensure_localized_name(name:, locale_code: Locale::DEFAULT_CODE, abbreviation: nil) ⇒ Object included from Named
-
#find_position(instrument, ordering_index) ⇒ Object
private
Finds the position of an instrument in the ordering.
-
#find_position_with_transposition(instrument, ordering_index) ⇒ Object
private
Finds the position and transposition information for an instrument.
-
#initialize(ensemble_type_key = DEFAULT_ENSEMBLE_TYPE_KEY) ⇒ ScoreOrder
constructor
private
A new instance of ScoreOrder.
- #localized_name(locale_code: Locale::DEFAULT_CODE) ⇒ Object included from Named
- #localized_name_in_default_locale ⇒ Object included from Named private
- #localized_name_in_locale_matching_language(locale) ⇒ Object included from Named private
- #localized_name_in_matching_locale(locale) ⇒ Object included from Named private
-
#localized_names ⇒ Object
included
from Named
Returns an array of LocalizedName instances that are synonymous with the name.
- #name(locale_code: Locale::DEFAULT_CODE) ⇒ Object included from Named
- #name=(name) ⇒ Object included from Named
- #normalize_to_instrument(input) ⇒ Object private
-
#order(instruments) ⇒ Object
Accepts a list of instruments and orders them according to this ensemble type's conventions.
Constructor Details
#initialize(ensemble_type_key = DEFAULT_ENSEMBLE_TYPE_KEY) ⇒ ScoreOrder (private)
Returns a new instance of ScoreOrder.
63 64 65 66 67 68 69 |
# File 'lib/head_music/instruments/score_order.rb', line 63 def initialize(ensemble_type_key = DEFAULT_ENSEMBLE_TYPE_KEY) @ensemble_type_key = ensemble_type_key.to_sym data = SCORE_ORDERS[ensemble_type_key.to_s] @sections = data["sections"] || [] self.name = data["name"] || ensemble_type_key.to_s.tr("_", " ").capitalize end |
Instance Attribute Details
#alias_name_keys ⇒ Object (readonly) Originally defined in module Named
Returns the value of attribute alias_name_keys.
#ensemble_type_key ⇒ Object (readonly)
Returns the value of attribute ensemble_type_key.
10 11 12 |
# File 'lib/head_music/instruments/score_order.rb', line 10 def ensemble_type_key @ensemble_type_key end |
#name_key ⇒ Object (readonly) Originally defined in module Named
Returns the value of attribute name_key.
#sections ⇒ Object (readonly)
Returns the value of attribute sections.
10 11 12 |
# File 'lib/head_music/instruments/score_order.rb', line 10 def sections @sections end |
Class Method Details
.get(ensemble_type) ⇒ Object
Factory method to get a ScoreOrder instance for a specific ensemble type
13 14 15 16 17 18 19 |
# File 'lib/head_music/instruments/score_order.rb', line 13 def self.get(ensemble_type) @instances ||= {} key = HeadMusic::Utilities::HashKey.for(ensemble_type) return unless SCORE_ORDERS.key?(key.to_s) @instances[key] ||= new(key) end |
.in_band_order(instruments) ⇒ Object
Convenience method to order instruments in concert band order
27 28 29 |
# File 'lib/head_music/instruments/score_order.rb', line 27 def self.in_band_order(instruments) get(:band).order(instruments) end |
.in_orchestral_order(instruments) ⇒ Object
Convenience method to order instruments in orchestral order
22 23 24 |
# File 'lib/head_music/instruments/score_order.rb', line 22 def self.in_orchestral_order(instruments) get(:orchestral).order(instruments) end |
Instance Method Details
#build_ordering_index ⇒ Object (private)
Builds an index mapping instrument names to their position in the order
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/head_music/instruments/score_order.rb', line 86 def build_ordering_index index = {} position = 0 sections.each do |section| instruments = section["instruments"] || [] instruments.each do |instrument_key| # Store position for this instrument key index[instrument_key.to_s] = position position += 1 end end index end |
#ensure_localized_name(name:, locale_code: Locale::DEFAULT_CODE, abbreviation: nil) ⇒ Object Originally defined in module Named
#find_position(instrument, ordering_index) ⇒ Object (private)
Finds the position of an instrument in the ordering
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/head_music/instruments/score_order.rb', line 103 def find_position(instrument, ordering_index) # Try exact match with name_key return ordering_index[instrument.name_key.to_s] if instrument.name_key && ordering_index.key?(instrument.name_key.to_s) # Try matching by family + range category (e.g., alto_saxophone -> saxophone family) if instrument.family_key family_base = instrument.family_key.to_s instrument_key = instrument.name_key.to_s # Check if this is a variant of a family (e.g., alto_saxophone) if instrument_key.include?(family_base) # Look for the specific variant first return ordering_index[instrument_key] if ordering_index.key?(instrument_key) # Fall back to generic family instrument if listed return ordering_index[family_base] if ordering_index.key?(family_base) end end # Try normalized name (lowercase, underscored) normalized = instrument.name.downcase.tr(" ", "_").tr("-", "_") return ordering_index[normalized] if ordering_index.key?(normalized) nil end |
#find_position_with_transposition(instrument, ordering_index) ⇒ Object (private)
Finds the position and transposition information for an instrument
130 131 132 133 134 135 136 137 138 |
# File 'lib/head_music/instruments/score_order.rb', line 130 def find_position_with_transposition(instrument, ordering_index) position = find_position(instrument, ordering_index) return nil unless position # Get the sounding transposition for secondary sorting transposition = instrument.default_sounding_transposition || 0 {position: position, transposition: transposition} end |
#localized_name(locale_code: Locale::DEFAULT_CODE) ⇒ Object Originally defined in module Named
#localized_name_in_default_locale ⇒ Object (private) Originally defined in module Named
#localized_name_in_locale_matching_language(locale) ⇒ Object (private) Originally defined in module Named
#localized_name_in_matching_locale(locale) ⇒ Object (private) Originally defined in module Named
#localized_names ⇒ Object Originally defined in module Named
Returns an array of LocalizedName instances that are synonymous with the name.
#name(locale_code: Locale::DEFAULT_CODE) ⇒ Object Originally defined in module Named
#name=(name) ⇒ Object Originally defined in module Named
#normalize_to_instrument(input) ⇒ Object (private)
71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/head_music/instruments/score_order.rb', line 71 def normalize_to_instrument(input) # Return if already an Instrument instance return input if input.is_a?(HeadMusic::Instruments::Instrument) # Return InstrumentType instances as-is for backward compatibility (duck typing) return input.default_instrument if input.is_a?(HeadMusic::Instruments::InstrumentType) # Return other objects that respond to required methods (mock objects, etc.) return input if input.respond_to?(:name_key) && input.respond_to?(:family_key) # Create an Instrument instance for string inputs HeadMusic::Instruments::Instrument.get(input) || HeadMusic::Instruments::InstrumentType.get(input) end |
#order(instruments) ⇒ Object
Accepts a list of instruments and orders them according to this ensemble type's conventions
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/head_music/instruments/score_order.rb', line 32 def order(instruments) valid_inputs = instruments.compact.reject { |i| i.respond_to?(:empty?) && i.empty? } instrument_objects = valid_inputs.map { |i| normalize_to_instrument(i) }.compact # Build ordering index ordering_index = build_ordering_index # Separate known and unknown instruments known_instruments = [] unknown_instruments = [] instrument_objects.each do |instrument| position_info = find_position_with_transposition(instrument, ordering_index) if position_info known_instruments << [instrument, position_info] else unknown_instruments << instrument end end # Sort known instruments by position (primary) and transposition (secondary) sorted_known = known_instruments.sort_by { |_, pos_info| [pos_info[:position], -pos_info[:transposition]] }.map(&:first) sorted_known + unknown_instruments.sort_by(&:to_s) end |