i18n-inflector 2.1.0 → 2.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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