jekyll-timeago 0.15.0 → 1.0.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: 53219f64cf2f2296edacdf4a4404de70b5e046031266f00838b0913d69371c29
4
- data.tar.gz: 8bba488eeb3a2498c03beb31c282300764392b3d392f7d5ec176682fd41847e8
3
+ metadata.gz: bd02d79b4df7829ed8f3f0709c05ba9a30269c270d822f1b0688b11d04570cdc
4
+ data.tar.gz: 02e9e2d294c95e585ebb550fe97ac837aa6bee19937a1b9812d15662bdc654f0
5
5
  SHA512:
6
- metadata.gz: 516cbd739e3c8c8824b441be6e83e079d9ea1009dfb59157b4d5dfbb35a56f352da704bfd10696ae17b6b957d308229c2553ef2e86cc0e2e14bf22c6ab18efcb
7
- data.tar.gz: 57dfdd94cd19b7f7395ee73346d78766d376439673b665774c7befed2fe9cee19008ed3929744d6abcaf5699dc9afe57610e358cfa7e277e34153b2cab09f0e4
6
+ metadata.gz: cfb1421c691b8979502e5678718e8ca5d25a16a172827cb6efc8ff1483fa3b32c3fb28953c86b1aaff8e306c7292b626241c495a9e25a1852818a275bd5d2b4a
7
+ data.tar.gz: cf53259ddca10910d3da16643cdd766294b71e737827ac8558856c7c32851474fbf5c2a0d8884446fdf4720d1e0fc0357abd34bbd319eb551ebf502824c041a9
@@ -1,6 +1,10 @@
1
1
  name: CI
2
2
 
3
- on: [push, pull_request]
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+ branches: [master]
4
8
 
5
9
  jobs:
6
10
  test:
@@ -11,7 +15,7 @@ jobs:
11
15
  strategy:
12
16
  fail-fast: false
13
17
  matrix:
14
- ruby: ['2.6', '2.7', '3.0', '3.1', '3.2', 'head']
18
+ ruby: ['2.7', '3.0', '3.1', '3.2', '3.3', 'head']
15
19
  gemfile: ['jekyll_v3', 'jekyll_v4']
16
20
  steps:
17
21
  - uses: actions/checkout@v3
data/.gitignore CHANGED
@@ -4,4 +4,6 @@ Gemfile.lock
4
4
  spec/_site
5
5
  .rpsec
6
6
  *.gemfile.lock
7
- .byebug_history
7
+ .byebug_history
8
+ .bundle
9
+ vendor/
data/README.md CHANGED
@@ -10,13 +10,14 @@ Main features:
10
10
 
11
11
  - Compute distance of dates, in words, ie: `1 week and 2 days ago`, `5 months ago`, `in 1 year`
12
12
  - Future times
13
+ - Alternative formats: short (`2y and 1mo ago`) and array (`['2 years', '1 month']`)
13
14
  - Out of the box support for `Jekyll` projects, available as a Liquid Filter and as a Liquid Tag
14
15
  - Localization
15
16
  - Level of detail customization
16
17
  - Command line utility
17
18
  - Approximate distance, with customizable threshold, ie: `366 days` becomes `1 year ago` instead of `1 year and 1 day ago`
18
19
 
19
- In fact, `jekyll-timeago` started as an extension for the [Liquid](https://github.com/Shopify/liquid) template engine, to be used in Jekyll and Octopress backed sites. But actually, you can use it easily on any Ruby project and even as a tool from the [terminal](#cli)!
20
+ In fact, `jekyll-timeago` started as an extension for the [Liquid](https://github.com/Shopify/liquid) template engine, to be used in Jekyll backed sites. But actually, you can use it easily on any Ruby project and even as a tool from the [terminal](#cli)!
20
21
 
21
22
  Read more about the `Jekyll` integration [in this section](#jekyll-integration).
22
23
 
@@ -84,7 +85,7 @@ puts timeago('2030-1-1')
84
85
 
85
86
  ### Options
86
87
 
87
- * `locale`
88
+ #### `locale`
88
89
 
89
90
  To use a different language:
90
91
 
@@ -97,7 +98,7 @@ To use a different language:
97
98
 
98
99
  Read more about the localization options [here](#localization).
99
100
 
100
- * `depth`
101
+ #### `depth`
101
102
 
102
103
  You are able to change the level of detail (from 1 up to 4, 2 by default) to get higher or lower granularity:
103
104
 
@@ -108,7 +109,7 @@ You are able to change the level of detail (from 1 up to 4, 2 by default) to get
108
109
  => "5 years, 5 months, 3 weeks and 4 days ago"
109
110
  ```
110
111
 
111
- - `threshold`
112
+ #### `threshold`
112
113
 
113
114
  The next component in the time must at least match this threshold to be picked. Set to 0 by default, so you don't get any approximations. Can be used to drop "straggling" values which are too low to be of any use (`in 7 months and 2 days` is as good as saying `in 7 months`).
114
115
 
@@ -117,6 +118,47 @@ The next component in the time must at least match this threshold to be picked.
117
118
  => "1 year ago"
118
119
  ```
119
120
 
121
+ #### `style`
122
+
123
+ Use `:short` style for abbreviated time formats:
124
+
125
+ ```ruby
126
+ >> timeago(Date.today.prev_day(365), style: :short)
127
+ => "1y ago"
128
+ >> timeago(Date.today.prev_day(30), style: :short)
129
+ => "1mo ago"
130
+ >> timeago(Date.today.prev_day(7), style: :short)
131
+ => "1w ago"
132
+ ```
133
+
134
+ Use `:array` style for structured data:
135
+
136
+ ```ruby
137
+ >> timeago(Date.today.prev_day(365), style: :array)
138
+ => ["1 year"]
139
+ >> timeago(Date.today.prev_day(160), style: :array)
140
+ => ["5 months", "1 week"]
141
+ ```
142
+
143
+ #### `only`
144
+
145
+ Use the `only` option to accumulate all time into a single unit. Supported values are `:years`, `:months`, `:weeks`, and `:days`:
146
+
147
+ ```ruby
148
+ >> timeago(Date.today.prev_day(365), only: :weeks)
149
+ => "52 weeks ago"
150
+ >> timeago(Date.today.prev_day(365), only: :months)
151
+ => "12 months ago"
152
+ >> timeago(Date.today.prev_day(100), only: :weeks)
153
+ => "14 weeks ago"
154
+ >> timeago(Date.today.prev_day(500), only: :days)
155
+ => "500 days ago"
156
+ >> timeago(Date.today.prev_day(365), only: :weeks, style: :short)
157
+ => "52w ago"
158
+ >> timeago(Date.today.prev_day(365), only: :months, locale: :es)
159
+ => "hace 12 meses"
160
+ ```
161
+
120
162
  ## Localization
121
163
 
122
164
  By default, `jekyll-timego` already provides translations for some languages. You can check the list [here](lib/locales/). However, you are able to provide your own translations, or even override the originals, easily.
@@ -137,11 +179,19 @@ If you want to contribute and support more default languages, please feel free t
137
179
  You can also use `jekyll-timeago` from the command line:
138
180
 
139
181
  ```
140
- > jekyll-timeago --help
141
- > jekyll-timeago 2016-1-1
182
+ > timeago --help
183
+ > timeago 2016-1-1
142
184
  2 years and 6 months ago
143
- > jekyll-timeago 2016-1-1 --locale fr
185
+ > timeago 2016-1-1 --locale fr
144
186
  il y a environ 2 années et 6 mois
187
+ > timeago 2016-1-1 2018-1-1 --style short
188
+ 2y ago
189
+ > timeago 2016-1-1 2018-1-1 -l es -s short
190
+ hace 2a y 1d
191
+ > timeago 2016-1-1 2018-1-1 --only weeks
192
+ 104 weeks ago
193
+ > timeago 2016-1-1 2018-1-1 --only months -s short
194
+ 24mo ago
145
195
  ```
146
196
 
147
197
  ### Console
@@ -149,7 +199,7 @@ il y a environ 2 années et 6 mois
149
199
  Starts a custom IRB session with the `timeago` method included:
150
200
 
151
201
  ```
152
- > jekyll-timeago --console
202
+ > timeago --console
153
203
  >> timeago(Date.today)
154
204
  => "today"
155
205
  ```
data/bin/timeago ADDED
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require_relative "../lib/jekyll-timeago"
4
+ require "optparse"
5
+
6
+ options = {}
7
+ show_help = false
8
+ show_version = false
9
+ start_console = false
10
+
11
+ parser = OptionParser.new do |opts|
12
+ opts.banner = <<~HELP_MESSAGE
13
+ Usage:
14
+
15
+ timeago <from_date> [to_date]
16
+
17
+ Notes:
18
+ [to_date] Optional, defaults to current date
19
+
20
+ Options:
21
+ HELP_MESSAGE
22
+
23
+ opts.on("-h", "--help", "Prints this message") do
24
+ show_help = true
25
+ end
26
+
27
+ opts.on("-v", "--version", "Prints the current version") do
28
+ show_version = true
29
+ end
30
+
31
+ opts.on("-c", "--console", "Starts an interactive IRB session with jekyll-timeago included") do
32
+ start_console = true
33
+ end
34
+
35
+ opts.on("-l", "--locale LOCALE", "Uses the provided locale") do |locale|
36
+ options[:locale] = locale
37
+ end
38
+
39
+ opts.on("-s", "--style STYLE", "Uses the provided style (short, array)") do |style|
40
+ options[:style] = style
41
+ end
42
+
43
+ opts.on("-o", "--only UNIT", "Accumulates time in specified unit (years, months, weeks, days)") do |unit|
44
+ options[:only] = unit
45
+ end
46
+ end
47
+
48
+ begin
49
+ parser.parse!
50
+ rescue OptionParser::InvalidOption, OptionParser::MissingArgument => e
51
+ puts "Error! #{e}"
52
+ puts parser
53
+ exit 1
54
+ end
55
+
56
+ if show_help
57
+ puts parser
58
+ elsif show_version
59
+ puts "v#{Jekyll::Timeago::VERSION}"
60
+ elsif start_console
61
+ require "irb"
62
+ include Jekyll::Timeago
63
+ IRB.start
64
+ elsif ARGV.empty?
65
+ puts parser
66
+ else
67
+ ARGV << options if !options.empty?
68
+
69
+ begin
70
+ puts Jekyll::Timeago.timeago *ARGV
71
+ rescue ArgumentError => e
72
+ puts "Error! #{e}"
73
+ end
74
+ end
@@ -14,6 +14,12 @@ module Jekyll
14
14
  # Default threshold
15
15
  DEFAULT_THRESHOLD = 0
16
16
 
17
+ # Available styles
18
+ STYLES = %w(default short array)
19
+
20
+ # Available "only" options
21
+ ONLY_OPTIONS = %w(years months weeks days)
22
+
17
23
  def timeago(from, to = Date.today, options = {})
18
24
  if to.is_a?(Hash)
19
25
  options = to
@@ -22,12 +28,14 @@ module Jekyll
22
28
 
23
29
  @options = options
24
30
 
25
- from = validate_date(from)
26
- to = validate_date(to)
27
- depth = validate_depth(@options[:depth] || @options["depth"])
28
- threshold = validate_threshold(@options[:threshold] || @options["threshold"])
31
+ @from = validate_date(from)
32
+ @to = validate_date(to)
33
+ @depth = validate_depth(@options[:depth] || @options["depth"])
34
+ @style = validate_style(@options[:style] || @options["style"])
35
+ @threshold = validate_threshold(@options[:threshold] || @options["threshold"])
36
+ @only = validate_only(@options[:only] || @options["only"])
29
37
 
30
- time_ago_to_now(from, to, depth, threshold)
38
+ time_ago_to_now
31
39
  end
32
40
 
33
41
  private
@@ -44,52 +52,153 @@ module Jekyll
44
52
  (1..MAX_DEPTH_LEVEL).include?(depth) ? depth : DEFAULT_DEPTH_LEVEL
45
53
  end
46
54
 
47
- def time_ago_to_now(from, to, depth, threshold)
48
- days_passed = (to - from).to_i
55
+ def validate_style(style)
56
+ style = style.to_s
57
+ STYLES.include?(style) ? style : nil
58
+ end
59
+
60
+ def validate_only(only)
61
+ return nil if only.nil?
62
+ only = only.to_s
63
+ ONLY_OPTIONS.include?(only) ? only : nil
64
+ end
65
+
66
+ def time_ago_to_now
67
+ days_passed = (@to - @from).to_i
49
68
 
50
69
  return t(:today) if days_passed == 0
51
70
  return t(:yesterday) if days_passed == 1
52
71
  return t(:tomorrow) if days_passed == -1
53
72
 
54
- past_or_future = from < to ? :past : :future
55
- slots = build_time_ago_slots(days_passed.abs, depth, threshold)
73
+ past_or_future = @from < @to ? :past : :future
74
+ slots = build_time_ago_slots(days_passed.abs)
56
75
 
57
- t(past_or_future, date_range: to_sentence(slots))
76
+ if @style == "array"
77
+ slots
78
+ else
79
+ t(past_or_future, date_range: to_sentence(slots))
80
+ end
58
81
  end
59
82
 
60
83
  def t(key, options = {})
61
84
  MiniI18n.t(key, @options.merge(options))
62
85
  end
63
86
 
64
- # Builds time ranges: ['1 month', '5 days']
65
- # - days_passed: integer in absolute
66
- # - depth: level of detail
67
- # - threshold: minimum fractional difference to keep for next slot
68
- # - current_slots: built time slots
69
- def build_time_ago_slots(days_passed, depth, threshold, current_slots = [])
70
- return current_slots if depth == 0 || days_passed == 0
87
+ # Translate a time unit, using short form if style is :short
88
+ def translate_unit(unit, count)
89
+ if @style == "short"
90
+ t("#{unit}_short", count: count)
91
+ else
92
+ t(unit, count: count)
93
+ end
94
+ end
95
+
96
+ # Builds time ranges with natural unit conversions: ['1 month', '5 days']
97
+ def build_time_ago_slots(days_passed)
98
+ # If "only" option is specified, calculate total time in that unit
99
+ return build_only_slots(days_passed) if @only
100
+
101
+ # Calculate components with natural unit conversions
102
+ components = calculate_natural_components(days_passed)
103
+
104
+ # Select components based on depth and threshold
105
+ selected = select_components(components, days_passed)
106
+
107
+ # Convert to translated strings
108
+ selected.map { |unit, count| translate_unit(unit, count) }
109
+ end
71
110
 
72
- range = days_to_range(days_passed)
73
- days = days_in(range)
74
- num_elems = (days_passed / days).to_i
111
+ # Build time slots when "only" option is specified
112
+ def build_only_slots(days_passed)
113
+ unit = @only.to_sym
114
+ count = calculate_total_in_unit(days_passed, unit)
115
+ [translate_unit(unit, count)]
116
+ end
75
117
 
76
- current_slots << t(range, count: num_elems)
118
+ # Calculate total time in specified unit
119
+ def calculate_total_in_unit(days_passed, unit)
120
+ case unit
121
+ when :days
122
+ days_passed
123
+ when :weeks
124
+ # Ensure minimum of 1 week if days_passed > 0
125
+ return 1 if days_passed > 0 && days_passed < 7
126
+ (days_passed / 7.0).round
127
+ when :months
128
+ # Ensure minimum of 1 month if days_passed > 0
129
+ return 1 if days_passed > 0 && days_passed < 30
130
+ (days_passed / 30.0).round
131
+ when :years
132
+ # Ensure minimum of 1 year if days_passed > 0
133
+ return 1 if days_passed > 0 && days_passed < 365
134
+ (days_passed / 365.0).round
135
+ end
136
+ end
77
137
 
78
- pending_days = days_passed - (num_elems * days)
138
+ def calculate_natural_components(days_passed)
139
+ years = days_passed / 365
140
+ remaining_days = days_passed % 365
141
+
142
+ months = remaining_days / 30
143
+ remaining_days = remaining_days % 30
144
+
145
+ weeks = remaining_days / 7
146
+ days = remaining_days % 7
147
+
148
+ normalize_units({ years: years, months: months, weeks: weeks, days: days })
149
+ end
79
150
 
80
- if pending_days >= (days_passed * threshold).floor
81
- build_time_ago_slots(pending_days, depth - 1, threshold, current_slots)
82
- else
83
- current_slots
151
+ def normalize_units(components)
152
+ # Convert 12+ months to years (handles any multiple: 12 → 1yr, 24 2yr, 36 → 3yr, etc.)
153
+ if components[:months] >= 12
154
+ additional_years = components[:months] / 12
155
+ components[:years] += additional_years
156
+ components[:months] = components[:months] % 12
84
157
  end
158
+
159
+ # Convert 4+ weeks to months (proportional conversion)
160
+ if components[:weeks] >= 4
161
+ additional_months = components[:weeks] / 4
162
+ components[:months] += additional_months
163
+ components[:weeks] = components[:weeks] % 4
164
+ end
165
+
166
+ # After adding months, check again for year conversion (handles cascading)
167
+ if components[:months] >= 12
168
+ additional_years = components[:months] / 12
169
+ components[:years] += additional_years
170
+ components[:months] = components[:months] % 12
171
+ end
172
+
173
+ components
174
+ end
175
+
176
+ # Select components based on depth and apply threshold filtering
177
+ def select_components(components, total_days)
178
+ result = []
179
+
180
+ [:years, :months, :weeks, :days].each do |unit|
181
+ count = components[unit]
182
+ if count > 0 && result.length < @depth
183
+ result << [unit, count]
184
+ end
185
+ end
186
+
187
+ apply_threshold_filtering(result, total_days)
85
188
  end
86
189
 
87
- def days_to_range(days)
88
- case days.abs
89
- when 1..6 then :days
90
- when 7..30 then :weeks
91
- when 31..365 then :months
92
- else :years
190
+ # Filter out components that don't meet the threshold
191
+ def apply_threshold_filtering(components, total_days)
192
+ return components if @threshold == 0 || components.length <= 1
193
+
194
+ # Calculate if smallest component meets threshold
195
+ last_unit, last_count = components.last
196
+ last_unit_days = last_count * days_in(last_unit)
197
+
198
+ if last_unit_days < (total_days * @threshold).floor
199
+ components[0...-1] # Remove last component
200
+ else
201
+ components
93
202
  end
94
203
  end
95
204
 
@@ -112,4 +221,4 @@ module Jekyll
112
221
  end
113
222
  end
114
223
  end
115
- end
224
+ end
@@ -1,5 +1,5 @@
1
1
  module Jekyll
2
2
  module Timeago
3
- VERSION = "0.15.0"
3
+ VERSION = "1.0.0"
4
4
  end
5
5
  end
data/lib/locales/ca.yml CHANGED
@@ -9,12 +9,16 @@ ca:
9
9
  years:
10
10
  one: '1 any'
11
11
  other: '%{count} anys'
12
+ years_short: '%{count}a'
12
13
  months:
13
14
  one: '1 mes'
14
15
  other: '%{count} mesos'
16
+ months_short: '%{count}m'
15
17
  weeks:
16
18
  one: '1 setmana'
17
19
  other: '%{count} setmanes'
20
+ weeks_short: '%{count}s'
18
21
  days:
19
22
  one: '1 dia'
20
23
  other: '%{count} dies'
24
+ days_short: '%{count}d'
data/lib/locales/de.yml CHANGED
@@ -9,12 +9,16 @@ de:
9
9
  years:
10
10
  one: '1 Jahr'
11
11
  other: '%{count} Jahren'
12
+ years_short: '%{count}j'
12
13
  months:
13
14
  one: '1 Monat'
14
15
  other: '%{count} Monaten'
16
+ months_short: '%{count}mo'
15
17
  weeks:
16
18
  one: '1 Woche'
17
19
  other: '%{count} Wochen'
20
+ weeks_short: '%{count}w'
18
21
  days:
19
22
  one: '1 Tag'
20
23
  other: '%{count} Tage'
24
+ days_short: '%{count}d'
data/lib/locales/en.yml CHANGED
@@ -9,12 +9,16 @@ en:
9
9
  years:
10
10
  one: '1 year'
11
11
  other: '%{count} years'
12
+ years_short: '%{count}y'
12
13
  months:
13
14
  one: '1 month'
14
15
  other: '%{count} months'
16
+ months_short: '%{count}mo'
15
17
  weeks:
16
18
  one: '1 week'
17
19
  other: '%{count} weeks'
20
+ weeks_short: '%{count}w'
18
21
  days:
19
22
  one: '1 day'
20
23
  other: '%{count} days'
24
+ days_short: '%{count}d'
data/lib/locales/es.yml CHANGED
@@ -9,12 +9,16 @@ es:
9
9
  years:
10
10
  one: '1 año'
11
11
  other: '%{count} años'
12
+ years_short: '%{count}a'
12
13
  months:
13
14
  one: '1 mes'
14
15
  other: '%{count} meses'
16
+ months_short: '%{count}m'
15
17
  weeks:
16
18
  one: '1 semana'
17
19
  other: '%{count} semanas'
20
+ weeks_short: '%{count}s'
18
21
  days:
19
22
  one: '1 día'
20
23
  other: '%{count} días'
24
+ days_short: '%{count}d'
data/lib/locales/fr.yml CHANGED
@@ -9,12 +9,16 @@ fr:
9
9
  years:
10
10
  one: '1 année'
11
11
  other: '%{count} années'
12
+ years_short: '%{count}a'
12
13
  months:
13
14
  one: '1 mois'
14
15
  other: '%{count} mois'
16
+ months_short: '%{count}mo'
15
17
  weeks:
16
18
  one: '1 semaine'
17
19
  other: '%{count} semaines'
20
+ weeks_short: '%{count}s'
18
21
  days:
19
22
  one: '1 jour'
20
23
  other: '%{count} jours'
24
+ days_short: '%{count}j'
data/lib/locales/it.yml CHANGED
@@ -9,12 +9,16 @@ it:
9
9
  years:
10
10
  one: '1 anno'
11
11
  other: '%{count} anni'
12
+ years_short: '%{count}a'
12
13
  months:
13
14
  one: '1 mese'
14
15
  other: '%{count} mesi'
16
+ months_short: '%{count}m'
15
17
  weeks:
16
18
  one: '1 settimana'
17
19
  other: '%{count} settimane'
20
+ weeks_short: '%{count}s'
18
21
  days:
19
22
  one: '1 giorno'
20
23
  other: '%{count} giorni'
24
+ days_short: '%{count}g'
data/lib/locales/ja.yaml CHANGED
@@ -9,12 +9,16 @@ ja:
9
9
  years:
10
10
  one: '1年'
11
11
  other: '%{count}年'
12
+ years_short: '%{count}年'
12
13
  months:
13
14
  one: '1ヶ月'
14
15
  other: '%{count}个月'
16
+ months_short: '%{count}月'
15
17
  weeks:
16
18
  one: '1週間'
17
19
  other: '%{count}週間'
20
+ weeks_short: '%{count}週'
18
21
  days:
19
22
  one: '1日'
20
23
  other: '%{count}日'
24
+ days_short: '%{count}日'
data/lib/locales/pt.yml CHANGED
@@ -9,12 +9,16 @@ pt:
9
9
  years:
10
10
  one: '1 ano'
11
11
  other: '%{count} anos'
12
+ years_short: '%{count}a'
12
13
  months:
13
14
  one: '1 mês'
14
15
  other: '%{count} meses'
16
+ months_short: '%{count}m'
15
17
  weeks:
16
18
  one: '1 semana'
17
19
  other: '%{count} semanas'
20
+ weeks_short: '%{count}s'
18
21
  days:
19
22
  one: '1 dia'
20
23
  other: '%{count} dias'
24
+ days_short: '%{count}d'
data/lib/locales/ru.yml CHANGED
@@ -10,15 +10,19 @@ ru:
10
10
  one: 'год'
11
11
  few: '%{count} года'
12
12
  other: '%{count} лет'
13
+ years_short: '%{count}г'
13
14
  months:
14
15
  one: 'месяц'
15
16
  few: '%{count} месяца'
16
17
  other: '%{count} месяцев'
18
+ months_short: '%{count}м'
17
19
  weeks:
18
20
  one: 'неделю'
19
21
  few: '%{count} недели'
20
22
  other: '%{count} недель'
23
+ weeks_short: '%{count}н'
21
24
  days:
22
25
  one: 'день'
23
26
  few: '%{count} дня'
24
27
  other: '%{count} дней'
28
+ days_short: '%{count}д'
@@ -0,0 +1,24 @@
1
+ tr:
2
+ today: 'bugün'
3
+ yesterday: 'dün'
4
+ tomorrow: 'yarın'
5
+ past: '%{date_range} önce'
6
+ future: '%{date_range} içinde'
7
+ last_word_connector: ', '
8
+ words_connector: ', '
9
+ years:
10
+ one: '1 yıl'
11
+ other: '%{count} yıl'
12
+ years_short: '%{count}y'
13
+ months:
14
+ one: '1 ay'
15
+ other: '%{count} ay'
16
+ months_short: '%{count}a'
17
+ weeks:
18
+ one: '1 hafta'
19
+ other: '%{count} hafta'
20
+ weeks_short: '%{count}h'
21
+ days:
22
+ one: '1 gün'
23
+ other: '%{count} gün'
24
+ days_short: '%{count}g'
@@ -9,12 +9,16 @@ zh_hans:
9
9
  years:
10
10
  one: '1年'
11
11
  other: '%{count}年'
12
+ years_short: '%{count}年'
12
13
  months:
13
14
  one: '1个月'
14
15
  other: '%{count}个月'
16
+ months_short: '%{count}月'
15
17
  weeks:
16
18
  one: '1周'
17
19
  other: '%{count}周'
20
+ weeks_short: '%{count}周'
18
21
  days:
19
22
  one: '1天'
20
23
  other: '%{count}天'
24
+ days_short: '%{count}天'
@@ -23,8 +23,8 @@ describe Jekyll::Timeago do
23
23
 
24
24
  expected =
25
25
  "<p>2 años</p>\n"\
26
- "<p>12 meses</p>\n"\
27
- "<p>12 meses</p>\n"\
26
+ "<p>1 año</p>\n"\
27
+ "<p>1 año</p>\n"\
28
28
  "<p>2 años</p>\n"\
29
29
  "<p>en 1 año</p>\n"
30
30
 
@@ -36,6 +36,11 @@ describe Jekyll::Timeago do
36
36
  let (:sample_date) { Date.new(2014, 7, 30) }
37
37
  let (:today) { Date.today }
38
38
 
39
+ before(:all) do
40
+ # Reset original translations
41
+ MiniI18n.configure { |config| config.load_translations(Pathname(__dir__).join("../lib/locales/*.yml")) }
42
+ end
43
+
39
44
  it 'yesterday, today and tomorrow' do
40
45
  expect(timeago(today.prev_day)).to eq("yesterday")
41
46
  expect(timeago(today)).to eq("today")
@@ -55,7 +60,7 @@ describe Jekyll::Timeago do
55
60
  expect(timeago(sample_date.next_day(1000), sample_date, locale: :ru)).to eq('через 2 года и 9 месяцев')
56
61
  end
57
62
 
58
- it 'allow different date formats' do
63
+ it 'allows different date formats' do
59
64
  expect(timeago('2010-1-1', '2012-1-1')).to eq('2 years ago')
60
65
  expect(timeago('2010/1/1', '2012/1/1')).to eq('2 years ago')
61
66
  expect(timeago('Jan 2010, 1', 'Jan 2012, 1')).to eq('2 years ago')
@@ -63,7 +68,7 @@ describe Jekyll::Timeago do
63
68
  expect(timeago('2014-10-06 20:00:00', '2014-10-07 20:00:00')).to eq('yesterday')
64
69
  end
65
70
 
66
- it 'allow to change level of detail' do
71
+ it 'allows to change level of detail' do
67
72
  expect(timeago(sample_date.prev_day(500), sample_date, depth: 1)).to eq('1 year ago')
68
73
  expect(timeago(sample_date.prev_day(500), sample_date, "depth" => 1)).to eq('1 year ago')
69
74
  expect(timeago(sample_date.prev_day(500), sample_date, depth: 2)).to eq('1 year and 4 months ago')
@@ -72,39 +77,138 @@ describe Jekyll::Timeago do
72
77
  expect(timeago(sample_date.prev_day(500), sample_date, depth: 5)).to eq('1 year and 4 months ago')
73
78
  end
74
79
 
75
- it 'allow threshold configuration' do
76
- expect(timeago(sample_date.prev_day(366), sample_date, threshold: 0.05)).to eq('1 year ago')
80
+ it 'allows threshold configuration' do
81
+ expect(timeago(sample_date.prev_day(366), sample_date, threshold: 0.1)).to eq('1 year ago')
82
+ end
83
+
84
+ it 'applies rounding rules for natural language' do
85
+ expect(timeago(sample_date.prev_day(58), sample_date)).to eq('2 months ago')
86
+ expect(timeago(sample_date.prev_day(360), sample_date)).to eq('1 year ago')
87
+ expect(timeago(sample_date.prev_day(725), sample_date)).to eq('2 years ago')
88
+ expect(timeago(sample_date.next_day(58), sample_date)).to eq('in 2 months')
89
+ expect(timeago(sample_date.next_day(360), sample_date)).to eq('in 1 year')
90
+ expect(timeago(sample_date.next_day(725), sample_date)).to eq('in 2 years')
91
+
92
+ # Test cases that should NOT round up
93
+ expect(timeago(sample_date.prev_day(44), sample_date)).to eq('1 month and 2 weeks ago')
94
+ expect(timeago(sample_date.prev_day(545), sample_date)).to eq('1 year and 6 months ago')
77
95
  end
78
96
 
79
- it 'allow localization' do
97
+ it 'allows localization' do
80
98
  expect(timeago(sample_date.prev_day(100), sample_date, locale: :fr)).to eq('il y a environ 3 mois et 1 semaine')
81
99
  expect(timeago(sample_date.prev_day(100), sample_date, locale: :ru)).to eq('3 месяца и неделю назад')
82
100
  end
101
+
102
+ it 'allows short style formatting' do
103
+ expect(timeago(sample_date.prev_day(365), sample_date, style: :short)).to eq('1y ago')
104
+ expect(timeago(sample_date.prev_day(365), sample_date, "style" => "short")).to eq('1y ago')
105
+ expect(timeago(sample_date.prev_day(730), sample_date, style: :short)).to eq('2y ago')
106
+ expect(timeago(sample_date.prev_day(30), sample_date, style: :short)).to eq('1mo ago')
107
+ expect(timeago(sample_date.prev_day(60), sample_date, style: :short)).to eq('2mo ago')
108
+ expect(timeago(sample_date.prev_day(7), sample_date, style: :short)).to eq('1w ago')
109
+ expect(timeago(sample_date.prev_day(14), sample_date, style: :short)).to eq('2w ago')
110
+ expect(timeago(sample_date.prev_day(1), sample_date, style: :short)).to eq('yesterday')
111
+ expect(timeago(sample_date.prev_day(2), sample_date, style: :short)).to eq('2d ago')
112
+ end
113
+
114
+ it 'allows short style with different locales' do
115
+ expect(timeago(sample_date.prev_day(365), sample_date, locale: :fr, style: :short)).to eq('il y a environ 1a')
116
+ expect(timeago(sample_date.prev_day(365), sample_date, locale: :ru, style: :short)).to eq('1г назад')
117
+ expect(timeago(sample_date.prev_day(365), sample_date, locale: :es, style: :short)).to eq('hace 1a')
118
+ expect(timeago(sample_date.prev_day(30), sample_date, locale: :de, style: :short)).to eq('vor 1mo')
119
+ end
120
+
121
+ it 'allows complex combinations with short style' do
122
+ expect(timeago(sample_date.prev_day(400), sample_date, style: :short)).to eq('1y and 1mo ago')
123
+ expect(timeago(sample_date.prev_day(100), sample_date, style: :short, depth: 1)).to eq('3mo ago')
124
+ expect(timeago(sample_date.prev_day(100), sample_date, style: :short, depth: 3)).to eq('3mo, 1w and 3d ago')
125
+ end
126
+
127
+ it 'allows array style formatting' do
128
+ expect(timeago(sample_date.prev_day(365), sample_date, style: :array)).to eq(['1 year'])
129
+ expect(timeago(sample_date.prev_day(365), sample_date, "style" => "array")).to eq(['1 year'])
130
+ expect(timeago(sample_date.prev_day(160), sample_date, style: :array)).to eq(['5 months', '1 week'])
131
+ expect(timeago(sample_date.prev_day(160), sample_date, style: :array, locale: :es)).to eq(['5 meses', '1 semana'])
132
+ end
133
+
134
+ it 'allows "only" option to accumulate time into single unit' do
135
+ # Test "only: :days"
136
+ expect(timeago(sample_date.prev_day(7), sample_date, only: :days)).to eq('7 days ago')
137
+ expect(timeago(sample_date.prev_day(7), sample_date, "only" => "days")).to eq('7 days ago')
138
+ expect(timeago(sample_date.prev_day(30), sample_date, only: :days)).to eq('30 days ago')
139
+
140
+ # Test "only: :weeks"
141
+ expect(timeago(sample_date.prev_day(7), sample_date, only: :weeks)).to eq('1 week ago')
142
+ expect(timeago(sample_date.prev_day(14), sample_date, only: :weeks)).to eq('2 weeks ago')
143
+ expect(timeago(sample_date.prev_day(30), sample_date, only: :weeks)).to eq('4 weeks ago')
144
+ expect(timeago(sample_date.prev_day(365), sample_date, only: :weeks)).to eq('52 weeks ago')
145
+
146
+ # Test "only: :months"
147
+ expect(timeago(sample_date.prev_day(30), sample_date, only: :months)).to eq('1 month ago')
148
+ expect(timeago(sample_date.prev_day(60), sample_date, only: :months)).to eq('2 months ago')
149
+ expect(timeago(sample_date.prev_day(365), sample_date, only: :months)).to eq('12 months ago')
150
+
151
+ # Test "only: :years"
152
+ expect(timeago(sample_date.prev_day(365), sample_date, only: :years)).to eq('1 year ago')
153
+ expect(timeago(sample_date.prev_day(730), sample_date, only: :years)).to eq('2 years ago')
154
+ expect(timeago(sample_date.prev_day(1000), sample_date, only: :years)).to eq('3 years ago')
155
+ end
156
+
157
+ it 'allows "only" option with different styles' do
158
+ # Test with short style
159
+ expect(timeago(sample_date.prev_day(365), sample_date, only: :weeks, style: :short)).to eq('52w ago')
160
+ expect(timeago(sample_date.prev_day(30), sample_date, only: :months, style: :short)).to eq('1mo ago')
161
+
162
+ # Test with array style
163
+ expect(timeago(sample_date.prev_day(365), sample_date, only: :weeks, style: :array)).to eq(['52 weeks'])
164
+ expect(timeago(sample_date.prev_day(30), sample_date, only: :months, style: :array)).to eq(['1 month'])
165
+ end
166
+
167
+ it 'allows "only" option with different locales' do
168
+ expect(timeago(sample_date.prev_day(30), sample_date, only: :weeks, locale: :es)).to eq('hace 4 semanas')
169
+ expect(timeago(sample_date.prev_day(365), sample_date, only: :months, locale: :fr)).to eq('il y a environ 12 mois')
170
+ end
83
171
  end
84
172
 
85
173
  context 'CLI' do
86
174
  it 'prints help message if called with no params or --help' do
87
- expect(`bin/jekyll-timeago`).to match("Usage")
88
- expect(`bin/jekyll-timeago --help`).to match("Usage")
175
+ expect(`bin/timeago`).to match("Usage")
176
+ expect(`bin/timeago --help`).to match("Usage")
89
177
  end
90
178
 
91
179
  it 'prints current version' do
92
- expect(`bin/jekyll-timeago -v`).to match("v#{Jekyll::Timeago::VERSION}")
93
- expect(`bin/jekyll-timeago --version`).to match("v#{Jekyll::Timeago::VERSION}")
180
+ expect(`bin/timeago -v`).to match("v#{Jekyll::Timeago::VERSION}")
181
+ expect(`bin/timeago --version`).to match("v#{Jekyll::Timeago::VERSION}")
94
182
  end
95
183
 
96
184
  it 'computes distance of dates' do
97
- expect(`bin/jekyll-timeago 2016-1-1 2016-1-5`).to match("4 days ago")
185
+ expect(`bin/timeago 2016-1-1 2016-1-5`).to match("4 days ago")
98
186
  end
99
187
 
100
188
  it 'prints error with invalid date' do
101
- expect(`bin/jekyll-timeago 0`).to match("Error!")
189
+ expect(`bin/timeago 0`).to match("Error!")
102
190
  end
103
191
 
104
192
  it 'with custom locale' do
105
- expect(`bin/jekyll-timeago 2016-1-1 2016-1-5 -l fr`).to match("il y a environ 4 jours")
106
- expect(`bin/jekyll-timeago 2016-1-1 2016-1-5 --locale fr`).to match("il y a environ 4 jours")
107
- expect(`bin/jekyll-timeago 2016-1-1 2016-1-5 --locale ru`).to match("4 дня назад")
193
+ expect(`bin/timeago 2016-1-1 2016-1-5 -l fr`).to match("il y a environ 4 jours")
194
+ expect(`bin/timeago 2016-1-1 2016-1-5 --locale fr`).to match("il y a environ 4 jours")
195
+ expect(`bin/timeago 2016-1-1 2016-1-5 --locale ru`).to match("4 дня назад")
196
+ end
197
+
198
+ it 'with short style' do
199
+ expect(`bin/timeago 2016-1-1 2018-1-1 -s short`).to match("2y and 1d ago")
200
+ expect(`bin/timeago 2016-1-1 2018-1-1 --style short`).to match("2y and 1d ago")
201
+ expect(`bin/timeago 2016-1-1 2016-2-1 -s short`).to match("1mo and 1d ago")
202
+ expect(`bin/timeago 2016-1-1 2018-1-1 -l fr -s short`).to match("il y a environ 2a")
203
+ expect(`bin/timeago 2016-1-1 2018-1-1 --locale ru --style short`).to match("2г и 1д назад")
204
+ end
205
+
206
+ it 'with only option' do
207
+ expect(`bin/timeago 2016-1-1 2018-1-1 --only weeks`).to match("104 weeks ago")
208
+ expect(`bin/timeago 2016-1-1 2018-1-1 -o months`).to match("24 months ago")
209
+ expect(`bin/timeago 2016-1-1 2016-2-1 --only days`).to match("31 days ago")
210
+ expect(`bin/timeago 2016-1-1 2018-1-1 -l fr --only months`).to match("il y a environ 24 mois")
211
+ expect(`bin/timeago 2016-1-1 2018-1-1 --only weeks -s short`).to match("104w ago")
108
212
  end
109
213
  end
110
214
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jekyll-timeago
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - markets
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-01-11 00:00:00.000000000 Z
11
+ date: 2025-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mini_i18n
@@ -85,7 +85,7 @@ description: A Ruby library to compute distance of dates in words. Originally bu
85
85
  email:
86
86
  - srmarc.ai@gmail.com
87
87
  executables:
88
- - jekyll-timeago
88
+ - timeago
89
89
  extensions: []
90
90
  extra_rdoc_files: []
91
91
  files:
@@ -96,7 +96,7 @@ files:
96
96
  - LICENSE
97
97
  - README.md
98
98
  - Rakefile
99
- - bin/jekyll-timeago
99
+ - bin/timeago
100
100
  - gemfiles/jekyll_v3.gemfile
101
101
  - gemfiles/jekyll_v4.gemfile
102
102
  - jekyll-timeago.gemspec
@@ -113,6 +113,7 @@ files:
113
113
  - lib/locales/ja.yaml
114
114
  - lib/locales/pt.yml
115
115
  - lib/locales/ru.yml
116
+ - lib/locales/tr.yml
116
117
  - lib/locales/zh_hans.yml
117
118
  - spec/jekyll-timeago_spec.rb
118
119
  - spec/source/_config.yml
@@ -123,7 +124,7 @@ homepage: https://github.com/markets/jekyll-timeago
123
124
  licenses:
124
125
  - MIT
125
126
  metadata: {}
126
- post_install_message:
127
+ post_install_message:
127
128
  rdoc_options: []
128
129
  require_paths:
129
130
  - lib
@@ -138,8 +139,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
139
  - !ruby/object:Gem::Version
139
140
  version: '0'
140
141
  requirements: []
141
- rubygems_version: 3.1.4
142
- signing_key:
142
+ rubygems_version: 3.4.10
143
+ signing_key:
143
144
  specification_version: 4
144
145
  summary: A date helper to compute distance of dates in words.
145
146
  test_files:
data/bin/jekyll-timeago DELETED
@@ -1,48 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require_relative "../lib/jekyll-timeago"
4
-
5
- help_message = <<~HELP_MESSAGE
6
- Usage:
7
-
8
- jekyll-timeago <from_date> [to_date]
9
-
10
- Notes:
11
- [to_date] Optional, defaults to current date
12
-
13
- Options:
14
- --help, -h Prints this message
15
- --version, -v Prints the current version
16
- --console, -c Starts an interactive IRB session with jekyll-timeago included
17
- --locale, -l Uses the provided locale
18
- HELP_MESSAGE
19
-
20
- if ARGV.empty? || ARGV.include?("--help") || ARGV.include?("-h")
21
- puts help_message
22
- elsif ARGV.include?("--version") || ARGV.include?("-v")
23
- puts "v#{Jekyll::Timeago::VERSION}"
24
- elsif ARGV.include?("--console") || ARGV.include?("-c")
25
- require "irb"
26
- include Jekyll::Timeago
27
-
28
- ARGV.clear
29
- IRB.start
30
- else
31
- custom_locale = "--locale" if ARGV.include?("--locale")
32
- custom_locale = "-l" if ARGV.include?("-l")
33
-
34
- if custom_locale
35
- index = ARGV.index(custom_locale)
36
- locale = ARGV.delete_at(index + 1)
37
- ARGV.delete_at(index)
38
-
39
- options = { locale: locale }
40
- ARGV << options
41
- end
42
-
43
- begin
44
- puts Jekyll::Timeago.timeago *ARGV
45
- rescue ArgumentError => e
46
- puts "Error! #{e}"
47
- end
48
- end