c357a6d4d2dcb94f40e6c9db4219bf504fb25262
[packages/precise/mcollective.git] / lib / mcollective / vendor / i18n / lib / i18n / backend / gettext.rb
1 require 'i18n/gettext'
2 require 'i18n/gettext/po_parser'
3
4 # Experimental support for using Gettext po files to store translations.
5 #
6 # To use this you can simply include the module to the Simple backend - or
7 # whatever other backend you are using.
8 #
9 #   I18n::Backend::Simple.include(I18n::Backend::Gettext)
10 #
11 # Now you should be able to include your Gettext translation (*.po) files to
12 # the I18n.load_path so they're loaded to the backend and you can use them as
13 # usual:
14 #
15 #  I18n.load_path += Dir["path/to/locales/*.po"]
16 #
17 # Following the Gettext convention this implementation expects that your
18 # translation files are named by their locales. E.g. the file en.po would
19 # contain the translations for the English locale.
20 module I18n
21   module Backend
22     module Gettext
23       class PoData < Hash
24         def set_comment(msgid_or_sym, comment)
25           # ignore
26         end
27       end
28
29       protected
30         def load_po(filename)
31           locale = ::File.basename(filename, '.po').to_sym
32           data = normalize(locale, parse(filename))
33           { locale => data }
34         end
35
36         def parse(filename)
37           GetText::PoParser.new.parse(::File.read(filename), PoData.new)
38         end
39
40         def normalize(locale, data)
41           data.inject({}) do |result, (key, value)|
42             unless key.nil? || key.empty?
43               key = key.gsub(I18n::Gettext::CONTEXT_SEPARATOR, '|')
44               key, value = normalize_pluralization(locale, key, value) if key.index("\000")
45
46               parts = key.split('|').reverse
47               normalized = parts.inject({}) do |_normalized, part|
48                 { part => _normalized.empty? ? value : _normalized }
49               end
50
51               result.deep_merge!(normalized)
52             end
53             result
54           end
55         end
56
57         def normalize_pluralization(locale, key, value)
58           # FIXME po_parser includes \000 chars that can not be turned into Symbols
59           key = key.gsub("\000", I18n::Gettext::PLURAL_SEPARATOR).split(I18n::Gettext::PLURAL_SEPARATOR).first
60
61           keys = I18n::Gettext.plural_keys(locale)
62           values = value.split("\000")
63           raise "invalid number of plurals: #{values.size}, keys: #{keys.inspect} on #{locale} locale for msgid #{key.inspect} with values #{values.inspect}" if values.size != keys.size
64
65           result = {}
66           values.each_with_index { |_value, ix| result[keys[ix]] = _value }
67           [key, result]
68         end
69
70     end
71   end
72 end