summaryrefslogtreecommitdiffstats
path: root/vendor/plugins/gloc-1.1.0/lib/gloc-internal.rb
blob: faed551cac8e99c662c2817ababac1b492381b6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# Copyright (c) 2005-2006 David Barri

require 'iconv'
require 'gloc-version'

module GLoc
  class GLocError < StandardError #:nodoc:
  end
  class InvalidArgumentsError < GLocError #:nodoc:
  end
  class InvalidKeyError < GLocError #:nodoc:
  end
  class RuleNotFoundError < GLocError #:nodoc:
  end
  class StringNotFoundError < GLocError #:nodoc:
  end
  
  class << self
    private
    
    def _add_localized_data(lang, symbol_hash, override, target) #:nodoc:
      lang= lang.to_sym
      if override
        target[lang] ||= {}
        target[lang].merge!(symbol_hash)
      else
        symbol_hash.merge!(target[lang]) if target[lang]
        target[lang]= symbol_hash
      end
    end
    
    def _add_localized_strings(lang, symbol_hash, override=true, strings_charset=nil) #:nodoc:
      _charset_required
      
      # Convert all incoming strings to the gloc charset
      if strings_charset
        Iconv.open(get_charset(lang), strings_charset) do |i|
          symbol_hash.each_pair {|k,v| symbol_hash[k]= i.iconv(v)}
        end
      end

      # Convert rules
      rules= {}
      old_kcode= $KCODE
      begin
        $KCODE= 'u'
        Iconv.open(UTF_8, get_charset(lang)) do |i|
          symbol_hash.each {|k,v|
            if /^_gloc_rule_(.+)$/ =~ k.to_s
              v= i.iconv(v) if v
              v= '""' if v.nil?
              rules[$1.to_sym]= eval "Proc.new do #{v} end"
            end
          }
        end
      ensure
        $KCODE= old_kcode
      end
      rules.keys.each {|k| symbol_hash.delete "_gloc_rule_#{k}".to_sym}
      
      # Add new localized data
      LOWERCASE_LANGUAGES[lang.to_s.downcase]= lang
      _add_localized_data(lang, symbol_hash, override, LOCALIZED_STRINGS)
      _add_localized_data(lang, rules, override, RULES)
    end
    
    def _charset_required #:nodoc:
      set_charset UTF_8 unless CONFIG[:internal_charset]
    end
    
    def _get_internal_state_vars
      [ CONFIG, LOCALIZED_STRINGS, RULES, LOWERCASE_LANGUAGES ]
    end
    
    def _get_lang_file_list(dir) #:nodoc:
      dir= File.join(RAILS_ROOT,'{.,vendor/plugins/*}','lang') if dir.nil?
      Dir[File.join(dir,'*.{yaml,yml}')]
    end
    
    def _l(symbol, language, *arguments) #:nodoc:
      symbol= symbol.to_sym if symbol.is_a?(String)
      raise InvalidKeyError.new("Symbol or String expected as key.") unless symbol.kind_of?(Symbol)
      
      translation= LOCALIZED_STRINGS[language][symbol] rescue nil
      if translation.nil?
        raise StringNotFoundError.new("There is no key called '#{symbol}' in the #{language} strings.") if CONFIG[:raise_string_not_found_errors]
        translation= symbol.to_s
      end
      
      begin
        return translation % arguments
      rescue => e
        raise InvalidArgumentsError.new("Translation value #{translation.inspect} with arguments #{arguments.inspect} caused error '#{e.message}'")
      end
    end
  
    def _l_has_string?(symbol,lang) #:nodoc:
      symbol= symbol.to_sym if symbol.is_a?(String)
      LOCALIZED_STRINGS[lang].has_key?(symbol.to_sym) rescue false
    end

    def _l_rule(symbol,lang) #:nodoc:
      symbol= symbol.to_sym if symbol.is_a?(String)
      raise InvalidKeyError.new("Symbol or String expected as key.") unless symbol.kind_of?(Symbol)

      r= RULES[lang][symbol] rescue nil
      raise RuleNotFoundError.new("There is no rule called '#{symbol}' in the #{lang} rules.") if r.nil?
      r
    end
    
    def _verbose_msg(type=nil)
      return unless CONFIG[:verbose]
      x= case type
        when :stats
          x= valid_languages.map{|l| ":#{l}(#{LOCALIZED_STRINGS[l].size}/#{RULES[l].size})"}.sort.join(', ')
          "Current stats -- #{x}"
        else
          yield
        end
      puts "[GLoc] #{x}"
    end
    
    public :_l, :_l_has_string?, :_l_rule
  end
  
  private
  
  unless const_defined?(:LOCALIZED_STRINGS)
    LOCALIZED_STRINGS= {}
    RULES= {}
    LOWERCASE_LANGUAGES= {}
  end
  
end