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/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
@@ -8,4 +8,3 @@ i18n-inflector is copyrighted software owned by Paweł Wilk
8
8
  software as long as you comply with either the terms of the LGPL
9
9
  (see the file {file:LGPL}),
10
10
  or Ruby's license (see the file {file:COPYING}).
11
-
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::Core} used to create inflector object attached to I18n backend
5
- * Class {I18n::Inflector::InflectionData} used by {I18n::Inflector::Core} instances to store
6
- inflection data and manipulate them, also is used by {I18n::Backend::Inflector} instances when loading
7
- translations to create new database within {I18n::Inflector::Core} instance attachend to backend
8
- * Class {I18n::Inflector::InflectionOptions} is used inside of {I18n::Inflector::Core} for keeping
9
- switches and options
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::Core} attached to backend
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::Inflector::Core} has an instance variable defined that contains database of translation data
20
- * Each entry in the internal database of {I18n::Inflector::Core} is indexed by locale and is kind of
21
- {I18n::Inflector::InflectionData}
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 the +i18n.inflections+ part for each locale and creates configuration
24
- that is keeped as an instance of {I18n::Inflector::InflectionData}. That data is registered within the
25
- inflecor object attached to backend that loaded the translations.
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
- * add some negative tests (e.g. empty kind, kinds as nils or empty striongs, tokens as empty strings...)
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
- * 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
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
- * 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?
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