class CSL::Locale::Terms
Attributes
@!attribute [r] ordinals @return [Hash] a private registry to map ordinals to the respective
term objects for quick ordinal look-up
@!attribute [r] registry @return [Hash] a private registry to map term names to the respective
term objects for quick term look-up
Public Class Methods
# File lib/csl/locale/term.rb, line 12 def initialize(attributes = {}) super(attributes) children[:term] = [] @registry = Term::Registry.new @ordinals = Term::Registry.new yield self if block_given? end
Public Instance Methods
# File lib/csl/locale/term.rb, line 166 def default_ordinals ordinals[:default] end
# File lib/csl/locale/term.rb, line 170 def drop_ordinals tmp = ordinals.values.flatten(1) ordinals.clear delete_children tmp end
# File lib/csl/locale/term.rb, line 162 def has_legacy_ordinals? has_ordinals? && !ordinals.key?(:default) end
@return [Boolean] whether or not ordinal terms are registered at this node
# File lib/csl/locale/term.rb, line 158 def has_ordinals? !ordinals.empty? end
@return [Boolean] whether or not regular terms are registered at this node
# File lib/csl/locale/term.rb, line 153 def has_terms? !registry.empty? end
If a style uses a term in a form that is undefined, there is a fallback to other forms: “verb-short” first falls back to “verb”, “symbol” first falls back to “short”, and “verb” and “short” both fall back to “long”. If no form fallback is available, nil is returned instead.
@return [Term, nil] the term that matches the query
# File lib/csl/locale/term.rb, line 53 def lookup(name, options = {}) options = Term.specialize(options) options[:name] = name = name.to_s options[:form] = 'long' unless options.key?(:form) # NB: currently only ordinals support gender-forms options.delete(:'gender-form') candidates = registry[name] return if candidates.empty? # loop terminates when a matching term is found or # when there are no more form fallbacks left while true do term = candidates.detect { |t| t.match?(options) } return term unless term.nil? fallback = Term.form_fallbacks[options[:form].to_s] return if fallback == options[:form] options[:form] = fallback end end
# File lib/csl/locale/term.rb, line 141 def lookup_legacy_ordinals_for(number, options = {}) case when (11..13).include?(number.abs % 100) ordinals[4].detect { |t| t.match?(options) } when (1..3).include?(number.abs % 10) ordinals[number.abs % 10].detect { |t| t.match?(options) } else ordinals[4].detect { |t| t.match?(options) } end end
# File lib/csl/locale/term.rb, line 113 def lookup_long_ordinal_for(number, options = {}) ordinals[number].detect { |t| t.long_ordinal? && t.match?(options) } end
# File lib/csl/locale/term.rb, line 134 def lookup_ordinal_for(number, divisor, options = {}) modulus = divisor ? (number % divisor) : number ordinals[modulus].detect do |t| t.short_ordinal? && t.match?(options) && t.match_modulo?(number) end end
# File lib/csl/locale/term.rb, line 117 def lookup_ordinals_for(number, options = {}) ordinal = lookup_ordinal_for(number, nil, options) return ordinal unless ordinal.nil? unless number < 100 ordinal = lookup_ordinal_for(number, 100, options) return ordinal unless ordinal.nil? end unless number < 10 ordinal = lookup_ordinal_for(number, 10, options) return ordinal unless ordinal.nil? end default_ordinals.detect { |t| t.match?(options) } end
# File lib/csl/locale/term.rb, line 79 def ordinalize(number, options = {}) return unless has_ordinals? options = Term.specialize(options) number = number.to_i.abs # try to match long-ordinals first if options.delete(:form).to_s =~ /^long/i ordinal = lookup_long_ordinal_for number, options return ordinal unless ordinal.nil? end # select CSL 1.0 or 1.0.1 algorithm algorithm = ordinalizer ordinal = send algorithm, number, options return ordinal unless ordinal.nil? # fallback to non-gendered version if options.delete(:'gender-form') ordinal = send algorithm, number, options end ordinal end
# File lib/csl/locale/term.rb, line 105 def ordinalizer if has_legacy_ordinals? :lookup_legacy_ordinals_for else :lookup_ordinals_for end end
@example
terms.store(term) terms.store('book', ['book', 'books']) terms.store('book', 'bk', :form => 'short')
Shorthand method to stores a new term translations.
@param [Term, String] the term; or the the term's name @param [String] the term's translation @param [Hash] additional term attributes
@return [self]
# File lib/csl/locale/term.rb, line 36 def store(term, translation = nil, options = nil) unless term.is_a?(Term) term = Term.new(:name => term) term.attributes.merge(options) unless options.nil? term.set(*translation) end self << term end
Private Instance Methods
# File lib/csl/locale/term.rb, line 190 def added_child(term) raise ValidationError, "failed to register term #{term.inspect}: name attribute missing" unless term.attribute?(:name) if term.ordinal? store = ordinals[term.ordinal] else store = registry[term[:name]] end delete_children store.select { |value| term.exact_match? value } store.push(term) term end
# File lib/csl/locale/term.rb, line 207 def deleted_child(term) if term.ordinal? ordinals[term.ordinal].delete(term) else registry[term[:name]].delete(term) end end