fast_gettext 1.8.0 → 2.3.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.
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