~tetradice1011/rumix/m17n

« back to all changes in this revision

Viewing changes to lib/locale/tag/rfc.rb

  • Committer: Dice
  • Date: 2009-05-10 11:24:59 UTC
  • Revision ID: tetradice+lp@gmail.com-20090510112459-8mtni5270r3n5a5d
create base for m17n

(多言語化のための基本的な環境を整えた)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
=begin
 
2
  locale/tag/rfc.rb - Locale::Tag::Rfc
 
3
 
 
4
  Copyright (C) 2008,2009  Masao Mutoh
 
5
 
 
6
  You may redistribute it and/or modify it under the same
 
7
  license terms as Ruby.
 
8
=end
 
9
 
 
10
require 'locale/tag/common'
 
11
 
 
12
module Locale 
 
13
  module Tag 
 
14
 
 
15
    # Language tag class for RFC4646(BCP47).
 
16
    class Rfc < Common
 
17
      SINGLETON = '[a-wyz0-9]'
 
18
      VARIANT = "(#{ALPHANUM}{5,8}|#{DIGIT}#{ALPHANUM}{3})" 
 
19
      EXTENSION = "(#{SINGLETON}(?:-#{ALPHANUM}{2,8})+)"
 
20
      PRIVATEUSE = "(x(?:-#{ALPHANUM}{1,8})+)"
 
21
      GRANDFATHERED = "#{ALPHA}{1,3}(?:-#{ALPHANUM}{2,8}){1,2}"
 
22
      
 
23
      TAG_RE = /\A#{LANGUAGE}(?:-#{SCRIPT})?
 
24
                  (?:-#{REGION})?((?:-#{VARIANT})*
 
25
                  (?:-#{EXTENSION})*(?:-#{PRIVATEUSE})?)\Z/ix
 
26
 
 
27
      attr_reader :extensions, :privateuse
 
28
 
 
29
      class << self
 
30
        include Util::Memoizable
 
31
        # Parse the language tag and return the new Locale::Tag::Rfc. 
 
32
        def parse(tag)
 
33
          if tag =~ /\APOSIX\Z/  # This is the special case of POSIX locale but match this regexp.
 
34
            nil
 
35
          elsif tag =~ TAG_RE
 
36
            lang, script, region, subtag = $1, $2, $3, $4
 
37
            extensions = []
 
38
            variants = []
 
39
            if subtag =~ /#{PRIVATEUSE}/
 
40
                subtag, privateuse = $`, $1
 
41
              # Private use for CLDR.
 
42
              if /x-ldml(.*)/ =~ privateuse
 
43
                p_subtag = $1 
 
44
                extensions = p_subtag.scan(/(^|-)#{EXTENSION}/i).collect{|v| p_subtag.sub!(v[1], ""); v[1]}
 
45
                variants = p_subtag.scan(/(^|-)#{VARIANT}(?=(-|$))/i).collect{|v| v[1]}
 
46
              end
 
47
            end
 
48
            extensions += subtag.scan(/(^|-)#{EXTENSION}/i).collect{|v| subtag.sub!(v[1], ""); v[1]}
 
49
            variants += subtag.scan(/(^|-)#{VARIANT}(?=(-|$))/i).collect{|v| v[1]}
 
50
            
 
51
            ret = self.new(lang, script, region, variants, extensions, privateuse)
 
52
            ret.tag = tag
 
53
            ret
 
54
          else
 
55
            nil
 
56
          end
 
57
        end
 
58
        memoize_dup :parse
 
59
      end
 
60
 
 
61
      def initialize(language, script = nil, region = nil, variants = [],
 
62
                   extensions = [], privateuse = nil)
 
63
        @extensions, @privateuse = extensions, privateuse
 
64
        super(language, script, region, variants)
 
65
      end
 
66
 
 
67
      # Sets the extensions as an Array.
 
68
      def extensions=(val)
 
69
        clear
 
70
        @extensions = val
 
71
      end
 
72
 
 
73
      # Sets the privateuse as a String
 
74
      def privateuse=(val)
 
75
        clear
 
76
        @privateuse = val
 
77
      end
 
78
 
 
79
      private
 
80
      def convert_to(klass)
 
81
        if klass == Rfc
 
82
          klass.new(language, script, region, variants, extensions, privateuse)
 
83
        elsif klass == Cldr
 
84
          exts = {}
 
85
          extensions.sort.each do |v|
 
86
            if v =~ /^k-(#{ALPHANUM}{2,})-(.*)$/i
 
87
              exts[$1] = $2
 
88
            end
 
89
          end
 
90
          klass.new(language, script, region, variants, exts)
 
91
        else
 
92
          super
 
93
        end
 
94
      end
 
95
 
 
96
      # Returns the language tag 
 
97
      #   <language>-<Script>-<REGION>-<variants>-<extensions>-<PRIVATEUSE>
 
98
      #   (e.g.) "ja-Hira-JP-variant"
 
99
      #
 
100
      # This is used in internal only. Use to_s instead.
 
101
      def to_string
 
102
        s = super.gsub(/_/, "-")
 
103
        @extensions.sort.each do |v|
 
104
          s << "-#{v}"
 
105
        end
 
106
        s << "-#{@privateuse}" if @privateuse
 
107
        s
 
108
      end
 
109
 
 
110
    end
 
111
  end
 
112
end