Class: CSL::Locale

Inherits:
Node show all
Extended by:
Loader
Includes:
Comparable
Defined in:
lib/csl/locale.rb,
lib/csl/locale/date.rb,
lib/csl/locale/term.rb,
lib/csl/locale/style_options.rb

Overview

CSL::Locales contain locale specific date formatting options, term translations, and a number ordinalizer.

Defined Under Namespace

Classes: Date, DatePart, StyleOptions, Term, Terms

Class Attribute Summary collapse

Instance Attribute Summary collapse

Attributes included from Loader

#extension, #prefix, #root

Attributes inherited from Node

#attributes

Attributes included from Treelike

#children, #nodename, #parent

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Loader

extend_name, extend_path, list, load

Methods inherited from Node

#attribute?, #attributes?, #attributes_for, constantize, create, create_attributes, #custom_attributes, #deep_copy, #default_attribute?, default_attributes, #default_attributes, #each, #exact_match?, #format_page_ranges?, #formatting_options, #has_attributes?, #has_default_attributes?, #has_language?, hide_default_attributes!, hide_default_attributes?, match?, #match?, matches?, #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(*arguments) {|_self| ... } ⇒ Locale

Returns a new locale. In the first form, the language/regions is set to the default language and region. In the second form the language/region is set by the passed-in IETF tag. The third form additionally accepts a hash of localize style-options. The fourth form is the standard node attribute initialize signature.

Examples:

Locale.new                                         #-> default
Locale.new('en')                                   #-> American English
Locale.new('en', :'punctuation-in-quote' => false) #-> with style-options
Locale.new(:lang => 'en-GB', :version => '1.0')    #-> British English

Yields:

  • (_self)

Yield Parameters:

  • _self (CSL::Locale)

    the object that the method was called on



101
102
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
128
129
130
131
# File 'lib/csl/locale.rb', line 101

def initialize(*arguments)
  case arguments.length
  when 0
    locale, attributes, options = Locale.default, {}, nil
  when 1
    if arguments[0].is_a?(Hash)
      arguments[0] = arguments[0].symbolize_keys

      locale = arguments[0].delete(:lang) ||
        arguments[0].delete(:'xml:lang') || Locale.default

      attributes, options = arguments
    else
      attributes, locale, options = {}, *arguments
    end
  when 2
    attributes, locale, options = {}, *arguments
  else
    raise ArgumentError, "wrong number of arguments (#{arguments.length} for 0..2)"
  end

  super(attributes, &nil)

  set(locale) unless locale.nil?

  unless options.nil?
    children[:'style-options'] = StyleOptions.new(options)
  end

  yield self if block_given?
end

Class Attribute Details

.defaultObject

Returns the value of attribute default.



36
37
38
# File 'lib/csl/locale.rb', line 36

def default
  @default
end

.languagesObject (readonly)

Returns the value of attribute languages.



37
38
39
# File 'lib/csl/locale.rb', line 37

def languages
  @languages
end

.regionsObject (readonly)

Returns the value of attribute regions.



37
38
39
# File 'lib/csl/locale.rb', line 37

def regions
  @regions
end

Instance Attribute Details

#regionObject

Returns the value of attribute region.



81
82
83
# File 'lib/csl/locale.rb', line 81

def region
  @region
end

Class Method Details

.load(input = nil) ⇒ Object



39
40
41
42
43
# File 'lib/csl/locale.rb', line 39

def load(input = nil)
  input ||= Locale.default
  input = normalize input if input.to_s =~ @tag_pattern
  super(input)
end

.normalize(tag) ⇒ String

Normalizes an IETF tag; adds a language’s default region or a region’s default language.

Examples:

Locale.normalize("en")  #-> "en-US"
Locale.normalize("-BR") #-> "pt-BR"

Parameters:

  • tag (String)

    an IETF tag to be normalized

Returns:

  • (String)

    the normalized IETF tag

Raises:

  • (ArgumentError)

    if the passed-in string is no IETF tag



56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/csl/locale.rb', line 56

def normalize(tag)
  tag = tag.to_s.strip

  raise ArgumentError, "not a valid IETF tag: #{tag.inspect}" unless
    tag =~ @tag_pattern

  language, region = tag.split(/-/)

  return [language, regions[language.to_sym]].compact.join('-') if region.nil?
  return [languages[region.to_sym], region].join('-') if language.empty?

  tag
end

Instance Method Details

#<=>(other) ⇒ 1, ...

Locales are sorted first by language, then by region; sort order is alphabetical with the following exceptions: the default locale is prioritised; in case of a language match the default region of that language will be prioritised (e.g., de-DE will come before de-AT even though the alphabetical order would be different).

Parameters:

  • other (Locale)

    the locale used for comparison

Returns:

  • (1, 0, -1, nil)

    the result of the comparison



406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
# File 'lib/csl/locale.rb', line 406

def <=>(other)
  case
  when !other.is_a?(Locale)
    nil
  when [language, region] == [other.language, other.region]
    0
  when default?
    -1
  when other.default?
    1
  when language == other.language
    case
    when default_region?
      -1
    when other.default_region?
      1
    else
      region <=> other.region
    end
  else
    language <=> other.language
  end
end

#added_to(node) ⇒ Object

Raises:



138
139
140
141
# File 'lib/csl/locale.rb', line 138

def added_to(node)
  raise ValidationError, "not allowed to add locale to #{node.nodename}" unless
    node.nodename == 'style'
end

#clearself

Sets the locale’s language and region to nil.

Returns:

  • (self)


191
192
193
194
# File 'lib/csl/locale.rb', line 191

def clear
  @language, @region = nil
  self
end

#default?Boolean

Returns:

  • (Boolean)


358
359
360
# File 'lib/csl/locale.rb', line 358

def default?
  to_s == Locale.default
end

#default_language?Boolean

Returns whether or not the Locale’s language is the default language for its region.

Returns:

  • (Boolean)

    whether or not the Locale’s language is the default language for its region



370
371
372
# File 'lib/csl/locale.rb', line 370

def default_language?
  language && language == Locale.languages[region]
end

#default_region?Boolean

Returns whehter or not the Locale’s region is the default region for its language.

Returns:

  • (Boolean)

    whehter or not the Locale’s region is the default region for its language



364
365
366
# File 'lib/csl/locale.rb', line 364

def default_region?
  region && region == Locale.regions[language]
end

#each_dateObject

Calls block once for each date format defined by the locale. If no block is given, an enumerator is returned instead.

Examples:

locale.each_date { |date_format| block } #-> locale
locale.each_date                         #-> enumerator


349
350
351
352
353
354
355
# File 'lib/csl/locale.rb', line 349

def each_date
  if block_given?
    date.each(&Proc.new)
  else
    enum_for :each_date
  end
end

#each_termObject

Calls block once for each term defined by the locale. If no block is given, an enumerator is returned instead.

Examples:

locale.each_term { |term| block } #-> locale
locale.each_term                  #-> enumerator


334
335
336
337
338
339
340
341
# File 'lib/csl/locale.rb', line 334

def each_term
  if block_given?
    terms.each(&Proc.new)
    self
  else
    enum_for :each_term
  end
end

#initialize_copy(other) ⇒ Object



133
134
135
136
# File 'lib/csl/locale.rb', line 133

def initialize_copy(other)
  @parent, @ancestors, @descendants, @siblings, @root, @depth = nil
  initialize(other.attributes.to_hash.merge(:lang => other.to_s))
end

#inspectString

Returns a string representation of the Locale.

Returns:

  • (String)

    a string representation of the Locale



436
437
438
# File 'lib/csl/locale.rb', line 436

def inspect
  "#<#{self.class.name} #{to_s}>"
end

#legacy?Boolean

Returns whether or not the Locale’s version is less than CSL-Ruby’s default version.

Returns:

  • (Boolean)

    whether or not the Locale’s version is less than CSL-Ruby’s default version



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

def legacy?
  version < Schema.major_version
end

#limit_day_ordinals!Object



268
269
270
271
272
273
274
# File 'lib/csl/locale.rb', line 268

def limit_day_ordinals!
  unless has_options?
    children[:'style-options'] = StyleOptions.new
  end

  options[:'limit-day-ordinals-to-day-1'] = true
end

#limit_day_ordinals?Boolean

Returns true when the option limit-day-ordinals-to-day-1 is true.

Returns:

  • (Boolean)

    true when the option limit-day-ordinals-to-day-1 is true



263
264
265
266
# File 'lib/csl/locale.rb', line 263

def limit_day_ordinals?
  return false unless has_options? && options.attribute?(:'limit-day-ordinals-to-day-1')
  !!(options[:'limit-day-ordinals-to-day-1'].to_s =~ /^true$/i)
end

#merge(*others) ⇒ Locale

Returns:



383
384
385
# File 'lib/csl/locale.rb', line 383

def merge(*others)
  deep_copy.merge!(*others)
end

#merge!(*others) ⇒ self

Returns:

  • (self)


388
389
390
391
392
393
394
395
# File 'lib/csl/locale.rb', line 388

def merge!(*others)
  others.each do |other|
    merge_options other
    merge_dates other
  end

  self
end

#ordinalize(number, options = {}) ⇒ String

Note:

For CSL 1.0 (and older) locales that do not define an “ordinal-00” term the algorithm specified by CSL 1.0 is used; otherwise uses the CSL 1.0.1 algorithm with improved support for languages other than English.

Ordinalizes the passed-in number using either the ordinal or long-ordinal forms defined by the locale. If a long-ordinal form is requested but not available, the regular ordinal will be returned instead.

Examples:

Locale.load('en').ordinalize(13)
#-> "13th"

de = Locale.load('de')
de.ordinalize(13)
#-> "13."

de.ordinalize(3, :form => :long, :gender => :feminine)
#-> "dritte"

Parameters:

  • number (#to_i)

    the number to ordinalize

  • options (Hash) (defaults to: {})

    formatting options

Options Hash (options):

  • :form (:short, :long) — default: :short

    which ordinals form to use

  • :gender (:feminine, :masculine, :neutral) — default: :neutral

    which ordinals gender-form to use

Returns:

  • (String)

    the ordinal for the passed-in number

Raises:

  • (ArgumentError)

    if number cannot be converted to an integer



249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/csl/locale.rb', line 249

def ordinalize(number, options = {})
  raise ArgumentError, "unable to ordinalize #{number}; integer expected" unless
    number.respond_to?(:to_i)

  number = number.to_i
  ordinal = terms.ordinalize number, options

  return number.to_s if ordinal.nil?
  return ordinal.to_s(options) if ordinal.long_ordinal?

  [number, ordinal.to_s(options)].join
end

#punctuation_in_quote!Object Also known as: punctuation_in_quotes!



283
284
285
286
287
288
289
# File 'lib/csl/locale.rb', line 283

def punctuation_in_quote!
  unless has_options?
    children[:'style-options'] = StyleOptions.new
  end

  options[:'punctuation-in-quote'] = true
end

#punctuation_in_quote?Boolean Also known as: punctuation_in_quotes?

Returns true when the option punctuation-in-quote is true.

Returns:

  • (Boolean)

    true when the option punctuation-in-quote is true



277
278
279
280
# File 'lib/csl/locale.rb', line 277

def punctuation_in_quote?
  return false unless has_options? && options.attribute?(:'punctuation-in-quote')
  !!(options[:'punctuation-in-quote'].to_s =~ /^true$/i)
end

#quote(string, escape = false) ⇒ String

Puts localized quotes around the passed-in string.

Returns:

  • (String)

    the quoted string



294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/csl/locale.rb', line 294

def quote(string, escape = false)
  oq, cq = t('open-quote'), t('close-quote')

  return string if oq.nil? || cq.nil? || (oq.empty? && cq.empty?)

  if escape
    oq = CSL.encode_xml_text(oq)
    cq = CSL.encode_xml_text(cq)
  end

  string = replace_with_inner_quotes(string, oq, cq, escape)

  if punctuation_in_quotes?
    "#{oq}#{string}#{cq}"
  else
    string, punctuation = string.split(/([\.,])$/, 2)

    "#{oq}#{string}#{cq}#{punctuation}"
  end
end

#replace_with_inner_quotes(string, open, close, escape = false) ⇒ Object



315
316
317
318
319
320
321
322
323
324
325
326
# File 'lib/csl/locale.rb', line 315

def replace_with_inner_quotes(string, open, close, escape = false)
  oq, cq = t('open-inner-quote'), t('close-inner-quote')

  return string if oq.nil? || cq.nil? || (oq.empty? && cq.empty?)

  if escape
    oq = CSL.encode_xml_text(oq)
    cq = CSL.encode_xml_text(cq)
  end

  string.gsub(/(#{open}|"\b)/, oq).gsub(/(#{close}|\b")/, cq)
end

#set(locale) ⇒ self

Sets language and region according to the passed-in locale string. If the region part is not defined by the string, this method will set the region to the default region for the given language.

Examples:

locale.set('en')    #-> sets language to :en, region to :US
locale.set('de-AT') #-> sets language to :de, region to :AT
locale.set('-DE')   #-> sets langauge to :de, region to :DE

Returns:

  • (self)

Raises:

  • (ArgumentError)

    if the argument is no valid locale string. A valid locale string is based on the syntax of IETF language tags; it consists of either a language or region tag (or both), separated by a hyphen.



184
185
186
187
# File 'lib/csl/locale.rb', line 184

def set(locale)
  @language, @region = Locale.normalize(locale).split(/-/).map(&:to_sym)
  self
end

#store(*arguments) ⇒ Object Also known as: learn

Stores a translation in the locale’s term registry.



207
208
209
210
211
212
213
214
# File 'lib/csl/locale.rb', line 207

def store(*arguments)
  unless has_terms?
    self << CSL::Locale::Terms.new
  end

  terms.store(*arguments)
  self
end

#to_sString

Returns the Locale’s IETF tag.

Returns:

  • (String)

    the Locale’s IETF tag



431
432
433
# File 'lib/csl/locale.rb', line 431

def to_s
  [language, region].compact.join('-')
end

#translate(name, options = {}) ⇒ String? Also known as: t

Returns the term’s translation.

Returns:

  • (String, nil)

    the term’s translation



197
198
199
200
201
202
# File 'lib/csl/locale.rb', line 197

def translate(name, options = {})
  return unless has_terms?

  term = terms.lookup name, options
  term && term.to_s(options)
end

#valid?Boolean

Returns:

  • (Boolean)


378
379
380
# File 'lib/csl/locale.rb', line 378

def valid?
  validate.empty?
end

#validateObject



374
375
376
# File 'lib/csl/locale.rb', line 374

def validate
  Schema.validate self
end

#versionObject



144
145
146
# File 'lib/csl/locale.rb', line 144

def version
  attributes[:version]
end

#version=(version) ⇒ Object

Raises:

  • (ArgumentError)


148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/csl/locale.rb', line 148

def version=(version)
  raise ArgumentError, "failed to set version to #{version}" unless
    version.respond_to?(:to_s)

  version = version.to_s.strip

  raise ArgumentError, "failed to set version to #{version}: not a version string" unless
    version =~ /^\d[\d\.]+$/

  if version > Schema.version
    warn "setting version to #{version}; latest supported version is #{Schema.version}"
  end

  attributes[:version] = version
end