tater 2.0.2 → 2.0.3

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.
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