i18n 1.14.4 → 1.14.5

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: ef99abbb2ed698cd9dd77ab484720a5ecf68be96a7064f2f8b432a69758ada07
4
- data.tar.gz: 0a4ade5577fe636c03d6ef9ca11f7a26b80a5c58078ee87c2f9dcf9fdd6882de
3
+ metadata.gz: 8e29c720198c6fd20a8ec55a99ad4ce81c2ff09abf74a55ee6e09513ac17546c
4
+ data.tar.gz: 6ad9b851da6ba7c857dbd79b9e817493f7eaba91be46f16cec3a86cb94c32c11
5
5
  SHA512:
6
- metadata.gz: 21b666c06e7c8ebdb78088ef2ecd8da866ebd414dff3f3a8535b3e950c12bf0f38695a22acac6da7775e8e245c7a99a0d1d9a6bc409e0ea3d552520a0be26f68
7
- data.tar.gz: c5f81a0bafbf70daa4a2c4374f3906ef31cea1d8f94d5d5e9b980224d1b6bc75f95cdd3e08709f6cae410c34f4285deb375d7e5b06e19f283743221606e23434
6
+ metadata.gz: 7de3901b122039da2a99507e40dbe5e57ce8e5622c14591ebf251adf563c763f55d2f1fb1bc7d54c5f2be427a37b81839e636de7eee434a53ab80a39c4f8bf53
7
+ data.tar.gz: 1bfd4bd7c5dd8de6df524ae64d652e2f785955a1928bd3bca66e3ba8515e2d4d60c83ff576c51ca84e744625874145c0850f301b8d2fd6090c226541ad389575
@@ -188,8 +188,8 @@ module I18n
188
188
  #
189
189
  # if the given subject is an array then:
190
190
  # each element of the array is recursively interpolated (until it finds a string)
191
- # method interpolates ["yes, %{user}", ["maybe no, %{user}, "no, %{user}"]], :user => "bartuz"
192
- # # => "["yes, bartuz",["maybe no, bartuz", "no, bartuz"]]"
191
+ # method interpolates ["yes, %{user}", ["maybe no, %{user}", "no, %{user}"]], :user => "bartuz"
192
+ # # => ["yes, bartuz", ["maybe no, bartuz", "no, bartuz"]]
193
193
  def interpolate(locale, subject, values = EMPTY_HASH)
194
194
  return subject if values.empty?
195
195
 
@@ -90,11 +90,13 @@ module I18n
90
90
  protected
91
91
 
92
92
  def compute(tags, include_defaults = true, exclude = [])
93
- result = Array(tags).flat_map do |tag|
93
+ result = []
94
+ Array(tags).each do |tag|
94
95
  tags = I18n::Locale::Tag.tag(tag).self_and_parents.map! { |t| t.to_sym } - exclude
95
- tags.each { |_tag| tags += compute(@map[_tag], false, exclude + tags) if @map[_tag] }
96
- tags
96
+ result += tags
97
+ tags.each { |_tag| result += compute(@map[_tag], false, exclude + result) if @map[_tag] }
97
98
  end
99
+
98
100
  result.push(*defaults) if include_defaults
99
101
  result.uniq!
100
102
  result.compact!
@@ -118,6 +118,24 @@ module I18n
118
118
  assert_raises(I18n::ReservedInterpolationKey) { interpolate(:interpolate) }
119
119
  end
120
120
 
121
+ test "interpolation: it does not raise I18n::ReservedInterpolationKey for escaped variables" do
122
+ assert_nothing_raised do
123
+ assert_equal '%{separator}', interpolate(:foo => :bar, :default => '%%{separator}')
124
+ end
125
+
126
+ # Note: The two interpolations below do not remove the escape character (%) because
127
+ # I18n should not alter the strings when no interpolation parameters are given,
128
+ # see the comment at the top of this file.
129
+ assert_nothing_raised do
130
+ assert_equal '%%{scope}', interpolate(:default => '%%{scope}')
131
+ end
132
+
133
+ I18n.backend.store_translations(:en, :interpolate => 'Hi %%{scope}!')
134
+ assert_nothing_raised do
135
+ assert_equal 'Hi %%{scope}!', interpolate(:interpolate)
136
+ end
137
+ end
138
+
121
139
  test "interpolation: deep interpolation for default string" do
122
140
  assert_equal 'Hi %{name}!', interpolate(:default => 'Hi %{name}!', :deep_interpolation => true)
123
141
  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.14.4"
4
+ VERSION = "1.14.5"
5
5
  end
data/lib/i18n.rb CHANGED
@@ -48,7 +48,7 @@ module I18n
48
48
  end
49
49
 
50
50
  def self.reserved_keys_pattern # :nodoc:
51
- @reserved_keys_pattern ||= /%\{(#{RESERVED_KEYS.join("|")})\}/
51
+ @reserved_keys_pattern ||= /(?<!%)%\{(#{RESERVED_KEYS.join("|")})\}/
52
52
  end
53
53
 
54
54
  module Base
@@ -231,6 +231,35 @@ module I18n
231
231
  end
232
232
  alias :t! :translate!
233
233
 
234
+ # Returns an array of interpolation keys for the given translation key
235
+ #
236
+ # *Examples*
237
+ #
238
+ # Suppose we have the following:
239
+ # I18n.t 'example.zero' == 'Zero interpolations'
240
+ # I18n.t 'example.one' == 'One interpolation %{foo}'
241
+ # I18n.t 'example.two' == 'Two interpolations %{foo} %{bar}'
242
+ # I18n.t 'example.three' == ['One %{foo}', 'Two %{bar}', 'Three %{baz}']
243
+ # I18n.t 'example.one', locale: :other == 'One interpolation %{baz}'
244
+ #
245
+ # Then we can expect the following results:
246
+ # I18n.interpolation_keys('example.zero') #=> []
247
+ # I18n.interpolation_keys('example.one') #=> ['foo']
248
+ # I18n.interpolation_keys('example.two') #=> ['foo', 'bar']
249
+ # I18n.interpolation_keys('example.three') #=> ['foo', 'bar', 'baz']
250
+ # I18n.interpolation_keys('one', scope: 'example', locale: :other) #=> ['baz']
251
+ # I18n.interpolation_keys('does-not-exist') #=> []
252
+ # I18n.interpolation_keys('example') #=> []
253
+ def interpolation_keys(key, **options)
254
+ raise I18n::ArgumentError if !key.is_a?(String) || key.empty?
255
+
256
+ return [] unless exists?(key, **options.slice(:locale, :scope))
257
+
258
+ translation = translate(key, **options.slice(:locale, :scope))
259
+ interpolation_keys_from_translation(translation)
260
+ .flatten.compact
261
+ end
262
+
234
263
  # Returns true if a translation exists for a given key, otherwise returns false.
235
264
  def exists?(key, _locale = nil, locale: _locale, **options)
236
265
  locale ||= config.locale
@@ -429,6 +458,17 @@ module I18n
429
458
  keys
430
459
  end
431
460
  end
461
+
462
+ def interpolation_keys_from_translation(translation)
463
+ case translation
464
+ when ::String
465
+ translation.scan(Regexp.union(I18n.config.interpolation_patterns))
466
+ when ::Array
467
+ translation.map { |element| interpolation_keys_from_translation(element) }
468
+ else
469
+ []
470
+ end
471
+ end
432
472
  end
433
473
 
434
474
  extend Base
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.14.4
4
+ version: 1.14.5
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: 2024-03-06 00:00:00.000000000 Z
16
+ date: 2024-05-06 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: concurrent-ruby