fast_gettext 1.8.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af7af45d00211da2791e03bf1f4f7c611d8c557a10f339189ebdf2a72008ff05
4
- data.tar.gz: 23040ab7524d7eb95b0e11fcc22a05a1ddf54eeeb88babade01c9876620447c5
3
+ metadata.gz: fd142399ba76554f219419441c5591bcbaec03952fd4e9c78fe10d3a4853f13e
4
+ data.tar.gz: f2bced062cbea2a26a5f516a827919d9b6a5851ac8cecd90fed2d1d3196d7f4b
5
5
  SHA512:
6
- metadata.gz: c9152caffa285a723a4681e23db5d0710465a5b47f2c2251f863026cf91da316cdd36155097038896d77cb1c5562af619e73cf29f69be70bebec28ac8bf6d272
7
- data.tar.gz: c59623e1c15a293922cfcdd457634a2cb5f082900ee0948d14d7d37c4ddac5533f1fa6437f8e9bc200cc391e9be4a8c6d416e72568017905f0be930fbd65bb00
6
+ metadata.gz: 4de75b912d96f43333ad82b6e4d6a185d883b23ace4d278ecd9aaca7670d751d17be1ed0413482f72296034b61b5cb1fe05261715f233cce07da5e776681fd13
7
+ data.tar.gz: a6ae68e754d3d99cd9ecc2f9337683adc6883b13dbd21f74e8135eb41a6d3d94764b583383642b68dda890a0ca6979b688e23df243aad99dd28ab696d3a7eb56
data/CHANGELOG CHANGED
@@ -1,11 +1,13 @@
1
+ 2.1.0 -- Remove taint checking https://github.com/grosser/fast_gettext/pull/133
2
+ 2.0.0 -- Changed p_ separator to \0004 https://github.com/grosser/fast_gettext/pull/107 add np and add gettext aliases
1
3
  1.6.0 -- Remove restrictions around yaml file names
2
4
  1.1.0 -- translations are no longer eager loaded for improved startup performance, pass `eager_load: true` to preload for example in preforked web server
3
5
  1.0.0 -- do not enforce attr_accessible unless ProtectedAttributes are loaded
4
- 0.9.0 -- reworked internals of caching to be plugable
6
+ 0.9.0 -- reworked internals of caching to be pluggable
5
7
  0.7.0 -- set_locale resets to default locale if none of the available locales was tried to set
6
- 0.6.0 -- plurals use singular translations as fallack e.g. you translated 'Axis' then n_('Axis','Axis',1) would return the translation for 'Axis' if no plural translation was found
8
+ 0.6.0 -- plurals use singular translations as fallback e.g. you translated 'Axis' then n_('Axis','Axis',1) would return the translation for 'Axis' if no plural translation was found
7
9
  0.4.14 -- "" is translated as "", not as gettext meta information
8
- 0.4.0 -- pluralisation_rules is no longer stored in each repository, only retrived. Added Chain and Logger repository.
10
+ 0.4.0 -- pluralisation_rules is no longer stored in each repository, only retrieved. Added Chain and Logger repository.
9
11
  0.3.6 -- FastGettext.default_locale=
10
12
  0.3.5 -- FastGettext.default_text_domain=
11
13
  0.3.4 -- Exceptions are thrown, not returned when translating without text domain
data/LICENSE ADDED
@@ -0,0 +1,78 @@
1
+ Copyright (C) 2013 Michael Grosser <michael@grosser.it>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ # for lib/fast_gettext/vendor/*
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+
23
+ Ruby is copyrighted free software by Yukihiro Matsumoto <matz@netlab.jp>.
24
+ You can redistribute it and/or modify it under either the terms of the
25
+ 2-clause BSDL (see the file BSDL), or the conditions below:
26
+
27
+ 1. You may make and give away verbatim copies of the source form of the
28
+ software without restriction, provided that you duplicate all of the
29
+ original copyright notices and associated disclaimers.
30
+
31
+ 2. You may modify your copy of the software in any way, provided that
32
+ you do at least ONE of the following:
33
+
34
+ a) place your modifications in the Public Domain or otherwise
35
+ make them Freely Available, such as by posting said
36
+ modifications to Usenet or an equivalent medium, or by allowing
37
+ the author to include your modifications in the software.
38
+
39
+ b) use the modified software only within your corporation or
40
+ organization.
41
+
42
+ c) give non-standard binaries non-standard names, with
43
+ instructions on where to get the original software distribution.
44
+
45
+ d) make other distribution arrangements with the author.
46
+
47
+ 3. You may distribute the software in object code or binary form,
48
+ provided that you do at least ONE of the following:
49
+
50
+ a) distribute the binaries and library files of the software,
51
+ together with instructions (in the manual page or equivalent)
52
+ on where to get the original distribution.
53
+
54
+ b) accompany the distribution with the machine-readable source of
55
+ the software.
56
+
57
+ c) give non-standard binaries non-standard names, with
58
+ instructions on where to get the original software distribution.
59
+
60
+ d) make other distribution arrangements with the author.
61
+
62
+ 4. You may modify and include the part of the software into any other
63
+ software (possibly commercial). But some files in the distribution
64
+ are not written by the author, so that they are not under these terms.
65
+
66
+ For the list of those files and their copying conditions, see the
67
+ file LEGAL.
68
+
69
+ 5. The scripts and library files supplied as input to or produced as
70
+ output from the software do not automatically fall under the
71
+ copyright of the software, but belong to whomever generated them,
72
+ and may be sold commercially, and may be aggregated with this
73
+ software.
74
+
75
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
76
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
77
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
78
+ PURPOSE.
data/Readme.md CHANGED
@@ -1,11 +1,12 @@
1
1
  FastGettext
2
2
  ===========
3
- GetText but 3.5 x faster, 560 x less memory, simple, clean namespace (7 vs 34) and threadsafe!
3
+ GetText but 12 x faster, 530 x less garbage, clean namespace (8 vs 26), simple and threadsafe!
4
4
 
5
5
  It supports multiple backends (.mo, .po, .yml files, Database(ActiveRecord + any other), Chain, Loggers) and can easily be extended.
6
6
 
7
7
  [Example Rails application](https://github.com/grosser/gettext_i18n_rails_example)
8
8
 
9
+
9
10
  Comparison
10
11
  ==========
11
12
  <table>
@@ -18,17 +19,17 @@ Comparison
18
19
  </tr>
19
20
  <tr>
20
21
  <td>Speed*</td>
21
- <td>0.82s</td>
22
- <td>1.36s</td>
23
- <td>4.88s</td>
24
- <td>21.77s</td>
22
+ <td>0.08s</td>
23
+ <td>0.14s</td>
24
+ <td>1.75s</td>
25
+ <td>3.75s</td>
25
26
  </tr>
26
27
  <tr>
27
- <td>RAM*</td>
28
- <td>4K</td>
29
- <td>8K</td>
30
- <td>4480K</td>
31
- <td>10100K</td>
28
+ <td>Objects*</td>
29
+ <td>11K</td>
30
+ <td>15K</td>
31
+ <td>8017K</td>
32
+ <td>7107K</td>
32
33
  </tr>
33
34
  <tr>
34
35
  <td>Included backends</td>
@@ -38,10 +39,12 @@ Comparison
38
39
  <td>yml (db/key-value/po/chain in other I18n backends)</td>
39
40
  </tr>
40
41
  </table>
41
- <small>*50.000 translations with ruby enterprise 1.8.6 through `rake benchmark`</small>
42
+ <small>*500.000 translations with ruby 2.5.3 through `bundle exec rake benchmark`</small>
43
+
42
44
 
43
45
  Setup
44
46
  =====
47
+
45
48
  ### 1. Install
46
49
 
47
50
  ```Bash
@@ -60,8 +63,8 @@ Or po files (less maintenance than mo)
60
63
 
61
64
  ```Ruby
62
65
  FastGettext.add_text_domain('my_app', path: 'locale', type: :po)
63
- # :ignore_fuzzy => true to not use fuzzy translations
64
- # :report_warning => false to hide warnings about obsolete/fuzzy translations
66
+ # ignore_fuzzy: true to not use fuzzy translations
67
+ # report_warning: false to hide warnings about obsolete/fuzzy translations
65
68
  ```
66
69
 
67
70
  Or yaml files (use I18n syntax/indentation)
@@ -77,7 +80,7 @@ Or database (scaleable, good for many locales/translators)
77
80
  ```Ruby
78
81
  # db access is cached <-> only first lookup hits the db
79
82
  require "fast_gettext/translation_repository/db"
80
- FastGettext::TranslationRepository::Db.require_models #load and include default models
83
+ FastGettext::TranslationRepository::Db.require_models # load and include default models
81
84
  FastGettext.add_text_domain('my_app', type: :db, model: TranslationKey)
82
85
  ```
83
86
 
@@ -86,24 +89,83 @@ Do this once in every Thread. (e.g. Rails -> ApplicationController)
86
89
 
87
90
  ```Ruby
88
91
  FastGettext.text_domain = 'my_app'
89
- FastGettext.available_locales = ['de','en','fr','en_US','en_UK'] # only allow these locales to be set (optional)
92
+ FastGettext.available_locales = ['de', 'en', 'fr', 'en_US', 'en_UK'] # only allow these locales to be set (optional)
90
93
  FastGettext.locale = 'de'
91
94
  ```
92
95
 
93
96
  ### 4. Start translating
94
97
 
95
- ```Ruby
96
- include FastGettext::Translation
97
- _('Car') == 'Auto'
98
- _('not-found') == 'not-found'
99
- s_('Namespace|not-found') == 'not-found'
100
- n_('Axis','Axis',3) == 'Achsen' #German plural of Axis
101
- _('Hello %{name}!') % {name: "Pete"} == 'Hello Pete!'
98
+ FastGettext supports all the translation methods of [ruby-gettext](http://github.com/ruby-gettext/gettext) with added support for block defaults.
99
+ (to get `*gettext` methods, use `FastGettext::TranslationAliased`)
100
+
101
+ #### `_()` or `gettext()`: basic translation
102
+
103
+ ```ruby
104
+ extend FastGettext::Translation
105
+ _('Car') == 'Auto' # found translation for 'Car'
106
+ _('not-found') == 'not-found' # The msgid is returned by default
107
+ ```
108
+
109
+ #### `n_()` or `ngettext()`: pluralization
110
+
111
+ ```ruby
112
+ n_('Car', 'Cars', 1) == 'Auto'
113
+ n_('Car', 'Cars', 2) == 'Autos' # German plural of Cars
114
+ ```
115
+
116
+ You'll often want to interpolate the results of `n_()` using ruby builtin `%` operator.
117
+
118
+ ```ruby
119
+ n_('Car', '%{n} Cars', 2) % { n: count } == '2 Autos'
120
+ ```
121
+
122
+ #### `p_()` or `pgettext()`: translation with context
123
+
124
+ ```ruby
125
+ p_('File', 'Open') == _("File\004Open") == "öffnen"
126
+ p_('Context', 'not-found') == 'not-found'
127
+ ```
128
+
129
+ #### `s_()` or `sgettext()`: translation with namespace
130
+
131
+ ```ruby
132
+ s_('File|Open') == _('File|Open') == "öffnen"
133
+ s_('Context|not-found') == 'not-found'
134
+ ```
135
+
136
+ The difference between `s_()` and `p_()` is largely based on how the translations
137
+ are stored. Your preference will be based on your workflow and translation editing
138
+ tools.
139
+
140
+ #### `pn_()` or `pngettext()`: context-aware pluralized
141
+
142
+ ```ruby
143
+ pn_('Fruit', 'Apple', 'Apples', 3) == 'Äpfel'
144
+ pn_('Fruit', 'Apple', 'Apples', 1) == 'Apfel'
145
+ ```
146
+
147
+ #### `sn_()` or `sngettext()`: without context pluralized
148
+
149
+ ```ruby
150
+ sn_('Fruit|Apple', 'Apples', 3) == 'Äpfel'
151
+ sn_('Fruit|Apple', 'Apples', 1) == 'Apfel'
152
+ ```
153
+
154
+ #### `N_()` and `Nn_()`: make dynamic translations available to the parser.
155
+
156
+ In many instances, your strings will not be found by the ruby parsing. These methods
157
+ allow for those strings to be discovered.
158
+
159
+ ```
160
+ N_("active"); N_("inactive"); N_("paused") # possible value of status for parser to find.
161
+ Nn_("active", "inactive", "paused") # alternative method
162
+ _("Your account is %{account_state}.") % { account_state: _(status) }
102
163
  ```
103
164
 
104
165
 
105
166
  Managing translations
106
- ============
167
+ =====================
168
+
107
169
  ### mo/po-files
108
170
  Generate .po or .mo files using GetText parser (example tasks at [gettext_i18n_rails](http://github.com/grosser/gettext_i18n_rails))
109
171
 
@@ -113,12 +175,12 @@ Tell Gettext where your .mo or .po files lie, e.g. for locale/de/my_app.po and l
113
175
  FastGettext.add_text_domain('my_app', path: 'locale')
114
176
  ```
115
177
 
116
- Use the [original GetText](http://github.com/mutoh/gettext) to create and manage po/mo-files.
178
+ Use the [original GetText](http://github.com/ruby-gettext/gettext) to create and manage po/mo-files.
117
179
  (Work on a po/mo parser & reader that is easier to use has started, contributions welcome @ [get_pomo](http://github.com/grosser/get_pomo) )
118
180
 
119
181
  ### Database
120
182
  [Example migration for ActiveRecord](http://github.com/grosser/fast_gettext/blob/master/examples/db/migration.rb)<br/>
121
- The default plural seperator is `||||` but you may overwrite it (or suggest a better one..).
183
+ The default plural separator is `||||` but you may overwrite it (or suggest a better one...).
122
184
 
123
185
  This is usable with any model DataMapper/Sequel or any other(non-database) backend, the only thing you need to do is respond to the self.translation(key, locale) call.
124
186
  If you want to use your own models, have a look at the [default models](http://github.com/grosser/fast_gettext/tree/master/lib/fast_gettext/translation_repository/db_models) to see what you want/need to implement.
@@ -130,7 +192,7 @@ Rails
130
192
  Try the [gettext_i18n_rails plugin](http://github.com/grosser/gettext_i18n_rails), it simplifies the setup.<br/>
131
193
  Try the [translation_db_engine](http://github.com/grosser/translation_db_engine), to manage your translations in a db.
132
194
 
133
- Setting `available_locales`,`text_domain` or `locale` will not work inside the `evironment.rb`,
195
+ Setting `available_locales`,`text_domain` or `locale` will not work inside the `environment.rb`,
134
196
  since it runs in a different thread then e.g. controllers, so set them inside your application_controller.
135
197
 
136
198
  ```Ruby
@@ -145,7 +207,7 @@ class ApplicationController ...
145
207
  include FastGettext::Translation
146
208
  before_filter :set_locale
147
209
  def set_locale
148
- FastGettext.available_locales = ['de','en',...]
210
+ FastGettext.available_locales = ['de', 'en', ...]
149
211
  FastGettext.text_domain = 'frontend'
150
212
  FastGettext.set_locale(params[:locale] || session[:locale] || request.env['HTTP_ACCEPT_LANGUAGE'])
151
213
  session[:locale] = I18n.locale = FastGettext.locale
@@ -155,6 +217,7 @@ class ApplicationController ...
155
217
 
156
218
  Advanced features
157
219
  =================
220
+
158
221
  ### Abnormal pluralisation
159
222
  Plurals are selected by index, think of it as `['car', 'cars'][index]`<br/>
160
223
  A pluralisation rule decides which form to use e.g. in english its `count == 1 ? 0 : 1`.<br/>
@@ -163,7 +226,7 @@ If you have any languages that do not fit this rule, you have to add a custom pl
163
226
  Via Ruby:
164
227
 
165
228
  ```Ruby
166
- FastGettext.pluralisation_rule = lambda{|count| count > 5 ? 1 : (count > 2 ? 0 : 2)}
229
+ FastGettext.pluralisation_rule = ->(count){ count > 5 ? 1 : (count > 2 ? 0 : 2)}
167
230
  ```
168
231
 
169
232
  Via mo/pofile:
@@ -179,7 +242,7 @@ If you only use one text domain, setting `FastGettext.default_text_domain = 'app
179
242
  is sufficient and no more `text_domain=` is needed
180
243
 
181
244
  ### default_locale
182
- If the simple rule of "first `availble_locale` or 'en'" is not suficcient for you, set `FastGettext.default_locale = 'de'`.
245
+ If the simple rule of "first `available_locale` or 'en'" is not sufficient for you, set `FastGettext.default_locale = 'de'`.
183
246
 
184
247
  ### default_available_locales
185
248
  Fallback when no available_locales are set
@@ -203,7 +266,7 @@ repos = [
203
266
  FastGettext::TranslationRepository.build('new', path: '....'),
204
267
  FastGettext::TranslationRepository.build('old', path: '....')
205
268
  ]
206
- FastGettext.add_text_domain 'combined', type: :chain, :chain: repos
269
+ FastGettext.add_text_domain 'combined', type: :chain, chain: repos
207
270
  ```
208
271
 
209
272
  ### Merge
@@ -213,8 +276,8 @@ a subordinate repository is added. This puts the burden on the load phase and sp
213
276
 
214
277
  ```Ruby
215
278
  repos = [
216
- FastGettext::TranslationRepository.build('new', :path: '....'),
217
- FastGettext::TranslationRepository.build('old', :path: '....')
279
+ FastGettext::TranslationRepository.build('new', path: '....'),
280
+ FastGettext::TranslationRepository.build('old', path: '....')
218
281
  ]
219
282
  domain = FastGettext.add_text_domain 'combined', type: :merge, chain: repos
220
283
  ```
@@ -232,7 +295,7 @@ When you want to know which keys could not be translated or were used, add a Log
232
295
  ```Ruby
233
296
  repos = [
234
297
  FastGettext::TranslationRepository.build('app', path: '....')
235
- FastGettext::TranslationRepository.build('logger', type: :logger, callback: lambda{|key_or_array_of_ids| ... }),
298
+ FastGettext::TranslationRepository.build('logger', type: :logger, callback: ->(key_or_array_of_ids) { ... }),
236
299
  }
237
300
  FastGettext.add_text_domain 'combined', type: :chain, chain: repos
238
301
  ```
@@ -242,11 +305,11 @@ Unfound may not always mean missing, if you choose not to translate a word becau
242
305
  A lambda or anything that responds to `call` will do as callback. A good starting point may be `examples/missing_translations_logger.rb`.
243
306
 
244
307
  ### Plugins
245
- Want a xml version ?
308
+ Want an xml version?
246
309
  Write your own TranslationRepository!
247
310
 
248
311
  ```Ruby
249
- # fast_gettext/translation_repository/xxx.rb
312
+ # fast_gettext/translation_repository/wtf.rb
250
313
  module FastGettext
251
314
  module TranslationRepository
252
315
  class Wtf
@@ -263,33 +326,65 @@ If you have more than one gettext domain, there are two sets of functions
263
326
  available:
264
327
 
265
328
  ```Ruby
266
- include FastGettext::TranslationMultidomain
329
+ extend FastGettext::TranslationMultidomain
267
330
 
268
331
  d_("domainname", "string") # finds 'string' in domain domainname
269
332
  dn_("domainname", "string", "strings", 1) # ditto
270
- # etc.
333
+ dp_("domainname", "context", "key")
334
+ ds_("domainname", "context|key")
335
+ dnp_("domainname", "context", "string", "strings")
336
+ dns_("domainname", "context|string", "strings")
271
337
  ```
272
338
 
273
339
  These are helper methods so you don't need to write:
274
340
 
275
341
  ```Ruby
276
- FastGettext.text_domain = "domainname"
277
- _("string")
342
+ FastGettext.with_domain("domainname") { _("string") }
278
343
  ```
279
344
 
280
345
  It is useful in Rails plugins in the views for example. The second set of
281
346
  functions are D functions which search for string in _all_ domains. If there
282
347
  are multiple translations in different domains, it returns them in random
283
- order (depends on the Ruby hash implementation):
348
+ order (depends on the Ruby hash implementation).
284
349
 
285
350
  ```Ruby
286
- include FastGettext::TranslationMultidomain
351
+ extend FastGettext::TranslationMultidomain
287
352
 
288
353
  D_("string") # finds 'string' in any domain
289
- # etc.
354
+ Dn_("string", "strings", 1) # ditto
355
+ Dp_("context", "key")
356
+ Ds_("context|key")
357
+ Dnp_("context", "string", "strings")
358
+ Dns_("context|string", "strings")
359
+ ```
360
+
361
+ Alternatively you can use [merge repository](https://github.com/grosser/fast_gettext#merge) to achieve the same behavior.
362
+
363
+ #### Block defaults
364
+
365
+ All the translation methods (including MultiDomain) support a block default, a feature not provided by ruby-gettext. When a translation is
366
+ not found, if a block is provided the block is always returned. Otherwise, a key is returned. Methods doing pluralization will attempt a simple translation of alternate keys.
367
+
368
+ ```ruby
369
+ _('not-found'){ "alternative default" } == alternate default
370
+ ```
371
+
372
+ This block default is useful when the default is a very long passage of text that wouldn't make a useful key. You can also instrument logging not found keys.
373
+
374
+ ```ruby
375
+ _('terms-and-conditions'){
376
+ load_terms_and_conditions
377
+ request_terms_and_conditions_translation_from_legal
378
+ }
379
+
380
+ # Override _ with logging
381
+ def _(key, &block)
382
+ result = gettext(key){ nil } # nil returned when not found
383
+ log_missing_translation_key(key) if result.nil?
384
+ result || (block ? block.call : key)
385
+ end
290
386
  ```
291
387
 
292
- Alternatively you can use [merge repository](https://github.com/grosser/fast_gettext#merge) to achieve the same behaviour.
293
388
 
294
389
  FAQ
295
390
  ===
@@ -297,13 +392,8 @@ FAQ
297
392
  - [Iconv require error in 1.9.2](http://exceptionz.wordpress.com/2010/02/03/how-to-fix-the-iconv-require-error-in-ruby-1-9)
298
393
 
299
394
 
300
- TODO
301
- ====
302
- - Add a fallback for Iconv.conv in ruby 1.9.4 -> lib/fast_gettext/vendor/iconv
303
- - YML backend that reads ActiveSupport::I18n files
304
-
305
- Author
306
- ======
395
+ Authors
396
+ =======
307
397
  Mo/Po-file parsing from Masao Mutoh, see vendor/README
308
398
 
309
399
  ### [Contributors](http://github.com/grosser/fast_gettext/contributors)
@@ -327,8 +417,9 @@ Mo/Po-file parsing from Masao Mutoh, see vendor/README
327
417
  - [Martin Meier](https://github.com/mameier)
328
418
  - [morcoteg](https://github.com/morcoteg)
329
419
  - [Daniel Schepers](https://github.com/tall-dan)
420
+ - [Robert Graff](https://github.com/rgraff)
330
421
 
331
422
  [Michael Grosser](http://grosser.it)<br/>
332
423
  michael@grosser.it<br/>
333
424
  License: MIT, some vendor parts under the same license terms as Ruby (see headers)<br/>
334
- [![Build Status](https://travis-ci.org/grosser/fast_gettext.png)](https://travis-ci.org/grosser/fast_gettext)
425
+ [![CI](https://github.com/grosser/fast_gettext/actions/workflows/actions.yml/badge.svg)](https://github.com/grosser/fast_gettext/actions/workflows/actions.yml)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FastGettext
2
4
  class Cache
3
5
  def initialize
@@ -8,13 +10,13 @@ module FastGettext
8
10
  def fetch(key)
9
11
  translation = @current[key]
10
12
  if translation.nil? # uncached
11
- @current[key] = yield || false # TODO get rid of this false hack and cache :missing
13
+ @current[key] = yield || false # TODO: get rid of this false hack and cache :missing
12
14
  else
13
15
  translation
14
16
  end
15
17
  end
16
18
 
17
- # TODO only used for tests, maybe if-else around it ...
19
+ # TODO: only used for tests, maybe if-else around it ...
18
20
  def []=(key, value)
19
21
  @current[key] = value
20
22
  end
@@ -1,13 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fast_gettext/vendor/mofile'
2
4
  module FastGettext
3
5
  # Responsibility:
4
6
  # - abstract mo files for Mo Repository
5
7
  class MoFile
6
- PLURAL_SEPERATOR = "\000"
8
+ PLURAL_SEPARATOR = "\000"
9
+ CONTEXT_SEPARATOR = "\004"
7
10
 
8
11
  # file => path or FastGettext::GetText::MOFile
9
- def initialize(file, options={})
12
+ def initialize(file, options = {})
10
13
  @filename = file
14
+ @data = nil
11
15
  load_data if options[:eager_load]
12
16
  end
13
17
 
@@ -15,17 +19,21 @@ module FastGettext
15
19
  data[key]
16
20
  end
17
21
 
18
- #returns the plural forms or all singular translations that where found
22
+ # returns the plural forms or all singular translations that where found
19
23
  # Car, Cars => [Auto,Autos] or []
20
24
  def plural(*msgids)
21
- split_plurals(self[msgids*PLURAL_SEPERATOR].to_s)
25
+ split_plurals(self[msgids * PLURAL_SEPARATOR].to_s)
22
26
  end
23
27
 
24
28
  def pluralisation_rule
25
- #gettext uses 0 as default rule, which would turn off all pluralisation, very clever...
26
- #additionally parsing fails when directly accessing po files, so this line was taken from gettext/mofile
27
- (data['']||'').split("\n").each do |line|
28
- return lambda{|n|eval($2)} if /^Plural-Forms:\s*nplurals\s*\=\s*(\d*);\s*plural\s*\=\s*([^;]*)\n?/ =~ line
29
+ # gettext uses 0 as default rule, which would turn off all pluralisation, very clever...
30
+ # additionally parsing fails when directly accessing po files, so this line was taken from gettext/mofile
31
+ (data[''] || '').split("\n").each do |line|
32
+ if /^Plural-Forms:\s*nplurals\s*\=\s*(\d*);\s*plural\s*\=\s*([^;]*)\n?/ =~ line
33
+ return ->(n) do # rubocop:disable Lint/UnusedBlockArgument
34
+ eval($2) # rubocop:disable Security/Eval
35
+ end
36
+ end
29
37
  end
30
38
  nil
31
39
  end
@@ -36,35 +44,37 @@ module FastGettext
36
44
  end
37
45
 
38
46
  def self.empty
39
- MoFile.new(File.join(File.dirname(__FILE__),'vendor','empty.mo'))
47
+ @empty ||= MoFile.new(File.join(__dir__, 'vendor', 'empty.mo'), eager_load: true).freeze
40
48
  end
41
49
 
42
50
  private
43
51
 
44
52
  def load_data
45
- @data = if @filename.is_a? FastGettext::GetText::MOFile
46
- @filename
47
- else
48
- FastGettext::GetText::MOFile.open(@filename, "UTF-8")
49
- end
53
+ @data =
54
+ if @filename.is_a? FastGettext::GetText::MOFile
55
+ @filename
56
+ else
57
+ FastGettext::GetText::MOFile.open(@filename, "UTF-8")
58
+ end
50
59
  make_singular_and_plural_available
51
60
  end
52
61
 
53
- #(if plural==singular, prefer singular)
62
+ # (if plural==singular, prefer singular)
54
63
  def make_singular_and_plural_available
55
64
  data = {}
56
- @data.each do |key,translation|
57
- next unless key.include? PLURAL_SEPERATOR
65
+ @data.each do |key, translation|
66
+ next unless key.include? PLURAL_SEPARATOR
67
+
58
68
  singular, plural = split_plurals(key)
59
69
  translation = split_plurals(translation)
60
70
  data[singular] ||= translation[0]
61
71
  data[plural] ||= translation[1]
62
72
  end
63
- @data.merge!(data){|key,old,new| old}
73
+ @data.merge!(data) { |_key, old, _new| old }
64
74
  end
65
75
 
66
76
  def split_plurals(singular_plural)
67
- singular_plural.split(PLURAL_SEPERATOR)
77
+ singular_plural.split(PLURAL_SEPARATOR)
68
78
  end
69
79
  end
70
80
  end
@@ -1,29 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'fast_gettext/mo_file'
2
4
  module FastGettext
3
5
  # Responsibility:
4
6
  # - abstract po files for Po Repository
5
7
  class PoFile < MoFile
6
- def initialize(file, options={})
8
+ def initialize(file, options = {})
7
9
  @options = options
8
10
  super
9
11
  end
10
12
 
11
- def self.to_mo_file(file, options={})
13
+ def self.to_mo_file(file, options = {})
12
14
  MoFile.new(parse_po_file(file, options))
13
15
  end
14
16
 
15
- protected
16
-
17
- def load_data
18
- @data = if @filename.is_a? FastGettext::GetText::MOFile
19
- @filename
20
- else
21
- FastGettext::PoFile.parse_po_file(@filename, @options)
22
- end
23
- make_singular_and_plural_available
24
- end
25
-
26
- def self.parse_po_file(file, options={})
17
+ def self.parse_po_file(file, options = {})
27
18
  require 'fast_gettext/vendor/poparser'
28
19
  parser = FastGettext::GetText::PoParser.new
29
20
 
@@ -35,5 +26,17 @@ module FastGettext
35
26
  parser.parse_file(file, mo_file)
36
27
  mo_file
37
28
  end
29
+
30
+ protected
31
+
32
+ def load_data
33
+ @data =
34
+ if @filename.is_a? FastGettext::GetText::MOFile
35
+ @filename
36
+ else
37
+ FastGettext::PoFile.parse_po_file(@filename, @options)
38
+ end
39
+ make_singular_and_plural_available
40
+ end
38
41
  end
39
42
  end