i18n-inflector 2.0.1 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +1 -0
- data/ChangeLog +412 -0
- data/Gemfile +1 -0
- data/Manifest.txt +6 -1
- data/README.rdoc +16 -11
- data/Rakefile +15 -2
- data/ci/i18n-inflector.gemspec +1 -1
- data/ci/i18nv4-Gemfile +15 -0
- data/docs/EXAMPLES +222 -0
- data/docs/HISTORY +31 -0
- data/docs/LEGAL +0 -1
- data/docs/RELATIONS +16 -13
- data/docs/TODO +25 -3
- data/lib/i18n-inflector/api.rb +964 -0
- data/lib/i18n-inflector/api_strict.rb +519 -0
- data/lib/i18n-inflector/backend.rb +77 -40
- data/lib/i18n-inflector/errors.rb +56 -14
- data/lib/i18n-inflector/inflection_data.rb +133 -105
- data/lib/i18n-inflector/inflection_data_strict.rb +290 -0
- data/lib/i18n-inflector/inflector.rb +21 -660
- data/lib/i18n-inflector/lazy_enum.rb +120 -0
- data/lib/i18n-inflector/long_comments.rb +203 -14
- data/lib/i18n-inflector/version.rb +1 -1
- data/lib/i18n-inflector.rb +5 -3
- data/test/inflector_test.rb +334 -34
- data/test/test_helper.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +10 -6
- metadata.gz.sig +0 -0
- data/lib/i18n-inflector/util.rb +0 -67
data/docs/EXAMPLES
ADDED
@@ -0,0 +1,222 @@
|
|
1
|
+
|
2
|
+
== Configuring inflections
|
3
|
+
|
4
|
+
This data will be used in any further example:
|
5
|
+
|
6
|
+
=== YAML
|
7
|
+
|
8
|
+
en:
|
9
|
+
i18n:
|
10
|
+
inflections:
|
11
|
+
|
12
|
+
@person:
|
13
|
+
i: "i"
|
14
|
+
you: "you"
|
15
|
+
he: "he"
|
16
|
+
she: "she"
|
17
|
+
it: "it"
|
18
|
+
u: @you
|
19
|
+
|
20
|
+
gender:
|
21
|
+
m: "male"
|
22
|
+
f: "female"
|
23
|
+
n: "neuter"
|
24
|
+
default: neuter
|
25
|
+
|
26
|
+
|
27
|
+
welcome: "Dear @{f:Lady|m:Sir|n:You|All}!"
|
28
|
+
sayit: "@person{i:I|u:You|he:He|she:She|it:It} @person{i:am|u:are|he,she,it:is}"
|
29
|
+
tobe: "%{person} @person{i:am|u:are|he,she,it:is}"
|
30
|
+
|
31
|
+
|
32
|
+
=== Code
|
33
|
+
|
34
|
+
I18n.backend.store_translations(:en, :i18n => { :inflections => {
|
35
|
+
:gender => {
|
36
|
+
:m => 'male',
|
37
|
+
:f => 'female',
|
38
|
+
:n => 'neuter',
|
39
|
+
:default => :n
|
40
|
+
},
|
41
|
+
:@person => {
|
42
|
+
:i => 'i',
|
43
|
+
:u => 'you',
|
44
|
+
:he => 'he',
|
45
|
+
:she => 'she',
|
46
|
+
:it => 'it',
|
47
|
+
:you => :@u
|
48
|
+
}
|
49
|
+
}})
|
50
|
+
|
51
|
+
I18n.backend.store_translations(:en, 'welcome' => 'Dear @{f:Lady|m:Sir|n:You|All}!')
|
52
|
+
I18n.backend.store_translations(:en, 'sayit' => '@person{i:I|u:You|he:He|she:She|it:It} @person{i:am|u:are|he,she,it:is}')
|
53
|
+
I18n.backend.store_translations(:en, 'tobe' => '%{person} @person{i:am|u:are|he,she,it:is}')
|
54
|
+
I18n.locale = :en
|
55
|
+
|
56
|
+
== Simple interpolation
|
57
|
+
|
58
|
+
When no option, it falls back to default token (n):
|
59
|
+
|
60
|
+
I18n.translate('welcome')
|
61
|
+
#=> "Dear You!"
|
62
|
+
|
63
|
+
When :m, it interpolates the m token's value:
|
64
|
+
|
65
|
+
I18n.translate('welcome', :gender => :m)
|
66
|
+
#=> "Dear Sir!"
|
67
|
+
|
68
|
+
When unknown, it falls back to default token (n):
|
69
|
+
|
70
|
+
I18n.translate('welcome', :gender => :unknown)
|
71
|
+
#=> "Dear You!"
|
72
|
+
|
73
|
+
When +nil+, it falls back to default token (n):
|
74
|
+
|
75
|
+
I18n.translate('welcome', :gender => nil)
|
76
|
+
#=> "Dear You!"
|
77
|
+
|
78
|
+
=== <tt>inflector_unknown_defaults</tt>
|
79
|
+
|
80
|
+
When <tt>:inflector_unknown_defaults</tt> is false, it falls back to free text:
|
81
|
+
|
82
|
+
I18n.translate('welcome', :gender => :unknown, :inflector_unknown_defaults => false)
|
83
|
+
#=> "Dear All!"
|
84
|
+
|
85
|
+
It also falls back when an inflection option is nil or empty:
|
86
|
+
|
87
|
+
I18n.translate('welcome', :gender => nil, :inflector_unknown_defaults => false)
|
88
|
+
#=> "Dear All!"
|
89
|
+
|
90
|
+
== Named pattern
|
91
|
+
|
92
|
+
Regular inflection option will be used if there is no strict inflection option:
|
93
|
+
|
94
|
+
I18n.translate('sayit', :person => :i)
|
95
|
+
#=> "I am"
|
96
|
+
|
97
|
+
Strict inflection option has precedence:
|
98
|
+
|
99
|
+
I18n.translate('sayit', :person => :i, :@person => :u)
|
100
|
+
#=> "You are"
|
101
|
+
|
102
|
+
|
103
|
+
Strict inflection option has precedence even if the option's value is messy:
|
104
|
+
|
105
|
+
I18n.translate('sayit', :person => :i, :@person => :unknown)
|
106
|
+
#=> " "
|
107
|
+
|
108
|
+
=== Using with interpolation argument
|
109
|
+
|
110
|
+
First part is interpolated using standard interpolation variable while
|
111
|
+
second part of the sentence comes from interpolation of inflection pattern.
|
112
|
+
The same option is feeding both engines.
|
113
|
+
|
114
|
+
I18n.translate('tobe', :person => :i)
|
115
|
+
#=> "i am"
|
116
|
+
|
117
|
+
Note funny thing. The interpolation variable +test+ takes value (+i+) from
|
118
|
+
+:person+ while option +:@person+ takes precedence when it comes to inflections.
|
119
|
+
Keep that in mind when combining regular interpolation variables with named patterns
|
120
|
+
while using the same variable for controlling both. Choose non-strict notation
|
121
|
+
for an option then.
|
122
|
+
|
123
|
+
I18n.translate('tobe', :person => :i, :@person => :u)
|
124
|
+
#=> "i are"
|
125
|
+
|
126
|
+
No free text in 'tobe' so the empty string is interpolated when strict kind is unknown:
|
127
|
+
|
128
|
+
I18n.translate('tobe', :person => :i, :@person => :unknown)
|
129
|
+
#=> "i "
|
130
|
+
|
131
|
+
== API
|
132
|
+
|
133
|
+
=== Getting kinds
|
134
|
+
|
135
|
+
Getting all known regular kinds:
|
136
|
+
|
137
|
+
I18n.inflector.kinds
|
138
|
+
#=> [:gender]
|
139
|
+
|
140
|
+
Getting all known strict kinds:
|
141
|
+
|
142
|
+
I18n.inflector.strict.kinds
|
143
|
+
#=> [:person]
|
144
|
+
|
145
|
+
Getting all known kinds for language 'pl':
|
146
|
+
|
147
|
+
I18n.inflector.kinds(:pl)
|
148
|
+
#=> []
|
149
|
+
|
150
|
+
<i>to be continued…</i>
|
151
|
+
|
152
|
+
== Real-life example for Polish language
|
153
|
+
|
154
|
+
Polish is highly inflected language. Additionally, position of a word in
|
155
|
+
a sentence is mutually coupled with meaning. That makes it extreemly
|
156
|
+
hard to create finite-state machine that would handle Polish grammar.
|
157
|
+
However, flection means that the same cores are combined with suffixes
|
158
|
+
and prefixes depending on many different kinds: gender, tense, form,
|
159
|
+
animation, declination and more. That makes Polish (and other Slavic
|
160
|
+
languages) alphabetically redundant. By interpolating common cores,
|
161
|
+
prefixes and suffixes of words we're able make our patterns compact.
|
162
|
+
|
163
|
+
=== YAML
|
164
|
+
|
165
|
+
pl:
|
166
|
+
are_you_sure: "@{m,f:Jesteś pew}@{m:ien|f:na}@{n:Na pewno}?"
|
167
|
+
|
168
|
+
i18n:
|
169
|
+
inflections:
|
170
|
+
gender:
|
171
|
+
f: "rodzaj żeński"
|
172
|
+
m: "rodzaj męski"
|
173
|
+
n: "forma bezosobowa"
|
174
|
+
masculine: @m
|
175
|
+
facet: @m
|
176
|
+
chłop: @m
|
177
|
+
chłopak: @m
|
178
|
+
chłopiec: @m
|
179
|
+
mąż: @m
|
180
|
+
feminine: @f
|
181
|
+
pani: @f
|
182
|
+
kobieta: @f
|
183
|
+
k: @f
|
184
|
+
dziewczyna: @f
|
185
|
+
baba: @f
|
186
|
+
babka: @f
|
187
|
+
facetka: @f
|
188
|
+
impersonal: @n
|
189
|
+
default: n
|
190
|
+
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
=== Code
|
195
|
+
|
196
|
+
# Using shorter form than YAML-listed
|
197
|
+
|
198
|
+
I18n.backend.store_translations(:pl, :i18n => { :inflections => { :gender =>
|
199
|
+
{ :f => 'f', :m=>'m', :n=>'n', :kobieta=>:@f, :facet => :@m, :default=>:n }}})
|
200
|
+
|
201
|
+
# Making use of commas makes it easy to implement DRY
|
202
|
+
# and re-use some parts of the words that are the same in two or more phrases
|
203
|
+
|
204
|
+
I18n.backend.store_translations(:pl, :are_you_sure => "@{m,f:Jesteś pew}@{m:ien|f:na}@{n:Na pewno}?")
|
205
|
+
|
206
|
+
I18n.locale = :pl
|
207
|
+
|
208
|
+
I18n.translate('are_you_sure', :gender => :kobieta)
|
209
|
+
#=> "Jesteś pewna?"
|
210
|
+
|
211
|
+
I18n.translate('are_you_sure', :gender => :facet)
|
212
|
+
#=> "Jesteś pewien?"
|
213
|
+
|
214
|
+
I18n.translate('are_you_sure')
|
215
|
+
#=> "Na pewno?"
|
216
|
+
|
217
|
+
# It would look like that without commas:
|
218
|
+
I18n.backend.store_translations(:pl, :are_you_sure => "@{m:Jesteś pewien|f:Jesteś pewna}@{n:Na pewno}?")
|
219
|
+
|
220
|
+
# That would also work but it's less readable.
|
221
|
+
# PS: Have you ever configured Sendmail? ;-)
|
222
|
+
I18n.backend.store_translations(:pl, :are_you_sure => "@{n:Na|m,f:Jesteś} pew@{m:ie}n@{f:a|n:o}?")
|
data/docs/HISTORY
CHANGED
@@ -1,3 +1,34 @@
|
|
1
|
+
=== 2.1.0 / 2011-01-27
|
2
|
+
|
3
|
+
* major enhancements
|
4
|
+
|
5
|
+
* Added named patterns support (strict kinds)
|
6
|
+
* API improved: major class is I18n::Inflector::API
|
7
|
+
* Added class I18n::Inflector::API_Strict for accessing strict inflections
|
8
|
+
* Added lazy enumerators for internal hashes, which saves some memory
|
9
|
+
* Added strict kinds detection (@-style kind names) to most of the methods from main API class
|
10
|
+
* Added new error classes: InflectionOptionNotFound and InflectionOptionIncorrect
|
11
|
+
* Added class for handling inflection data for strict kinds: I18n::Inflector::InflectionData_Strict
|
12
|
+
* Inflections for regular and strict kinds are handled by separate data structures and objects
|
13
|
+
* Documentation updated
|
14
|
+
|
15
|
+
* minor bugfixes
|
16
|
+
|
17
|
+
* Error reporting fixed in some places
|
18
|
+
* Strict kinds interpolation improved
|
19
|
+
* Removed some slow blocks
|
20
|
+
* Loading inflection tokens cleaned up
|
21
|
+
|
22
|
+
=== 2.0.1 / 2011-01-15
|
23
|
+
|
24
|
+
* minor enhancements
|
25
|
+
|
26
|
+
* Documentation updated
|
27
|
+
|
28
|
+
* minor bugfixes
|
29
|
+
|
30
|
+
* Fixed duplicated dependency generation in Hoe
|
31
|
+
|
1
32
|
=== 2.0.0 / 2011-01-14
|
2
33
|
|
3
34
|
* major enhancements
|
data/docs/LEGAL
CHANGED
data/docs/RELATIONS
CHANGED
@@ -1,25 +1,28 @@
|
|
1
1
|
== This library contains
|
2
2
|
|
3
3
|
* Module {I18n::Inflector} containing everything
|
4
|
-
* Class {I18n::Inflector::
|
5
|
-
* Class {I18n::Inflector::
|
6
|
-
|
7
|
-
|
8
|
-
* Class {I18n::Inflector::InflectionOptions}
|
9
|
-
|
4
|
+
* Class {I18n::Inflector::API} used to create inflector object attached to I18n backend (handles regular and strict kinds)
|
5
|
+
* Class {I18n::Inflector::API_Strict} which instance is attached to {I18n::Inflector::API} and handles strict kinds
|
6
|
+
* Class {I18n::Inflector::InflectionData} used to store inflection data for regular kinds and tokens
|
7
|
+
* Class {I18n::Inflector::InflectionData_Strict} used to store inflection data for strict kinds and tokens
|
8
|
+
* Class {I18n::Inflector::InflectionOptions} used for keeping switches and options
|
9
|
+
* Class {I18n::Inflector::LazyHashEnumerator} used to manage lazy evaluation of internal data
|
10
10
|
* Module {I18n::Backend::Inflector} used to alter methods of {I18n::Backend::Simple}
|
11
|
+
* Several classes for error reporting
|
11
12
|
|
12
13
|
== Relations
|
13
14
|
|
14
15
|
* {I18n.backend} is the currently used backend and the instance of {I18n::Backend::Simple}
|
15
|
-
* {I18n.backend.inflector} is the instance of {I18n::Inflector::
|
16
|
+
* {I18n.backend.inflector} is the instance of {I18n::Inflector::API} attached to backend
|
16
17
|
* {I18n.inflector} is the proxy module method that calls inflector for currently used backend {I18n.backend.inflector}
|
17
18
|
* {I18n.backend.inflector.options} is the instance of {I18n::Inflector::InflectionOptions} and
|
18
19
|
mainly it controls a behavior of interpolation method
|
19
|
-
* {I18n
|
20
|
-
*
|
21
|
-
|
20
|
+
* {I18n.backend.inflector.strict} is the instance of {I18n::Inflector::API_Strict} and handles strict kinds
|
21
|
+
* {I18n.backend.inflector} uses {I18n.backend.inflector.strict} to access strict kinds when it's needed
|
22
|
+
* {I18n::Inflector::API} has an instance variable @idb that contains database of inflections indexed by locale
|
23
|
+
* {I18n::Inflector::API_Strict} has an instance variable @idb that contains database of inflections indexed by locale
|
24
|
+
* Translation databases are kind of {I18n::Inflector::InflectionData} and {I18n::Inflector::InflectionData_Strict}
|
22
25
|
* When initializing translations a method from {I18n::Backend::Simple} (altered by {I18n::Backend::Inflector})
|
23
|
-
takes the loaded data, processes
|
24
|
-
|
25
|
-
|
26
|
+
takes the loaded data, processes their <tt>i18n.inflections</tt> scope for each locale and creates database
|
27
|
+
objects which are kind of {I18n::Inflector::InflectionData} and {I18n::Inflector::InflectionData_Strict}. That
|
28
|
+
objects are then attached to instances of {I18n::Inflector::API} and {I18n::Inflector::API_Strict}.
|
data/docs/TODO
CHANGED
@@ -1,9 +1,31 @@
|
|
1
1
|
== Near future
|
2
2
|
|
3
|
-
*
|
3
|
+
* do something with that to_h that creates intermediate array
|
4
|
+
|
5
|
+
* add a switch that causes inflection arguments to be gathered and removed before using original
|
6
|
+
version of translate and then injected when interpolating happens (default value
|
7
|
+
for that switch should be true if there is I18n version 4 installed)
|
8
|
+
|
9
|
+
- not so good idea to turn it on by default since the same variable may be used to interpolate
|
10
|
+
inflections and for direct interpolation
|
11
|
+
|
12
|
+
* attach inflection key name to some raised errors
|
13
|
+
|
14
|
+
* add some external iterators for tokens, aliases, kinds, true_tokens
|
15
|
+
|
16
|
+
* allow different descriptions for aliases pointing to the same token, e.g.: now: @present ="description"
|
4
17
|
|
5
18
|
== Distant future
|
6
19
|
|
7
|
-
*
|
20
|
+
* Loud tokens: description substitution, e.g.: "Dear @{u|i:me}" gives "Dear You" if u is described as "You"
|
21
|
+
|
22
|
+
* Combined patterns (!!!!!!!!!!!!)
|
23
|
+
|
24
|
+
- @person+time{i+now:am|i+past:was}
|
25
|
+
- @person+time{i+now:am|i+past:was|he,she,it+now:is}
|
26
|
+
- @g_sender+g_receiver{...} - for Hebrew for example
|
27
|
+
|
28
|
+
* case-insensitivity switch for inflection options (?)
|
8
29
|
|
9
|
-
*
|
30
|
+
* think about allowing negative matches to be AND-ed, e.g.: !m&!f:impersonal (?)
|
31
|
+
- that will double positive-matching syntax, and make it even less KISS
|