tater 2.0.2 → 2.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/tater.rb +108 -64
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: eb7166fcdf9b548f8837e4411bfe5d83712f202e1de27c299fa0e5694b50bc2b
4
- data.tar.gz: ab3f53e56fa8538f39ce59ba9f2e42496e5bea116a880fc26e23ad2091e5e93c
3
+ metadata.gz: 7e5ec34021f3488e2ef8ef3365abc37258813e5d9a79b8dbd0a49fb8254c946a
4
+ data.tar.gz: 8613b2a54d59d0b4a64f84790e60f55316447714d6013a6751041a2aa9dada6a
5
5
  SHA512:
6
- metadata.gz: ceb821ff34a086711feb0df9e21a7aa4c7891a3e84fc52a9cf62d5972462c6ab0a5f81eef2ab820ef95df7211dda82e2a56299a1ced017e468c50358b6e537db
7
- data.tar.gz: 2ad3f4c078bb63e39b5650254f92cb3859c39c73f4eaf2dfae18320e60712bf2c632e42c38770c39a456ee62f13fbf6262e1fef527846c17c53d7ebd859fa6de
6
+ metadata.gz: f65062d798ace02b68084b1a9189f09c092e32f2a819bd88909d651038a205a36b60816f8c6e890614c9aaea1a17e074b89a7f3a5163969bf10c6f35a8eac56e
7
+ data.tar.gz: cf3ae7da9a2d911f90aa93dd1f2e088425becf21d2b5558c485d86002bcccf09a4bdccfed39385442a7865a27e76196aa68bf90b259ea30f5b8beeda8eb1807c
data/lib/tater.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  require 'bigdecimal'
3
+ require 'date'
4
+ require 'time'
3
5
  require 'yaml'
4
6
 
5
7
  # Tater is a internationalization (i18n) and localization (l10n) library
@@ -190,9 +192,9 @@ class Tater
190
192
  # @option options [String] :locale
191
193
  # The locale to use in lieu of the current default.
192
194
  # @option options [String] :delimiter
193
- # The delimiter to use when localizing numberic values.
195
+ # The delimiter to use when localizing numeric values.
194
196
  # @option options [String] :separator
195
- # The separator to use when localizing numberic values.
197
+ # The separator to use when localizing numeric values.
196
198
  # @option options [String] :two_words_connector
197
199
  # The string used to join two array elements together e.g. " and ".
198
200
  # @option options [String] :words_connector
@@ -208,70 +210,11 @@ class Tater
208
210
  when String
209
211
  object
210
212
  when Numeric
211
- delimiter = options[:delimiter] || lookup('numeric.delimiter', locale: options[:locale])
212
- separator = options[:separator] || lookup('numeric.separator', locale: options[:locale])
213
- precision = options[:precision] || 2
214
-
215
- raise(MissingLocalizationFormat, "Numeric localization delimiter ('numeric.delimiter') missing or not passed as option :delimiter") unless delimiter
216
- raise(MissingLocalizationFormat, "Numeric localization separator ('numeric.separator') missing or not passed as option :separator") unless separator
217
-
218
- # Break the number up into integer and fraction parts.
219
- integer = Utils.string_from_numeric(object)
220
- integer, fraction = integer.split('.') unless object.is_a?(Integer)
221
-
222
- if integer.length > 3
223
- integer.gsub!(DELIMITING_REGEX) do |number|
224
- "#{ number }#{ delimiter }"
225
- end
226
- end
227
-
228
- if precision.zero? || fraction.nil?
229
- integer
230
- else
231
- "#{ integer }#{ separator }#{ fraction.ljust(precision, '0').slice(0, precision) }"
232
- end
213
+ localize_numeric(object, options)
233
214
  when Date, Time, DateTime
234
- format = lookup("#{ object.class.to_s.downcase }.formats.#{ options[:format] || DEFAULT }", locale: options[:locale]) || options[:format] || DEFAULT
235
-
236
- # Heavily cribbed from I18n, many thanks to the people who sorted this out
237
- # before I worked on this library.
238
- format = format.gsub(SUBSTITUTION_REGEX) do |match|
239
- case match
240
- when '%a' then lookup('date.abbreviated_days', locale: options[:locale])[object.wday]
241
- when '%^a' then lookup('date.abbreviated_days', locale: options[:locale])[object.wday].upcase
242
- when '%A' then lookup('date.days', locale: options[:locale])[object.wday]
243
- when '%^A' then lookup('date.days', locale: options[:locale])[object.wday].upcase
244
- when '%b' then lookup('date.abbreviated_months', locale: options[:locale])[object.mon - 1]
245
- when '%^b' then lookup('date.abbreviated_months', locale: options[:locale])[object.mon - 1].upcase
246
- when '%B' then lookup('date.months', locale: options[:locale])[object.mon - 1]
247
- when '%^B' then lookup('date.months', locale: options[:locale])[object.mon - 1].upcase
248
- when '%p' then lookup("time.#{ object.hour < 12 ? 'am' : 'pm' }", locale: options[:locale]).upcase if object.respond_to?(:hour) # rubocop:disable Metrics/BlockNesting
249
- when '%P' then lookup("time.#{ object.hour < 12 ? 'am' : 'pm' }", locale: options[:locale]).downcase if object.respond_to?(:hour) # rubocop:disable Metrics/BlockNesting
250
- end
251
- end
252
-
253
- object.strftime(format)
215
+ localize_datetime(object, options)
254
216
  when Array
255
- case object.length
256
- when 0
257
- ''
258
- when 1
259
- object[0]
260
- when 2
261
- two_words_connector = options[:two_words_connector] || lookup('array.two_words_connector', locale: options[:locale])
262
-
263
- raise(MissingLocalizationFormat, "Sentence localization connector ('array.two_words_connector') missing or not passed as option :two_words_connector") unless two_words_connector
264
-
265
- "#{ object[0] }#{ two_words_connector }#{ object[1] }"
266
- else
267
- last_word_connector = options[:last_word_connector] || lookup('array.last_word_connector', locale: options[:locale])
268
- words_connector = options[:words_connector] || lookup('array.words_connector', locale: options[:locale])
269
-
270
- raise(MissingLocalizationFormat, "Sentence localization connector ('array.last_word_connector') missing or not passed as option :last_word_connector") unless last_word_connector
271
- raise(MissingLocalizationFormat, "Sentence localization connector ('array.words_connector') missing or not passed as option :words_connector") unless words_connector
272
-
273
- "#{ object[0...-1].join(words_connector) }#{ last_word_connector }#{ object[-1] }"
274
- end
217
+ localize_array(object, options)
275
218
  else
276
219
  raise(UnLocalizableObject, "The object class #{ object.class } cannot be localized by Tater.")
277
220
  end
@@ -420,4 +363,105 @@ class Tater
420
363
  def cached(key, locale, cascade)
421
364
  @cache.dig(locale, cascade, key)
422
365
  end
366
+
367
+ # Localize an Array object.
368
+ #
369
+ # @param object [Array<String>]
370
+ # The array to localize.
371
+ # @param options [Hash]
372
+ # Options to configure localization.
373
+ # @return [String]
374
+ # The localize array string.
375
+ def localize_array(object, options)
376
+ case object.length
377
+ when 0
378
+ ''
379
+ when 1
380
+ object[0]
381
+ when 2
382
+ two_words_connector = options[:two_words_connector] || lookup('array.two_words_connector', locale: options[:locale])
383
+
384
+ raise(MissingLocalizationFormat, "Sentence localization connector ('array.two_words_connector') missing or not passed as option :two_words_connector") unless two_words_connector
385
+
386
+ "#{ object[0] }#{ two_words_connector }#{ object[1] }"
387
+ else
388
+ last_word_connector = options[:last_word_connector] || lookup('array.last_word_connector', locale: options[:locale])
389
+ words_connector = options[:words_connector] || lookup('array.words_connector', locale: options[:locale])
390
+
391
+ raise(MissingLocalizationFormat, "Sentence localization connector ('array.last_word_connector') missing or not passed as option :last_word_connector") unless last_word_connector
392
+ raise(MissingLocalizationFormat, "Sentence localization connector ('array.words_connector') missing or not passed as option :words_connector") unless words_connector
393
+
394
+ "#{ object[0...-1].join(words_connector) }#{ last_word_connector }#{ object[-1] }"
395
+ end
396
+ end
397
+
398
+ # Localize a Date, DateTime, or Time object.
399
+ #
400
+ # @param object [Date, DateTime, Time]
401
+ # The date-ish object to localize.
402
+ # @param options [Hash]
403
+ # Options to configure localization.
404
+ # @return [String]
405
+ # The localized date string.
406
+ def localize_datetime(object, options)
407
+ frmt = options[:format] || DEFAULT
408
+ loc = options[:locale]
409
+ format = lookup("#{ object.class.to_s.downcase }.formats.#{ frmt }", locale: loc) || frmt
410
+
411
+ # Heavily cribbed from I18n, many thanks to the people who sorted this out
412
+ # before I worked on this library.
413
+ format = format.gsub(SUBSTITUTION_REGEX) do |match|
414
+ case match
415
+ when '%a' then lookup('date.abbreviated_days', locale: loc)[object.wday]
416
+ when '%^a' then lookup('date.abbreviated_days', locale: loc)[object.wday].upcase
417
+ when '%A' then lookup('date.days', locale: loc)[object.wday]
418
+ when '%^A' then lookup('date.days', locale: loc)[object.wday].upcase
419
+ when '%b' then lookup('date.abbreviated_months', locale: loc)[object.mon - 1]
420
+ when '%^b' then lookup('date.abbreviated_months', locale: loc)[object.mon - 1].upcase
421
+ when '%B' then lookup('date.months', locale: loc)[object.mon - 1]
422
+ when '%^B' then lookup('date.months', locale: loc)[object.mon - 1].upcase
423
+ when '%p' then lookup("time.#{ object.hour < 12 ? 'am' : 'pm' }", locale: loc).upcase if object.respond_to?(:hour)
424
+ when '%P' then lookup("time.#{ object.hour < 12 ? 'am' : 'pm' }", locale: loc).downcase if object.respond_to?(:hour)
425
+ end
426
+ end
427
+
428
+ if format.include?('%')
429
+ object.strftime(format)
430
+ else
431
+ format
432
+ end
433
+ end
434
+
435
+ # Localize a Numeric object.
436
+ #
437
+ # @param object [Array<String>, Date, Time, DateTime, Numeric]
438
+ # The object to localize.
439
+ # @param options [Hash]
440
+ # Options to configure localization.
441
+ # @return [String]
442
+ # The localized numeric string.
443
+ def localize_numeric(object, options)
444
+ delimiter = options[:delimiter] || lookup('numeric.delimiter', locale: options[:locale])
445
+ separator = options[:separator] || lookup('numeric.separator', locale: options[:locale])
446
+ precision = options[:precision] || 2
447
+
448
+ raise(MissingLocalizationFormat, "Numeric localization delimiter ('numeric.delimiter') missing or not passed as option :delimiter") unless delimiter
449
+ raise(MissingLocalizationFormat, "Numeric localization separator ('numeric.separator') missing or not passed as option :separator") unless separator
450
+
451
+ # Break the number up into integer and fraction parts.
452
+ integer = Utils.string_from_numeric(object)
453
+ integer, fraction = integer.split('.') unless object.is_a?(Integer)
454
+
455
+ if object >= 1_000
456
+ integer.gsub!(DELIMITING_REGEX) do |number|
457
+ "#{ number }#{ delimiter }"
458
+ end
459
+ end
460
+
461
+ if precision.zero? || fraction.nil?
462
+ integer
463
+ else
464
+ "#{ integer }#{ separator }#{ fraction.ljust(precision, '0').slice(0, precision) }"
465
+ end
466
+ end
423
467
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tater
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.2
4
+ version: 2.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evan Lecklider
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-06-21 00:00:00.000000000 Z
11
+ date: 2021-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler