class CSL::Locale::Terms

Attributes

ordinals[R]

@!attribute [r] ordinals @return [Hash] a private registry to map ordinals to the respective

term objects for quick ordinal look-up
registry[R]

@!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

new(attributes = {}) { |self| ... } click to toggle source
Calls superclass method
# 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

[](name, options = {})
Alias for: lookup
default_ordinals() click to toggle source
# File lib/csl/locale/term.rb, line 166
def default_ordinals
  ordinals[:default]
end
drop_ordinals() click to toggle source
# File lib/csl/locale/term.rb, line 170
def drop_ordinals
  tmp = ordinals.values.flatten(1)
  ordinals.clear
  delete_children tmp
end
has_legacy_ordinals?() click to toggle source
# File lib/csl/locale/term.rb, line 162
def has_legacy_ordinals?
  has_ordinals? && !ordinals.key?(:default)
end
has_ordinals?() click to toggle source

@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
has_terms?() click to toggle source

@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
lookup(name, options = {}) click to toggle source

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
Also aliased as: []
lookup_legacy_ordinals_for(number, options = {}) click to toggle source
# 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
lookup_long_ordinal_for(number, options = {}) click to toggle source
# 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
lookup_ordinal_for(number, divisor, options = {}) click to toggle source
# 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
lookup_ordinals_for(number, options = {}) click to toggle source
# 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
ordinalize(number, options = {}) click to toggle source
# 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
ordinalizer() click to toggle source
# File lib/csl/locale/term.rb, line 105
def ordinalizer
  if has_legacy_ordinals?
    :lookup_legacy_ordinals_for
  else
    :lookup_ordinals_for
  end
end
store(term, translation = nil, options = nil) click to toggle source

@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

added_child(term) click to toggle source
# 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
deleted_child(term) click to toggle source
# 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