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

def initialize(*arguments)
  case arguments.length
  when 0
    locale, attributes, options = nil, {}, 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')

      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.blank?

  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



425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# File 'lib/csl/locale.rb', line 425

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.to_s <=> other.region.to_s
    end
  else
    language.to_s <=> other.language.to_s
  end
end

#added_to(node) ⇒ Object

Raises:



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

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)


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

def clear
  @language, @region = nil
  self
end

#default?Boolean

Returns:

  • (Boolean)


361
362
363
# File 'lib/csl/locale.rb', line 361

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



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

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



367
368
369
# File 'lib/csl/locale.rb', line 367

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

#each_date(&block) ⇒ Object

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


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

def each_date(&block)
  if block_given?
    if date.is_a? CSL::Node
      yield date
    else
      date.each(&block)
    end
  else
    enum_for :each_date
  end
end

#each_term(&block) ⇒ Object

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


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

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

#initialize_copy(other) ⇒ Object



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

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



455
456
457
# File 'lib/csl/locale.rb', line 455

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



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

def legacy?
  version < Schema.major_version
end

#like?(other) ⇒ Boolean

Returns:

  • (Boolean)


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

def like?(other)
  return false unless other.is_a? Locale
  return true  if other.universal?

  language == other.language
end

#limit_day_ordinals!Object



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

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



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

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:



397
398
399
# File 'lib/csl/locale.rb', line 397

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

#merge!(*others) ⇒ self

Returns:

  • (self)


402
403
404
405
406
407
408
409
410
# File 'lib/csl/locale.rb', line 402

def merge!(*others)
  others.each do |other|
    merge_options other
    merge_dates other
    merge_terms 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



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

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!



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

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



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

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



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

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



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

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

#reverse_merge(other) ⇒ Object



412
413
414
# File 'lib/csl/locale.rb', line 412

def reverse_merge(other)
  other.merge(self)
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.



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

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.



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

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



450
451
452
# File 'lib/csl/locale.rb', line 450

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



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

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

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

#universal?Boolean

Returns:

  • (Boolean)


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

def universal?
  language.nil?
end

#valid?Boolean

Returns:

  • (Boolean)


392
393
394
# File 'lib/csl/locale.rb', line 392

def valid?
  validate.empty?
end

#validateObject



388
389
390
# File 'lib/csl/locale.rb', line 388

def validate
  Schema.validate self
end

#versionObject



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

def version
  attributes[:version]
end

#version=(version) ⇒ Object

Raises:

  • (ArgumentError)


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

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