/lib/ruby/locale/lib/locale/tag/common.rb

https://github.com/marnen/hive · Ruby · 129 lines · 82 code · 14 blank · 33 comment · 10 complexity · 2459f24922fc39f3c90214f77e63d710 MD5 · raw file

  1. =begin
  2. locale/tag/common.rb - Locale::Tag::Common
  3. Copyright (C) 2008,2009 Masao Mutoh
  4. You may redistribute it and/or modify it under the same
  5. license terms as Ruby.
  6. =end
  7. require 'locale/tag/simple'
  8. module Locale
  9. module Tag
  10. # Common Language tag class for Ruby.
  11. # Java and MS Windows use this format.
  12. #
  13. # * ja (language: RFC4646)
  14. # * ja_JP (country: RFC4646(2 alpha or 3 digit))
  15. # * ja-JP
  16. # * ja_Hira_JP (script: 4 characters)
  17. # * ja-Hira-JP
  18. # * ja_Hira_JP_MOBILE (variants: more than 2 characters or 3 digit)
  19. # * ja_Hira_JP_MOBILE_IPHONE (2 variants example)
  20. #
  21. class Common < Simple
  22. LANGUAGE = "(#{ALPHA}{2,3}|#{ALPHA}{4}|#{ALPHA}{5,8})" #RFC4646 (ISO639/reserved/registered)
  23. SCRIPT = "(#{ALPHA}{4})"
  24. VARIANT = "(#{ALPHANUM}{3,}|#{DIGIT}#{ALPHANUM}{3})" #RFC3066 compatible
  25. TAG_RE = /\A#{LANGUAGE}(?:[-_]#{SCRIPT})?
  26. (?:[-_]#{REGION})?((?:[-_]#{VARIANT})*)\Z/ix
  27. attr_reader :script, :variants
  28. class << self
  29. include Util::Memoizable
  30. # Parse the language tag and return the new Locale::Tag::Common.
  31. def parse(tag)
  32. if tag =~ /\APOSIX\Z/ # This is the special case of POSIX locale but match this regexp.
  33. nil
  34. elsif tag =~ TAG_RE
  35. lang, script, region, subtag = $1, $2, $3, $4
  36. variants = subtag.scan(/(^|[-_])#{VARIANT}(?=([-_]|$))/i).collect{|v| v[1]}
  37. ret = self.new(lang, script, region, variants)
  38. ret.tag = tag
  39. ret
  40. else
  41. nil
  42. end
  43. end
  44. memoize_dup :parse
  45. end
  46. # Create a Locale::Tag::Common.
  47. def initialize(language, script = nil, region = nil, variants = [])
  48. @script, @variants = script, variants
  49. @script = @script.capitalize if @script
  50. super(language, region)
  51. end
  52. # Set the script (with capitalize)
  53. def script=(val)
  54. clear
  55. @script = val
  56. @script = @script.capitalize if @script
  57. @script
  58. end
  59. # Set the variants as an Array.
  60. def variants=(val)
  61. clear
  62. @variants = val
  63. end
  64. # Returns an Array of tag-candidates order by priority.
  65. # Use Locale.candidates instead of this method.
  66. #
  67. # Locale::Tag::Rfc, Cldr don't have their own candidates,
  68. # because it's meaningless to compare the extensions, privateuse, etc.
  69. def candidates
  70. [self.class.new(language, script, region, variants), #ja-Kana-JP-FOO
  71. self.class.new(language, script, region), #ja-Kana-JP
  72. self.class.new(language, nil, region, variants), #ja-JP-FOO
  73. self.class.new(language, nil, region), #ja-JP
  74. self.class.new(language, script, nil, variants), #ja-Kana-FOO
  75. self.class.new(language, script), #ja-Kana
  76. self.class.new(language, nil, nil, variants), #ja-FOO
  77. self.class.new(language)] #ja
  78. end
  79. memoize_dup :candidates
  80. private
  81. def convert_to(klass) #:nodoc:
  82. if klass == Simple
  83. super
  84. elsif klass == Posix
  85. if variants.size > 0
  86. var = variants.join("-")
  87. else
  88. var = nil
  89. end
  90. klass.new(language, region, nil, var)
  91. elsif klass == Cldr
  92. klass.new(language, script, region, variants.map{|v| v.upcase})
  93. else
  94. klass.new(language, script, region, variants)
  95. end
  96. end
  97. # Returns the common language tag with "_".
  98. # <language>_<Script>_<REGION>_VARIANTS1_VARIANTS2
  99. # (e.g.) "ja_Hira_JP_VARIANTS1_VARIANTS2"
  100. #
  101. # This is used in internal only. Use to_s instead.
  102. def to_string
  103. s = @language.dup
  104. s << "_" << @script if @script
  105. s << "_" << @region if @region
  106. @variants.each do |v|
  107. s << "_#{v}"
  108. end
  109. s
  110. end
  111. end
  112. end
  113. end