i18n-inflector 1.0.11 → 2.0.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/.yardopts +2 -1
- data/ChangeLog +141 -6
- data/Gemfile +1 -0
- data/Manifest.txt +6 -2
- data/README.rdoc +32 -28
- data/Rakefile +4 -7
- data/ci/i18n-inflector.gemspec +3 -3
- data/docs/COPYING +1 -1
- data/docs/HISTORY +16 -1
- data/docs/LEGAL +1 -1
- data/docs/{LGPL-LICENSE → LGPL} +0 -0
- data/docs/RELATIONS +25 -0
- data/docs/TODO +5 -5
- data/lib/i18n-inflector/backend.rb +268 -0
- data/lib/i18n-inflector/errors.rb +12 -9
- data/lib/i18n-inflector/inflection_data.rb +329 -0
- data/lib/i18n-inflector/inflector.rb +396 -564
- data/lib/i18n-inflector/long_comments.rb +329 -407
- data/lib/i18n-inflector/options.rb +201 -0
- data/lib/i18n-inflector/util.rb +67 -0
- data/lib/i18n-inflector/version.rb +2 -2
- data/lib/i18n-inflector.rb +5 -1
- data/test/inflector_test.rb +182 -101
- data.tar.gz.sig +0 -0
- metadata +29 -10
- metadata.gz.sig +0 -0
- data/lib/i18n-inflector/shortcuts.rb +0 -154
data/docs/TODO
CHANGED
@@ -1,9 +1,9 @@
|
|
1
|
+
== Near future
|
1
2
|
|
3
|
+
* add some negative tests (e.g. empty kind, kinds as nils or empty striongs, tokens as empty strings...)
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
* use commas in patterns to separate tokens that should have to the same value
|
5
|
+
== Distant future
|
6
6
|
|
7
|
-
*
|
7
|
+
* named patterns: @gender{m:xx|f:xxx|n:xzc} - such pattern may allow multiple tokens but it breaks the logic unless some marker will be given in configuration like !gender: that would inform engine that exact kind must be present in a pattern
|
8
8
|
|
9
|
-
* use tilde symbols (~) to allow multiple negative matches. the values will be joined as they are interpolated (with other negative matches or a positive
|
9
|
+
* use tilde symbols (~) to allow multiple negative matches. the values will be joined as they are interpolated (with other negative matches or a positive; it just means that the processing won't stop on some particular token) – is this good idea anyway?
|
@@ -0,0 +1,268 @@
|
|
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 I18n::Backend::Inflector module,
|
8
|
+
# which extends I18n::Backend::Simple by adding the ability
|
9
|
+
# to interpolate patterns containing inflection tokens
|
10
|
+
# defined in translation data.
|
11
|
+
|
12
|
+
module I18n
|
13
|
+
|
14
|
+
# @abstract This namespace is shared with I18n subsystem.
|
15
|
+
module Backend
|
16
|
+
|
17
|
+
# This module contains methods that are adding
|
18
|
+
# tokenized inflection support to internal I18n classes.
|
19
|
+
# It is intened to be included in the Simple backend
|
20
|
+
# module so that it will patch translate method in order
|
21
|
+
# to interpolate additional inflection tokens present in translations.
|
22
|
+
# Usually you don't have to know what's here to use it.
|
23
|
+
module Inflector
|
24
|
+
|
25
|
+
# This accessor allows to reach API methods of the
|
26
|
+
# inflector object associated with this class.
|
27
|
+
def inflector
|
28
|
+
inflector_try_init
|
29
|
+
@inflector
|
30
|
+
end
|
31
|
+
|
32
|
+
# Cleans up internal hashes containg kinds, inflections and aliases.
|
33
|
+
#
|
34
|
+
# @api public
|
35
|
+
# @note It calls {I18n::Backend::Simple#reload! I18n::Backend::Simple#reload!}
|
36
|
+
# @return [Boolean] the result of calling ancestor's method
|
37
|
+
def reload!
|
38
|
+
@inflector = nil
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
# Translates given key taking care of inflections.
|
43
|
+
#
|
44
|
+
# @api public
|
45
|
+
# @see I18n::Inflector::Core#interpolate
|
46
|
+
# @see I18n::Inflector::InflectionOptions
|
47
|
+
# @param [Symbol] locale locale
|
48
|
+
# @param [Symbol,String] key translation key
|
49
|
+
# @param [Hash] options a set of options to pass to the translation routines.
|
50
|
+
# @note Inflector requires at least one of the +options+ to have a value that
|
51
|
+
# corresponds with token present in a pattern (or its alias). The name of that
|
52
|
+
# particular option should be the same as the name of a kind of tokens from a pattern.
|
53
|
+
# All +options+ along with a +string+ and +locale+ are passed to
|
54
|
+
# {I18n::Backend::Simple#translate I18n::Backend::Simple#translate}
|
55
|
+
# and the result is processed by {I18n::Inflector::Core#interpolate}
|
56
|
+
# @return [String] the translated string with interpolated patterns
|
57
|
+
def translate(locale, key, options = {})
|
58
|
+
translated_string = super
|
59
|
+
|
60
|
+
return translated_string if locale.to_s.empty?
|
61
|
+
|
62
|
+
unless @inflector.inflected_locale?(locale)
|
63
|
+
return translated_string.gsub(I18n::Inflector::PATTERN,'')
|
64
|
+
end
|
65
|
+
|
66
|
+
unless translated_string.include?(I18n::Inflector::FAST_MATCHER)
|
67
|
+
return translated_string
|
68
|
+
end
|
69
|
+
|
70
|
+
@inflector.interpolate(translated_string, locale, options.dup)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Stores translations in memory.
|
74
|
+
#
|
75
|
+
# @api public
|
76
|
+
# @raise [I18n::InvalidLocale] if the given +locale+ is invalid
|
77
|
+
# @raise [I18n::BadInflectionToken] if a name of some loaded token is invalid
|
78
|
+
# @raise [I18n::BadInflectionAlias] if a loaded alias points to a token that does not exists
|
79
|
+
# @raise [I18n::DuplicatedInflectionToken] if a token has already appeard in loaded configuration
|
80
|
+
# @note If inflections are changed it will regenerate proper internal
|
81
|
+
# structures.
|
82
|
+
# @return [Hash] the stored translations
|
83
|
+
def store_translations(locale, data, options = {})
|
84
|
+
r = super
|
85
|
+
inflector_try_init
|
86
|
+
if data.respond_to?(:has_key?)
|
87
|
+
subdata = (data[:i18n] || data['i18n'])
|
88
|
+
unless subdata.nil?
|
89
|
+
subdata = (subdata[:inflections] || subdata['inflections'])
|
90
|
+
unless subdata.nil?
|
91
|
+
inflection_data = load_inflection_tokens(locale, r[:i18n][:inflections])
|
92
|
+
@inflector.add_database(inflection_data)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
r
|
97
|
+
end
|
98
|
+
|
99
|
+
protected
|
100
|
+
|
101
|
+
# Initializes internal hashes used for keeping inflections configuration.
|
102
|
+
#
|
103
|
+
# @return [void]
|
104
|
+
def inflector_try_init
|
105
|
+
return nil if (defined?(@inflector) && !@inflector.nil?)
|
106
|
+
@inflector = I18n::Inflector::Core.new
|
107
|
+
nil
|
108
|
+
end
|
109
|
+
|
110
|
+
# Takes care of loading inflection tokens
|
111
|
+
# for all languages (locales) that have them
|
112
|
+
# defined.
|
113
|
+
#
|
114
|
+
# @note It calls {I18n::Backend::Simple#init_translations I18n::Backend::Simple#init_translations}
|
115
|
+
# @raise [I18n::BadInflectionToken] if a name of some loaded token is invalid
|
116
|
+
# @raise [I18n::BadInflectionAlias] if a loaded alias points to a token that does not exists
|
117
|
+
# @raise [I18n::DuplicatedInflectionToken] if a token has already appeard in loaded configuration
|
118
|
+
# @return [Boolean] +true+ if everything went fine
|
119
|
+
def init_translations
|
120
|
+
inflector_try_init
|
121
|
+
super
|
122
|
+
end
|
123
|
+
|
124
|
+
# Gives an access to the internal structure containing configuration data
|
125
|
+
# for a given locale.
|
126
|
+
#
|
127
|
+
# @note Under some very rare conditions this method may be called while
|
128
|
+
# translation data is loading. It must always return when translations
|
129
|
+
# are not initialized. Otherwise it will cause loops and someone in Poland
|
130
|
+
# will eat a kittien!
|
131
|
+
# @param [Symbol] locale the locale to use
|
132
|
+
# @return [Hash,nil] part of the translation data that
|
133
|
+
# reflects inflections for a given locale or +nil+
|
134
|
+
# if translations are not initialized
|
135
|
+
def inflection_subtree(locale)
|
136
|
+
return nil unless initialized?
|
137
|
+
lookup(locale, :"i18n.inflections", [], :fallback => true, :raise => :false)
|
138
|
+
end
|
139
|
+
|
140
|
+
# Resolves an alias for a token if the given +token+ is an alias.
|
141
|
+
#
|
142
|
+
# @note It does take care of aliasing loops (max traverses is set to 64).
|
143
|
+
# @raise [I18n::BadInflectionToken] if a name of the token that alias points to is corrupted
|
144
|
+
# @raise [I18n::BadInflectionAlias] if an alias points to token that does not exists
|
145
|
+
# @return [Symbol] the true token that alias points to if the given +token+
|
146
|
+
# is an alias or the given +token+ if it is a true token
|
147
|
+
# @overload shorten_inflection_alias(token, kind, locale)
|
148
|
+
# Resolves an alias for a token if the given +token+ is an alias for the given +locale+ and +kind+.
|
149
|
+
# @note This version uses internal subtree and needs the translation data to be initialized.
|
150
|
+
# @param [Symbol] token the token name
|
151
|
+
# @param [Symbol] kind the kind of the given token
|
152
|
+
# @param [Symbol] locale the locale to use
|
153
|
+
# @return [Symbol] the true token that alias points to if the given +token+
|
154
|
+
# is an alias or the given +token+ if it is a true token
|
155
|
+
# @overload shorten_inflection_alias(token, kind, locale, subtree)
|
156
|
+
# Resolves an alias for a token if the given +token+ is an alias for the given +locale+ and +kind+.
|
157
|
+
# @param [Symbol] token the token name
|
158
|
+
# @param [Symbol] kind the kind of the given token
|
159
|
+
# @param [Symbol] locale the locale to use
|
160
|
+
# @param [Hash] subtree the tree (in a form of nested Hashes) containing inflection tokens to scan
|
161
|
+
# @return [Symbol] the true token that alias points to if the given +token+
|
162
|
+
# is an alias or the given +token+ if it is a true token
|
163
|
+
def shorten_inflection_alias(token, kind, locale, subtree=nil, count=0)
|
164
|
+
count += 1
|
165
|
+
return nil if count > 64
|
166
|
+
|
167
|
+
inflections_tree = subtree || inflection_subtree(locale)
|
168
|
+
return nil if (inflections_tree.nil? || inflections_tree.empty?)
|
169
|
+
|
170
|
+
kind_subtree = inflections_tree[kind]
|
171
|
+
value = kind_subtree[token].to_s
|
172
|
+
|
173
|
+
if value[0..0] != I18n::Inflector::ALIAS_MARKER
|
174
|
+
if kind_subtree.has_key?(token)
|
175
|
+
return token
|
176
|
+
else
|
177
|
+
# that should never happend but who knows
|
178
|
+
raise I18n::BadInflectionToken.new(locale, token, kind)
|
179
|
+
end
|
180
|
+
else
|
181
|
+
orig_token = token
|
182
|
+
token = value[1..-1]
|
183
|
+
if token.to_s.empty?
|
184
|
+
raise I18n::BadInflectionToken.new(locale, token, kind)
|
185
|
+
end
|
186
|
+
token = token.to_sym
|
187
|
+
if kind_subtree[token].nil?
|
188
|
+
raise BadInflectionAlias.new(locale, orig_token, kind, token)
|
189
|
+
else
|
190
|
+
shorten_inflection_alias(token, kind, locale, inflections_tree, count)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
# Uses the inflections subtree and creates internal mappings
|
197
|
+
# to resolve kinds assigned to inflection tokens and aliases, including defaults.
|
198
|
+
# @return [Hash,nil] the internal Hash containing inflections tokens or +nil+ if something went wrong
|
199
|
+
# @raise [I18n::BadInflectionToken] if a name of some loaded token is invalid
|
200
|
+
# @raise [I18n::BadInflectionAlias] if a loaded alias points to a token that does not exists
|
201
|
+
# @raise [I18n::DuplicatedInflectionToken] if a token has already appeard in loaded configuration
|
202
|
+
# @overload load_inflection_tokens(locale)
|
203
|
+
# @note That version calls the {inflection_subtree} method to obtain internal translations data.
|
204
|
+
# Loads inflection tokens for the given locale using internal hash of stored translations. Requires
|
205
|
+
# translations to be initialized.
|
206
|
+
# @param [Symbol] locale the locale to use and work for
|
207
|
+
# @return [Hash,nil] the internal Hash containing inflections or +nil+ if translations were not initialized
|
208
|
+
# @overload load_inflection_tokens(locale, subtree)
|
209
|
+
# Loads inflection tokens for the given locale using data given in an argument
|
210
|
+
# @param [Symbol] locale the locale to use and work for
|
211
|
+
# @param [Hash] subtree the tree (in a form of nested Hashes) containing inflection tokens to scan
|
212
|
+
# @return [Hash,nil] the internal Hash containing inflections or +nil+ if the given subtree was wrong or empty
|
213
|
+
def load_inflection_tokens(locale, subtree=nil)
|
214
|
+
inflections_tree = subtree || inflection_subtree(locale)
|
215
|
+
return nil if (inflections_tree.nil? || inflections_tree.empty?)
|
216
|
+
|
217
|
+
idb = I18n::Inflector::InflectionData.new(locale)
|
218
|
+
|
219
|
+
inflections_tree.each_pair do |kind, tokens|
|
220
|
+
tokens.each_pair do |token, description|
|
221
|
+
|
222
|
+
# test for duplicate
|
223
|
+
if idb.has_token?(token)
|
224
|
+
raise I18n::DuplicatedInflectionToken.new(idb.get_kind(token), kind, token)
|
225
|
+
end
|
226
|
+
|
227
|
+
# validate token's name
|
228
|
+
raise I18n::BadInflectionToken.new(locale, token, kind) if token.to_s.empty?
|
229
|
+
|
230
|
+
# validate token's description
|
231
|
+
if description.nil?
|
232
|
+
raise I18n::BadInflectionToken.new(locale, token, kind, description)
|
233
|
+
elsif description[0..0] == I18n::Inflector::ALIAS_MARKER
|
234
|
+
next
|
235
|
+
end
|
236
|
+
|
237
|
+
# handle default token for a kind
|
238
|
+
if token == :default
|
239
|
+
if idb.has_default_token?(kind) # should never happend unless someone is messing with @translations
|
240
|
+
raise I18n::DuplicatedInflectionToken.new(kind, nil, token)
|
241
|
+
end
|
242
|
+
idb.set_default_token(kind, description)
|
243
|
+
next
|
244
|
+
end
|
245
|
+
|
246
|
+
idb.add_token(token, kind, description)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
# handle aliases
|
251
|
+
inflections_tree.each_pair do |kind, tokens|
|
252
|
+
tokens.each_pair do |token, description|
|
253
|
+
next if description[0..0] != I18n::Inflector::ALIAS_MARKER
|
254
|
+
real_token = shorten_inflection_alias(token, kind, locale, inflections_tree)
|
255
|
+
idb.add_alias(token, real_token) unless real_token.nil?
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
# process and validate defaults
|
260
|
+
valid = idb.validate_default_tokens
|
261
|
+
raise I18n::BadInflectionAlias.new(locale, :default, valid[0], valid[1]) unless valid.nil?
|
262
|
+
|
263
|
+
idb
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
#
|
3
3
|
# Author:: Paweł Wilk (mailto:pw@gnu.org)
|
4
4
|
# Copyright:: (c) 2011 by Paweł Wilk
|
5
|
-
# License:: This program is licensed under the terms of {file:LGPL
|
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
7
|
# This file contains error reporting classes for I18n::Backend::Inflector module.
|
8
8
|
|
@@ -37,7 +37,7 @@ module I18n
|
|
37
37
|
"pattern #{pattern.inspect} is invalid"
|
38
38
|
end
|
39
39
|
end
|
40
|
-
|
40
|
+
|
41
41
|
# This is raised when an inflection token used in a pattern does not match
|
42
42
|
# an assumed kind determined by reading previous tokens from that pattern.
|
43
43
|
class MisplacedInflectionToken < ArgumentError
|
@@ -45,7 +45,7 @@ module I18n
|
|
45
45
|
def initialize(pattern, token, kind)
|
46
46
|
@pattern, @token, @kind = pattern, token, kind
|
47
47
|
super "inflection token #{token.inspect} from pattern #{pattern.inspect} " +
|
48
|
-
"is not of expected kind #{kind.inspect}"
|
48
|
+
"is not of the expected kind #{kind.inspect}"
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -69,22 +69,25 @@ module I18n
|
|
69
69
|
def initialize(locale, token, kind, pointer)
|
70
70
|
@locale, @token, @kind, @pointer = locale, token, kind, pointer
|
71
71
|
what = token == :default ? "default token" : "alias"
|
72
|
-
|
73
|
-
|
72
|
+
lang = locale.nil? ? "" : "for language #{locale.inspect} "
|
73
|
+
kinn = kind.nil? ? "" : "of kind #{kind.inspect} "
|
74
|
+
super "the #{what} #{token.inspect}" + kinn + lang +
|
75
|
+
"points to an unknown token #{pointer.inspect}"
|
74
76
|
end
|
75
77
|
end
|
76
|
-
|
78
|
+
|
77
79
|
# This is raised when an inflection token or its description has a bad name. This
|
78
80
|
# includes an empty name or a name containing prohibited characters.
|
79
81
|
class BadInflectionToken < ArgumentError
|
80
82
|
attr_reader :locale, :token, :kind, :description
|
81
|
-
def initialize(locale, token, kind, description=nil)
|
83
|
+
def initialize(locale, token, kind=nil, description=nil)
|
82
84
|
@locale, @token, @kind, @description = locale, token, kind, description
|
85
|
+
kinn = kind.nil? ? "" : "of kind #{kind.inspect} "
|
83
86
|
if description.nil?
|
84
|
-
super "Inflection token #{token.inspect}
|
87
|
+
super "Inflection token #{token.inspect} " + kinn +
|
85
88
|
"for language #{locale.inspect} has a bad name"
|
86
89
|
else
|
87
|
-
super "Inflection token #{token.inspect}
|
90
|
+
super "Inflection token #{token.inspect} " + kinn +
|
88
91
|
"for language #{locale.inspect} has a bad description #{description.inspect}"
|
89
92
|
end
|
90
93
|
end
|
@@ -0,0 +1,329 @@
|
|
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 utility methods,
|
8
|
+
# that are used by I18n::Inflector and I18n::Backend::Inflector.
|
9
|
+
|
10
|
+
# @abstract This namespace is shared with I18n subsystem.
|
11
|
+
module I18n
|
12
|
+
module Inflector
|
13
|
+
|
14
|
+
# This class contains structures for keeping parsed translation data
|
15
|
+
# and basic operations for performing on them.
|
16
|
+
class InflectionData
|
17
|
+
|
18
|
+
# Initializes internal structures.
|
19
|
+
def initialize(locale=nil)
|
20
|
+
dummy_token = {:kind=>nil,:target=>nil,:description=>nil}
|
21
|
+
@kinds = Hash.new(false)
|
22
|
+
@tokens = Hash.new(dummy_token)
|
23
|
+
@defaults = {}
|
24
|
+
@locale = locale
|
25
|
+
end
|
26
|
+
|
27
|
+
# Locale that this database works on.
|
28
|
+
attr_reader :locale
|
29
|
+
|
30
|
+
# Adds an alias (overwriting existing alias).
|
31
|
+
#
|
32
|
+
# @param [Symbol] name the name of an alias
|
33
|
+
# @param [Symbol] target the target token for the given +alias+
|
34
|
+
# @return [Boolean] +true+ if everything went ok, +false+ otherwise
|
35
|
+
# (in case of bad or +nil+ names or non-existent targets)
|
36
|
+
def add_alias(name, target)
|
37
|
+
target = target.to_s
|
38
|
+
name = name.to_s
|
39
|
+
return false if (name.empty? || target.empty?)
|
40
|
+
name = name.to_sym
|
41
|
+
target = target.to_sym
|
42
|
+
kind = get_kind(target)
|
43
|
+
return false if kind.nil?
|
44
|
+
@tokens[name] = {}
|
45
|
+
@tokens[name][:kind] = kind
|
46
|
+
@tokens[name][:target] = target
|
47
|
+
@tokens[name][:description] = @tokens[target][:description]
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
# Adds a token (overwriting existing token).
|
52
|
+
#
|
53
|
+
# @param [Symbol] token the name of a token to add
|
54
|
+
# @param [Symbol] kind the kind of a token
|
55
|
+
# @param [String] description the description of a token
|
56
|
+
# @return [void]
|
57
|
+
def add_token(token, kind, description)
|
58
|
+
token = token.to_sym
|
59
|
+
@tokens[token] = {}
|
60
|
+
@tokens[token][:kind] = kind.to_sym
|
61
|
+
@tokens[token][:description] = description.to_s
|
62
|
+
@kinds[kind] = true
|
63
|
+
end
|
64
|
+
|
65
|
+
# Sets the default token for a kind.
|
66
|
+
#
|
67
|
+
# @param [Symbol] kind the kind to which the default
|
68
|
+
# token should be assigned
|
69
|
+
# @param [Symbol] target the token to set
|
70
|
+
# @return [void]
|
71
|
+
def set_default_token(kind, target)
|
72
|
+
@defaults[kind.to_sym] = target.to_sym
|
73
|
+
end
|
74
|
+
|
75
|
+
# Tests if the token is a true token.
|
76
|
+
#
|
77
|
+
# @overload has_true_token?(token)
|
78
|
+
# Tests if the token is a true token.
|
79
|
+
# @param [Symbol] token the identifier of a token
|
80
|
+
# @return [Boolean] +true+ if the given +token+ is
|
81
|
+
# a token and not an alias, +false+ otherwise
|
82
|
+
# @overload has_true_token?(token, kind)
|
83
|
+
# Tests if the token is a true token.
|
84
|
+
# @param [Symbol] token the identifier of a token
|
85
|
+
# @param [Symbol] kind the identifier of a kind
|
86
|
+
# @return [Boolean] +true+ if the given +token+ is
|
87
|
+
# a token and not an alias, and is a kind of
|
88
|
+
# the given kind, +false+ otherwise
|
89
|
+
def has_true_token?(token, kind=nil)
|
90
|
+
o = @tokens[token]
|
91
|
+
k = o[:kind]
|
92
|
+
return false if (k.nil? || !o[:target].nil?)
|
93
|
+
kind.nil? ? true : k == kind
|
94
|
+
end
|
95
|
+
|
96
|
+
# Tests if a token (or alias) is present.
|
97
|
+
#
|
98
|
+
# @overload has_token(token)
|
99
|
+
# Tests if a token (or alias) is present.
|
100
|
+
# @param [Symbol] token the identifier of a token
|
101
|
+
# @return [Boolean] +true+ if the given +token+
|
102
|
+
# (which may be an alias) exists
|
103
|
+
# @overload has_token(token, kind)
|
104
|
+
# Tests if a token (or alias) is present.
|
105
|
+
# @param [Symbol] token the identifier of a token
|
106
|
+
# @param [Symbol] kind the identifier of a kind
|
107
|
+
# @return [Boolean] +true+ if the given +token+
|
108
|
+
# (which may be an alias) exists and if kind of
|
109
|
+
# the given kind
|
110
|
+
def has_token?(token, kind=nil)
|
111
|
+
k = @tokens[token][:kind]
|
112
|
+
kind.nil? ? !k.nil? : k == kind
|
113
|
+
end
|
114
|
+
|
115
|
+
# Tests if a kind exists.
|
116
|
+
#
|
117
|
+
# @param [Symbol] kind the identifier of a kind
|
118
|
+
# @return [Boolean] +true+ if the given +kind+ exists
|
119
|
+
def has_kind?(kind)
|
120
|
+
@kinds.has_key?(kind)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Tests if a kind has a default token assigned.
|
124
|
+
#
|
125
|
+
# @param [Symbol] kind the identifier of a kind
|
126
|
+
# @return [Boolean] +true+ if there is a default
|
127
|
+
# token of the given kind
|
128
|
+
def has_default_token?(kind)
|
129
|
+
@defaults.has_key?(kind)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Tests if a given alias is really an alias.
|
133
|
+
#
|
134
|
+
# @overload has_alias?(alias_name)
|
135
|
+
# Tests if a given alias is really an alias.
|
136
|
+
# @param [Symbol] alias_name the identifier of an alias
|
137
|
+
# @return [Boolean] +true+ if the given alias is really an alias,
|
138
|
+
# +false+ otherwise
|
139
|
+
# @overload has_alias?(alias_name, kind)
|
140
|
+
# Tests if a given alias is really an alias.
|
141
|
+
# @param [Symbol] alias_name the identifier of an alias
|
142
|
+
# @param [Symbol] kind the identifier of a kind
|
143
|
+
# @return [Boolean] +true+ if the given alias is really an alias
|
144
|
+
# being a kind of the given kind, +false+ otherwise
|
145
|
+
def has_alias?(alias_name, kind=nil)
|
146
|
+
o = @tokens[alias_name]
|
147
|
+
return false if o[:target].nil?
|
148
|
+
kind.nil? ? true : o[:kind] == kind
|
149
|
+
end
|
150
|
+
|
151
|
+
# Reads the all the true tokens (not aliases).
|
152
|
+
#
|
153
|
+
# @return [Hash] the true tokens in a
|
154
|
+
# form of Hash (<tt>token => description</tt>)
|
155
|
+
# @overload get_true_tokens(kind)
|
156
|
+
# Reads the all the true tokens (not aliases).
|
157
|
+
# @return [Hash] the true tokens in a
|
158
|
+
# form of Hash (<tt>token => description</tt>)
|
159
|
+
# @overload get_true_tokens(kind)
|
160
|
+
# Reads the all the true tokens (not aliases).
|
161
|
+
# @param [Symbol] kind the identifier of a kind
|
162
|
+
# @return [Hash] the true tokens of the given kind in a
|
163
|
+
# form of Hash (<tt>token => description</tt>)
|
164
|
+
def get_true_tokens(kind=nil)
|
165
|
+
tokens = @tokens.reject{|k,v| !v[:target].nil?}
|
166
|
+
tokens = tokens.reject{|k,v| v[:kind]!=kind} unless kind.nil?
|
167
|
+
tokens.merge(tokens){|k,v| v[:description]}
|
168
|
+
end
|
169
|
+
|
170
|
+
# Reads the all the aliases.
|
171
|
+
#
|
172
|
+
# @return [Hash] the aliases in a
|
173
|
+
# form of Hash (<tt>alias => target</tt>)
|
174
|
+
# @overload get_aliases(kind)
|
175
|
+
# Reads the all the aliases.
|
176
|
+
# @return [Hash] the aliases in a
|
177
|
+
# form of Hash (<tt>alias => target</tt>)
|
178
|
+
# @overload get_aliases(kind)
|
179
|
+
# Reads the all the aliases.
|
180
|
+
# @param [Symbol] kind the identifier of a kind
|
181
|
+
# @return [Hash] the aliases of the given kind in a
|
182
|
+
# form of Hash (<tt>alias => target</tt>)
|
183
|
+
def get_aliases(kind=nil)
|
184
|
+
aliases = @tokens.reject{|k,v| v[:target].nil?}
|
185
|
+
aliases = aliases.reject{|k,v| v[:kind]!=kind} unless kind.nil?
|
186
|
+
aliases.merge(aliases){|k,v| v[:target]}
|
187
|
+
end
|
188
|
+
|
189
|
+
# Reads the all the tokens in a way that it is possible to
|
190
|
+
# distinguish true tokens from aliases.
|
191
|
+
#
|
192
|
+
# @note True tokens have descriptions (String) and aliases
|
193
|
+
# have targets (Symbol) assigned.
|
194
|
+
# @return [Hash] the tokens in a
|
195
|
+
# form of Hash (<tt>token => description|target</tt>)
|
196
|
+
# @overload get_raw_tokens
|
197
|
+
# Reads the all the tokens.
|
198
|
+
# @return [Hash] the tokens in a
|
199
|
+
# form of Hash (<tt>token => description|target</tt>)
|
200
|
+
# @overload get_raw_tokens(kind)
|
201
|
+
# Reads the all the tokens.
|
202
|
+
# @param [Symbol] kind the identifier of a kind
|
203
|
+
# @return [Hash] the tokens of the given kind in a
|
204
|
+
# form of Hash (<tt>token => description|target</tt>)
|
205
|
+
def get_raw_tokens(kind=nil)
|
206
|
+
get_true_tokens(kind).merge(get_aliases(kind))
|
207
|
+
end
|
208
|
+
|
209
|
+
# Reads the all the tokens (including aliases).
|
210
|
+
#
|
211
|
+
# @note Use {get_raw_tokens} if you want to distinguish
|
212
|
+
# true tokens from aliases.
|
213
|
+
# @return [Hash] the tokens in a
|
214
|
+
# form of Hash (<tt>token => description</tt>)
|
215
|
+
# @overload get_raw_tokens(kind)
|
216
|
+
# Reads the all the tokens (including aliases).
|
217
|
+
# @return [Hash] the tokens in a
|
218
|
+
# form of Hash (<tt>token => description</tt>)
|
219
|
+
# @overload get_raw_tokens(kind)
|
220
|
+
# Reads the all the tokens (including aliases).
|
221
|
+
# @param [Symbol] kind the identifier of a kind
|
222
|
+
# @return [Hash] the tokens of the given kind in a
|
223
|
+
# form of Hash (<tt>token => description</tt>)
|
224
|
+
def get_tokens(kind=nil)
|
225
|
+
tokens = @tokens
|
226
|
+
tokens = tokens.reject{|k,v| v[:kind]!=kind} unless kind.nil?
|
227
|
+
tokens.merge(tokens){|k,v| v[:description]}
|
228
|
+
end
|
229
|
+
|
230
|
+
# Gets a target token for the alias.
|
231
|
+
#
|
232
|
+
# @param [Symbol] alias_name the identifier of an alias
|
233
|
+
# @return [Symbol,nil] the token that the given alias points to
|
234
|
+
# or +nil+ if it isn't really an alias
|
235
|
+
def get_target_for_alias(alias_name)
|
236
|
+
@tokens[alias_name][:target]
|
237
|
+
end
|
238
|
+
|
239
|
+
# Gets a kind of the given token or alias.
|
240
|
+
#
|
241
|
+
# @param [Symbol] token identifier of a token
|
242
|
+
# @return [Symbol,nil] the kind of the given +token+
|
243
|
+
# or +nil+ if the token is unknown
|
244
|
+
def get_kind(token)
|
245
|
+
@tokens[token][:kind]
|
246
|
+
end
|
247
|
+
|
248
|
+
# Gets a true token for the given identifier.
|
249
|
+
#
|
250
|
+
# @note If the given +token+ is really an alias it will
|
251
|
+
# be resolved and the real token pointed by that alias
|
252
|
+
# will be returned.
|
253
|
+
# @overload get_true_token(token)
|
254
|
+
# Gets a true token for the given token identifier.
|
255
|
+
# @param [Symbol] token the identifier of a token
|
256
|
+
# @return [Symbol,nil] the true token for the given +token+
|
257
|
+
# or +nil+ if the token is unknown
|
258
|
+
# @overload get_true_token(token, kind)
|
259
|
+
# Gets a true token for the given token identifier and the
|
260
|
+
# given kind.
|
261
|
+
# @param [Symbol] token the identifier of a token
|
262
|
+
# @param [Symbol] kind the identifier of a kind
|
263
|
+
# @return [Symbol,nil] the true token for the given +token+
|
264
|
+
# or +nil+ if the token is unknown or is not kind of the
|
265
|
+
# given kind
|
266
|
+
def get_true_token(token, kind=nil)
|
267
|
+
o = @tokens[token]
|
268
|
+
k = o[:kind]
|
269
|
+
return nil if k.nil?
|
270
|
+
r = (o[:target] || token)
|
271
|
+
return r if kind.nil?
|
272
|
+
k == kind ? r : nil
|
273
|
+
end
|
274
|
+
|
275
|
+
# Gets all known kinds.
|
276
|
+
#
|
277
|
+
# @return [Array<Symbol>] an array containing all the known kinds
|
278
|
+
def get_kinds
|
279
|
+
@kinds.keys
|
280
|
+
end
|
281
|
+
|
282
|
+
# Reads the default token of a kind.
|
283
|
+
#
|
284
|
+
# @note It will always return true token (not an alias).
|
285
|
+
# @param [Symbol] kind the identifier of a kind
|
286
|
+
# @return [Symbol,nil] the default token of the given +kind+
|
287
|
+
# or +nil+ if there is no default token set
|
288
|
+
def get_default_token(kind)
|
289
|
+
@defaults[kind]
|
290
|
+
end
|
291
|
+
|
292
|
+
# Gets a description of a token or alias.
|
293
|
+
#
|
294
|
+
# @note If the token is really an alias it will resolve the alias first.
|
295
|
+
# @param [Symbol] token the identifier of a token
|
296
|
+
# @return [String,nil] the string containing description of the given
|
297
|
+
# token (which may be an alias) or +nil+ if the token is unknown
|
298
|
+
def get_description(token)
|
299
|
+
@tokens[token][:description]
|
300
|
+
end
|
301
|
+
|
302
|
+
# This method validates default tokens assigned
|
303
|
+
# for kinds and replaces targets with true tokens
|
304
|
+
# if they are aliases.
|
305
|
+
#
|
306
|
+
# @return [nil,Array<Symbol>] +nil+ if everything went fine,
|
307
|
+
# two dimensional array containing kind and target
|
308
|
+
# in case of error while geting a token
|
309
|
+
def validate_default_tokens
|
310
|
+
@defaults.each_pair do |kind, pointer|
|
311
|
+
ttok = get_true_token(pointer)
|
312
|
+
return [kind, pointer] if ttok.nil?
|
313
|
+
set_default_token(kind, ttok)
|
314
|
+
end
|
315
|
+
return nil
|
316
|
+
end
|
317
|
+
|
318
|
+
# Test if the inflection data have no elements.
|
319
|
+
#
|
320
|
+
# @return [Boolean] +true+ if the inflection data
|
321
|
+
# have no elements
|
322
|
+
def empty?
|
323
|
+
@tokens.empty?
|
324
|
+
end
|
325
|
+
|
326
|
+
end # InflectionData
|
327
|
+
|
328
|
+
end
|
329
|
+
end
|