jekyll-timeago 0.8.2 → 0.9.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 +4 -4
- data/.gitignore +2 -1
- data/.travis.yml +16 -0
- data/Appraisals +13 -0
- data/LICENSE +1 -1
- data/README.md +65 -30
- data/bin/jekyll-timeago +27 -0
- data/gemfiles/jekyll_v1.gemfile +7 -0
- data/gemfiles/jekyll_v2.gemfile +8 -0
- data/gemfiles/jekyll_v3.gemfile +8 -0
- data/jekyll-timeago.gemspec +2 -4
- data/{_config.yml.example → lib/jekyll-timeago/config/_config.yml.example.en} +0 -0
- data/lib/jekyll-timeago/config/_config.yml.example.es +18 -0
- data/lib/jekyll-timeago/config/_config.yml.example.fr +19 -0
- data/lib/jekyll-timeago/core.rb +147 -0
- data/lib/jekyll-timeago/filter.rb +2 -143
- data/lib/jekyll-timeago/tag.rb +3 -6
- data/lib/jekyll-timeago/version.rb +1 -1
- data/lib/jekyll-timeago.rb +9 -2
- data/spec/jekyll-timeago_spec.rb +107 -0
- data/spec/source/_config.yml +2 -2
- data/spec/source/index.html +1 -2
- data/spec/spec_helper.rb +4 -16
- metadata +30 -8
- data/script/console +0 -13
- data/spec/jekyll_timeago_spec.rb +0 -82
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d4b2b6bddb90157fb80c3c7fecd1154856803d8
|
4
|
+
data.tar.gz: 430dbea158d988267bc00b3ea9c5c5708e030355
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb56e09b24cbf51da1efab5f62d55f95149093e9d2e5efddd30906db6be23a6e69c7062d715eb0e21a43a6a1dc9972815827594d2f46f231c68690a53f13955f
|
7
|
+
data.tar.gz: 144e8ca11755ec40da5ac4ce3e2dfd83a071fe569247f0c3fca6a0153dead5cdda6c0c5f5bfc56fccda6f46d2979242f50bdbf79afedfc75e5601c81ddf9cfce
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
language: ruby
|
2
|
+
|
3
|
+
cache: bundler
|
4
|
+
|
5
|
+
sudo: false
|
6
|
+
|
2
7
|
rvm:
|
8
|
+
- 2.2
|
3
9
|
- 2.1
|
4
10
|
- 2.0
|
5
11
|
- 1.9.3
|
12
|
+
|
13
|
+
gemfile:
|
14
|
+
- gemfiles/jekyll_v1.gemfile
|
15
|
+
- gemfiles/jekyll_v2.gemfile
|
16
|
+
- gemfiles/jekyll_v3.gemfile
|
17
|
+
|
18
|
+
matrix:
|
19
|
+
exclude:
|
20
|
+
- rvm: 1.9.3
|
21
|
+
gemfile: gemfiles/jekyll_v3.gemfile
|
data/Appraisals
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
appraise 'jekyll-v1' do
|
2
|
+
gem 'jekyll', '~> 1.5'
|
3
|
+
end
|
4
|
+
|
5
|
+
appraise 'jekyll-v2' do
|
6
|
+
gem 'jekyll', '~> 2.5'
|
7
|
+
gem 'listen', '< 3.1.0' if RUBY_VERSION <= "2.2"
|
8
|
+
end
|
9
|
+
|
10
|
+
appraise 'jekyll-v3' do
|
11
|
+
gem 'jekyll', '~> 3.0'
|
12
|
+
gem 'listen', '< 3.1.0' if RUBY_VERSION <= "2.2"
|
13
|
+
end
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -2,21 +2,24 @@
|
|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/jekyll-timeago) [](https://travis-ci.org/markets/jekyll-timeago)
|
4
4
|
|
5
|
-
|
5
|
+
> A Ruby library to compute distance of dates in words. Originally built for Jekyll, as a Liquid extension.
|
6
6
|
|
7
|
-
|
8
|
-
* Future time
|
9
|
-
* Usage via Filter or Tag
|
10
|
-
* Localization
|
11
|
-
* Level of detail
|
7
|
+
Main features:
|
12
8
|
|
13
|
-
|
9
|
+
* Compute distance of dates in words, ie: `1 week and 2 days ago`, `5 months ago`, `in 1 year`
|
10
|
+
* Future times.
|
11
|
+
* Out of the box support for `Jekyll` (v1, v2 and v3) projects, available as a Liquid Filter and as a Liquid Tag.
|
12
|
+
* Localization (i18n).
|
13
|
+
* Level of detail.
|
14
|
+
* Available via the command line.
|
15
|
+
|
16
|
+
In fact, `jekyll-timeago` started just as an extension for [Liquid](https://github.com/Shopify/liquid) template engine, to be used in Jekyll and Octopress backed sites. But actually, you can use it easily in any Ruby project. Read more about usage outside Jekyll [in this section](#usage-outside-jekyll).
|
14
17
|
|
15
18
|
## Installation
|
16
19
|
|
17
|
-
You have
|
20
|
+
You have different options to install and plugging it into Jekyll projects:
|
18
21
|
|
19
|
-
**Via Jekyll plugin system**
|
22
|
+
**Via Jekyll plugin system (recommended)**
|
20
23
|
|
21
24
|
Install the `gem` to your system:
|
22
25
|
|
@@ -27,33 +30,27 @@ gem install jekyll-timeago
|
|
27
30
|
In your `_config.yml` file, add a new array with the key gems and the values of the gem names of the plugins you’d like to use. In this case:
|
28
31
|
|
29
32
|
```
|
30
|
-
gems:
|
33
|
+
gems:
|
34
|
+
- jekyll-timeago
|
31
35
|
```
|
32
36
|
|
33
37
|
**Via Bundler**
|
34
38
|
|
35
|
-
Add this gem to your `Gemfile` and run `bundle`:
|
36
|
-
|
37
|
-
```
|
38
|
-
gem 'jekyll-timeago'
|
39
|
-
```
|
40
|
-
|
41
|
-
Then load the plugin adding the following into some file under `_plugins/` folder:
|
39
|
+
Add this gem to your `Gemfile` and run `bundle install`:
|
42
40
|
|
43
41
|
```ruby
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
Bundler.require(:default)
|
42
|
+
group :jekyll_plugins do
|
43
|
+
gem 'jekyll-timeago'
|
44
|
+
end
|
48
45
|
```
|
49
46
|
|
50
|
-
**Manually**
|
47
|
+
**Manually (less recommended)**
|
51
48
|
|
52
|
-
Alternatively, you can simply copy [
|
49
|
+
Alternatively, you can simply copy the files under [lib/jekyll-timeago](lib/jekyll-timeago/) directly into your `_plugins/` directory. All those files will be loaded by Jekyll.
|
53
50
|
|
54
51
|
## Usage
|
55
52
|
|
56
|
-
By default `timeago` computes distance of dates from passed date to current date (using `Date.today`). But you are able to modify this range passing a second argument
|
53
|
+
By default, the `timeago` helper computes distance of dates from passed date to current date (using `Date.today`). But you are able to modify this range by passing a second argument. Examples:
|
57
54
|
|
58
55
|
**Filter example**:
|
59
56
|
|
@@ -81,7 +78,9 @@ Passing a second parameter:
|
|
81
78
|
|
82
79
|
## Localization
|
83
80
|
|
84
|
-
|
81
|
+
This plugin allows you to localize the strings needed to build the sentences. To do this, you just need to add some extra keys in your `_config.yml`. You can simply copy them from one of the [provided examples](lib/jekyll-timeago/config/). Or even, translate it to your site's language just overriding it.
|
82
|
+
|
83
|
+
English example (default):
|
85
84
|
|
86
85
|
```
|
87
86
|
jekyll_timeago:
|
@@ -104,7 +103,7 @@ jekyll_timeago:
|
|
104
103
|
day: 'day'
|
105
104
|
```
|
106
105
|
|
107
|
-
**NOTE** You also can
|
106
|
+
**NOTE** You also can play with suffixes and prefixes to modify the sentences. For example, set `suffix: nil` and you'll get only the distance of dates: `1 year, 4 months and 1 week`.
|
108
107
|
|
109
108
|
## Level of detail (Depth)
|
110
109
|
|
@@ -115,9 +114,33 @@ You are able to change the level of detail (from 1 up to 4, 2 by default) to get
|
|
115
114
|
* Depht => 3 `1 year, 4 months and 1 week ago`
|
116
115
|
* Depht => 4 `1 year, 4 months, 1 week and 4 days ago`
|
117
116
|
|
118
|
-
##
|
117
|
+
## Usage outside Jekyll
|
118
|
+
|
119
|
+
You just need to install the gem to your application (add `gem 'jekyll-timeago'` to your Gemfile). From now on, you can use the provided method by calling:
|
119
120
|
|
120
|
-
|
121
|
+
```ruby
|
122
|
+
Jekyll::Timeago::Core.timeago(from, to, options)
|
123
|
+
```
|
124
|
+
|
125
|
+
Note, that you can use the `options` parameter to override the default localization or the level of detail.
|
126
|
+
|
127
|
+
Or if you have the gem installed in your system and you're not using Bundler:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
require 'jekyll-timeago'
|
131
|
+
puts Jekyll::Timeago::Core.timeago(from, to, options)
|
132
|
+
```
|
133
|
+
|
134
|
+
## CLI
|
135
|
+
|
136
|
+
```
|
137
|
+
$ jekyll-timeago 2016-1-1
|
138
|
+
2 months and 6 days ago
|
139
|
+
```
|
140
|
+
|
141
|
+
### Console
|
142
|
+
|
143
|
+
Run `$ jekyll-timeago --console` to start a custom IRB session and play with the `timeago` method:
|
121
144
|
|
122
145
|
```ruby
|
123
146
|
>> timeago(Date.today)
|
@@ -143,12 +166,24 @@ Run `script/console` to start a custom IRB session and play with `timeago` metho
|
|
143
166
|
Play with `options`:
|
144
167
|
|
145
168
|
```ruby
|
146
|
-
>>
|
169
|
+
>> configure "yesterday" => "ayer"
|
147
170
|
=> "ayer"
|
148
171
|
>> timeago(Date.today - 1.day)
|
149
172
|
=> "ayer"
|
150
173
|
```
|
151
174
|
|
175
|
+
## Development
|
176
|
+
|
177
|
+
Any kind of feedback, bug report, idea or enhancement are really appreciated.
|
178
|
+
|
179
|
+
To contribute, just fork the repo, hack on it and send a pull request. Don't forget to add specs for behaviour changes and run the test suite:
|
180
|
+
|
181
|
+
```
|
182
|
+
bundle exec appraisal rake
|
183
|
+
```
|
184
|
+
|
185
|
+
`Appraisal` library is used to ensure compatibility with different Jekyll versions. Check out current supported versions [here](Appraisals).
|
186
|
+
|
152
187
|
## License
|
153
188
|
|
154
|
-
Copyright (c) 2013-
|
189
|
+
Copyright (c) 2013-2016 Marc Anguera. Jekyll-Timeago is released under the [MIT](LICENSE) License.
|
data/bin/jekyll-timeago
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative "../lib/jekyll-timeago/core"
|
4
|
+
include Jekyll::Timeago::Core
|
5
|
+
|
6
|
+
help_message = <<END
|
7
|
+
Usage:
|
8
|
+
|
9
|
+
jekyll-timeago <from_date> [to_date]
|
10
|
+
|
11
|
+
Notes:
|
12
|
+
[to_date] Optional, defaults to current date
|
13
|
+
|
14
|
+
Options:
|
15
|
+
--help, -h Print this message
|
16
|
+
--console Start an interactive session with jekyll-timeago included
|
17
|
+
END
|
18
|
+
|
19
|
+
if ARGV.empty? || ARGV.include?("--help") || ARGV.include?("-h")
|
20
|
+
puts help_message
|
21
|
+
elsif ARGV.include? "--console"
|
22
|
+
require "irb"
|
23
|
+
ARGV.clear
|
24
|
+
IRB.start
|
25
|
+
else
|
26
|
+
puts timeago *ARGV
|
27
|
+
end
|
data/jekyll-timeago.gemspec
CHANGED
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'jekyll-timeago/version'
|
1
|
+
require './lib/jekyll-timeago/version'
|
5
2
|
|
6
3
|
Gem::Specification.new do |spec|
|
7
4
|
spec.name = "jekyll-timeago"
|
@@ -23,4 +20,5 @@ Gem::Specification.new do |spec|
|
|
23
20
|
spec.add_development_dependency "rake"
|
24
21
|
spec.add_development_dependency "rspec"
|
25
22
|
spec.add_development_dependency "activesupport"
|
23
|
+
spec.add_development_dependency "appraisal"
|
26
24
|
end
|
File without changes
|
@@ -0,0 +1,18 @@
|
|
1
|
+
jekyll_timeago:
|
2
|
+
depth: 2 # Nivel de detalle
|
3
|
+
today: 'hoy'
|
4
|
+
yesterday: 'ayer'
|
5
|
+
tomorrow: 'mañana'
|
6
|
+
and: 'y'
|
7
|
+
suffix: ''
|
8
|
+
prefix: 'hace'
|
9
|
+
suffix_future: ''
|
10
|
+
prefix_future: 'en'
|
11
|
+
years: 'años'
|
12
|
+
year: 'año'
|
13
|
+
months: 'meses'
|
14
|
+
month: 'mes'
|
15
|
+
weeks: 'semanas'
|
16
|
+
week: 'semana'
|
17
|
+
days: 'días'
|
18
|
+
day: 'día'
|
@@ -0,0 +1,19 @@
|
|
1
|
+
jekyll_timeago:
|
2
|
+
depth: 2 # niveau de détail
|
3
|
+
today: "aujourd'hui"
|
4
|
+
yesterday: "hier"
|
5
|
+
tomorrow: "demain"
|
6
|
+
and: "et"
|
7
|
+
suffix: ""
|
8
|
+
prefix: "il y a environ"
|
9
|
+
suffix_future: ""
|
10
|
+
prefix_future: "dans"
|
11
|
+
years: "années"
|
12
|
+
year: "année"
|
13
|
+
months: "mois"
|
14
|
+
month: "mois"
|
15
|
+
weeks: "semaines"
|
16
|
+
week: "semaine"
|
17
|
+
days: "jours"
|
18
|
+
day: "jour"
|
19
|
+
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module Jekyll
|
4
|
+
module Timeago
|
5
|
+
module Core
|
6
|
+
extend self
|
7
|
+
|
8
|
+
DAYS_PER = {
|
9
|
+
:days => 1,
|
10
|
+
:weeks => 7,
|
11
|
+
:months => 30,
|
12
|
+
:years => 365
|
13
|
+
}
|
14
|
+
|
15
|
+
# Max level of detail
|
16
|
+
# years > months > weeks > days
|
17
|
+
# 1 year and 7 months and 2 weeks and 6 days
|
18
|
+
MAX_DEPTH_LEVEL = 4
|
19
|
+
|
20
|
+
# Default level of detail
|
21
|
+
# 1 month and 5 days, 3 weeks and 2 days, 2 years and 6 months
|
22
|
+
DEFAULT_DEPTH_LEVEL = 2
|
23
|
+
|
24
|
+
def timeago(from, to = Date.today, options = {})
|
25
|
+
if to.is_a?(Hash)
|
26
|
+
options = to
|
27
|
+
to = Date.today
|
28
|
+
end
|
29
|
+
|
30
|
+
@defaults = defaults unless defined?(@defaults)
|
31
|
+
@options = @defaults.merge(options)
|
32
|
+
|
33
|
+
from = validate_date!(from)
|
34
|
+
to = validate_date!(to)
|
35
|
+
depth = validate_depth!(@options["depth"])
|
36
|
+
|
37
|
+
time_ago_to_now(from, to, depth)
|
38
|
+
end
|
39
|
+
|
40
|
+
def configure(options = {})
|
41
|
+
@defaults = defaults.merge(options)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def validate_date!(date)
|
47
|
+
Date.parse(date.to_s)
|
48
|
+
end
|
49
|
+
|
50
|
+
def validate_depth!(depth)
|
51
|
+
(1..MAX_DEPTH_LEVEL).include?(depth) or raise("Invalid depth level: #{depth.inspect}")
|
52
|
+
depth
|
53
|
+
end
|
54
|
+
|
55
|
+
def defaults
|
56
|
+
{
|
57
|
+
"depth" => DEFAULT_DEPTH_LEVEL,
|
58
|
+
"today" => 'today',
|
59
|
+
"yesterday" => 'yesterday',
|
60
|
+
"tomorrow" => 'tomorrow',
|
61
|
+
"and" => 'and',
|
62
|
+
"suffix" => 'ago',
|
63
|
+
"prefix" => '',
|
64
|
+
"suffix_future" => '',
|
65
|
+
"prefix_future" => 'in',
|
66
|
+
"years" => 'years',
|
67
|
+
"year" => 'year',
|
68
|
+
"months" => 'months',
|
69
|
+
"month" => 'month',
|
70
|
+
"weeks" => 'weeks',
|
71
|
+
"week" => 'week',
|
72
|
+
"days" => 'days',
|
73
|
+
"day" => 'day'
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
def translate(key)
|
78
|
+
@options[key.to_s]
|
79
|
+
end
|
80
|
+
alias_method :t, :translate
|
81
|
+
|
82
|
+
# Days passed to time ago sentence
|
83
|
+
def time_ago_to_now(from, to, depth)
|
84
|
+
days_passed = (to - from).to_i
|
85
|
+
|
86
|
+
return t(:today) if days_passed == 0
|
87
|
+
return t(:yesterday) if days_passed == 1
|
88
|
+
return t(:tomorrow) if days_passed == -1
|
89
|
+
|
90
|
+
future = days_passed < 0
|
91
|
+
slots = build_time_ago_slots(days_passed.abs, depth)
|
92
|
+
sentence = to_sentence(slots)
|
93
|
+
|
94
|
+
if future
|
95
|
+
"#{t(:prefix_future)} #{sentence} #{t(:suffix_future)}".strip
|
96
|
+
else
|
97
|
+
"#{t(:prefix)} #{sentence} #{t(:suffix)}".strip
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Builds time ranges: ['1 month', '5 days']
|
102
|
+
# - days_passed: integer in absolute
|
103
|
+
# - depth: level of detail
|
104
|
+
# - current_slots: built time slots
|
105
|
+
def build_time_ago_slots(days_passed, depth, current_slots = [])
|
106
|
+
return current_slots if depth == 0 || days_passed == 0
|
107
|
+
|
108
|
+
time_range = days_to_time_range(days_passed)
|
109
|
+
days = DAYS_PER[time_range]
|
110
|
+
num_elems = (days_passed / days).to_i
|
111
|
+
|
112
|
+
range_type = if num_elems == 1
|
113
|
+
t(time_range[0...-1]) # singularize key
|
114
|
+
else
|
115
|
+
t(time_range)
|
116
|
+
end
|
117
|
+
|
118
|
+
current_slots << "#{num_elems} #{range_type}"
|
119
|
+
pending_days = days_passed - (num_elems * days)
|
120
|
+
build_time_ago_slots(pending_days, depth - 1, current_slots)
|
121
|
+
end
|
122
|
+
|
123
|
+
# Number of days to minimum period time which can be grouped
|
124
|
+
def days_to_time_range(days_passed)
|
125
|
+
case days_passed.abs
|
126
|
+
when 1..6
|
127
|
+
:days
|
128
|
+
when 7..30
|
129
|
+
:weeks
|
130
|
+
when 31..365
|
131
|
+
:months
|
132
|
+
else
|
133
|
+
:years
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Array to sentence: ['1 month', '1 week', '5 days'] => "1 month, 1 week and 5 days"
|
138
|
+
def to_sentence(slots)
|
139
|
+
if slots.length == 1
|
140
|
+
slots[0]
|
141
|
+
else
|
142
|
+
"#{slots[0...-1].join(', ')} #{t(:and)} #{slots[-1]}"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -1,152 +1,11 @@
|
|
1
|
-
require 'date'
|
2
|
-
|
3
1
|
module Jekyll
|
4
2
|
module Timeago
|
5
3
|
module Filter
|
6
|
-
extend self
|
7
|
-
|
8
|
-
DAYS_PER = {
|
9
|
-
:days => 1,
|
10
|
-
:weeks => 7,
|
11
|
-
:months => 30,
|
12
|
-
:years => 365
|
13
|
-
}
|
14
|
-
|
15
|
-
# Max level of detail
|
16
|
-
# years > months > weeks > days
|
17
|
-
# 1 year and 7 months and 2 weeks and 6 days
|
18
|
-
MAX_DEPTH_LEVEL = 4
|
19
|
-
|
20
|
-
# Default level of detail
|
21
|
-
# 1 month and 5 days, 3 weeks and 2 days, 2 years and 6 months
|
22
|
-
DEFAULT_DEPTH_LEVEL = 2
|
23
|
-
|
24
4
|
def timeago(from, to = Date.today)
|
25
|
-
|
26
|
-
to = validate_date!(to)
|
27
|
-
depth = validate_depth!(options[:depth])
|
28
|
-
|
29
|
-
time_ago_to_now(from, to, depth)
|
30
|
-
end
|
31
|
-
|
32
|
-
def options
|
33
|
-
@options ||= setup
|
34
|
-
end
|
35
|
-
|
36
|
-
# Restore default configuration
|
37
|
-
def reset!
|
38
|
-
setup
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def validate_date!(date)
|
44
|
-
Date.parse(date.to_s)
|
45
|
-
end
|
46
|
-
|
47
|
-
def validate_depth!(depth)
|
48
|
-
(1..MAX_DEPTH_LEVEL).include?(depth) or raise("Invalid depth level: #{depth.inspect}")
|
49
|
-
depth
|
50
|
-
end
|
51
|
-
|
52
|
-
# Load settings from Jekyll configuration
|
53
|
-
def jekyll_config
|
54
|
-
@jekyll_config ||= Jekyll.configuration({}).fetch('jekyll_timeago', {}) rescue {}
|
55
|
-
end
|
5
|
+
config = @context.registers[:site].config.fetch('jekyll_timeago', {})
|
56
6
|
|
57
|
-
|
58
|
-
def setup
|
59
|
-
@options = {
|
60
|
-
:depth => jekyll_config['depth'] || DEFAULT_DEPTH_LEVEL,
|
61
|
-
:today => jekyll_config['today'] || 'today',
|
62
|
-
:yesterday => jekyll_config['yesterday'] || 'yesterday',
|
63
|
-
:tomorrow => jekyll_config['tomorrow'] || 'tomorrow',
|
64
|
-
:and => jekyll_config['and'] ||'and',
|
65
|
-
:suffix => jekyll_config['suffix'] || 'ago',
|
66
|
-
:prefix => jekyll_config['prefix'] || '',
|
67
|
-
:suffix_future => jekyll_config['suffix_future'] || '',
|
68
|
-
:prefix_future => jekyll_config['prefix_future'] || 'in',
|
69
|
-
:years => jekyll_config['years'] || 'years',
|
70
|
-
:year => jekyll_config['year'] || 'year',
|
71
|
-
:months => jekyll_config['months'] || 'months',
|
72
|
-
:month => jekyll_config['month'] || 'month',
|
73
|
-
:weeks => jekyll_config['weeks'] || 'weeks',
|
74
|
-
:week => jekyll_config['week'] || 'week',
|
75
|
-
:days => jekyll_config['days'] || 'days',
|
76
|
-
:day => jekyll_config['day'] || 'day'
|
77
|
-
}
|
78
|
-
end
|
79
|
-
|
80
|
-
def translate(key)
|
81
|
-
options[key.to_sym]
|
82
|
-
end
|
83
|
-
alias_method :t, :translate
|
84
|
-
|
85
|
-
# Days passed to time ago sentence
|
86
|
-
def time_ago_to_now(from, to, depth)
|
87
|
-
days_passed = (to - from).to_i
|
88
|
-
|
89
|
-
return t(:today) if days_passed == 0
|
90
|
-
return t(:yesterday) if days_passed == 1
|
91
|
-
return t(:tomorrow) if days_passed == -1
|
92
|
-
|
93
|
-
future = days_passed < 0
|
94
|
-
slots = build_time_ago_slots(days_passed.abs, depth)
|
95
|
-
sentence = to_sentence(slots)
|
96
|
-
|
97
|
-
if future
|
98
|
-
"#{t(:prefix_future)} #{sentence} #{t(:suffix_future)}".strip
|
99
|
-
else
|
100
|
-
"#{t(:prefix)} #{sentence} #{t(:suffix)}".strip
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
# Builds time ranges: ['1 month', '5 days']
|
105
|
-
# - days_passed: integer in absolute
|
106
|
-
# - depth: level of detail
|
107
|
-
# - current_slots: built time slots
|
108
|
-
def build_time_ago_slots(days_passed, depth, current_slots = [])
|
109
|
-
return current_slots if depth == 0 || days_passed == 0
|
110
|
-
|
111
|
-
time_range = days_to_time_range(days_passed)
|
112
|
-
days = DAYS_PER[time_range]
|
113
|
-
num_elems = (days_passed / days).to_i
|
114
|
-
|
115
|
-
range_type = if num_elems == 1
|
116
|
-
t(time_range[0...-1]) # singularize key
|
117
|
-
else
|
118
|
-
t(time_range)
|
119
|
-
end
|
120
|
-
|
121
|
-
current_slots << "#{num_elems} #{range_type}"
|
122
|
-
pending_days = days_passed - (num_elems * days)
|
123
|
-
build_time_ago_slots(pending_days, depth - 1, current_slots)
|
124
|
-
end
|
125
|
-
|
126
|
-
# Number of days to minimum period time which can be grouped
|
127
|
-
def days_to_time_range(days_passed)
|
128
|
-
case days_passed.abs
|
129
|
-
when 1..6
|
130
|
-
:days
|
131
|
-
when 7..30
|
132
|
-
:weeks
|
133
|
-
when 31..365
|
134
|
-
:months
|
135
|
-
else
|
136
|
-
:years
|
137
|
-
end
|
138
|
-
end
|
139
|
-
|
140
|
-
# Array to sentence: ['1 month', '1 week', '5 days'] => "1 month, 1 week and 5 days"
|
141
|
-
def to_sentence(slots)
|
142
|
-
if slots.length == 1
|
143
|
-
slots[0]
|
144
|
-
else
|
145
|
-
"#{slots[0...-1].join(', ')} #{t(:and)} #{slots[-1]}"
|
146
|
-
end
|
7
|
+
Jekyll::Timeago::Core.timeago(from, to, config)
|
147
8
|
end
|
148
9
|
end
|
149
10
|
end
|
150
11
|
end
|
151
|
-
|
152
|
-
Liquid::Template.register_filter(Jekyll::Timeago::Filter) if defined?(Liquid)
|
data/lib/jekyll-timeago/tag.rb
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
module Jekyll
|
2
2
|
module Timeago
|
3
3
|
class Tag < Liquid::Tag
|
4
|
-
include Jekyll::Timeago::Filter
|
5
|
-
|
6
4
|
def initialize(tag_name, dates, tokens)
|
7
5
|
super
|
8
6
|
@dates = dates.strip.split(' ')
|
@@ -10,15 +8,14 @@ module Jekyll
|
|
10
8
|
|
11
9
|
def render(context)
|
12
10
|
from, to = @dates[0], @dates[1]
|
11
|
+
config = context.registers[:site].config.fetch('jekyll_timeago', {})
|
13
12
|
|
14
13
|
if to
|
15
|
-
timeago(from, to)
|
14
|
+
Jekyll::Timeago::Core.timeago(from, to, config)
|
16
15
|
else
|
17
|
-
timeago(from)
|
16
|
+
Jekyll::Timeago::Core.timeago(from, config)
|
18
17
|
end
|
19
18
|
end
|
20
19
|
end
|
21
20
|
end
|
22
21
|
end
|
23
|
-
|
24
|
-
Liquid::Template.register_tag('timeago', Jekyll::Timeago::Tag) if defined?(Liquid)
|
data/lib/jekyll-timeago.rb
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
-
require 'jekyll-timeago/
|
2
|
-
require 'jekyll-timeago/tag'
|
1
|
+
require 'jekyll-timeago/core'
|
3
2
|
require 'jekyll-timeago/version'
|
3
|
+
|
4
|
+
if defined?(Liquid)
|
5
|
+
require 'jekyll-timeago/filter'
|
6
|
+
require 'jekyll-timeago/tag'
|
7
|
+
|
8
|
+
Liquid::Template.register_filter(Jekyll::Timeago::Filter)
|
9
|
+
Liquid::Template.register_tag('timeago', Jekyll::Timeago::Tag)
|
10
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Jekyll::Timeago do
|
4
|
+
context 'Jekyll integration' do
|
5
|
+
let(:overrides) do
|
6
|
+
{
|
7
|
+
"source" => source_dir,
|
8
|
+
"destination" => dest_dir,
|
9
|
+
"url" => "http://example.org",
|
10
|
+
}
|
11
|
+
end
|
12
|
+
let(:config) { Jekyll.configuration(overrides) }
|
13
|
+
let(:site) { Jekyll::Site.new(config) }
|
14
|
+
let(:contents) { File.read(dest_dir("index.html")) }
|
15
|
+
|
16
|
+
it 'setup from Jekyll configuration' do
|
17
|
+
expect(site.config['jekyll_timeago']).to eql(configuration_file['jekyll_timeago'])
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'process successfully the site using filters and tags' do
|
21
|
+
expect { site.process }.to_not raise_error
|
22
|
+
|
23
|
+
lines = [
|
24
|
+
"<p>2 years yeah</p>",
|
25
|
+
"<p>12 months yeah</p>",
|
26
|
+
"<p>12 months yeah</p>",
|
27
|
+
"<p>2 years yeah</p>"
|
28
|
+
]
|
29
|
+
expect(contents).to eq(lines.join("\n"))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'Core' do
|
34
|
+
let (:sample_date) { Date.new(2014, 7, 30) }
|
35
|
+
let (:today) { Date.today }
|
36
|
+
|
37
|
+
before do
|
38
|
+
Jekyll::Timeago::Core.configure
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'does not accept invalid depth' do
|
42
|
+
expect { timeago(today, sample_date, "depth" => 5) }.to raise_error
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'accepts a hash (options) as a second parameter (implicit "to")' do
|
46
|
+
expect(timeago(today, "today" => "during the day")).to eq("during the day")
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'yesterday, today and tomorrow' do
|
50
|
+
expect(timeago(today - 1.day)).to eql("yesterday")
|
51
|
+
expect(timeago(today)).to eql("today")
|
52
|
+
expect(timeago(today + 1.day)).to eql("tomorrow")
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'past time' do
|
56
|
+
expect(timeago(sample_date - 10.days, sample_date)).to eql('1 week and 3 days ago')
|
57
|
+
expect(timeago(sample_date - 100.days, sample_date)).to eql('3 months and 1 week ago')
|
58
|
+
expect(timeago(sample_date - 500.days, sample_date)).to eql('1 year and 4 months ago')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'future time' do
|
62
|
+
expect(timeago(sample_date + 7.days, sample_date)).to eql('in 1 week')
|
63
|
+
expect(timeago(sample_date + 1000.days, sample_date)).to eql('in 2 years and 9 months')
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'allow different date formats' do
|
67
|
+
expect(timeago('2010-1-1', '2012-1-1')).to eql('2 years ago')
|
68
|
+
expect(timeago('2010/1/1', '2012/1/1')).to eql('2 years ago')
|
69
|
+
expect(timeago('Jan 2010, 1', 'Jan 2012, 1')).to eql('2 years ago')
|
70
|
+
expect(timeago('2014-10-06 20:00:00', '2014-10-07 20:00:00')).to eql('yesterday')
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'allow to change defaults at global level' do
|
74
|
+
Jekyll::Timeago::Core.configure("year" => nil, "depth" => 1, "suffix" => nil)
|
75
|
+
expect(timeago(sample_date - 500.days, sample_date)).to eql('1')
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'allow to change level of detail' do
|
79
|
+
expect(timeago(sample_date - 500.days, sample_date, "depth" => 1)).to eql('1 year ago')
|
80
|
+
expect(timeago(sample_date - 500.days, sample_date, "depth" => 3)).to eql('1 year, 4 months and 2 weeks ago')
|
81
|
+
expect(timeago(sample_date - 500.days, sample_date, "depth" => 4)).to eql('1 year, 4 months, 2 weeks and 1 day ago')
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'allow localization' do
|
85
|
+
new_options = {
|
86
|
+
"prefix" => 'hace',
|
87
|
+
"months" => 'meses',
|
88
|
+
"and" => 'y',
|
89
|
+
"week" => 'semana',
|
90
|
+
"suffix" => nil
|
91
|
+
}
|
92
|
+
|
93
|
+
expect(timeago(sample_date - 100.days, sample_date, new_options)).to eql('hace 3 meses y 1 semana')
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'CLI' do
|
98
|
+
it 'prints help message if called with no params or --help' do
|
99
|
+
expect(`jekyll-timeago`).to match("Usage")
|
100
|
+
expect(`jekyll-timeago --help`).to match("Usage")
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'computes distance of dates' do
|
104
|
+
expect(`jekyll-timeago 2016-1-1 2016-1-5`).to match("4 days ago")
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/spec/source/_config.yml
CHANGED
data/spec/source/index.html
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'fileutils'
|
2
|
-
require 'active_support'
|
3
|
-
require 'active_support/core_ext'
|
2
|
+
require 'active_support/all'
|
4
3
|
require 'jekyll'
|
5
|
-
require File.expand_path('lib/jekyll-timeago
|
4
|
+
require File.expand_path('lib/jekyll-timeago')
|
6
5
|
|
7
6
|
RSpec.configure do |config|
|
8
7
|
config.run_all_when_everything_filtered = true
|
@@ -26,18 +25,7 @@ RSpec.configure do |config|
|
|
26
25
|
YAML.load_file(File.join(SOURCE_DIR, '_config.yml'))
|
27
26
|
end
|
28
27
|
|
29
|
-
def
|
30
|
-
Jekyll.
|
31
|
-
'source' => source_dir,
|
32
|
-
'destination' => dest_dir
|
33
|
-
}))
|
34
|
-
end
|
35
|
-
|
36
|
-
def timeago(from, to = Date.today)
|
37
|
-
Jekyll::Timeago::Filter.timeago(from, to)
|
38
|
-
end
|
39
|
-
|
40
|
-
def options
|
41
|
-
@options ||= Jekyll::Timeago::Filter.options
|
28
|
+
def timeago(from, to = Date.today, options = {})
|
29
|
+
Jekyll::Timeago::Core.timeago(from, to, options)
|
42
30
|
end
|
43
31
|
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.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- markets
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll
|
@@ -80,28 +80,50 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: appraisal
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
description: Custom timeago filter for Jekyll (Liquid Filter and Tag). Localization
|
84
98
|
and futures supported.
|
85
99
|
email:
|
86
100
|
- srmarc.ai@gmail.com
|
87
|
-
executables:
|
101
|
+
executables:
|
102
|
+
- jekyll-timeago
|
88
103
|
extensions: []
|
89
104
|
extra_rdoc_files: []
|
90
105
|
files:
|
91
106
|
- ".gitignore"
|
92
107
|
- ".travis.yml"
|
108
|
+
- Appraisals
|
93
109
|
- Gemfile
|
94
110
|
- LICENSE
|
95
111
|
- README.md
|
96
112
|
- Rakefile
|
97
|
-
-
|
113
|
+
- bin/jekyll-timeago
|
114
|
+
- gemfiles/jekyll_v1.gemfile
|
115
|
+
- gemfiles/jekyll_v2.gemfile
|
116
|
+
- gemfiles/jekyll_v3.gemfile
|
98
117
|
- jekyll-timeago.gemspec
|
99
118
|
- lib/jekyll-timeago.rb
|
119
|
+
- lib/jekyll-timeago/config/_config.yml.example.en
|
120
|
+
- lib/jekyll-timeago/config/_config.yml.example.es
|
121
|
+
- lib/jekyll-timeago/config/_config.yml.example.fr
|
122
|
+
- lib/jekyll-timeago/core.rb
|
100
123
|
- lib/jekyll-timeago/filter.rb
|
101
124
|
- lib/jekyll-timeago/tag.rb
|
102
125
|
- lib/jekyll-timeago/version.rb
|
103
|
-
-
|
104
|
-
- spec/jekyll_timeago_spec.rb
|
126
|
+
- spec/jekyll-timeago_spec.rb
|
105
127
|
- spec/source/_config.yml
|
106
128
|
- spec/source/index.html
|
107
129
|
- spec/spec_helper.rb
|
@@ -125,13 +147,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
125
147
|
version: '0'
|
126
148
|
requirements: []
|
127
149
|
rubyforge_project:
|
128
|
-
rubygems_version: 2.2.
|
150
|
+
rubygems_version: 2.2.2
|
129
151
|
signing_key:
|
130
152
|
specification_version: 4
|
131
153
|
summary: Custom timeago filter for Jekyll (Liquid Filter and Tag). Localization and
|
132
154
|
futures supported.
|
133
155
|
test_files:
|
134
|
-
- spec/
|
156
|
+
- spec/jekyll-timeago_spec.rb
|
135
157
|
- spec/source/_config.yml
|
136
158
|
- spec/source/index.html
|
137
159
|
- spec/spec_helper.rb
|
data/script/console
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
lib = File.expand_path('../../lib', __FILE__)
|
4
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
-
|
6
|
-
require 'jekyll-timeago/filter'
|
7
|
-
include Jekyll::Timeago::Filter
|
8
|
-
|
9
|
-
require 'active_support/core_ext'
|
10
|
-
|
11
|
-
require 'irb'
|
12
|
-
ARGV.clear
|
13
|
-
IRB.start
|
data/spec/jekyll_timeago_spec.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Jekyll::Timeago do
|
4
|
-
context 'Jekyll integration' do
|
5
|
-
let(:site) do
|
6
|
-
Jekyll::Site.new(site_configuration)
|
7
|
-
end
|
8
|
-
|
9
|
-
it 'setup from Jekyll configuration' do
|
10
|
-
expect(site.config['jekyll_timeago']).to eql(configuration_file['jekyll_timeago'])
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'process successfully the site using filters and tags' do
|
14
|
-
expect { site.process }.to_not raise_error
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
context 'Timeago calculations' do
|
19
|
-
let (:sample_date) { Date.new(2014, 7, 30) }
|
20
|
-
|
21
|
-
before(:each) do
|
22
|
-
Jekyll::Timeago::Filter.reset!
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'does not accept invalid depth' do
|
26
|
-
options[:depth] = 5
|
27
|
-
|
28
|
-
expect { timeago(today) }.to raise_error
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'yesterday, today and tomorrow' do
|
32
|
-
today = Date.today
|
33
|
-
|
34
|
-
expect(timeago(today - 1.day)).to eql(options[:yesterday])
|
35
|
-
expect(timeago(today)).to eql(options[:today])
|
36
|
-
expect(timeago(today + 1.day)).to eql(options[:tomorrow])
|
37
|
-
end
|
38
|
-
|
39
|
-
context 'past time' do
|
40
|
-
it 'should process distances' do
|
41
|
-
expect(timeago(sample_date - 10.days, sample_date)).to eql('1 week and 3 days ago')
|
42
|
-
expect(timeago(sample_date - 100.days, sample_date)).to eql('3 months and 1 week ago')
|
43
|
-
expect(timeago(sample_date - 500.days, sample_date)).to eql('1 year and 4 months ago')
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
context 'future time' do
|
48
|
-
it 'should process distances' do
|
49
|
-
expect(timeago(sample_date + 7.days, sample_date)).to eql('in 1 week')
|
50
|
-
expect(timeago(sample_date + 1000.days, sample_date)).to eql('in 2 years and 9 months')
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'allow different date inputs' do
|
55
|
-
expect(timeago('2010-1-1', '2012-1-1')).to eql('2 years ago')
|
56
|
-
expect(timeago('2010/1/1', '2012/1/1')).to eql('2 years ago')
|
57
|
-
expect(timeago('Jan 2010, 1', 'Jan 2012, 1')).to eql('2 years ago')
|
58
|
-
expect(timeago('2014-10-06 20:00:00', '2014-10-07 20:00:00')).to eql('yesterday')
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'allow to change level of detail' do
|
62
|
-
options[:depth] = 1
|
63
|
-
expect(timeago(sample_date - 500.days, sample_date)).to eql('1 year ago')
|
64
|
-
|
65
|
-
options[:depth] = 3
|
66
|
-
expect(timeago(sample_date - 500.days, sample_date)).to eql('1 year, 4 months and 2 weeks ago')
|
67
|
-
|
68
|
-
options[:depth] = 4
|
69
|
-
expect(timeago(sample_date - 500.days, sample_date)).to eql('1 year, 4 months, 2 weeks and 1 day ago')
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'allow localization' do
|
73
|
-
options[:prefix] = 'hace'
|
74
|
-
options[:months] = 'meses'
|
75
|
-
options[:and] = 'y'
|
76
|
-
options[:week] = 'semana'
|
77
|
-
options[:suffix] = nil
|
78
|
-
|
79
|
-
expect(timeago(sample_date - 100.days, sample_date)).to eql('hace 3 meses y 1 semana')
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|