Class: CSL::Locale::Terms

Inherits:
Node show all
Defined in:
lib/csl/locale/term.rb

Instance Attribute Summary

Attributes inherited from Node

#attributes

Attributes included from Treelike

#children, #nodename, #parent

Instance Method Summary collapse

Methods inherited from Node

#<=>, #attribute?, #attributes?, #attributes_for, constantize, create, create_attributes, #custom_attributes, #deep_copy, #default_attribute?, #default_attributes, default_attributes, #exact_match?, #format_page_ranges?, #formatting_options, #has_attributes?, #has_default_attributes?, #has_language?, hide_default_attributes!, hide_default_attributes?, #initialize_copy, #inspect, match?, #match?, matches?, #merge!, #page_range_format, parse, parse!, #quotes?, #reverse_merge!, #save_to, show_default_attributes!, #strip_periods?, #tags, #textnode?, types

Methods included from Extensions::Nesting

#nesting

Methods included from PrettyPrinter

#pretty_print, #tags, #to_xml

Methods included from Treelike

#<<, #add_child, #add_children, #ancestors, #closest, #delete_child, #delete_children, #depth, #descendants, #each_ancestor, #each_child, #each_descendant, #each_sibling, #empty?, #find_child, #find_children, #has_children?, #root, #root?, #siblings, #unlink

Constructor Details

#initialize(attributes = {}) {|_self| ... } ⇒ Terms

Returns a new instance of Terms.

Yields:

  • (_self)

Yield Parameters:



12
13
14
15
16
17
18
19
20
# 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

Instance Method Details

#default_ordinalsObject



166
167
168
# File 'lib/csl/locale/term.rb', line 166

def default_ordinals
  ordinals[:default]
end

#drop_ordinalsObject



170
171
172
173
174
# 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?Boolean

Returns:

  • (Boolean)


162
163
164
# File 'lib/csl/locale/term.rb', line 162

def has_legacy_ordinals?
  has_ordinals? && !ordinals.key?(:default)
end

#has_ordinals?Boolean

Returns whether or not ordinal terms are registered at this node.

Returns:

  • (Boolean)

    whether or not ordinal terms are registered at this node



158
159
160
# File 'lib/csl/locale/term.rb', line 158

def has_ordinals?
  !ordinals.empty?
end

#has_terms?Boolean

Returns whether or not regular terms are registered at this node.

Returns:

  • (Boolean)

    whether or not regular terms are registered at this node



153
154
155
# File 'lib/csl/locale/term.rb', line 153

def has_terms?
  !registry.empty?
end

#lookup(name, options = {}) ⇒ Term? Also known as: []

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.

Returns:

  • (Term, nil)

    the term that matches the query



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# 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

#lookup_legacy_ordinals_for(number, options = {}) ⇒ Object



141
142
143
144
145
146
147
148
149
150
# 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 = {}) ⇒ Object



113
114
115
# 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 = {}) ⇒ Object



134
135
136
137
138
139
# 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 = {}) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# 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 = {}) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# 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

#ordinalizerObject



105
106
107
108
109
110
111
# 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) ⇒ self

Shorthand method to stores a new term translations.

Examples:

terms.store(term)
terms.store('book', ['book', 'books'])
terms.store('book', 'bk', :form => 'short')

Parameters:

  • the (Term, String)

    term; or the the term’s name

  • the (String)

    term’s translation

  • additional (Hash)

    term attributes

Returns:

  • (self)


36
37
38
39
40
41
42
43
44
# 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