i18n-inflector 2.1.0 → 2.2.0

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.
@@ -8,16 +8,62 @@
8
8
 
9
9
  module I18n
10
10
 
11
- # @abstract This class is a parent class for exceptions raised when
11
+ # @abstract It is a parent class for all exceptions
12
+ # related to inflections.
13
+ class InflectionException < I18n::ArgumentError
14
+
15
+ attr_accessor :token
16
+ attr_accessor :kind
17
+ attr_accessor :key
18
+
19
+ def initialize(locale, token, kind)
20
+ @locale, @token, @kind = locale, token, kind
21
+ @key = nil
22
+ super()
23
+ end
24
+
25
+ end
26
+
27
+ # @abstract It is a parent class for all exceptions
28
+ # related to inflection patterns that are processed.
29
+ class InflectionPatternException < InflectionException
30
+
31
+ attr_accessor :pattern
32
+
33
+ def initialize(locale, pattern, token, kind)
34
+ super(locale, token, kind)
35
+ @pattern = pattern
36
+ end
37
+
38
+ def message
39
+ mkey = @key.nil? ? "" : ".#{@key}"
40
+ @pattern.nil? ? "" : "#{@locale}#{mkey}: #{@pattern} - "
41
+ end
42
+
43
+ end
44
+
45
+ # @abstract It is a parent class for all exceptions
46
+ # related to configuration data of inflections that is processed.
47
+ class InflectionConfigurationException < InflectionException
48
+
49
+ attr_accessor :locale
50
+
51
+ def message
52
+ mkey = @key.nil? ? ".i18n.inflections.#{@kind}" : ".#{@key}"
53
+ "#{@locale}#{mkey}: "
54
+ end
55
+
56
+ end
57
+
58
+ # @abstract It is a parent class for exceptions raised when
12
59
  # inflection option is bad or missing.
13
- class InvalidOptionForKind < ArgumentError
60
+ class InvalidOptionForKind < InflectionPatternException
14
61
 
15
- attr_reader :pattern, :kind, :token, :option
62
+ attr_accessor :option
16
63
 
17
- def initialize(pattern, kind, token, option)
18
- @pattern, @kind, @token, @option, @option_present = pattern, kind, token, option
19
- @message ||= ""
20
- super(@message)
64
+ def initialize(locale, pattern, token, kind, option)
65
+ super(locale, pattern, token, kind)
66
+ @option = option
21
67
  end
22
68
 
23
69
  end
@@ -26,73 +72,129 @@ module I18n
26
72
  # is determined by looking at token placed in a pattern.
27
73
  class InflectionOptionNotFound < InvalidOptionForKind
28
74
 
29
- def initialize(pattern, kind, token, option=nil)
30
- kind = kind.to_s
75
+ def message
76
+ kind = @kind.to_s
31
77
  unless kind.empty?
32
- if kind[0..0] == I18n::Inflector::NAMED_MARKER
33
- kind = ":#{kind} (or :#{kind[1..-1]})"
78
+ if kind[0..0] == I18n::Inflector::Config::Markers::PATTERN
79
+ kindmsg = ":#{kind} (or :#{kind[1..-1]})"
34
80
  else
35
- kind = kind.to_sym.inspect
81
+ kindmsg = kind.to_sym.inspect
36
82
  end
37
83
  end
38
- @message = "option #{kind} required by the " +
39
- "pattern #{pattern.inspect} was not found"
40
- super
84
+ super +
85
+ "required option #{kindmsg} was not found"
41
86
  end
42
87
 
43
88
  end
44
89
 
45
90
  # This exception will be raised when a required option, describing token selected
46
- # for a kind, is +nil+, empty or doesn't match any acceptable tokens.
91
+ # for a kind contains a token that is not of the given kind.
47
92
  class InflectionOptionIncorrect < InvalidOptionForKind
48
93
 
49
- def initialize(pattern, kind, token, option)
50
- @message = "value #{option.inspect} of option #{kind.inspect} required by " +
51
- "#{pattern.inspect} does not match any token"
52
- super
94
+ def message
95
+ super +
96
+ "required value #{@option.inspect} of option #{@kind.inspect} " \
97
+ "does not match any token"
53
98
  end
54
99
 
55
100
  end
56
101
 
57
- # This is raised when token given in pattern is invalid (empty or has no
102
+ # This is raised when a token given in a pattern is invalid (empty or has no
58
103
  # kind assigned).
59
- class InvalidInflectionToken < ArgumentError
104
+ class InvalidInflectionToken < InflectionPatternException
105
+
106
+ def initialize(locale, pattern, token, kind=nil)
107
+ super(locale, pattern, token, kind)
108
+ end
109
+
110
+ def message
111
+ badkind = ""
112
+ if (!@token.to_s.empty? && !kind.nil?)
113
+ kind = @kind.to_s.empty? ? "" : @kind.to_sym
114
+ badkind = " (processed kind: #{kind.inspect})"
115
+ end
116
+ super + "token #{@token.to_s.inspect} is invalid" + badkind
117
+ end
118
+
119
+ end
60
120
 
61
- attr_reader :pattern, :token
121
+ # This is raised when an inflection option name is invalid (contains
122
+ # reserved symbols).
123
+ class InvalidInflectionOption < InflectionPatternException
62
124
 
63
- def initialize(pattern, token)
64
- @pattern, @token = pattern, token
65
- super "token #{token.inspect} used in translation " +
66
- "pattern #{pattern.inspect} is invalid"
125
+ def initialize(locale, pattern, option)
126
+ super(locale, pattern, nil, option)
127
+ end
128
+
129
+ def message
130
+ super + "inflection option #{@kind.inspect} is invalid"
131
+ end
132
+
133
+ end
134
+
135
+ # This is raised when a kind given in a pattern is invalid (empty, reserved
136
+ # or containing a reserved character).
137
+ class InvalidInflectionKind < InflectionPatternException
138
+
139
+ def initialize(locale, pattern, kind)
140
+ super(locale, pattern, nil, kind)
141
+ end
142
+
143
+ def message
144
+ super + "kind #{@kind.to_s.inspect} is invalid"
67
145
  end
68
146
 
69
147
  end
70
148
 
71
149
  # This is raised when an inflection token used in a pattern does not match
72
- # an assumed kind determined by reading previous tokens from that pattern.
73
- class MisplacedInflectionToken < ArgumentError
150
+ # an assumed kind determined by reading previous tokens from that pattern
151
+ # or by the given strict kind of a named pattern.
152
+ class MisplacedInflectionToken < InflectionPatternException
153
+
154
+ def initialize(locale, pattern, token, kind)
155
+ super(locale, pattern, token, kind)
156
+ end
74
157
 
75
- attr_reader :pattern, :token, :kind
158
+ def message
159
+ super +
160
+ "token #{@token.to_s.inspect} " \
161
+ "is not of the expected kind #{@kind.inspect}"
162
+ end
163
+
164
+ end
165
+
166
+ # This is raised when a complex inflection pattern is malformed
167
+ # and cannot be reduced to regular patterns.
168
+ class ComplexPatternMalformed < InflectionPatternException
169
+
170
+ def initialize(locale, pattern, token, complex_kind)
171
+ unless pattern.include?(I18n::Inflector::Config::Markers::PATTERN)
172
+ pattern = I18n::Inflector::Config::Markers::PATTERN + "#{complex_kind}{#{pattern}}"
173
+ end
174
+ super(locale, pattern, token, complex_kind)
175
+ end
76
176
 
77
- def initialize(pattern, token, kind)
78
- @pattern, @token, @kind = pattern, token, kind
79
- super "inflection token #{token.inspect} from pattern #{pattern.inspect} " +
80
- "is not of the expected kind #{kind.inspect}"
177
+ def message
178
+ super + "pattern is malformed; token count differs from kind count"
81
179
  end
82
180
 
83
181
  end
84
182
 
85
183
  # This is raised when an inflection token of the same name is already defined in
86
184
  # inflections tree of translation data.
87
- class DuplicatedInflectionToken < ArgumentError
185
+ class DuplicatedInflectionToken < InflectionConfigurationException
88
186
 
89
- attr_reader :original_kind, :kind, :token
187
+ attr_accessor :original_kind
90
188
 
91
- def initialize(original_kind, kind, token)
92
- @original_kind, @kind, @token = original_kind, kind, token
93
- and_cannot = kind.nil? ? "" : "and cannot be used with kind #{kind.inspect}"
94
- super "inflection token #{token.inspect} was already assigned " +
95
- "to kind #{original_kind} " + and_cannot
189
+ def initialize(locale, token, kind, original_kind)
190
+ super(locale, token, kind)
191
+ @original_kind = original_kind
192
+ end
193
+
194
+ def message
195
+ super +
196
+ "token #{@token.inspect} " \
197
+ "was already assigned to the kind #{@original_kind.inspect}"
96
198
  end
97
199
 
98
200
  end
@@ -100,39 +202,63 @@ module I18n
100
202
  # This is raised when an alias for an inflection token points to a token that
101
203
  # doesn't exists. It is also raised when default token of some kind points
102
204
  # to a non-existent token.
103
- class BadInflectionAlias < ArgumentError
205
+ class BadInflectionAlias < InflectionConfigurationException
104
206
 
105
- attr_reader :locale, :token, :kind, :pointer
207
+ attr_accessor :pointer
106
208
 
107
209
  def initialize(locale, token, kind, pointer)
108
- @locale, @token, @kind, @pointer = locale, token, kind, pointer
109
- what = token == :default ? "default token" : "alias"
110
- lang = locale.nil? ? "" : "for language #{locale.inspect} "
111
- kinn = kind.nil? ? "" : "of kind #{kind.inspect} "
112
- super "the #{what} #{token.inspect} " + kinn + lang +
113
- "points to an unknown token #{pointer.inspect}"
210
+ super(locale, token, kind)
211
+ @pointer = pointer
212
+ end
213
+
214
+ def message
215
+ what = token == :default ? "default token" : "alias #{@token.inspect}"
216
+ super +
217
+ "the #{what} " \
218
+ "points to an unknown token #{@pointer.inspect}"
114
219
  end
115
220
 
116
221
  end
117
222
 
118
223
  # This is raised when an inflection token or its description has a bad name. This
119
224
  # includes an empty name or a name containing prohibited characters.
120
- class BadInflectionToken < ArgumentError
225
+ class BadInflectionToken < InflectionConfigurationException
121
226
 
122
- attr_reader :locale, :token, :kind, :description
227
+ attr_accessor :description
123
228
 
124
229
  def initialize(locale, token, kind=nil, description=nil)
125
- @locale, @token, @kind, @description = locale, token, kind, description
126
- kinn = kind.nil? ? "" : "of kind #{kind.inspect} "
127
- if description.nil?
128
- super "Inflection token #{token.inspect} " + kinn +
129
- "for language #{locale.inspect} has a bad name"
230
+ super(locale, token, kind)
231
+ @description = description
232
+ end
233
+
234
+ def message
235
+ if @description.nil?
236
+ super +
237
+ "inflection token #{@token.inspect} " \
238
+ "has a bad name"
130
239
  else
131
- super "Inflection token #{token.inspect} " + kinn +
132
- "for language #{locale.inspect} has a bad description #{description.inspect}"
240
+ super +
241
+ "inflection token #{@token.inspect} " \
242
+ "has a bad description #{@description.inspect}"
133
243
  end
134
244
  end
135
245
 
136
246
  end
137
247
 
248
+
249
+ # This is raised when an inflection kind has a bad name
250
+ # or is not a root for a tree of tokens.
251
+ class BadInflectionKind < InflectionConfigurationException
252
+
253
+ def initialize(locale, kind)
254
+ super(locale, nil, kind)
255
+ end
256
+
257
+ def message
258
+ super +
259
+ "inflection kind #{@kind.inspect} has bad name or type"
260
+ end
261
+
262
+ end
263
+
138
264
  end
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ #
3
+ # Author:: Paweł Wilk (mailto:pw@gnu.org)
4
+ # Copyright:: (c) 2011 by Paweł Wilk
5
+ # License:: This program is licensed under the terms of {file:LGPL GNU Lesser General Public License} or {file:COPYING Ruby License}.
6
+ #
7
+ # This file contains more intuitive version of Set.
8
+
9
+ require 'set'
10
+
11
+ module I18n
12
+ module Inflector
13
+
14
+ # This class keeps sets of data
15
+ class HSet < Set
16
+
17
+ # This method performs a fast check
18
+ # if an element exists in a set.
19
+ #
20
+ # @return [Boolean]
21
+ def [](k)
22
+ @hash[k] == true
23
+ end
24
+
25
+ end
26
+
27
+ end
28
+ end
@@ -22,6 +22,7 @@ module I18n
22
22
  @kinds = Hash.new(false)
23
23
  @tokens = Hash.new(DUMMY_TOKEN)
24
24
  @defaults = Hash.new
25
+ @known_kinds = nil
25
26
  @lazy_tokens = LazyHashEnumerator.new(@tokens)
26
27
  @locale = locale
27
28
  end
@@ -74,6 +75,7 @@ module I18n
74
75
  @tokens[token][:kind] = kind.to_sym
75
76
  @tokens[token][:description] = description.to_s
76
77
  @kinds[kind] = true
78
+ @known_kinds = nil
77
79
  end
78
80
 
79
81
  # Tests if the token is a true token.
@@ -319,7 +321,7 @@ module I18n
319
321
  #
320
322
  # @return [Array<Symbol>] an array containing all the known kinds
321
323
  def get_kinds
322
- @kinds.keys
324
+ @known_kinds ||= @kinds.keys
323
325
  end
324
326
 
325
327
  # Reads the default token of a kind.
@@ -45,6 +45,7 @@ module I18n
45
45
  @tokens = Hash.new(DUMMY_TOKENS)
46
46
  @lazy_tokens = Hash.new(DUMMY_T_LAZY)
47
47
  @defaults = Hash.new
48
+ @known_kinds = nil
48
49
  @locale = locale
49
50
  end
50
51
 
@@ -82,6 +83,7 @@ module I18n
82
83
  kind = kind.to_sym
83
84
  kind_tree = @tokens[kind]
84
85
  if kind_tree.equal?(DUMMY_TOKENS)
86
+ @known_kinds = nil
85
87
  kind_tree = @tokens[kind] = Hash.new(DUMMY_TOKEN)
86
88
  @lazy_tokens[kind] = LazyHashEnumerator.new(kind_tree)
87
89
  end
@@ -252,7 +254,7 @@ module I18n
252
254
  # @return [Array<Symbol>] an array containing all the known strict
253
255
  # kinds
254
256
  def get_kinds
255
- @tokens.keys
257
+ @known_kinds ||= @tokens.keys
256
258
  end
257
259
 
258
260
  # Reads the default token of a strict kind.
@@ -4,7 +4,7 @@
4
4
  # Copyright:: (c) 2011 by Paweł Wilk
5
5
  # License:: This program is licensed under the terms of {file:LGPL GNU Lesser General Public License} or {file:COPYING Ruby License}.
6
6
  #
7
- # This file contains I18n::Inflector module,
7
+ # This file contains a stub of I18n::Inflector module,
8
8
  # which extends I18n by adding the ability
9
9
  # to interpolate patterns containing inflection tokens
10
10
  # defined in translation data and manipulate on that data.
@@ -24,44 +24,6 @@ module I18n
24
24
 
25
25
  module Inflector
26
26
 
27
- # @private
28
- def get_reserved_keys
29
- return I18n::RESERVED_KEYS if defined?(I18n::RESERVED_KEYS)
30
- return I18n::Backend::Base::RESERVED_KEYS if defined?(I18n::Backend::Base::RESERVED_KEYS)
31
- return I18n::Backend::Simple::RESERVED_KEYS if defined?(I18n::Backend::Simple::RESERVED_KEYS)
32
- return RESERVED_KEYS if defined?(RESERVED_KEYS)
33
- []
34
- end
35
- module_function :get_reserved_keys
36
-
37
- # Contains <tt>@</tt> string that is used to quickly fallback
38
- # to standard +translate+ method if it's not found.
39
- FAST_MATCHER = '@'
40
-
41
- # Contains a regular expression that catches patterns.
42
- PATTERN = /(.?)@([^\{]*)\{([^\}]+)\}/
43
-
44
- # Contains a regular expression that catches tokens.
45
- TOKENS = /(?:([^\:\|]+):+([^\|]+)\1?)|([^:\|]+)/
46
-
47
- # Contains a symbol that indicates an alias.
48
- ALIAS_MARKER = '@'
49
-
50
- # Contains a symbol that indicates a named pattern.
51
- NAMED_MARKER = '@'
52
-
53
- # Conatins a symbol used to separate multiple tokens.
54
- OPERATOR_MULTI = ','
55
-
56
- # Conatins a symbol used to mark tokens as negative.
57
- OPERATOR_NOT = '!'
58
-
59
- # Contains a list of escape symbols that cause pattern to be escaped.
60
- ESCAPES = { '@' => true, '\\' => true }
61
-
62
- # Reserved keys
63
- INFLECTOR_RESERVED_KEYS = I18n::Inflector.get_reserved_keys
64
-
65
27
  end # module Inflector
66
28
 
67
29
  end # module I18n