r18n-core 3.1.1 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/ChangeLog.md +398 -0
  3. data/README.md +63 -47
  4. data/base/cy.yml +34 -0
  5. data/lib/r18n-core.rb +37 -38
  6. data/lib/r18n-core/filter_list.rb +21 -13
  7. data/lib/r18n-core/filters.rb +43 -48
  8. data/lib/r18n-core/helpers.rb +2 -2
  9. data/lib/r18n-core/i18n.rb +70 -78
  10. data/lib/r18n-core/locale.rb +137 -107
  11. data/lib/r18n-core/locales/af.rb +36 -0
  12. data/lib/r18n-core/locales/az.rb +38 -0
  13. data/lib/r18n-core/locales/bg.rb +29 -0
  14. data/{locales → lib/r18n-core/locales}/ca.rb +9 -6
  15. data/{locales → lib/r18n-core/locales}/cs.rb +15 -11
  16. data/lib/r18n-core/locales/cy.rb +50 -0
  17. data/{locales → lib/r18n-core/locales}/da.rb +10 -7
  18. data/lib/r18n-core/locales/de.rb +33 -0
  19. data/{locales → lib/r18n-core/locales}/en-au.rb +2 -2
  20. data/{locales → lib/r18n-core/locales}/en-gb.rb +2 -2
  21. data/{locales → lib/r18n-core/locales}/en-us.rb +4 -3
  22. data/lib/r18n-core/locales/en.rb +51 -0
  23. data/{locales → lib/r18n-core/locales}/eo.rb +6 -4
  24. data/lib/r18n-core/locales/es-cl.rb +16 -0
  25. data/{locales → lib/r18n-core/locales}/es-us.rb +5 -4
  26. data/{locales → lib/r18n-core/locales}/es.rb +7 -3
  27. data/{locales → lib/r18n-core/locales}/fa.rb +2 -2
  28. data/lib/r18n-core/locales/fi.rb +39 -0
  29. data/lib/r18n-core/locales/fr.rb +39 -0
  30. data/{locales → lib/r18n-core/locales}/gl.rb +5 -3
  31. data/{locales → lib/r18n-core/locales}/hr.rb +13 -10
  32. data/{locales → lib/r18n-core/locales}/hu.rb +10 -7
  33. data/{locales → lib/r18n-core/locales}/id.rb +8 -4
  34. data/lib/r18n-core/locales/it.rb +37 -0
  35. data/{locales → lib/r18n-core/locales}/ja.rb +5 -4
  36. data/{locales → lib/r18n-core/locales}/kk.rb +12 -8
  37. data/{locales → lib/r18n-core/locales}/ko.rb +0 -0
  38. data/lib/r18n-core/locales/lv.rb +46 -0
  39. data/lib/r18n-core/locales/mn.rb +30 -0
  40. data/{locales → lib/r18n-core/locales}/nb.rb +6 -4
  41. data/lib/r18n-core/locales/nl.rb +31 -0
  42. data/{locales → lib/r18n-core/locales}/no.rb +0 -0
  43. data/lib/r18n-core/locales/pl.rb +45 -0
  44. data/{locales → lib/r18n-core/locales}/pt-br.rb +1 -1
  45. data/lib/r18n-core/locales/pt.rb +37 -0
  46. data/lib/r18n-core/locales/ru.rb +46 -0
  47. data/{locales → lib/r18n-core/locales}/sk.rb +13 -9
  48. data/{locales → lib/r18n-core/locales}/sr-latn.rb +10 -8
  49. data/{locales → lib/r18n-core/locales}/sv-se.rb +7 -5
  50. data/lib/r18n-core/locales/th.rb +41 -0
  51. data/{locales → lib/r18n-core/locales}/tr.rb +7 -6
  52. data/lib/r18n-core/locales/uk.rb +31 -0
  53. data/lib/r18n-core/locales/vi.rb +37 -0
  54. data/{locales → lib/r18n-core/locales}/zh-cn.rb +2 -2
  55. data/{locales → lib/r18n-core/locales}/zh-tw.rb +4 -4
  56. data/{locales → lib/r18n-core/locales}/zh.rb +7 -4
  57. data/lib/r18n-core/translated.rb +38 -37
  58. data/lib/r18n-core/translated_string.rb +19 -8
  59. data/lib/r18n-core/translation.rb +24 -19
  60. data/lib/r18n-core/unsupported_locale.rb +14 -6
  61. data/lib/r18n-core/untranslated.rb +23 -7
  62. data/lib/r18n-core/utils.rb +19 -23
  63. data/lib/r18n-core/version.rb +1 -1
  64. data/lib/r18n-core/yaml_loader.rb +17 -13
  65. data/lib/r18n-core/yaml_methods.rb +3 -1
  66. metadata +245 -118
  67. data/.rspec +0 -1
  68. data/Rakefile +0 -13
  69. data/locales/af.rb +0 -32
  70. data/locales/az.rb +0 -34
  71. data/locales/bg.rb +0 -25
  72. data/locales/de.rb +0 -29
  73. data/locales/en.rb +0 -48
  74. data/locales/fi.rb +0 -35
  75. data/locales/fr.rb +0 -35
  76. data/locales/it.rb +0 -34
  77. data/locales/lv.rb +0 -41
  78. data/locales/mn.rb +0 -27
  79. data/locales/nl.rb +0 -28
  80. data/locales/pl.rb +0 -40
  81. data/locales/pt.rb +0 -29
  82. data/locales/ru.rb +0 -41
  83. data/locales/th.rb +0 -37
  84. data/locales/uk.rb +0 -27
  85. data/locales/vi.rb +0 -33
  86. data/r18n-core.gemspec +0 -29
  87. data/spec/filters_spec.rb +0 -324
  88. data/spec/i18n_spec.rb +0 -260
  89. data/spec/locale_spec.rb +0 -216
  90. data/spec/locales/cs_spec.rb +0 -23
  91. data/spec/locales/en-us_spec.rb +0 -13
  92. data/spec/locales/en_spec.rb +0 -13
  93. data/spec/locales/fa_spec.rb +0 -10
  94. data/spec/locales/fr_spec.rb +0 -9
  95. data/spec/locales/hu_spec.rb +0 -17
  96. data/spec/locales/it_spec.rb +0 -10
  97. data/spec/locales/no_spec.rb +0 -9
  98. data/spec/locales/pl_spec.rb +0 -23
  99. data/spec/locales/ru_spec.rb +0 -23
  100. data/spec/locales/sk_spec.rb +0 -23
  101. data/spec/locales/th_spec.rb +0 -9
  102. data/spec/locales/vi_spec.rb +0 -8
  103. data/spec/r18n_spec.rb +0 -172
  104. data/spec/spec_helper.rb +0 -41
  105. data/spec/translated_spec.rb +0 -163
  106. data/spec/translation_spec.rb +0 -164
  107. data/spec/translations/extension/deep/en.yml +0 -1
  108. data/spec/translations/extension/en.yml +0 -2
  109. data/spec/translations/extension/notransl.yml +0 -1
  110. data/spec/translations/general/en.yml +0 -47
  111. data/spec/translations/general/nolocale.yml +0 -6
  112. data/spec/translations/general/ru.yml +0 -7
  113. data/spec/translations/two/en.yml +0 -2
  114. data/spec/translations/two/fr.yml +0 -0
  115. data/spec/yaml_loader_spec.rb +0 -61
data/base/cy.yml ADDED
@@ -0,0 +1,34 @@
1
+ ok: 'Iawn'
2
+ save: 'Cadw'
3
+ cancel: 'Canslo'
4
+ 'yes': 'Ie'
5
+ 'no': 'Na'
6
+ exit: 'Gadael'
7
+ delete: 'Dileu'
8
+
9
+ human_time:
10
+ after_days: !!pl
11
+ 1: 'ar ôl %1 diwrnod'
12
+ 2: 'ar ôl %1 ddiwrnod'
13
+ n: 'ar ôl %1 diwrnod'
14
+ tomorrow: 'yfory'
15
+ after_hours: !!pl
16
+ 1: 'ar ôl %1 awr'
17
+ n: 'ar ôl %1 awr'
18
+ after_minutes: !!pl
19
+ 1: 'ar ôl %1 munud'
20
+ n: 'ar ôl %1 munud'
21
+ now: 'nawr'
22
+ today: 'heddiw'
23
+ minutes_ago: !!pl
24
+ 1: '%1 munud yn ôl'
25
+ 2: '%1 funud yn ôl'
26
+ n: '%1 munud yn ôl'
27
+ hours_ago: !!pl
28
+ 1: '%1 awr yn ôl'
29
+ n: '%1 awr yn ôl'
30
+ yesterday: 'ddoe'
31
+ days_ago: !!pl
32
+ 1: '%1 diwrnod yn ôl'
33
+ 2: '%1 ddiwrnod yn ôl'
34
+ n: '%1 diwrnod yn ôl'
data/lib/r18n-core.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Main file to load all neccessary classes for i18n support.
3
+ # Main file to load all necessary classes for i18n support.
4
4
  #
5
5
  # Copyright (C) 2008 Andrey “A.I.” Sitnik <andrey@sitnik.ru>
6
6
  #
@@ -35,40 +35,25 @@
35
35
  require_relative File.join('r18n-core', file)
36
36
  end
37
37
 
38
+ # Root module with singleton methods
38
39
  module R18n
39
40
  autoload :Translated, 'r18n-core/translated'
40
41
 
41
42
  class << self
42
- # Set I18n object globally. You can miss translation +places+, it will be
43
- # taken from <tt>R18n.default_places</tt>.
44
- def set(i18n = nil, places = R18n.default_places, &block)
45
- @i18n =
46
- if block_given?
47
- @setter = block
48
- nil
49
- elsif i18n.is_a? I18n
50
- i18n
51
- else
52
- I18n.new(i18n, places)
53
- end
43
+ # Set I18n object globally. You can miss translation `places`, it will be
44
+ # taken from `R18n.default_places`.
45
+ def set(i18n, places = R18n.default_places)
46
+ @i18n = i18n.is_a?(I18n) ? i18n : I18n.new(i18n, places)
54
47
  end
55
48
 
56
49
  # Set I18n object to current thread.
57
- def thread_set(i18n = nil, &block)
58
- if block_given?
59
- thread[:r18n_setter] = block
60
- thread[:r18n_i18n] = nil
61
- else
62
- thread[:r18n_i18n] = i18n
63
- end
50
+ def thread_set(i18n)
51
+ thread[:r18n_i18n] = i18n
64
52
  end
65
53
 
66
54
  # Get I18n object for current thread.
67
55
  def get
68
- thread[:r18n_i18n] ||
69
- (thread[:r18n_setter] && thread_set(thread[:r18n_setter].call)) ||
70
- @i18n ||
71
- (@setter && set(@setter.call))
56
+ thread[:r18n_i18n] || @i18n
72
57
  end
73
58
 
74
59
  # Clean translations cache.
@@ -90,48 +75,62 @@ module R18n
90
75
  Thread.current
91
76
  end
92
77
 
93
- # Translate message. Alias for <tt>R18n.get.t</tt>.
78
+ # Translate message. Alias for `R18n.get.t`.
94
79
  def t(*params)
95
80
  get.t(*params)
96
81
  end
97
82
 
98
- # Localize object. Alias for <tt>R18n.get.l</tt>.
83
+ # Localize object. Alias for `R18n.get.l`.
99
84
  def l(*params)
100
85
  get.l(*params)
101
86
  end
102
87
 
103
- # Return I18n object for +locale+. Useful to temporary change locale,
88
+ # Return I18n object for `locale`. Useful to temporary change locale,
104
89
  # for example, to show text in locales list:
105
90
  #
106
91
  # - R18n.available_locales.each do |locale|
107
92
  # - R18n.change(locale).t.language_title
93
+ #
94
+ # It also can be used with block:
95
+ #
96
+ # - R18n.change(locale) { t.language_title }
108
97
  def change(locale)
109
98
  locale = locale.code if locale.is_a? Locale
110
99
  exists = get ? get.locales.map(&:code) : []
111
100
  places = get ? get.translation_places : R18n.default_places
112
- R18n::I18n.new([locale] + exists, places)
101
+
102
+ i18n = R18n::I18n.new([locale] + exists, places)
103
+
104
+ if block_given?
105
+ old_thread_i18n = thread[:r18n_i18n]
106
+ thread_set i18n
107
+ yield
108
+ thread[:r18n_i18n] = old_thread_i18n
109
+ end
110
+
111
+ i18n
113
112
  end
114
113
 
115
- # Return Locale object by locale code. Its shortcut for
116
- # <tt>R18n::Locale.load(code)</tt>.
114
+ # Return Locale object by locale code. It's shortcut for
115
+ # `R18n::Locale.load(code)`.
117
116
  def locale(code)
118
117
  R18n::Locale.load(code)
119
118
  end
120
119
 
121
- # Return Array of locales with available translations. You can miss
122
- # translation +places+, it will be taken from <tt>R18n.default_places</tt>.
120
+ # Return `Array` of locales with available translations. You can miss
121
+ # translation `places`, it will be taken from `R18n.default_places`.
123
122
  def available_locales(places = R18n.default_places)
124
123
  R18n::I18n.convert_places(places).map(&:available).flatten.uniq
125
124
  end
126
125
 
127
- # Default places for <tt>R18n.set</tt> and <tt>R18n.available_locales</tt>.
126
+ # Default places for `R18n.set` and `R18n.available_locales`.
128
127
  #
129
128
  # You can set block to calculate places dynamically:
130
129
  # R18n.default_places { settings.i18n_places }
131
130
  attr_writer :default_places
132
131
 
133
132
  def default_places(&block)
134
- if block_given?
133
+ if block
135
134
  @default_places = block
136
135
  elsif @default_places.is_a? Proc
137
136
  @default_places.call
@@ -140,15 +139,15 @@ module R18n
140
139
  end
141
140
  end
142
141
 
143
- # Default loader class, which will be used if you didn’t send loader to
144
- # +I18n.new+ (object with +available+ and +load+ methods).
142
+ # Default loader class, which will be used if you did not send loader to
143
+ # `I18n.new` (object with `available` and `load` methods).
145
144
  attr_accessor :default_loader
146
145
 
147
146
  # Loaders with extension translations. If application translations with
148
- # same locale isnt exists, extension file willn’t be used.
147
+ # same locale isn't exists, extension file will not be used.
149
148
  attr_accessor :extension_places
150
149
 
151
- # Hash of hash-like (see Moneta) object to store loaded translations.
150
+ # `Hash` of hash-like (see Moneta) object to store loaded translations.
152
151
  attr_accessor :cache
153
152
  end
154
153
 
@@ -18,10 +18,10 @@
18
18
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
19
 
20
20
  module R18n
21
- # Superclass for +GlobalFilterList+ and +CustomFilterList+ with filters
21
+ # Superclass for `GlobalFilterList` and `CustomFilterList` with filters
22
22
  # processing.
23
23
  class FilterList
24
- # Process +value+ by filters in +enabled+.
24
+ # Process `value` by filters in `enabled`.
25
25
  def process(filters_type, type, value, locale, path, params)
26
26
  config = { locale: locale, path: path }
27
27
 
@@ -39,15 +39,17 @@ module R18n
39
39
 
40
40
  # Shortcut to process `R18n::Typed`.
41
41
  def process_typed(filters_type, typed_value, params)
42
- process(filters_type,
43
- typed_value.type,
44
- typed_value.value,
45
- typed_value.locale,
46
- typed_value.path,
47
- params)
42
+ process(
43
+ filters_type,
44
+ typed_value.type,
45
+ typed_value.value,
46
+ typed_value.locale,
47
+ typed_value.path,
48
+ params
49
+ )
48
50
  end
49
51
 
50
- # Process +value+ by global filters in +enabled+.
52
+ # Process `value` by global filters in `enabled`.
51
53
  def process_string(filters_type, value, config, params)
52
54
  config = { locale: value.locale, path: config } if config.is_a? String
53
55
 
@@ -55,18 +57,19 @@ module R18n
55
57
  value = f.call(value, config, *params)
56
58
  end
57
59
 
58
- if value.class == String
60
+ if value.instance_of? String
59
61
  TranslatedString.new(value, config[:locale], config[:path], self)
60
62
  else
61
63
  value
62
64
  end
63
65
  end
64
66
 
65
- # Array of enabled filters with +filters_type+ for +type+.
67
+ # `Array` of enabled filters with `filters_type` for `type`.
66
68
  def enabled(filters_type, type)
67
- if filters_type == :passive
69
+ case filters_type
70
+ when :passive
68
71
  passive(type)
69
- elsif filters_type == :active
72
+ when :active
70
73
  active(type)
71
74
  else
72
75
  all(type)
@@ -109,6 +112,8 @@ module R18n
109
112
  # Filter list for I18n object with custom disabled/enabled filters.
110
113
  class CustomFilterList < FilterList
111
114
  def initialize(on, off)
115
+ super()
116
+
112
117
  @on = Array(on).map { |i| Filters.defined[i] }
113
118
  @off = Array(off).map { |i| Filters.defined[i] }
114
119
  @changed_types = (@on + @off).map(&:types).flatten.uniq
@@ -137,6 +142,7 @@ module R18n
137
142
  def passive(type)
138
143
  enabled = Filters.passive_enabled[type]
139
144
  return enabled unless @changed_passive.include? type
145
+
140
146
  enabled = enabled.reject { |i| @off_by_type[type].include? i }
141
147
  enabled + @on_by_type[type].select(&:passive)
142
148
  end
@@ -144,6 +150,7 @@ module R18n
144
150
  def active(type)
145
151
  enabled = Filters.active_enabled[type]
146
152
  return enabled unless @changed_active.include? type
153
+
147
154
  enabled = enabled.reject { |i| @off_by_type[type].include? i }
148
155
  enabled + @on_by_type[type].reject(&:passive)
149
156
  end
@@ -151,6 +158,7 @@ module R18n
151
158
  def all(type)
152
159
  enabled = Filters.enabled[type]
153
160
  return enabled unless @changed_types.include? type
161
+
154
162
  enabled = enabled.reject { |i| @off_by_type[type].include? i }
155
163
  enabled + @on_by_type[type]
156
164
  end
@@ -42,14 +42,14 @@ module R18n
42
42
  #
43
43
  # i18n.filtered('_') #=> "This_content_will_be_processed_by_filter!"
44
44
  #
45
- # Use String class as type to add global filter for all translated strings:
45
+ # Use `String` class as type to add global filter for all translated strings:
46
46
  #
47
47
  # R18n::Filters.add(String, :escape_html) do |content, config, params|
48
48
  # escape_html(content)
49
49
  # end
50
50
  #
51
51
  # Filter config contain two parameters: translation locale and path. But it is
52
- # Hash and you can add you own parameter to cross-filter communications:
52
+ # `Hash` and you can add you own parameter to cross-filter communications:
53
53
  #
54
54
  # R18n::Filters.add(String, :hide_truth) do |content, config|
55
55
  # return content if config[:censorship_check]
@@ -74,28 +74,28 @@ module R18n
74
74
  # i18n.filtered('_') #=> "This_content_will_be_processed_by_filter!"
75
75
  # R18n::Filters.delete(:no_space)
76
76
  #
77
- # You can enabled/disabled filters only for special I18n object:
77
+ # You can enabled/disabled filters only for special `I18n` object:
78
78
  #
79
79
  # R18n::I18n.new('en', nil, on_filters: [:untranslated_html, :no_space],
80
80
  # off_filters: :untranslated )
81
81
  module Filters
82
82
  class << self
83
- # Hash of filter names to Filters.
83
+ # `Hash` of filter names to Filters.
84
84
  attr_accessor :defined
85
85
 
86
- # Hash of types to all Filters.
86
+ # `Hash` of types to all Filters.
87
87
  attr_accessor :by_type
88
88
 
89
- # Hash of types to enabled active filters.
89
+ # `Hash` of types to enabled active filters.
90
90
  attr_accessor :active_enabled
91
91
 
92
- # Hash of types to enabled passive filters.
92
+ # `Hash` of types to enabled passive filters.
93
93
  attr_accessor :passive_enabled
94
94
 
95
- # Hash of types to enabled passive and active filters.
95
+ # `Hash` of types to enabled passive and active filters.
96
96
  attr_accessor :enabled
97
97
 
98
- # Rebuild +active_enabled+ and +passive_enabled+ for +type+.
98
+ # Rebuild `active_enabled` and `passive_enabled` for `type`.
99
99
  def rebuild_enabled!(type)
100
100
  @passive_enabled[type] = []
101
101
  @active_enabled[type] = []
@@ -103,6 +103,7 @@ module R18n
103
103
 
104
104
  @by_type[type].each do |filter|
105
105
  next unless filter.enabled?
106
+
106
107
  @enabled[type] << filter
107
108
  if filter.passive?
108
109
  @passive_enabled[type] << filter
@@ -112,17 +113,17 @@ module R18n
112
113
  end
113
114
  end
114
115
 
115
- # Add new filter for +type+ with +name+ and return filter object. You
116
- # can use String class as +type+ to add global filter for all translated
116
+ # Add new filter for `type` with `name` and return filter object. You
117
+ # can use `String` class as `type` to add global filter for all translated
117
118
  # string.
118
119
  #
119
- # Filter content will be sent to +block+ as first argument, struct with
120
+ # Filter content will be sent to `block` as first argument, struct with
120
121
  # config as second and filters parameters will be in next arguments.
121
122
  #
122
123
  # Options:
123
- # * +position+ – change order on processing several filters for same type.
124
+ # * `position` – change order on processing several filters for same type.
124
125
  # Note that passive filters will be always run before active.
125
- # * +passive+ – if +true+, filter will process only on translation
126
+ # * `passive` – if `true`, filter will process only on translation
126
127
  # loading. Note that you must add all passive before load translation.
127
128
  def add(types, name = nil, options = {}, &block)
128
129
  if name.is_a? Hash
@@ -161,7 +162,7 @@ module R18n
161
162
  filter
162
163
  end
163
164
 
164
- # Delete +filter+ by name or Filter object.
165
+ # Delete `filter` by name or Filter object.
165
166
  def delete(filter)
166
167
  filter = @defined[filter] unless filter.is_a? Filter
167
168
  return unless filter
@@ -173,7 +174,7 @@ module R18n
173
174
  end
174
175
  end
175
176
 
176
- # Disable +filter+ by name or Filter object.
177
+ # Disable `filter` by name or Filter object.
177
178
  def off(filter)
178
179
  filter = @defined[filter] unless filter.is_a? Filter
179
180
  return unless filter
@@ -182,7 +183,7 @@ module R18n
182
183
  filter.types.each { |type| rebuild_enabled! type }
183
184
  end
184
185
 
185
- # Turn on disabled +filter+ by name or Filter object.
186
+ # Turn on disabled `filter` by name or Filter object.
186
187
  def on(filter)
187
188
  filter = @defined[filter] unless filter.is_a? Filter
188
189
  return unless filter
@@ -191,7 +192,7 @@ module R18n
191
192
  filter.types.each { |type| rebuild_enabled! type }
192
193
  end
193
194
 
194
- # Return filters, which be added inside +block+.
195
+ # Return filters, which be added inside `block`.
195
196
  def listen(&_block)
196
197
  filters = []
197
198
  @new_filter_listener = proc { |i| filters << i }
@@ -209,7 +210,7 @@ module R18n
209
210
 
210
211
  Filter = Struct.new(:name, :types, :block, :enabled, :passive) do
211
212
  def call(*params)
212
- block.call(*params)
213
+ instance_exec(*params, &block)
213
214
  end
214
215
 
215
216
  def enabled?
@@ -222,14 +223,8 @@ module R18n
222
223
  end
223
224
  end
224
225
 
225
- Filters.add('proc', :procedure) do |content, _config, *params|
226
- # rubocop:disable Security/Eval
227
- eval("proc { #{content} }", nil, __FILE__, __LINE__).call(*params)
228
- # rubocop:enable Security/Eval
229
- end
230
-
231
226
  # Class to mark unpluralized translation.
232
- class UnpluralizetedTranslation < Translation
227
+ class UnpluralizedTranslation < Translation
233
228
  end
234
229
 
235
230
  Filters.add('pl', :pluralization) do |content, config, param|
@@ -239,7 +234,7 @@ module R18n
239
234
  type = 'n' unless content.key? type
240
235
  content[type]
241
236
  else
242
- UnpluralizetedTranslation.new(
237
+ UnpluralizedTranslation.new(
243
238
  config[:locale], config[:path],
244
239
  locale: config[:locale], translations: content
245
240
  )
@@ -248,13 +243,11 @@ module R18n
248
243
 
249
244
  Filters.add(String, :variables) do |content, config, *params|
250
245
  cached_params = []
251
- content.to_s.gsub(/\%\d/) do |key|
246
+ content.to_s.gsub(/%\d/) do |key|
252
247
  i = key[1..-1].to_i
253
248
  unless cached_params.include? i - 1
254
249
  param = config[:locale].localize(params[i - 1])
255
- if defined? ActiveSupport::SafeBuffer
256
- param = ActiveSupport::SafeBuffer.new + param
257
- end
250
+ param = ActiveSupport::SafeBuffer.new + param if defined? ActiveSupport::SafeBuffer
258
251
 
259
252
  cached_params[i - 1] = param
260
253
  end
@@ -265,13 +258,11 @@ module R18n
265
258
  Filters.add(String, :named_variables) do |content, config, params|
266
259
  if params.is_a? Hash
267
260
  content = content.clone
268
- params.each_pair do |name, value|
269
- value = config[:locale].localize(value)
270
- if defined? ActiveSupport::SafeBuffer
271
- value = ActiveSupport::SafeBuffer.new + value
272
- end
273
- content.gsub! "%{#{name}}", value
274
- content.gsub! "{{#{name}}}", value
261
+ content.gsub!(/(?:%{(\w+)}|{{(\w+)}})/) do |name|
262
+ key = name.delete('%{}').to_sym
263
+ value = config[:locale].localize(params[key])
264
+ value = ActiveSupport::SafeBuffer.new + value if defined? ActiveSupport::SafeBuffer
265
+ value
275
266
  end
276
267
  end
277
268
  content
@@ -282,20 +273,23 @@ module R18n
282
273
  "#{translated}[#{untranslated}]"
283
274
  end
284
275
 
285
- Filters.add(Untranslated, :untranslated_bash) do |_v, _c, transl, untransl|
286
- "#{transl}\e[0;31m[#{untransl}]\e[0m"
276
+ Filters.add(Untranslated, :untranslated_bash) do |_v, _c, translated, untranslated|
277
+ "#{translated}\e[0;31m[#{untranslated}]\e[0m"
287
278
  end
288
279
  Filters.off(:untranslated_bash)
289
280
 
290
- Filters.add(Untranslated, :untranslated_html) do |_v, _c, transl, untransl|
281
+ Filters.add(Untranslated, :untranslated_html) do |_v, _c, translated, untranslated|
291
282
  prefix = '<span style="color: red">['
292
283
  postfix = ']</span>'
293
- if prefix.respond_to? :html_safe
294
- prefix = prefix.html_safe
295
- postfix = postfix.html_safe
296
- transl + prefix + untransl + postfix
284
+ if defined? ActiveSupport::SafeBuffer
285
+ ## Not every project with `ActiveSupport` has `ActionView`
286
+ ## https://github.com/r18n/r18n/issues/251
287
+ ## I guess, we can trust to developers here
288
+ translated = ActiveSupport::SafeBuffer.new + translated
289
+ untranslated = ActiveSupport::SafeBuffer.new + untranslated
290
+ translated + prefix.html_safe + untranslated + postfix.html_safe
297
291
  else
298
- Utils.escape_html(transl) + prefix + Utils.escape_html(untransl) + postfix
292
+ Utils.escape_html(translated) + prefix + Utils.escape_html(untranslated) + postfix
299
293
  end
300
294
  end
301
295
  Filters.off(:untranslated_html)
@@ -310,8 +304,9 @@ module R18n
310
304
  content
311
305
  end
312
306
 
313
- Filters.add([String, 'markdown', 'textile'],
314
- :global_escape_html, passive: true) do |html, config|
307
+ Filters.add(
308
+ [String, 'markdown', 'textile'], :global_escape_html, passive: true
309
+ ) do |html, config|
315
310
  if config[:dont_escape_html]
316
311
  html
317
312
  else