i18n 0.4.0 → 1.14.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/MIT-LICENSE +0 -0
 - data/README.md +127 -0
 - data/lib/i18n/backend/base.rb +189 -111
 - data/lib/i18n/backend/cache.rb +58 -22
 - data/lib/i18n/backend/cache_file.rb +36 -0
 - data/lib/i18n/backend/cascade.rb +9 -10
 - data/lib/i18n/backend/chain.rb +95 -42
 - data/lib/i18n/backend/fallbacks.rb +68 -22
 - data/lib/i18n/backend/flatten.rb +13 -8
 - data/lib/i18n/backend/gettext.rb +33 -25
 - data/lib/i18n/backend/interpolation_compiler.rb +12 -14
 - data/lib/i18n/backend/key_value.rb +112 -10
 - data/lib/i18n/backend/lazy_loadable.rb +184 -0
 - data/lib/i18n/backend/memoize.rb +13 -7
 - data/lib/i18n/backend/metadata.rb +12 -6
 - data/lib/i18n/backend/pluralization.rb +64 -25
 - data/lib/i18n/backend/simple.rb +44 -18
 - data/lib/i18n/backend/transliterator.rb +43 -33
 - data/lib/i18n/backend.rb +5 -3
 - data/lib/i18n/config.rb +91 -10
 - data/lib/i18n/exceptions.rb +118 -22
 - data/lib/i18n/gettext/helpers.rb +14 -4
 - data/lib/i18n/gettext/po_parser.rb +7 -7
 - data/lib/i18n/gettext.rb +6 -5
 - data/lib/i18n/interpolate/ruby.rb +53 -0
 - data/lib/i18n/locale/fallbacks.rb +33 -26
 - data/lib/i18n/locale/tag/parents.rb +8 -8
 - data/lib/i18n/locale/tag/rfc4646.rb +0 -2
 - data/lib/i18n/locale/tag/simple.rb +2 -4
 - data/lib/i18n/locale.rb +2 -0
 - data/lib/i18n/middleware.rb +17 -0
 - data/lib/i18n/tests/basics.rb +58 -0
 - data/lib/i18n/tests/defaults.rb +52 -0
 - data/lib/i18n/tests/interpolation.rb +167 -0
 - data/lib/i18n/tests/link.rb +66 -0
 - data/lib/i18n/tests/localization/date.rb +122 -0
 - data/lib/i18n/tests/localization/date_time.rb +103 -0
 - data/lib/i18n/tests/localization/procs.rb +118 -0
 - data/lib/i18n/tests/localization/time.rb +103 -0
 - data/lib/i18n/tests/localization.rb +19 -0
 - data/lib/i18n/tests/lookup.rb +81 -0
 - data/lib/i18n/tests/pluralization.rb +35 -0
 - data/lib/i18n/tests/procs.rb +66 -0
 - data/lib/i18n/tests.rb +14 -0
 - data/lib/i18n/utils.rb +55 -0
 - data/lib/i18n/version.rb +3 -1
 - data/lib/i18n.rb +200 -87
 - metadata +64 -56
 - data/CHANGELOG.textile +0 -135
 - data/README.textile +0 -93
 - data/lib/i18n/backend/active_record/missing.rb +0 -65
 - data/lib/i18n/backend/active_record/store_procs.rb +0 -38
 - data/lib/i18n/backend/active_record/translation.rb +0 -93
 - data/lib/i18n/backend/active_record.rb +0 -61
 - data/lib/i18n/backend/cldr.rb +0 -100
 - data/lib/i18n/core_ext/hash.rb +0 -29
 - data/lib/i18n/core_ext/string/interpolate.rb +0 -98
 
| 
         @@ -1,4 +1,6 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            # encoding: utf-8
         
     | 
| 
      
 2 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
       2 
4 
     | 
    
         
             
            module I18n
         
     | 
| 
       3 
5 
     | 
    
         
             
              module Backend
         
     | 
| 
       4 
6 
     | 
    
         
             
                module Transliterator
         
     | 
| 
         @@ -43,55 +45,63 @@ module I18n 
     | 
|
| 
       43 
45 
     | 
    
         
             
                      "Ç"=>"C", "È"=>"E", "É"=>"E", "Ê"=>"E", "Ë"=>"E", "Ì"=>"I", "Í"=>"I",
         
     | 
| 
       44 
46 
     | 
    
         
             
                      "Î"=>"I", "Ï"=>"I", "Ð"=>"D", "Ñ"=>"N", "Ò"=>"O", "Ó"=>"O", "Ô"=>"O",
         
     | 
| 
       45 
47 
     | 
    
         
             
                      "Õ"=>"O", "Ö"=>"O", "×"=>"x", "Ø"=>"O", "Ù"=>"U", "Ú"=>"U", "Û"=>"U",
         
     | 
| 
       46 
     | 
    
         
            -
                      "Ü"=>"U", "Ý"=>"Y", "Þ"=>"Th", "ß"=>"ss", " 
     | 
| 
       47 
     | 
    
         
            -
                      " 
     | 
| 
       48 
     | 
    
         
            -
                      " 
     | 
| 
       49 
     | 
    
         
            -
                      " 
     | 
| 
       50 
     | 
    
         
            -
                      " 
     | 
| 
       51 
     | 
    
         
            -
                      " 
     | 
| 
       52 
     | 
    
         
            -
                      " 
     | 
| 
       53 
     | 
    
         
            -
                      " 
     | 
| 
       54 
     | 
    
         
            -
                      " 
     | 
| 
       55 
     | 
    
         
            -
                      " 
     | 
| 
       56 
     | 
    
         
            -
                      " 
     | 
| 
       57 
     | 
    
         
            -
                      " 
     | 
| 
       58 
     | 
    
         
            -
                      " 
     | 
| 
       59 
     | 
    
         
            -
                      " 
     | 
| 
       60 
     | 
    
         
            -
                      " 
     | 
| 
       61 
     | 
    
         
            -
                      "ņ"=>"n", "Ň"=>"N", "ň"=>"n", "ʼn"=>"'n", "Ŋ"=>"NG", 
     | 
| 
       62 
     | 
    
         
            -
                      "Ō"=>"O", "ō"=>"o", "Ŏ"=>"O", "ŏ"=>"o", "Ő"=>"O", "ő"=>"o", 
     | 
| 
       63 
     | 
    
         
            -
                      "œ"=>"oe", "Ŕ"=>"R", "ŕ"=>"r", "Ŗ"=>"R", "ŗ"=>"r", "Ř"=>"R", 
     | 
| 
       64 
     | 
    
         
            -
                      "Ś"=>"S", "ś"=>"s", "Ŝ"=>"S", "ŝ"=>"s", "Ş"=>"S", "ş"=>"s", 
     | 
| 
       65 
     | 
    
         
            -
                      "š"=>"s", "Ţ"=>"T", "ţ"=>"t", "Ť"=>"T", "ť"=>"t", "Ŧ"=>"T", 
     | 
| 
       66 
     | 
    
         
            -
                      "Ũ"=>"U", "ũ"=>"u", "Ū"=>"U", "ū"=>"u", "Ŭ"=>"U", "ŭ"=>"u", 
     | 
| 
       67 
     | 
    
         
            -
                      "ů"=>"u", "Ű"=>"U", "ű"=>"u", "Ų"=>"U", "ų"=>"u", "Ŵ"=>"W", 
     | 
| 
       68 
     | 
    
         
            -
                      "Ŷ"=>"Y", "ŷ"=>"y", "Ÿ"=>"Y", "Ź"=>"Z", "ź"=>"z", "Ż"=>"Z", 
     | 
| 
       69 
     | 
    
         
            -
                      "Ž"=>"Z", "ž"=>"z"
         
     | 
| 
       70 
     | 
    
         
            -
                    }
         
     | 
| 
      
 48 
     | 
    
         
            +
                      "Ü"=>"U", "Ý"=>"Y", "Þ"=>"Th", "ß"=>"ss", "ẞ"=>"SS", "à"=>"a",
         
     | 
| 
      
 49 
     | 
    
         
            +
                      "á"=>"a", "â"=>"a", "ã"=>"a", "ä"=>"a", "å"=>"a", "æ"=>"ae", "ç"=>"c",
         
     | 
| 
      
 50 
     | 
    
         
            +
                      "è"=>"e", "é"=>"e", "ê"=>"e", "ë"=>"e", "ì"=>"i", "í"=>"i", "î"=>"i",
         
     | 
| 
      
 51 
     | 
    
         
            +
                      "ï"=>"i", "ð"=>"d", "ñ"=>"n", "ò"=>"o", "ó"=>"o", "ô"=>"o", "õ"=>"o",
         
     | 
| 
      
 52 
     | 
    
         
            +
                      "ö"=>"o", "ø"=>"o", "ù"=>"u", "ú"=>"u", "û"=>"u", "ü"=>"u", "ý"=>"y",
         
     | 
| 
      
 53 
     | 
    
         
            +
                      "þ"=>"th", "ÿ"=>"y", "Ā"=>"A", "ā"=>"a", "Ă"=>"A", "ă"=>"a", "Ą"=>"A",
         
     | 
| 
      
 54 
     | 
    
         
            +
                      "ą"=>"a", "Ć"=>"C", "ć"=>"c", "Ĉ"=>"C", "ĉ"=>"c", "Ċ"=>"C", "ċ"=>"c",
         
     | 
| 
      
 55 
     | 
    
         
            +
                      "Č"=>"C", "č"=>"c", "Ď"=>"D", "ď"=>"d", "Đ"=>"D", "đ"=>"d", "Ē"=>"E",
         
     | 
| 
      
 56 
     | 
    
         
            +
                      "ē"=>"e", "Ĕ"=>"E", "ĕ"=>"e", "Ė"=>"E", "ė"=>"e", "Ę"=>"E", "ę"=>"e",
         
     | 
| 
      
 57 
     | 
    
         
            +
                      "Ě"=>"E", "ě"=>"e", "Ĝ"=>"G", "ĝ"=>"g", "Ğ"=>"G", "ğ"=>"g", "Ġ"=>"G",
         
     | 
| 
      
 58 
     | 
    
         
            +
                      "ġ"=>"g", "Ģ"=>"G", "ģ"=>"g", "Ĥ"=>"H", "ĥ"=>"h", "Ħ"=>"H", "ħ"=>"h",
         
     | 
| 
      
 59 
     | 
    
         
            +
                      "Ĩ"=>"I", "ĩ"=>"i", "Ī"=>"I", "ī"=>"i", "Ĭ"=>"I", "ĭ"=>"i", "Į"=>"I",
         
     | 
| 
      
 60 
     | 
    
         
            +
                      "į"=>"i", "İ"=>"I", "ı"=>"i", "IJ"=>"IJ", "ij"=>"ij", "Ĵ"=>"J", "ĵ"=>"j",
         
     | 
| 
      
 61 
     | 
    
         
            +
                      "Ķ"=>"K", "ķ"=>"k", "ĸ"=>"k", "Ĺ"=>"L", "ĺ"=>"l", "Ļ"=>"L", "ļ"=>"l",
         
     | 
| 
      
 62 
     | 
    
         
            +
                      "Ľ"=>"L", "ľ"=>"l", "Ŀ"=>"L", "ŀ"=>"l", "Ł"=>"L", "ł"=>"l", "Ń"=>"N",
         
     | 
| 
      
 63 
     | 
    
         
            +
                      "ń"=>"n", "Ņ"=>"N", "ņ"=>"n", "Ň"=>"N", "ň"=>"n", "ʼn"=>"'n", "Ŋ"=>"NG",
         
     | 
| 
      
 64 
     | 
    
         
            +
                      "ŋ"=>"ng", "Ō"=>"O", "ō"=>"o", "Ŏ"=>"O", "ŏ"=>"o", "Ő"=>"O", "ő"=>"o",
         
     | 
| 
      
 65 
     | 
    
         
            +
                      "Œ"=>"OE", "œ"=>"oe", "Ŕ"=>"R", "ŕ"=>"r", "Ŗ"=>"R", "ŗ"=>"r", "Ř"=>"R",
         
     | 
| 
      
 66 
     | 
    
         
            +
                      "ř"=>"r", "Ś"=>"S", "ś"=>"s", "Ŝ"=>"S", "ŝ"=>"s", "Ş"=>"S", "ş"=>"s",
         
     | 
| 
      
 67 
     | 
    
         
            +
                      "Š"=>"S", "š"=>"s", "Ţ"=>"T", "ţ"=>"t", "Ť"=>"T", "ť"=>"t", "Ŧ"=>"T",
         
     | 
| 
      
 68 
     | 
    
         
            +
                      "ŧ"=>"t", "Ũ"=>"U", "ũ"=>"u", "Ū"=>"U", "ū"=>"u", "Ŭ"=>"U", "ŭ"=>"u",
         
     | 
| 
      
 69 
     | 
    
         
            +
                      "Ů"=>"U", "ů"=>"u", "Ű"=>"U", "ű"=>"u", "Ų"=>"U", "ų"=>"u", "Ŵ"=>"W",
         
     | 
| 
      
 70 
     | 
    
         
            +
                      "ŵ"=>"w", "Ŷ"=>"Y", "ŷ"=>"y", "Ÿ"=>"Y", "Ź"=>"Z", "ź"=>"z", "Ż"=>"Z",
         
     | 
| 
      
 71 
     | 
    
         
            +
                      "ż"=>"z", "Ž"=>"Z", "ž"=>"z"
         
     | 
| 
      
 72 
     | 
    
         
            +
                    }.freeze
         
     | 
| 
       71 
73 
     | 
    
         | 
| 
       72 
74 
     | 
    
         
             
                    def initialize(rule = nil)
         
     | 
| 
       73 
75 
     | 
    
         
             
                      @rule = rule
         
     | 
| 
       74 
     | 
    
         
            -
                       
     | 
| 
      
 76 
     | 
    
         
            +
                      add_default_approximations
         
     | 
| 
       75 
77 
     | 
    
         
             
                      add rule if rule
         
     | 
| 
       76 
78 
     | 
    
         
             
                    end
         
     | 
| 
       77 
79 
     | 
    
         | 
| 
       78 
80 
     | 
    
         
             
                    def transliterate(string, replacement = nil)
         
     | 
| 
      
 81 
     | 
    
         
            +
                      replacement ||= DEFAULT_REPLACEMENT_CHAR
         
     | 
| 
       79 
82 
     | 
    
         
             
                      string.gsub(/[^\x00-\x7f]/u) do |char|
         
     | 
| 
       80 
     | 
    
         
            -
                        approximations[char] || replacement 
     | 
| 
      
 83 
     | 
    
         
            +
                        approximations[char] || replacement
         
     | 
| 
       81 
84 
     | 
    
         
             
                      end
         
     | 
| 
       82 
85 
     | 
    
         
             
                    end
         
     | 
| 
       83 
86 
     | 
    
         | 
| 
       84 
87 
     | 
    
         
             
                    private
         
     | 
| 
       85 
88 
     | 
    
         | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
             
     | 
| 
      
 89 
     | 
    
         
            +
                    def approximations
         
     | 
| 
      
 90 
     | 
    
         
            +
                      @approximations ||= {}
         
     | 
| 
      
 91 
     | 
    
         
            +
                    end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                    def add_default_approximations
         
     | 
| 
      
 94 
     | 
    
         
            +
                      DEFAULT_APPROXIMATIONS.each do |key, value|
         
     | 
| 
      
 95 
     | 
    
         
            +
                        approximations[key] = value
         
     | 
| 
       88 
96 
     | 
    
         
             
                      end
         
     | 
| 
      
 97 
     | 
    
         
            +
                    end
         
     | 
| 
       89 
98 
     | 
    
         | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
                        approximations. 
     | 
| 
      
 99 
     | 
    
         
            +
                    # Add transliteration rules to the approximations hash.
         
     | 
| 
      
 100 
     | 
    
         
            +
                    def add(hash)
         
     | 
| 
      
 101 
     | 
    
         
            +
                      hash.each do |key, value|
         
     | 
| 
      
 102 
     | 
    
         
            +
                        approximations[key.to_s] = value.to_s
         
     | 
| 
       94 
103 
     | 
    
         
             
                      end
         
     | 
| 
      
 104 
     | 
    
         
            +
                    end
         
     | 
| 
       95 
105 
     | 
    
         
             
                  end
         
     | 
| 
       96 
106 
     | 
    
         
             
                end
         
     | 
| 
       97 
107 
     | 
    
         
             
              end
         
     | 
    
        data/lib/i18n/backend.rb
    CHANGED
    
    | 
         @@ -1,16 +1,18 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            module I18n
         
     | 
| 
       2 
4 
     | 
    
         
             
              module Backend
         
     | 
| 
       3 
     | 
    
         
            -
                autoload :ActiveRecord,          'i18n/backend/active_record'
         
     | 
| 
       4 
5 
     | 
    
         
             
                autoload :Base,                  'i18n/backend/base'
         
     | 
| 
       5 
     | 
    
         
            -
                autoload :InterpolationCompiler, 'i18n/backend/interpolation_compiler'
         
     | 
| 
       6 
6 
     | 
    
         
             
                autoload :Cache,                 'i18n/backend/cache'
         
     | 
| 
      
 7 
     | 
    
         
            +
                autoload :CacheFile,             'i18n/backend/cache_file'
         
     | 
| 
       7 
8 
     | 
    
         
             
                autoload :Cascade,               'i18n/backend/cascade'
         
     | 
| 
       8 
9 
     | 
    
         
             
                autoload :Chain,                 'i18n/backend/chain'
         
     | 
| 
       9 
     | 
    
         
            -
                autoload :Cldr,                  'i18n/backend/cldr'
         
     | 
| 
       10 
10 
     | 
    
         
             
                autoload :Fallbacks,             'i18n/backend/fallbacks'
         
     | 
| 
       11 
11 
     | 
    
         
             
                autoload :Flatten,               'i18n/backend/flatten'
         
     | 
| 
       12 
12 
     | 
    
         
             
                autoload :Gettext,               'i18n/backend/gettext'
         
     | 
| 
      
 13 
     | 
    
         
            +
                autoload :InterpolationCompiler, 'i18n/backend/interpolation_compiler'
         
     | 
| 
       13 
14 
     | 
    
         
             
                autoload :KeyValue,              'i18n/backend/key_value'
         
     | 
| 
      
 15 
     | 
    
         
            +
                autoload :LazyLoadable,          'i18n/backend/lazy_loadable'
         
     | 
| 
       14 
16 
     | 
    
         
             
                autoload :Memoize,               'i18n/backend/memoize'
         
     | 
| 
       15 
17 
     | 
    
         
             
                autoload :Metadata,              'i18n/backend/metadata'
         
     | 
| 
       16 
18 
     | 
    
         
             
                autoload :Pluralization,         'i18n/backend/pluralization'
         
     | 
    
        data/lib/i18n/config.rb
    CHANGED
    
    | 
         @@ -1,14 +1,19 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'set'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
       1 
5 
     | 
    
         
             
            module I18n
         
     | 
| 
       2 
6 
     | 
    
         
             
              class Config
         
     | 
| 
       3 
7 
     | 
    
         
             
                # The only configuration value that is not global and scoped to thread is :locale.
         
     | 
| 
       4 
8 
     | 
    
         
             
                # It defaults to the default_locale.
         
     | 
| 
       5 
9 
     | 
    
         
             
                def locale
         
     | 
| 
       6 
     | 
    
         
            -
                  @locale  
     | 
| 
      
 10 
     | 
    
         
            +
                  defined?(@locale) && @locale != nil ? @locale : default_locale
         
     | 
| 
       7 
11 
     | 
    
         
             
                end
         
     | 
| 
       8 
12 
     | 
    
         | 
| 
       9 
13 
     | 
    
         
             
                # Sets the current locale pseudo-globally, i.e. in the Thread.current hash.
         
     | 
| 
       10 
14 
     | 
    
         
             
                def locale=(locale)
         
     | 
| 
       11 
     | 
    
         
            -
                   
     | 
| 
      
 15 
     | 
    
         
            +
                  I18n.enforce_available_locales!(locale)
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @locale = locale && locale.to_sym
         
     | 
| 
       12 
17 
     | 
    
         
             
                end
         
     | 
| 
       13 
18 
     | 
    
         | 
| 
       14 
19 
     | 
    
         
             
                # Returns the current backend. Defaults to +Backend::Simple+.
         
     | 
| 
         @@ -28,19 +33,42 @@ module I18n 
     | 
|
| 
       28 
33 
     | 
    
         | 
| 
       29 
34 
     | 
    
         
             
                # Sets the current default locale. Used to set a custom default locale.
         
     | 
| 
       30 
35 
     | 
    
         
             
                def default_locale=(locale)
         
     | 
| 
       31 
     | 
    
         
            -
                   
     | 
| 
      
 36 
     | 
    
         
            +
                  I18n.enforce_available_locales!(locale)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  @@default_locale = locale && locale.to_sym
         
     | 
| 
       32 
38 
     | 
    
         
             
                end
         
     | 
| 
       33 
39 
     | 
    
         | 
| 
       34 
40 
     | 
    
         
             
                # Returns an array of locales for which translations are available.
         
     | 
| 
       35 
     | 
    
         
            -
                # Unless you  
     | 
| 
       36 
     | 
    
         
            -
                # the call will be delegated to the backend 
     | 
| 
      
 41 
     | 
    
         
            +
                # Unless you explicitly set these through I18n.available_locales=
         
     | 
| 
      
 42 
     | 
    
         
            +
                # the call will be delegated to the backend.
         
     | 
| 
       37 
43 
     | 
    
         
             
                def available_locales
         
     | 
| 
       38 
     | 
    
         
            -
                  @@available_locales ||=  
     | 
| 
      
 44 
     | 
    
         
            +
                  @@available_locales ||= nil
         
     | 
| 
      
 45 
     | 
    
         
            +
                  @@available_locales || backend.available_locales
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                # Caches the available locales list as both strings and symbols in a Set, so
         
     | 
| 
      
 49 
     | 
    
         
            +
                # that we can have faster lookups to do the available locales enforce check.
         
     | 
| 
      
 50 
     | 
    
         
            +
                def available_locales_set #:nodoc:
         
     | 
| 
      
 51 
     | 
    
         
            +
                  @@available_locales_set ||= available_locales.inject(Set.new) do |set, locale|
         
     | 
| 
      
 52 
     | 
    
         
            +
                    set << locale.to_s << locale.to_sym
         
     | 
| 
      
 53 
     | 
    
         
            +
                  end
         
     | 
| 
       39 
54 
     | 
    
         
             
                end
         
     | 
| 
       40 
55 
     | 
    
         | 
| 
       41 
56 
     | 
    
         
             
                # Sets the available locales.
         
     | 
| 
       42 
57 
     | 
    
         
             
                def available_locales=(locales)
         
     | 
| 
       43 
     | 
    
         
            -
                  @@available_locales = locales
         
     | 
| 
      
 58 
     | 
    
         
            +
                  @@available_locales = Array(locales).map { |locale| locale.to_sym }
         
     | 
| 
      
 59 
     | 
    
         
            +
                  @@available_locales = nil if @@available_locales.empty?
         
     | 
| 
      
 60 
     | 
    
         
            +
                  @@available_locales_set = nil
         
     | 
| 
      
 61 
     | 
    
         
            +
                end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                # Returns true if the available_locales have been initialized
         
     | 
| 
      
 64 
     | 
    
         
            +
                def available_locales_initialized?
         
     | 
| 
      
 65 
     | 
    
         
            +
                  ( !!defined?(@@available_locales) && !!@@available_locales )
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                # Clears the available locales set so it can be recomputed again after I18n
         
     | 
| 
      
 69 
     | 
    
         
            +
                # gets reloaded.
         
     | 
| 
      
 70 
     | 
    
         
            +
                def clear_available_locales_set #:nodoc:
         
     | 
| 
      
 71 
     | 
    
         
            +
                  @@available_locales_set = nil
         
     | 
| 
       44 
72 
     | 
    
         
             
                end
         
     | 
| 
       45 
73 
     | 
    
         | 
| 
       46 
74 
     | 
    
         
             
                # Returns the current default scope separator. Defaults to '.'
         
     | 
| 
         @@ -53,9 +81,10 @@ module I18n 
     | 
|
| 
       53 
81 
     | 
    
         
             
                  @@default_separator = separator
         
     | 
| 
       54 
82 
     | 
    
         
             
                end
         
     | 
| 
       55 
83 
     | 
    
         | 
| 
       56 
     | 
    
         
            -
                #  
     | 
| 
      
 84 
     | 
    
         
            +
                # Returns the current exception handler. Defaults to an instance of
         
     | 
| 
      
 85 
     | 
    
         
            +
                # I18n::ExceptionHandler.
         
     | 
| 
       57 
86 
     | 
    
         
             
                def exception_handler
         
     | 
| 
       58 
     | 
    
         
            -
                  @@exception_handler ||=  
     | 
| 
      
 87 
     | 
    
         
            +
                  @@exception_handler ||= ExceptionHandler.new
         
     | 
| 
       59 
88 
     | 
    
         
             
                end
         
     | 
| 
       60 
89 
     | 
    
         | 
| 
       61 
90 
     | 
    
         
             
                # Sets the exception handler.
         
     | 
| 
         @@ -63,6 +92,29 @@ module I18n 
     | 
|
| 
       63 
92 
     | 
    
         
             
                  @@exception_handler = exception_handler
         
     | 
| 
       64 
93 
     | 
    
         
             
                end
         
     | 
| 
       65 
94 
     | 
    
         | 
| 
      
 95 
     | 
    
         
            +
                # Returns the current handler for situations when interpolation argument
         
     | 
| 
      
 96 
     | 
    
         
            +
                # is missing. MissingInterpolationArgument will be raised by default.
         
     | 
| 
      
 97 
     | 
    
         
            +
                def missing_interpolation_argument_handler
         
     | 
| 
      
 98 
     | 
    
         
            +
                  @@missing_interpolation_argument_handler ||= lambda do |missing_key, provided_hash, string|
         
     | 
| 
      
 99 
     | 
    
         
            +
                    raise MissingInterpolationArgument.new(missing_key, provided_hash, string)
         
     | 
| 
      
 100 
     | 
    
         
            +
                  end
         
     | 
| 
      
 101 
     | 
    
         
            +
                end
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
                # Sets the missing interpolation argument handler. It can be any
         
     | 
| 
      
 104 
     | 
    
         
            +
                # object that responds to #call. The arguments that will be passed to #call
         
     | 
| 
      
 105 
     | 
    
         
            +
                # are the same as for MissingInterpolationArgument initializer. Use +Proc.new+
         
     | 
| 
      
 106 
     | 
    
         
            +
                # if you don't care about arity.
         
     | 
| 
      
 107 
     | 
    
         
            +
                #
         
     | 
| 
      
 108 
     | 
    
         
            +
                # == Example:
         
     | 
| 
      
 109 
     | 
    
         
            +
                # You can suppress raising an exception and return string instead:
         
     | 
| 
      
 110 
     | 
    
         
            +
                #
         
     | 
| 
      
 111 
     | 
    
         
            +
                #   I18n.config.missing_interpolation_argument_handler = Proc.new do |key|
         
     | 
| 
      
 112 
     | 
    
         
            +
                #     "#{key} is missing"
         
     | 
| 
      
 113 
     | 
    
         
            +
                #   end
         
     | 
| 
      
 114 
     | 
    
         
            +
                def missing_interpolation_argument_handler=(exception_handler)
         
     | 
| 
      
 115 
     | 
    
         
            +
                  @@missing_interpolation_argument_handler = exception_handler
         
     | 
| 
      
 116 
     | 
    
         
            +
                end
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
       66 
118 
     | 
    
         
             
                # Allow clients to register paths providing translation data sources. The
         
     | 
| 
       67 
119 
     | 
    
         
             
                # backend defines acceptable sources.
         
     | 
| 
       68 
120 
     | 
    
         
             
                #
         
     | 
| 
         @@ -79,6 +131,35 @@ module I18n 
     | 
|
| 
       79 
131 
     | 
    
         
             
                # behave like a Ruby Array.
         
     | 
| 
       80 
132 
     | 
    
         
             
                def load_path=(load_path)
         
     | 
| 
       81 
133 
     | 
    
         
             
                  @@load_path = load_path
         
     | 
| 
      
 134 
     | 
    
         
            +
                  @@available_locales_set = nil
         
     | 
| 
      
 135 
     | 
    
         
            +
                  backend.reload!
         
     | 
| 
      
 136 
     | 
    
         
            +
                end
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                # Whether or not to verify if locales are in the list of available locales.
         
     | 
| 
      
 139 
     | 
    
         
            +
                # Defaults to true.
         
     | 
| 
      
 140 
     | 
    
         
            +
                @@enforce_available_locales = true
         
     | 
| 
      
 141 
     | 
    
         
            +
                def enforce_available_locales
         
     | 
| 
      
 142 
     | 
    
         
            +
                  @@enforce_available_locales
         
     | 
| 
      
 143 
     | 
    
         
            +
                end
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                def enforce_available_locales=(enforce_available_locales)
         
     | 
| 
      
 146 
     | 
    
         
            +
                  @@enforce_available_locales = enforce_available_locales
         
     | 
| 
      
 147 
     | 
    
         
            +
                end
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                # Returns the current interpolation patterns. Defaults to
         
     | 
| 
      
 150 
     | 
    
         
            +
                # I18n::DEFAULT_INTERPOLATION_PATTERNS.
         
     | 
| 
      
 151 
     | 
    
         
            +
                def interpolation_patterns
         
     | 
| 
      
 152 
     | 
    
         
            +
                  @@interpolation_patterns ||= I18n::DEFAULT_INTERPOLATION_PATTERNS.dup
         
     | 
| 
      
 153 
     | 
    
         
            +
                end
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
                # Sets the current interpolation patterns. Used to set a interpolation
         
     | 
| 
      
 156 
     | 
    
         
            +
                # patterns.
         
     | 
| 
      
 157 
     | 
    
         
            +
                #
         
     | 
| 
      
 158 
     | 
    
         
            +
                # E.g. using {{}} as a placeholder like "{{hello}}, world!":
         
     | 
| 
      
 159 
     | 
    
         
            +
                #
         
     | 
| 
      
 160 
     | 
    
         
            +
                #   I18n.config.interpolation_patterns << /\{\{(\w+)\}\}/
         
     | 
| 
      
 161 
     | 
    
         
            +
                def interpolation_patterns=(interpolation_patterns)
         
     | 
| 
      
 162 
     | 
    
         
            +
                  @@interpolation_patterns = interpolation_patterns
         
     | 
| 
       82 
163 
     | 
    
         
             
                end
         
     | 
| 
       83 
164 
     | 
    
         
             
              end
         
     | 
| 
       84 
     | 
    
         
            -
            end
         
     | 
| 
      
 165 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/i18n/exceptions.rb
    CHANGED
    
    | 
         @@ -1,14 +1,34 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #  
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
              def initialize(message = nil)
         
     | 
| 
       5 
     | 
    
         
            -
                super(message || "key not found")
         
     | 
| 
       6 
     | 
    
         
            -
              end
         
     | 
| 
       7 
     | 
    
         
            -
            end unless defined?(KeyError)
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'cgi'
         
     | 
| 
       8 
4 
     | 
    
         | 
| 
       9 
5 
     | 
    
         
             
            module I18n
         
     | 
| 
      
 6 
     | 
    
         
            +
              class ExceptionHandler
         
     | 
| 
      
 7 
     | 
    
         
            +
                def call(exception, _locale, _key, _options)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  if exception.is_a?(MissingTranslation)
         
     | 
| 
      
 9 
     | 
    
         
            +
                    exception.message
         
     | 
| 
      
 10 
     | 
    
         
            +
                  else
         
     | 
| 
      
 11 
     | 
    
         
            +
                    raise exception
         
     | 
| 
      
 12 
     | 
    
         
            +
                  end
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
       10 
16 
     | 
    
         
             
              class ArgumentError < ::ArgumentError; end
         
     | 
| 
       11 
17 
     | 
    
         | 
| 
      
 18 
     | 
    
         
            +
              class Disabled < ArgumentError
         
     | 
| 
      
 19 
     | 
    
         
            +
                def initialize(method)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  super(<<~MESSAGE)
         
     | 
| 
      
 21 
     | 
    
         
            +
                    I18n.#{method} is currently disabled, likely because your application is still in its loading phase.
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                    This method is meant to display text in the user locale, so calling it before the user locale has
         
     | 
| 
      
 24 
     | 
    
         
            +
                    been set is likely to display text from the wrong locale to some users.
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                    If you have a legitimate reason to access i18n data outside of the user flow, you can do so by passing
         
     | 
| 
      
 27 
     | 
    
         
            +
                    the desired locale explicitly with the `locale` argument, e.g. `I18n.#{method}(..., locale: :en)`
         
     | 
| 
      
 28 
     | 
    
         
            +
                  MESSAGE
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
       12 
32 
     | 
    
         
             
              class InvalidLocale < ArgumentError
         
     | 
| 
       13 
33 
     | 
    
         
             
                attr_reader :locale
         
     | 
| 
       14 
34 
     | 
    
         
             
                def initialize(locale)
         
     | 
| 
         @@ -17,29 +37,71 @@ module I18n 
     | 
|
| 
       17 
37 
     | 
    
         
             
                end
         
     | 
| 
       18 
38 
     | 
    
         
             
              end
         
     | 
| 
       19 
39 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
              class  
     | 
| 
       21 
     | 
    
         
            -
                attr_reader : 
     | 
| 
       22 
     | 
    
         
            -
                def initialize( 
     | 
| 
       23 
     | 
    
         
            -
                  @ 
     | 
| 
       24 
     | 
    
         
            -
                   
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
             
     | 
| 
      
 40 
     | 
    
         
            +
              class InvalidLocaleData < ArgumentError
         
     | 
| 
      
 41 
     | 
    
         
            +
                attr_reader :filename
         
     | 
| 
      
 42 
     | 
    
         
            +
                def initialize(filename, exception_message)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  @filename, @exception_message = filename, exception_message
         
     | 
| 
      
 44 
     | 
    
         
            +
                  super "can not load translations from #{filename}: #{exception_message}"
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
              end
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
              class MissingTranslation < ArgumentError
         
     | 
| 
      
 49 
     | 
    
         
            +
                module Base
         
     | 
| 
      
 50 
     | 
    
         
            +
                  PERMITTED_KEYS = [:scope, :default].freeze
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                  attr_reader :locale, :key, :options
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                  def initialize(locale, key, options = EMPTY_HASH)
         
     | 
| 
      
 55 
     | 
    
         
            +
                    @key, @locale, @options = key, locale, options.slice(*PERMITTED_KEYS)
         
     | 
| 
      
 56 
     | 
    
         
            +
                    options.each { |k, v| self.options[k] = v.inspect if v.is_a?(Proc) }
         
     | 
| 
      
 57 
     | 
    
         
            +
                  end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                  def keys
         
     | 
| 
      
 60 
     | 
    
         
            +
                    @keys ||= I18n.normalize_keys(locale, key, options[:scope]).tap do |keys|
         
     | 
| 
      
 61 
     | 
    
         
            +
                      keys << 'no key' if keys.size < 2
         
     | 
| 
      
 62 
     | 
    
         
            +
                    end
         
     | 
| 
      
 63 
     | 
    
         
            +
                  end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  def message
         
     | 
| 
      
 66 
     | 
    
         
            +
                    if (default = options[:default]).is_a?(Array) && default.any?
         
     | 
| 
      
 67 
     | 
    
         
            +
                      other_options = ([key, *default]).map { |k| normalized_option(k).prepend('- ') }.join("\n")
         
     | 
| 
      
 68 
     | 
    
         
            +
                      "Translation missing. Options considered were:\n#{other_options}"
         
     | 
| 
      
 69 
     | 
    
         
            +
                    else
         
     | 
| 
      
 70 
     | 
    
         
            +
                      "Translation missing: #{keys.join('.')}"
         
     | 
| 
      
 71 
     | 
    
         
            +
                    end
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  def normalized_option(key)
         
     | 
| 
      
 75 
     | 
    
         
            +
                    I18n.normalize_keys(locale, key, options[:scope]).join('.')
         
     | 
| 
      
 76 
     | 
    
         
            +
                  end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                  alias :to_s :message
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  def to_exception
         
     | 
| 
      
 81 
     | 
    
         
            +
                    MissingTranslationData.new(locale, key, options)
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
       27 
83 
     | 
    
         
             
                end
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                include Base
         
     | 
| 
      
 86 
     | 
    
         
            +
              end
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
              class MissingTranslationData < ArgumentError
         
     | 
| 
      
 89 
     | 
    
         
            +
                include MissingTranslation::Base
         
     | 
| 
       28 
90 
     | 
    
         
             
              end
         
     | 
| 
       29 
91 
     | 
    
         | 
| 
       30 
92 
     | 
    
         
             
              class InvalidPluralizationData < ArgumentError
         
     | 
| 
       31 
     | 
    
         
            -
                attr_reader :entry, :count
         
     | 
| 
       32 
     | 
    
         
            -
                def initialize(entry, count)
         
     | 
| 
       33 
     | 
    
         
            -
                  @entry, @count = entry, count
         
     | 
| 
       34 
     | 
    
         
            -
                  super "translation data #{entry.inspect} can not be used with :count => #{count}"
         
     | 
| 
      
 93 
     | 
    
         
            +
                attr_reader :entry, :count, :key
         
     | 
| 
      
 94 
     | 
    
         
            +
                def initialize(entry, count, key)
         
     | 
| 
      
 95 
     | 
    
         
            +
                  @entry, @count, @key = entry, count, key
         
     | 
| 
      
 96 
     | 
    
         
            +
                  super "translation data #{entry.inspect} can not be used with :count => #{count}. key '#{key}' is missing."
         
     | 
| 
       35 
97 
     | 
    
         
             
                end
         
     | 
| 
       36 
98 
     | 
    
         
             
              end
         
     | 
| 
       37 
99 
     | 
    
         | 
| 
       38 
100 
     | 
    
         
             
              class MissingInterpolationArgument < ArgumentError
         
     | 
| 
       39 
     | 
    
         
            -
                attr_reader :values, :string
         
     | 
| 
       40 
     | 
    
         
            -
                def initialize(values, string)
         
     | 
| 
       41 
     | 
    
         
            -
                  @values, @string = values, string
         
     | 
| 
       42 
     | 
    
         
            -
                  super "missing interpolation argument in #{string.inspect} (#{values.inspect} given)"
         
     | 
| 
      
 101 
     | 
    
         
            +
                attr_reader :key, :values, :string
         
     | 
| 
      
 102 
     | 
    
         
            +
                def initialize(key, values, string)
         
     | 
| 
      
 103 
     | 
    
         
            +
                  @key, @values, @string = key, values, string
         
     | 
| 
      
 104 
     | 
    
         
            +
                  super "missing interpolation argument #{key.inspect} in #{string.inspect} (#{values.inspect} given)"
         
     | 
| 
       43 
105 
     | 
    
         
             
                end
         
     | 
| 
       44 
106 
     | 
    
         
             
              end
         
     | 
| 
       45 
107 
     | 
    
         | 
| 
         @@ -58,4 +120,38 @@ module I18n 
     | 
|
| 
       58 
120 
     | 
    
         
             
                  super "can not load translations from #{filename}, the file type #{type} is not known"
         
     | 
| 
       59 
121 
     | 
    
         
             
                end
         
     | 
| 
       60 
122 
     | 
    
         
             
              end
         
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
              class UnsupportedMethod < ArgumentError
         
     | 
| 
      
 125 
     | 
    
         
            +
                attr_reader :method, :backend_klass, :msg
         
     | 
| 
      
 126 
     | 
    
         
            +
                def initialize(method, backend_klass, msg)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  @method = method
         
     | 
| 
      
 128 
     | 
    
         
            +
                  @backend_klass = backend_klass
         
     | 
| 
      
 129 
     | 
    
         
            +
                  @msg = msg
         
     | 
| 
      
 130 
     | 
    
         
            +
                  super "#{backend_klass} does not support the ##{method} method. #{msg}"
         
     | 
| 
      
 131 
     | 
    
         
            +
                end
         
     | 
| 
      
 132 
     | 
    
         
            +
              end
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
              class InvalidFilenames < ArgumentError
         
     | 
| 
      
 135 
     | 
    
         
            +
                NUMBER_OF_ERRORS_SHOWN = 20
         
     | 
| 
      
 136 
     | 
    
         
            +
                def initialize(file_errors)
         
     | 
| 
      
 137 
     | 
    
         
            +
                  super <<~MSG
         
     | 
| 
      
 138 
     | 
    
         
            +
                    Found #{file_errors.count} error(s).
         
     | 
| 
      
 139 
     | 
    
         
            +
                    The first #{[file_errors.count, NUMBER_OF_ERRORS_SHOWN].min} error(s):
         
     | 
| 
      
 140 
     | 
    
         
            +
                    #{file_errors.map(&:message).first(NUMBER_OF_ERRORS_SHOWN).join("\n")}
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                    To use the LazyLoadable backend:
         
     | 
| 
      
 143 
     | 
    
         
            +
                    1. Filenames must start with the locale.
         
     | 
| 
      
 144 
     | 
    
         
            +
                    2. An underscore must separate the locale with any optional text that follows.
         
     | 
| 
      
 145 
     | 
    
         
            +
                    3. The file must only contain translation data for the single locale.
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                    Example:
         
     | 
| 
      
 148 
     | 
    
         
            +
                    "/config/locales/fr.yml" which contains:
         
     | 
| 
      
 149 
     | 
    
         
            +
                    ```yml
         
     | 
| 
      
 150 
     | 
    
         
            +
                      fr:
         
     | 
| 
      
 151 
     | 
    
         
            +
                        dog:
         
     | 
| 
      
 152 
     | 
    
         
            +
                          chien
         
     | 
| 
      
 153 
     | 
    
         
            +
                    ```
         
     | 
| 
      
 154 
     | 
    
         
            +
                  MSG
         
     | 
| 
      
 155 
     | 
    
         
            +
                end
         
     | 
| 
      
 156 
     | 
    
         
            +
              end
         
     | 
| 
      
 157 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/i18n/gettext/helpers.rb
    CHANGED
    
    | 
         @@ -1,4 +1,5 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #  
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       2 
3 
     | 
    
         
             
            require 'i18n/gettext'
         
     | 
| 
       3 
4 
     | 
    
         | 
| 
       4 
5 
     | 
    
         
             
            module I18n
         
     | 
| 
         @@ -6,10 +7,19 @@ module I18n 
     | 
|
| 
       6 
7 
     | 
    
         
             
                # Implements classical Gettext style accessors. To use this include the
         
     | 
| 
       7 
8 
     | 
    
         
             
                # module to the global namespace or wherever you want to use it.
         
     | 
| 
       8 
9 
     | 
    
         
             
                #
         
     | 
| 
       9 
     | 
    
         
            -
                #   include I18n::Helpers 
     | 
| 
      
 10 
     | 
    
         
            +
                #   include I18n::Gettext::Helpers
         
     | 
| 
       10 
11 
     | 
    
         
             
                module Helpers
         
     | 
| 
       11 
     | 
    
         
            -
                   
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
      
 12 
     | 
    
         
            +
                  # Makes dynamic translation messages readable for the gettext parser.
         
     | 
| 
      
 13 
     | 
    
         
            +
                  # <tt>_(fruit)</tt> cannot be understood by the gettext parser. To help the parser find all your translations,
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # you can add <tt>fruit = N_("Apple")</tt> which does not translate, but tells the parser: "Apple" needs translation.
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # * msgid: the message id.
         
     | 
| 
      
 16 
     | 
    
         
            +
                  # * Returns: msgid.
         
     | 
| 
      
 17 
     | 
    
         
            +
                  def N_(msgsid)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    msgsid
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def gettext(msgid, options = EMPTY_HASH)
         
     | 
| 
      
 22 
     | 
    
         
            +
                    I18n.t(msgid, **{:default => msgid, :separator => '|'}.merge(options))
         
     | 
| 
       13 
23 
     | 
    
         
             
                  end
         
     | 
| 
       14 
24 
     | 
    
         
             
                  alias _ gettext
         
     | 
| 
       15 
25 
     | 
    
         | 
| 
         @@ -28,7 +28,7 @@ module_eval <<'..end src/poparser.ry modeval..id7a99570e05', 'src/poparser.ry', 
     | 
|
| 
       28 
28 
     | 
    
         
             
                ret.gsub!(/\\"/, "\"")
         
     | 
| 
       29 
29 
     | 
    
         
             
                ret
         
     | 
| 
       30 
30 
     | 
    
         
             
              end
         
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
       32 
32 
     | 
    
         
             
              def parse(str, data, ignore_fuzzy = true)
         
     | 
| 
       33 
33 
     | 
    
         
             
                @comments = []
         
     | 
| 
       34 
34 
     | 
    
         
             
                @data = data
         
     | 
| 
         @@ -64,7 +64,7 @@ module_eval <<'..end src/poparser.ry modeval..id7a99570e05', 'src/poparser.ry', 
     | 
|
| 
       64 
64 
     | 
    
         
             
            	str = $'
         
     | 
| 
       65 
65 
     | 
    
         
             
                  when /\A\#(.*)/
         
     | 
| 
       66 
66 
     | 
    
         
             
            	@q.push [:COMMENT, $&]
         
     | 
| 
       67 
     | 
    
         
            -
            	str = $' 
     | 
| 
      
 67 
     | 
    
         
            +
            	str = $'
         
     | 
| 
       68 
68 
     | 
    
         
             
                  when /\A\"(.*)\"/
         
     | 
| 
       69 
69 
     | 
    
         
             
            	@q.push [:STRING, $1]
         
     | 
| 
       70 
70 
     | 
    
         
             
            	str = $'
         
     | 
| 
         @@ -73,7 +73,7 @@ module_eval <<'..end src/poparser.ry modeval..id7a99570e05', 'src/poparser.ry', 
     | 
|
| 
       73 
73 
     | 
    
         
             
            	#@q.push [:STRING, c]
         
     | 
| 
       74 
74 
     | 
    
         
             
            	str = str[1..-1]
         
     | 
| 
       75 
75 
     | 
    
         
             
                  end
         
     | 
| 
       76 
     | 
    
         
            -
                end 
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
       77 
77 
     | 
    
         
             
                @q.push [false, '$end']
         
     | 
| 
       78 
78 
     | 
    
         
             
                if $DEBUG
         
     | 
| 
       79 
79 
     | 
    
         
             
                  @q.each do |a,b|
         
     | 
| 
         @@ -88,7 +88,7 @@ module_eval <<'..end src/poparser.ry modeval..id7a99570e05', 'src/poparser.ry', 
     | 
|
| 
       88 
88 
     | 
    
         
             
                end
         
     | 
| 
       89 
89 
     | 
    
         
             
                @data
         
     | 
| 
       90 
90 
     | 
    
         
             
              end
         
     | 
| 
       91 
     | 
    
         
            -
             
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
       92 
92 
     | 
    
         
             
              def next_token
         
     | 
| 
       93 
93 
     | 
    
         
             
                @q.shift
         
     | 
| 
       94 
94 
     | 
    
         
             
              end
         
     | 
| 
         @@ -101,11 +101,11 @@ module_eval <<'..end src/poparser.ry modeval..id7a99570e05', 'src/poparser.ry', 
     | 
|
| 
       101 
101 
     | 
    
         
             
                @comments.clear
         
     | 
| 
       102 
102 
     | 
    
         
             
                @msgctxt = ""
         
     | 
| 
       103 
103 
     | 
    
         
             
              end
         
     | 
| 
       104 
     | 
    
         
            -
             
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
       105 
105 
     | 
    
         
             
              def on_comment(comment)
         
     | 
| 
       106 
106 
     | 
    
         
             
                @fuzzy = true if (/fuzzy/ =~ comment)
         
     | 
| 
       107 
107 
     | 
    
         
             
                @comments << comment
         
     | 
| 
       108 
     | 
    
         
            -
              end 
     | 
| 
      
 108 
     | 
    
         
            +
              end
         
     | 
| 
       109 
109 
     | 
    
         | 
| 
       110 
110 
     | 
    
         | 
| 
       111 
111 
     | 
    
         
             
            ..end src/poparser.ry modeval..id7a99570e05
         
     | 
| 
         @@ -245,7 +245,7 @@ module_eval <<'.,.,', 'src/poparser.ry', 25 
     | 
|
| 
       245 
245 
     | 
    
         | 
| 
       246 
246 
     | 
    
         
             
            module_eval <<'.,.,', 'src/poparser.ry', 48
         
     | 
| 
       247 
247 
     | 
    
         
             
              def _reduce_8( val, _values, result )
         
     | 
| 
       248 
     | 
    
         
            -
                if @fuzzy and $ignore_fuzzy 
     | 
| 
      
 248 
     | 
    
         
            +
                if @fuzzy and $ignore_fuzzy
         
     | 
| 
       249 
249 
     | 
    
         
             
                  if val[1] != ""
         
     | 
| 
       250 
250 
     | 
    
         
             
                    $stderr.print _("Warning: fuzzy message was ignored.\n")
         
     | 
| 
       251 
251 
     | 
    
         
             
                    $stderr.print "         msgid '#{val[1]}'\n"
         
     | 
    
        data/lib/i18n/gettext.rb
    CHANGED
    
    | 
         @@ -1,4 +1,4 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            #  
     | 
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
       2 
2 
     | 
    
         | 
| 
       3 
3 
     | 
    
         
             
            module I18n
         
     | 
| 
       4 
4 
     | 
    
         
             
              module Gettext
         
     | 
| 
         @@ -10,11 +10,12 @@ module I18n 
     | 
|
| 
       10 
10 
     | 
    
         
             
                @@plural_keys = { :en => [:one, :other] }
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
12 
     | 
    
         
             
                class << self
         
     | 
| 
       13 
     | 
    
         
            -
                  # returns an array of plural keys for the given locale  
     | 
| 
       14 
     | 
    
         
            -
                  # convert from gettext's 
     | 
| 
      
 13 
     | 
    
         
            +
                  # returns an array of plural keys for the given locale or the whole hash
         
     | 
| 
      
 14 
     | 
    
         
            +
                  # of locale mappings to plural keys so that we can convert from gettext's
         
     | 
| 
      
 15 
     | 
    
         
            +
                  # integer-index based style
         
     | 
| 
       15 
16 
     | 
    
         
             
                  # TODO move this information to the pluralization module
         
     | 
| 
       16 
     | 
    
         
            -
                  def plural_keys( 
     | 
| 
       17 
     | 
    
         
            -
                    @@plural_keys[ 
     | 
| 
      
 17 
     | 
    
         
            +
                  def plural_keys(*args)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    args.empty? ? @@plural_keys : @@plural_keys[args.first] || @@plural_keys[:en]
         
     | 
| 
       18 
19 
     | 
    
         
             
                  end
         
     | 
| 
       19 
20 
     | 
    
         | 
| 
       20 
21 
     | 
    
         
             
                  def extract_scope(msgid, separator)
         
     | 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            # heavily based on Masao Mutoh's gettext String interpolation extension
         
     | 
| 
      
 4 
     | 
    
         
            +
            # http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module I18n
         
     | 
| 
      
 7 
     | 
    
         
            +
              DEFAULT_INTERPOLATION_PATTERNS = [
         
     | 
| 
      
 8 
     | 
    
         
            +
                /%%/,
         
     | 
| 
      
 9 
     | 
    
         
            +
                /%\{([\w|]+)\}/,                            # matches placeholders like "%{foo} or %{foo|word}"
         
     | 
| 
      
 10 
     | 
    
         
            +
                /%<(\w+)>([^\d]*?\d*\.?\d*[bBdiouxXeEfgGcps])/  # matches placeholders like "%<foo>.d"
         
     | 
| 
      
 11 
     | 
    
         
            +
              ].freeze
         
     | 
| 
      
 12 
     | 
    
         
            +
              INTERPOLATION_PATTERN = Regexp.union(DEFAULT_INTERPOLATION_PATTERNS)
         
     | 
| 
      
 13 
     | 
    
         
            +
              deprecate_constant :INTERPOLATION_PATTERN
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              INTERPOLATION_PATTERNS_CACHE = Hash.new do |hash, patterns|
         
     | 
| 
      
 16 
     | 
    
         
            +
                hash[patterns] = Regexp.union(patterns)
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
              private_constant :INTERPOLATION_PATTERNS_CACHE
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 21 
     | 
    
         
            +
                # Return String or raises MissingInterpolationArgument exception.
         
     | 
| 
      
 22 
     | 
    
         
            +
                # Missing argument's logic is handled by I18n.config.missing_interpolation_argument_handler.
         
     | 
| 
      
 23 
     | 
    
         
            +
                def interpolate(string, values)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  raise ReservedInterpolationKey.new($1.to_sym, string) if string =~ I18n.reserved_keys_pattern
         
     | 
| 
      
 25 
     | 
    
         
            +
                  raise ArgumentError.new('Interpolation values must be a Hash.') unless values.kind_of?(Hash)
         
     | 
| 
      
 26 
     | 
    
         
            +
                  interpolate_hash(string, values)
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def interpolate_hash(string, values)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  pattern = INTERPOLATION_PATTERNS_CACHE[config.interpolation_patterns]
         
     | 
| 
      
 31 
     | 
    
         
            +
                  interpolated = false
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  interpolated_string = string.gsub(pattern) do |match|
         
     | 
| 
      
 34 
     | 
    
         
            +
                    interpolated = true
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                    if match == '%%'
         
     | 
| 
      
 37 
     | 
    
         
            +
                      '%'
         
     | 
| 
      
 38 
     | 
    
         
            +
                    else
         
     | 
| 
      
 39 
     | 
    
         
            +
                      key = ($1 || $2 || match.tr("%{}", "")).to_sym
         
     | 
| 
      
 40 
     | 
    
         
            +
                      value = if values.key?(key)
         
     | 
| 
      
 41 
     | 
    
         
            +
                                values[key]
         
     | 
| 
      
 42 
     | 
    
         
            +
                              else
         
     | 
| 
      
 43 
     | 
    
         
            +
                                config.missing_interpolation_argument_handler.call(key, values, string)
         
     | 
| 
      
 44 
     | 
    
         
            +
                              end
         
     | 
| 
      
 45 
     | 
    
         
            +
                      value = value.call(values) if value.respond_to?(:call)
         
     | 
| 
      
 46 
     | 
    
         
            +
                      $3 ? sprintf("%#{$3}", value) : value
         
     | 
| 
      
 47 
     | 
    
         
            +
                    end
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  interpolated ? interpolated_string : string
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     |