]> git.openstreetmap.org Git - rails.git/blobdiff - vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb
Add Globalize2 so that we get some nice fall backs to other languages when a translat...
[rails.git] / vendor / plugins / globalize2 / lib / globalize / locale / language_tag.rb
diff --git a/vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb b/vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb
new file mode 100644 (file)
index 0000000..d9aae54
--- /dev/null
@@ -0,0 +1,81 @@
+# for specifications see http://en.wikipedia.org/wiki/IETF_language_tag
+#
+# SimpleParser does not implement advanced usages such as grandfathered tags
+
+module Globalize
+  module Locale
+    module Rfc4646
+      SUBTAGS = [:language, :script, :region, :variant, :extension, :privateuse, :grandfathered]
+      FORMATS = {:language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase}
+    end
+    
+    class LanguageTag < Struct.new(*Rfc4646::SUBTAGS)
+      class << self
+        def parser
+          @@parser ||= SimpleParser
+        end
+    
+        def parser=(parser)
+          @@parser = parser
+        end
+    
+        def tag(tag)
+          matches = parser.match(tag)
+          new *matches if matches
+        end
+      end
+  
+      Rfc4646::FORMATS.each do |name, format|
+        define_method(name) { self[name].send(format) unless self[name].nil? }
+      end
+      
+      def to_sym
+        to_s.to_sym
+      end
+      
+      def to_s
+        @tag ||= to_a.compact.join("-")
+      end
+  
+      def to_a
+        members.collect {|attr| self.send(attr) }
+      end
+  
+      def parent
+        segs = to_a.compact
+        segs.length < 2 ? nil : LanguageTag.tag(segs[0..(segs.length-2)].join('-'))
+      end
+      
+      def parents(include_self = true)
+        result, parent = [], self.dup
+        result << parent if include_self
+        while parent = parent.parent
+          result << parent
+        end
+        result
+      end
+  
+      module SimpleParser
+        PATTERN = %r{\A(?:
+          ([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language
+          (?:-([a-z]{4}))?                                        # script
+          (?:-([a-z]{2}|\d{3}))?                                  # region
+          (?:-([0-9a-z]{5,8}|\d[0-9a-z]{3}))*                     # variant
+          (?:-([0-9a-wyz](?:-[0-9a-z]{2,8})+))*                   # extension
+          (?:-(x(?:-[0-9a-z]{1,8})+))?|                           # privateuse subtag
+          (x(?:-[0-9a-z]{1,8})+)|                                 # privateuse tag
+          /* ([a-z]{1,3}(?:-[0-9a-z]{2,8}){1,2}) */               # grandfathered
+          )\z}xi 
+
+        class << self
+          def match(tag)
+            c = PATTERN.match(tag.to_s).captures
+            c[0..4] << (c[5].nil? ? c[6] : c[5])  << c[7] # TODO c[7] is grandfathered, throw a NotImplemented exception here?
+          rescue
+            false
+          end
+        end
+      end
+    end
+  end
+end