Class: Lang::Tag::Langtag

Inherits:
Composition show all
Includes:
Canonicalization, Filtering, Lookup
Defined in:
lib/lang/tag/lookup.rb,
lib/lang/tag/langtag.rb,
lib/lang/tag/filtering.rb,
lib/lang/tag/canonicalization.rb

Overview

– Filtering is defined for the language tags only.

RFC 4647, Section 3.3 Filtering is used to select the set of language tags that matches a given language priority list. ++

Constant Summary

Constants included from Canonicalization

Canonicalization::PREFIX_REGEX, Canonicalization::PRIVATE_LANGUAGE_REGEX, Canonicalization::PRIVATE_REGION_REGEX, Canonicalization::PRIVATE_SCRIPT_REGEX

Constants included from Filtering

Filtering::WILDCARD

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Canonicalization

#canonicalize, #canonicalize!, #same?, #suppress_script, #suppress_script!, #to_extlang_form, #to_extlang_form!

Methods included from Filtering

#matched_by_basic_range?, #matched_by_extended_range?

Methods included from Lookup

#in?, #lookup_candidates

Methods inherited from Composition

#==, #===, #composition, #dup, #eql?, #hash, #inspect, #length, #nicecase, #subtags_count, #to_a

Constructor Details

#initialize(thing = nil) ⇒ Langtag

Returns a new instance of Langtag.



18
19
20
# File 'lib/lang/tag/langtag.rb', line 18

def initialize(thing = nil)
  recompose(thing) if thing
end

Instance Attribute Details

#extensions_sequenceObject

Returns the value of attribute extensions_sequence.



16
17
18
# File 'lib/lang/tag/langtag.rb', line 16

def extensions_sequence
  @extensions_sequence
end

#languageObject

Returns the value of attribute language.



16
17
18
# File 'lib/lang/tag/langtag.rb', line 16

def language
  @language
end

#privateuse_sequenceObject

Returns the value of attribute privateuse_sequence.



16
17
18
# File 'lib/lang/tag/langtag.rb', line 16

def privateuse_sequence
  @privateuse_sequence
end

#regionObject

Returns the value of attribute region.



16
17
18
# File 'lib/lang/tag/langtag.rb', line 16

def region
  @region
end

#scriptObject

Returns the value of attribute script.



16
17
18
# File 'lib/lang/tag/langtag.rb', line 16

def script
  @script
end

#variants_sequenceObject

Returns the value of attribute variants_sequence.



16
17
18
# File 'lib/lang/tag/langtag.rb', line 16

def variants_sequence
  @variants_sequence
end

Instance Method Details

#defer_validation(&block) ⇒ Object

Raises:

  • (LocalJumpError)


348
349
350
351
352
353
354
355
# File 'lib/lang/tag/langtag.rb', line 348

def defer_validation(&block)
  raise LocalJumpError, "No block given." unless block
  @validation_deferred = true
  yield
  @validation_deferred = false
  validate
  nil
end

#extension(key) ⇒ Object

Returns a sequense of subtags for a singleton passed. Works case-insensitively.



270
271
272
273
274
275
276
# File 'lib/lang/tag/langtag.rb', line 270

def extension(key)
  return nil unless @extensions
  sequence = @extensions[key] || @extensions[key = key.downcase]
  return sequence unless String === sequence
  @extensions[key] = sequence.split(HYPHEN) #lazy
  @extensions[key]
end

#extensions=(value) ⇒ Object

Friendly version of the #extensions_sequence=. Sets the sequence of extensions for this langtag.



231
232
233
234
# File 'lib/lang/tag/langtag.rb', line 231

def extensions=(value)
  subtags = Array(value).flatten
  self.extensions_sequence = subtags.empty? ? nil : subtags.join(HYPHEN)
end

#extlangObject

Returns a second component of the extended language, if any.



78
79
80
81
82
# File 'lib/lang/tag/langtag.rb', line 78

def extlang
  return nil unless @language
  decompose_language unless @primary
  @extlang
end

#has_singleton?(key) ⇒ Boolean Also known as: has_extension?

Checks if self has a singleton passed. Works case-insensitively.

Returns:

  • (Boolean)


281
282
283
284
# File 'lib/lang/tag/langtag.rb', line 281

def has_singleton?(key)
  return false unless @extensions
  @extensions.key?(key) || @extensions.key?(key.downcase)
end

#has_variant?(sequence) ⇒ Boolean

Checks if self has a variant or a sequence of variants passed. Works case-insensitively.

Returns:

  • (Boolean)


203
204
205
206
# File 'lib/lang/tag/langtag.rb', line 203

def has_variant?(sequence)
  return false unless @variants_sequence
  /(?:^|-)#{sequence}(?:-|$)/i === @variants_sequence
end

#nicecase!Object



367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
# File 'lib/lang/tag/langtag.rb', line 367

def nicecase!

  # ugly, but faster than recompose

  if @language && @language.downcase!
    @primary = nil
    @extlang = nil
  end

  # [ISO639-1] recommends that language codes be written in lowercase ('mn' Mongolian).
  # [ISO15924] recommends that script codes use lowercase with the initial letter capitalized ('Cyrl' Cyrillic).
  # [ISO3166-1] recommends that country codes be capitalized ('MN' Mongolia).

  @script.capitalize! if @script
  @region.upcase! if @region

  @variants = nil if @variants_sequence &&
    @variants_sequence.downcase!

  set_extensions_sequence(@extensions_sequence) if @extensions_sequence &&
    @extensions_sequence.downcase!

  @privateuse = nil if @privateuse_sequence &&
    @privateuse_sequence.downcase!

  @sequence = nil
end

#primaryObject

Returns a primary language subtag.



70
71
72
73
74
# File 'lib/lang/tag/langtag.rb', line 70

def primary
  return nil unless @language
  decompose_language unless @primary
  @primary
end

#privateuseObject

– RFC 5646, sec. 2.2.7: Private use subtags are used to indicate distinctions in language that are important in a given context by private agreement.

RFC 5646, sec. 2.2.7: For example, suppose a group of scholars is studying some texts in medieval Greek. They might agree to use some collection of private use subtags to identify different styles of writing in the texts. For example, they might use ‘el-x-koine’ for documents in the “common” style while using ‘el-x-attic’ for other documents that mimic the Attic style. These subtags would not be recognized by outside processes or systems, but might be useful in categorizing various texts for study by those in the group. ++



304
305
306
307
# File 'lib/lang/tag/langtag.rb', line 304

def privateuse
  return nil unless @privateuse_sequence
  @privateuse ||= @privateuse_sequence.split(HYPHEN)[1..-1]
end

#privateuse=(value) ⇒ Object

Friendly version of the #privateuse_sequence=. Sets the ‘privateuse’ sequence for this langtag.

Example

tag = Lang::Tag('de')
tag.privateuse = ['private', 'use', 'sequence']
tag.privateuse_sequence #=> 'x-private-use-sequence'


318
319
320
321
322
323
324
325
326
# File 'lib/lang/tag/langtag.rb', line 318

def privateuse=(value)
  subtags = Array(value).flatten
  if subtags.empty?
    self.privateuse_sequence = nil
  else
    self.privateuse_sequence = subtags.unshift(PRIVATEUSE).join(HYPHEN)
    @privateuse = subtags
  end
end

#recompose(thing) ⇒ Object

Raises:

  • (TypeError)


407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
# File 'lib/lang/tag/langtag.rb', line 407

def recompose(thing)

  raise TypeError, "Can't convert #{thing.class} into String" unless thing.respond_to?(:to_str)
  tag = thing.to_str

  if LANGTAG_REGEX === tag

    dirty

    @sequence               = tag
    @primary                = nil
    @extlang                = nil
    @language               = $1
    @script                 = $2
    @region                 = $3
    set_variants_sequence     $4[1..-1]
    set_extensions_sequence   $5[1..-1]
    @privateuse_sequence    = $'[1..-1]
    @privateuse             = nil

  else
    raise ArgumentError, "Ill-formed, grandfathered or 'privateuse' language tag: #{thing.inspect}."
  end
  self
end

#singletonsObject

Builds an ordered list of downcased singletons.



260
261
262
263
264
265
# File 'lib/lang/tag/langtag.rb', line 260

def singletons
  return nil unless @extensions
  keys = @extensions.keys
  keys.sort!
  keys
end

#to_sObject



395
396
397
398
399
400
401
402
403
404
405
# File 'lib/lang/tag/langtag.rb', line 395

def to_s
  return @sequence if @sequence
  @sequence = ""
  @sequence << @language if @language
  @sequence << HYPHEN << @script if @script
  @sequence << HYPHEN << @region if @region
  @sequence << HYPHEN << @variants_sequence if @variants_sequence
  @sequence << HYPHEN << @extensions_sequence if @extensions_sequence
  @sequence << HYPHEN << @privateuse_sequence if @privateuse_sequence
  @sequence
end

#variantsObject

Returns a list of variants of this lantag.



184
185
186
187
# File 'lib/lang/tag/langtag.rb', line 184

def variants
  return nil unless @variants_sequence
  @variants ||= @variants_sequence.split(HYPHEN_SPLITTER)
end

#variants=(value) ⇒ Object

Friendly version of the #variants_sequence=. Sets the sequence of variants for this langtag.

Example

tag = Lang::Tag('sl')
tag.variants = ['rozaj', 'solba', '1994']
tag.variants_sequence #=> 'rozaj-solba-1994'
tag.variants #=> ['rozaj', 'solba', '1994']


172
173
174
175
176
177
178
179
180
# File 'lib/lang/tag/langtag.rb', line 172

def variants=(value)
  subtags = Array(value).flatten
  if subtags.empty?
    self.variants_sequence = nil
  else
    self.variants_sequence = subtags.join(HYPHEN)
    @variants = subtags
  end
end