i18n 1.11.0 → 1.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fec00bc17a2d4f9845a6bf1394deefaab31a14460c440d5012db8939d4de2d19
4
- data.tar.gz: d5b2c057789154f3db274d6c0612dec850c2af96127c37204ac81308636ca841
3
+ metadata.gz: e85066f2cf6bbf170ff946391c6037d0335e5314d0c1e0723e980d5ee7df7af0
4
+ data.tar.gz: 2a4629aa0644c2a6e8cc5d175d4912b5f5cd4abc066dd5ee196270b7a3eadd08
5
5
  SHA512:
6
- metadata.gz: 468a6a2336896a0f5185350c16a49929e27b2201efe92bc5d067a7a03787bfa814bbe2de838be78205d870961e023633d8dbd494f488b1a6d77773082ed442de
7
- data.tar.gz: d6fb232b7a711de31cbc3ce93a624a858684c3f8258eb558774b36da2aa2a0ba9baa6bf6c65901cbdfc06f44b6810c383e6c0dd47eb1569c4ddb07394332f81d
6
+ metadata.gz: '01326189eb7b675594bd63c802ae9470135e9aab222de4df1429c99c585b9b59b172ed62386c03b82fd45c862bbb42484dc89e0289c83970315f9a5fa03ba91c'
7
+ data.tar.gz: 290489ae277759fe65197e65d6486b7cca67605c2c98197a472c91bb2496d9db168dfd2082706b87f6f806051827b8df12cc0037258f3bf10d5f74a9ddb9f575
data/README.md CHANGED
@@ -26,7 +26,7 @@ gem 'i18n'
26
26
  Then configure I18n with some translations, and a default locale:
27
27
 
28
28
  ```ruby
29
- I18n.load_path << Dir[File.expand_path("config/locales") + "/*.yml"]
29
+ I18n.load_path += Dir[File.expand_path("config/locales") + "/*.yml"]
30
30
  I18n.default_locale = :en # (note that `en` is already the default!)
31
31
  ```
32
32
 
@@ -54,7 +54,7 @@ module I18n
54
54
  end
55
55
 
56
56
  deep_interpolation = options[:deep_interpolation]
57
- values = Utils.except(options, *RESERVED_KEYS)
57
+ values = Utils.except(options, *RESERVED_KEYS) unless options.empty?
58
58
  if values
59
59
  entry = if deep_interpolation
60
60
  deep_interpolate(locale, entry, values)
@@ -66,7 +66,7 @@ module I18n
66
66
  end
67
67
 
68
68
  def exists?(locale, key, options = EMPTY_HASH)
69
- lookup(locale, key) != nil
69
+ lookup(locale, key, options[:scope]) != nil
70
70
  end
71
71
 
72
72
  # Acts the same as +strftime+, but uses a localized version of the
@@ -123,7 +123,12 @@ module I18n
123
123
  # first translation that can be resolved. Otherwise it tries to resolve
124
124
  # the translation directly.
125
125
  def default(locale, object, subject, options = EMPTY_HASH)
126
- options = options.reject { |key, value| key == :default }
126
+ if options.size == 1 && options.has_key?(:default)
127
+ options = {}
128
+ else
129
+ options = Utils.except(options, :default)
130
+ end
131
+
127
132
  case subject
128
133
  when Array
129
134
  subject.each do |item|
@@ -166,7 +171,7 @@ module I18n
166
171
  # Other backends can implement more flexible or complex pluralization rules.
167
172
  def pluralize(locale, entry, count)
168
173
  entry = entry.reject { |k, _v| k == :attributes } if entry.is_a?(Hash)
169
- return entry unless entry.is_a?(Hash) && count && entry.values.none? { |v| v.is_a?(Hash) }
174
+ return entry unless entry.is_a?(Hash) && count
170
175
 
171
176
  key = pluralization_key(entry, count)
172
177
  raise InvalidPluralizationData.new(entry, count, key) unless entry.has_key?(key)
@@ -282,8 +287,8 @@ module I18n
282
287
  when '%^b' then I18n.t!(:"date.abbr_month_names", :locale => locale, :format => format)[object.mon].upcase
283
288
  when '%B' then I18n.t!(:"date.month_names", :locale => locale, :format => format)[object.mon]
284
289
  when '%^B' then I18n.t!(:"date.month_names", :locale => locale, :format => format)[object.mon].upcase
285
- when '%p' then I18n.t!(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format).upcase if object.respond_to? :hour
286
- when '%P' then I18n.t!(:"time.#{object.hour < 12 ? :am : :pm}", :locale => locale, :format => format).downcase if object.respond_to? :hour
290
+ when '%p' then I18n.t!(:"time.#{(object.respond_to?(:hour) ? object.hour : 0) < 12 ? :am : :pm}", :locale => locale, :format => format).upcase
291
+ when '%P' then I18n.t!(:"time.#{(object.respond_to?(:hour) ? object.hour : 0) < 12 ? :am : :pm}", :locale => locale, :format => format).downcase
287
292
  end
288
293
  end
289
294
  rescue MissingTranslationData => e
@@ -41,6 +41,12 @@ module I18n
41
41
 
42
42
  pluralizer = pluralizer(locale)
43
43
  if pluralizer.respond_to?(:call)
44
+ # Deprecation: The use of the `zero` key in this way is incorrect.
45
+ # Users that want a different string for the case of `count == 0` should use the explicit "0" key instead.
46
+ # We keep this incorrect behaviour for now for backwards compatibility until we can remove it.
47
+ # Ref: https://github.com/ruby-i18n/i18n/issues/629
48
+ return entry[:zero] if count == 0 && entry.has_key?(:zero)
49
+
44
50
  # "0" and "1" are special cases
45
51
  # https://unicode-org.github.io/cldr/ldml/tr35-numbers.html#Explicit_0_1_rules
46
52
  if count == 0 || count == 1
@@ -21,6 +21,9 @@ module I18n
21
21
  class Simple
22
22
  module Implementation
23
23
  include Base
24
+
25
+ # Mutex to ensure that concurrent translations loading will be thread-safe
26
+ MUTEX = Mutex.new
24
27
 
25
28
  def initialized?
26
29
  @initialized ||= false
@@ -68,7 +71,11 @@ module I18n
68
71
  # call `init_translations`
69
72
  init_translations if do_init && !initialized?
70
73
 
71
- @translations ||= Concurrent::Hash.new { |h, k| h[k] = Concurrent::Hash.new }
74
+ @translations ||= Concurrent::Hash.new do |h, k|
75
+ MUTEX.synchronize do
76
+ h[k] = Concurrent::Hash.new
77
+ end
78
+ end
72
79
  end
73
80
 
74
81
  protected
@@ -94,7 +101,7 @@ module I18n
94
101
  return nil unless result.has_key?(_key)
95
102
  end
96
103
  result = result[_key]
97
- result = resolve_entry(locale, _key, result, options.merge(:scope => nil)) if result.is_a?(Symbol)
104
+ result = resolve_entry(locale, _key, result, Utils.except(options.merge(:scope => nil), :count)) if result.is_a?(Symbol)
98
105
  result
99
106
  end
100
107
  end
@@ -45,30 +45,30 @@ module I18n
45
45
  "Ç"=>"C", "È"=>"E", "É"=>"E", "Ê"=>"E", "Ë"=>"E", "Ì"=>"I", "Í"=>"I",
46
46
  "Î"=>"I", "Ï"=>"I", "Ð"=>"D", "Ñ"=>"N", "Ò"=>"O", "Ó"=>"O", "Ô"=>"O",
47
47
  "Õ"=>"O", "Ö"=>"O", "×"=>"x", "Ø"=>"O", "Ù"=>"U", "Ú"=>"U", "Û"=>"U",
48
- "Ü"=>"U", "Ý"=>"Y", "Þ"=>"Th", "ß"=>"ss", "à"=>"a", "á"=>"a", "â"=>"a",
49
- "ã"=>"a", "ä"=>"a", "å"=>"a", "æ"=>"ae", "ç"=>"c", "è"=>"e", "é"=>"e",
50
- "ê"=>"e", "ë"=>"e", "ì"=>"i", "í"=>"i", "î"=>"i", "ï"=>"i", "ð"=>"d",
51
- "ñ"=>"n", "ò"=>"o", "ó"=>"o", "ô"=>"o", "õ"=>"o", "ö"=>"o", "ø"=>"o",
52
- "ù"=>"u", "ú"=>"u", "û"=>"u", "ü"=>"u", "ý"=>"y", "þ"=>"th", "ÿ"=>"y",
53
- "Ā"=>"A", "ā"=>"a", "Ă"=>"A", "ă"=>"a", "Ą"=>"A", "ą"=>"a", "Ć"=>"C",
54
- "ć"=>"c", "Ĉ"=>"C", "ĉ"=>"c", "Ċ"=>"C", "ċ"=>"c", "Č"=>"C", "č"=>"c",
55
- "Ď"=>"D", "ď"=>"d", "Đ"=>"D", "đ"=>"d", "Ē"=>"E", "ē"=>"e", "Ĕ"=>"E",
56
- "ĕ"=>"e", "Ė"=>"E", "ė"=>"e", "Ę"=>"E", "ę"=>"e", "Ě"=>"E", "ě"=>"e",
57
- "Ĝ"=>"G", "ĝ"=>"g", "Ğ"=>"G", "ğ"=>"g", "Ġ"=>"G", "ġ"=>"g", "Ģ"=>"G",
58
- "ģ"=>"g", "Ĥ"=>"H", "ĥ"=>"h", "Ħ"=>"H", "ħ"=>"h", "Ĩ"=>"I", "ĩ"=>"i",
59
- "Ī"=>"I", "ī"=>"i", "Ĭ"=>"I", "ĭ"=>"i", "Į"=>"I", "į"=>"i", "İ"=>"I",
60
- "ı"=>"i", "IJ"=>"IJ", "ij"=>"ij", "Ĵ"=>"J", "ĵ"=>"j", "Ķ"=>"K", "ķ"=>"k",
61
- "ĸ"=>"k", "Ĺ"=>"L", "ĺ"=>"l", "Ļ"=>"L", "ļ"=>"l", "Ľ"=>"L", "ľ"=>"l",
62
- "Ŀ"=>"L", "ŀ"=>"l", "Ł"=>"L", "ł"=>"l", "Ń"=>"N", "ń"=>"n", "Ņ"=>"N",
63
- "ņ"=>"n", "Ň"=>"N", "ň"=>"n", "ʼn"=>"'n", "Ŋ"=>"NG", "ŋ"=>"ng",
64
- "Ō"=>"O", "ō"=>"o", "Ŏ"=>"O", "ŏ"=>"o", "Ő"=>"O", "ő"=>"o", "Œ"=>"OE",
65
- "œ"=>"oe", "Ŕ"=>"R", "ŕ"=>"r", "Ŗ"=>"R", "ŗ"=>"r", "Ř"=>"R", "ř"=>"r",
66
- "Ś"=>"S", "ś"=>"s", "Ŝ"=>"S", "ŝ"=>"s", "Ş"=>"S", "ş"=>"s", "Š"=>"S",
67
- "š"=>"s", "Ţ"=>"T", "ţ"=>"t", "Ť"=>"T", "ť"=>"t", "Ŧ"=>"T", "ŧ"=>"t",
68
- "Ũ"=>"U", "ũ"=>"u", "Ū"=>"U", "ū"=>"u", "Ŭ"=>"U", "ŭ"=>"u", "Ů"=>"U",
69
- "ů"=>"u", "Ű"=>"U", "ű"=>"u", "Ų"=>"U", "ų"=>"u", "Ŵ"=>"W", "ŵ"=>"w",
70
- "Ŷ"=>"Y", "ŷ"=>"y", "Ÿ"=>"Y", "Ź"=>"Z", "ź"=>"z", "Ż"=>"Z", "ż"=>"z",
71
- "Ž"=>"Z", "ž"=>"z"
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
72
  }.freeze
73
73
 
74
74
  def initialize(rule = nil)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # heavily based on Masao Mutoh's gettext String interpolation extension
2
4
  # http://github.com/mutoh/gettext/blob/f6566738b981fe0952548c421042ad1e0cdfb31e/lib/gettext/core_ext/string.rb
3
5
 
@@ -10,6 +12,11 @@ module I18n
10
12
  INTERPOLATION_PATTERN = Regexp.union(DEFAULT_INTERPOLATION_PATTERNS)
11
13
  deprecate_constant :INTERPOLATION_PATTERN
12
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
+
13
20
  class << self
14
21
  # Return String or raises MissingInterpolationArgument exception.
15
22
  # Missing argument's logic is handled by I18n.config.missing_interpolation_argument_handler.
@@ -20,7 +27,12 @@ module I18n
20
27
  end
21
28
 
22
29
  def interpolate_hash(string, values)
23
- string.gsub(Regexp.union(config.interpolation_patterns)) do |match|
30
+ pattern = INTERPOLATION_PATTERNS_CACHE[config.interpolation_patterns]
31
+ interpolated = false
32
+
33
+ interpolated_string = string.gsub(pattern) do |match|
34
+ interpolated = true
35
+
24
36
  if match == '%%'
25
37
  '%'
26
38
  else
@@ -34,6 +46,8 @@ module I18n
34
46
  $3 ? sprintf("%#{$3}", value) : value
35
47
  end
36
48
  end
49
+
50
+ interpolated ? interpolated_string : string
37
51
  end
38
52
  end
39
53
  end
@@ -34,6 +34,11 @@ module I18n
34
34
  assert_equal 'Sa', I18n.l(@date, :format => '%a', :locale => :de)
35
35
  end
36
36
 
37
+ test "localize Date: given an meridian indicator format it returns the correct meridian indicator" do
38
+ assert_equal 'AM', I18n.l(@date, :format => '%p', :locale => :de)
39
+ assert_equal 'am', I18n.l(@date, :format => '%P', :locale => :de)
40
+ end
41
+
37
42
  test "localize Date: given an abbreviated and uppercased day name format it returns the correct abbreviated day name in upcase" do
38
43
  assert_equal 'sa'.upcase, I18n.l(@date, :format => '%^a', :locale => :de)
39
44
  end
data/lib/i18n/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module I18n
4
- VERSION = "1.11.0"
4
+ VERSION = "1.13.0"
5
5
  end
data/lib/i18n.rb CHANGED
@@ -331,12 +331,11 @@ module I18n
331
331
  # keys are Symbols.
332
332
  def normalize_keys(locale, key, scope, separator = nil)
333
333
  separator ||= I18n.default_separator
334
+ locale = locale.to_sym if locale
334
335
 
335
- [
336
- *normalize_key(locale, separator),
337
- *normalize_key(scope, separator),
338
- *normalize_key(key, separator)
339
- ]
336
+ result = [locale]
337
+ result.concat(normalize_key(scope, separator)) if scope
338
+ result.concat(normalize_key(key, separator))
340
339
  end
341
340
 
342
341
  # Returns true when the passed locale, which can be either a String or a
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.11.0
4
+ version: 1.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2022-07-10 00:00:00.000000000 Z
16
+ date: 2023-04-26 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: concurrent-ruby