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.
- data/ChangeLog +412 -0
- data/Manifest.txt +3 -0
- data/README.rdoc +38 -17
- data/docs/EXAMPLES +111 -22
- data/docs/HISTORY +37 -0
- data/docs/TODO +3 -27
- data/lib/i18n-inflector/api.rb +22 -234
- data/lib/i18n-inflector/api_strict.rb +1 -1
- data/lib/i18n-inflector/backend.rb +78 -23
- data/lib/i18n-inflector/config.rb +297 -0
- data/lib/i18n-inflector/errors.rb +184 -58
- data/lib/i18n-inflector/hset.rb +28 -0
- data/lib/i18n-inflector/inflection_data.rb +3 -1
- data/lib/i18n-inflector/inflection_data_strict.rb +3 -1
- data/lib/i18n-inflector/inflector.rb +1 -39
- data/lib/i18n-inflector/interpolate.rb +404 -0
- data/lib/i18n-inflector/lazy_enum.rb +52 -6
- data/lib/i18n-inflector/long_comments.rb +463 -157
- data/lib/i18n-inflector/options.rb +116 -20
- data/lib/i18n-inflector/version.rb +1 -1
- data/lib/i18n-inflector.rb +4 -1
- data/test/inflector_test.rb +179 -22
- data.tar.gz.sig +0 -0
- metadata +7 -4
- metadata.gz.sig +0 -0
@@ -8,16 +8,62 @@
|
|
8
8
|
|
9
9
|
module I18n
|
10
10
|
|
11
|
-
# @abstract
|
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 <
|
60
|
+
class InvalidOptionForKind < InflectionPatternException
|
14
61
|
|
15
|
-
|
62
|
+
attr_accessor :option
|
16
63
|
|
17
|
-
def initialize(
|
18
|
-
|
19
|
-
@
|
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
|
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::
|
33
|
-
|
78
|
+
if kind[0..0] == I18n::Inflector::Config::Markers::PATTERN
|
79
|
+
kindmsg = ":#{kind} (or :#{kind[1..-1]})"
|
34
80
|
else
|
35
|
-
|
81
|
+
kindmsg = kind.to_sym.inspect
|
36
82
|
end
|
37
83
|
end
|
38
|
-
|
39
|
-
|
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
|
91
|
+
# for a kind contains a token that is not of the given kind.
|
47
92
|
class InflectionOptionIncorrect < InvalidOptionForKind
|
48
93
|
|
49
|
-
def
|
50
|
-
|
51
|
-
|
52
|
-
|
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 <
|
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
|
-
|
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,
|
64
|
-
|
65
|
-
|
66
|
-
|
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
|
-
|
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
|
-
|
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
|
78
|
-
|
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 <
|
185
|
+
class DuplicatedInflectionToken < InflectionConfigurationException
|
88
186
|
|
89
|
-
|
187
|
+
attr_accessor :original_kind
|
90
188
|
|
91
|
-
def initialize(
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
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 <
|
205
|
+
class BadInflectionAlias < InflectionConfigurationException
|
104
206
|
|
105
|
-
|
207
|
+
attr_accessor :pointer
|
106
208
|
|
107
209
|
def initialize(locale, token, kind, pointer)
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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 <
|
225
|
+
class BadInflectionToken < InflectionConfigurationException
|
121
226
|
|
122
|
-
|
227
|
+
attr_accessor :description
|
123
228
|
|
124
229
|
def initialize(locale, token, kind=nil, description=nil)
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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
|
132
|
-
|
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
|