edtf 0.0.8 → 0.0.9
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.
- data/README.md +18 -6
- data/lib/edtf.rb +2 -0
- data/lib/edtf/extensions.rb +11 -0
- data/lib/edtf/parser.y +19 -16
- data/lib/edtf/set.rb +79 -0
- data/lib/edtf/version.rb +1 -1
- data/spec/edtf/interval_spec.rb +9 -9
- data/spec/edtf/set_spec.rb +73 -0
- metadata +18 -15
data/README.md
CHANGED
@@ -21,10 +21,6 @@ EDTF-Ruby parser implements all levels and features of the EDTF specification
|
|
21
21
|
nested expressions (the parser will not accept some of the more complex
|
22
22
|
examples, though).
|
23
23
|
|
24
|
-
The level 2 list extensions (203 and 204) currently return simple Ruby arrays;
|
25
|
-
therefore, advanced behavior (such as 'earlier' or 'later') is parsed correctly
|
26
|
-
but not yet exposed by the Ruby API.
|
27
|
-
|
28
24
|
EDTF-Ruby has been confirmed to work on the following Ruby implementations:
|
29
25
|
1.9.3, 1.9.2, 1.8.7, Rubinius, and JRuby. Active Support's date extensions
|
30
26
|
are currently listed as a dependency, because of a number of many functional
|
@@ -39,8 +35,9 @@ You can access parse EDTF strings either using `Date.edtf` or `EDTF.parse`
|
|
39
35
|
(both methods come with an alternative bang! version, that will raise an error
|
40
36
|
if the string cannot be parsed instead of silently returning nil); if
|
41
37
|
given a valid EDTF string the return value will either be an (extended) `Date`,
|
42
|
-
`EDTF::Interval` or `Range` (for masked precision strings)
|
43
|
-
a Date, you can print the corresponding EDTF string using the
|
38
|
+
`EDTF::Interval`, `EDTF::Set`, or `Range` (for masked precision strings)
|
39
|
+
instance. Given a Date, you can print the corresponding EDTF string using the
|
40
|
+
`#edtf` method.
|
44
41
|
|
45
42
|
$ [sudo] gem install edtf
|
46
43
|
$ irb
|
@@ -86,6 +83,21 @@ a Date, you can print the corresponding EDTF string using the `#edtf` method.
|
|
86
83
|
=> true # an open ended interval covers today
|
87
84
|
> Date.edtf("(1999-(02)~-23)?").edtf
|
88
85
|
=> "1999?-(02)?~-23?" # when printing, EDTF-Ruby reduces nested parentheses
|
86
|
+
> s = Date.edtf('{1667,1668, 1670..1672}')
|
87
|
+
> s.include?(Date.edtf('1669'))
|
88
|
+
=> false
|
89
|
+
> s.include?(Date.edtf('1671'))
|
90
|
+
=> true # the range is enumerated for membership tests
|
91
|
+
> s.length
|
92
|
+
=> 3 # but we're still aware that there were only three elements
|
93
|
+
> s.map(&:year)
|
94
|
+
=> [1667, 1668, 1670, 1671, 1672] # when enumerated there are 5 elements
|
95
|
+
> s.earlier?
|
96
|
+
=> false # the original list was not vague
|
97
|
+
> s.earlier! # but we can make it so
|
98
|
+
> s.edtf
|
99
|
+
=> "{..1667, 1668, 1670..1672}"
|
100
|
+
|
89
101
|
|
90
102
|
For additional features take a look at the documentation or the extensive
|
91
103
|
list of rspec examples.
|
data/lib/edtf.rb
CHANGED
@@ -40,6 +40,7 @@ autoload :Rational, 'rational'
|
|
40
40
|
|
41
41
|
require 'forwardable'
|
42
42
|
require 'enumerator'
|
43
|
+
require 'set'
|
43
44
|
|
44
45
|
require 'active_support/core_ext/date/calculations'
|
45
46
|
require 'active_support/core_ext/date_time/calculations'
|
@@ -56,6 +57,7 @@ require 'edtf/date_time'
|
|
56
57
|
require 'edtf/epoch'
|
57
58
|
require 'edtf/season'
|
58
59
|
require 'edtf/interval'
|
60
|
+
require 'edtf/set'
|
59
61
|
require 'edtf/parser'
|
60
62
|
require 'edtf/extensions'
|
61
63
|
|
data/lib/edtf/extensions.rb
CHANGED
data/lib/edtf/parser.y
CHANGED
@@ -219,29 +219,32 @@ rule
|
|
219
219
|
;
|
220
220
|
|
221
221
|
|
222
|
-
choice_list : '[' list ']'
|
222
|
+
choice_list : '[' list ']' { result = val[1].choice! }
|
223
223
|
|
224
224
|
inclusive_list : '{' list '}' { result = val[1] }
|
225
225
|
|
226
|
-
list : earlier { result = val }
|
227
|
-
| earlier ',' list_elements ',' later { result = [val[0]] + val[2] + [val[4]] }
|
228
|
-
| earlier ',' list_elements { result = [val[0]] + val[2] }
|
229
|
-
| earlier ',' later { result = [val[0]] + [val[2]] }
|
230
|
-
| list_elements ',' later { result = val[0] + [val[2]] }
|
231
|
-
| list_elements
|
232
|
-
| later { result = val }
|
226
|
+
list : earlier { result = EDTF::Set.new(val[0]).earlier! }
|
227
|
+
| earlier ',' list_elements ',' later { result = EDTF::Set.new([val[0]] + val[2] + [val[4]]).earlier!.later! }
|
228
|
+
| earlier ',' list_elements { result = EDTF::Set.new([val[0]] + val[2]).earlier! }
|
229
|
+
| earlier ',' later { result = EDTF::Set.new([val[0]] + [val[2]]).earlier!.later! }
|
230
|
+
| list_elements ',' later { result = EDTF::Set.new(val[0] + [val[2]]).later! }
|
231
|
+
| list_elements { result = EDTF::Set.new(*val[0]) }
|
232
|
+
| later { result = EDTF::Set.new(val[0]).later! }
|
233
233
|
;
|
234
234
|
|
235
235
|
list_elements : list_element { result = [val[0]].flatten }
|
236
236
|
| list_elements ',' list_element { result = val[0] + [val[2]].flatten }
|
237
237
|
;
|
238
|
-
|
239
|
-
list_element :
|
240
|
-
|
|
241
|
-
| unspecified
|
242
|
-
| consecutives { result = val[0].map { |d| Date.new(*d) } }
|
238
|
+
|
239
|
+
list_element : atomic
|
240
|
+
| consecutives
|
243
241
|
;
|
244
242
|
|
243
|
+
atomic : date
|
244
|
+
| partial_uncertain_or_approximate
|
245
|
+
| unspecified
|
246
|
+
;
|
247
|
+
|
245
248
|
earlier : DOTS date { result = val[1] }
|
246
249
|
|
247
250
|
later : year_month_day DOTS { result = Date.new(*val[0]).year_precision! }
|
@@ -249,9 +252,9 @@ rule
|
|
249
252
|
| year DOTS { result = Date.new(val[0]).year_precision! }
|
250
253
|
;
|
251
254
|
|
252
|
-
consecutives : year_month_day DOTS year_month_day
|
253
|
-
| year_month DOTS year_month
|
254
|
-
| year DOTS year
|
255
|
+
consecutives : year_month_day DOTS year_month_day { result = (Date.new(val[0]).day_precision! .. Date.new(val[2]).day_precision!) }
|
256
|
+
| year_month DOTS year_month { result = (Date.new(val[0]).month_precision! .. Date.new(val[2]).month_precision!) }
|
257
|
+
| year DOTS year { result = (Date.new(val[0]).year_precision! .. Date.new(val[2]).year_precision!) }
|
255
258
|
;
|
256
259
|
|
257
260
|
partial_unspecified :
|
data/lib/edtf/set.rb
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
module EDTF
|
2
|
+
|
3
|
+
class Set
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
include Enumerable
|
7
|
+
include Comparable
|
8
|
+
|
9
|
+
def_delegators :@dates, :size, :length, :empty?
|
10
|
+
def_delegators :to_a, :include?
|
11
|
+
|
12
|
+
attr_accessor :choice, :later, :earlier
|
13
|
+
|
14
|
+
|
15
|
+
def initialize(*dates)
|
16
|
+
@dates = ::Set.new(dates.flatten)
|
17
|
+
@choice, @later, @earlier = false, false, false
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize_copy(other)
|
21
|
+
@set = other.to_set
|
22
|
+
end
|
23
|
+
|
24
|
+
[:choice, :later, :earlier].each do |m|
|
25
|
+
define_method("#{m}?") { send(m) }
|
26
|
+
define_method("#{m}!") do
|
27
|
+
send("#{m}=", true)
|
28
|
+
self
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def <<(date)
|
33
|
+
dates << date
|
34
|
+
self
|
35
|
+
end
|
36
|
+
|
37
|
+
def each
|
38
|
+
if block_given?
|
39
|
+
to_a.each(&Proc.new)
|
40
|
+
self
|
41
|
+
else
|
42
|
+
to_enum
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def edtf
|
47
|
+
parenthesize(dates.map { |d| d.respond_to?(:edtf) ? d.edtf : d.to_s }.join(', '))
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_a
|
51
|
+
dates.map { |d| Array(d) }.flatten
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_set
|
55
|
+
to_a.to_set
|
56
|
+
end
|
57
|
+
|
58
|
+
alias to_s edtf
|
59
|
+
|
60
|
+
def <=>(other)
|
61
|
+
return nil unless other.respond_to?(:to_a)
|
62
|
+
to_a <=> other.to_a
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
attr_reader :dates
|
68
|
+
|
69
|
+
def parenthesize(string)
|
70
|
+
p = choice? ? %w([ ]) : %w({ })
|
71
|
+
p[-1,0] = '..' if earlier?
|
72
|
+
p[-1,0] = string unless string.empty?
|
73
|
+
p[-1,0] = '..' if later?
|
74
|
+
p.join
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
data/lib/edtf/version.rb
CHANGED
data/spec/edtf/interval_spec.rb
CHANGED
@@ -39,7 +39,7 @@ module EDTF
|
|
39
39
|
end
|
40
40
|
|
41
41
|
it 'does not include christmas day 2009' do
|
42
|
-
interval.should_not
|
42
|
+
interval.should_not be_include(Date.new(2009,12,24))
|
43
43
|
end
|
44
44
|
|
45
45
|
it 'christmas day 2009 is less than max' do
|
@@ -51,11 +51,11 @@ module EDTF
|
|
51
51
|
end
|
52
52
|
|
53
53
|
it 'covers christmas day 2009' do
|
54
|
-
interval.should
|
54
|
+
interval.should be_cover(Date.new(2009,12,24))
|
55
55
|
end
|
56
56
|
|
57
57
|
it 'covers 2011-12-31' do
|
58
|
-
interval.should
|
58
|
+
interval.should be_cover(Date.new(2011,12,31))
|
59
59
|
end
|
60
60
|
|
61
61
|
end
|
@@ -64,15 +64,15 @@ module EDTF
|
|
64
64
|
let(:interval) { Date.edtf('2008-08-23/2011-07-01') }
|
65
65
|
|
66
66
|
it 'includes christmas day 2009' do
|
67
|
-
interval.should
|
67
|
+
interval.should be_include(Date.new(2009,12,24))
|
68
68
|
end
|
69
69
|
|
70
70
|
it 'covers christmas day 2009' do
|
71
|
-
interval.should
|
71
|
+
interval.should be_cover(Date.new(2009,12,24))
|
72
72
|
end
|
73
73
|
|
74
74
|
it 'does not cover 2011-07-02' do
|
75
|
-
interval.should_not
|
75
|
+
interval.should_not be_cover(Date.new(2011,07,02))
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
@@ -94,15 +94,15 @@ module EDTF
|
|
94
94
|
end
|
95
95
|
|
96
96
|
it 'includes christmas day 2009' do
|
97
|
-
interval.should
|
97
|
+
interval.should be_include(Date.new(2009,12,24))
|
98
98
|
end
|
99
99
|
|
100
100
|
it 'covers christmas day 2009' do
|
101
|
-
interval.should
|
101
|
+
interval.should be_cover(Date.new(2009,12,24))
|
102
102
|
end
|
103
103
|
|
104
104
|
it 'covers 2023-07-02' do
|
105
|
-
interval.should
|
105
|
+
interval.should be_cover(Date.new(2023,07,02))
|
106
106
|
end
|
107
107
|
|
108
108
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module EDTF
|
2
|
+
describe 'Sets' do
|
3
|
+
|
4
|
+
describe 'constructor' do
|
5
|
+
|
6
|
+
it 'creates a new empty set by default' do
|
7
|
+
Set.new.should be_empty
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#edtf' do
|
13
|
+
|
14
|
+
it 'returns {} by default' do
|
15
|
+
Set.new.edtf.should == '{}'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'returns [] for empty choice lists' do
|
19
|
+
Set.new.choice!.edtf.should == '[]'
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns {1984} if the set contains the year 1984' do
|
23
|
+
Set.new(Date.edtf('1984')).edtf.should == '{1984}'
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'returns {1984, 1985-10} for the set containing these dates' do
|
27
|
+
Set.new(Date.edtf('1984'), Date.new(1984,10).month_precision).edtf.should == '{1984, 1984-10}'
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'returns {..1984, 1985-10} for the set containing these dates and earlier == true' do
|
31
|
+
Set.new(Date.edtf('1984'), Date.new(1984,10).month_precision).earlier!.edtf.should == '{..1984, 1984-10}'
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns {1984, 1985-10..} for the set containing these dates and later == true' do
|
35
|
+
Set.new(Date.edtf('1984'), Date.new(1984,10).month_precision).later!.edtf.should == '{1984, 1984-10..}'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'returns [1667, 1668, 1670..1672] for the years 1667, 1668 and the interval 1670..1672' do
|
39
|
+
s = Set.new.choice!
|
40
|
+
s << Date.edtf('1667') << Date.edtf('1668')
|
41
|
+
s << (Date.edtf('1670') .. Date.edtf('1672'))
|
42
|
+
s.edtf.should == '[1667, 1668, 1670..1672]'
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
describe 'the set [1667, 1668, 1670..1672]' do
|
48
|
+
let(:set) { Set.new(Date.edtf('1667'), Date.edtf('1668'), Date.edtf('1670')..Date.edtf('1672')).choice! }
|
49
|
+
|
50
|
+
it 'includes the year 1671' do
|
51
|
+
set.should include(Date.new(1671).year_precision!)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'does not include the date 1671-01-01' do
|
55
|
+
set.should_not include(Date.new(1671))
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'does not include the year 1669' do
|
59
|
+
set.should_not include(Date.new(1669).year_precision!)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'has a length of 3' do
|
63
|
+
set.should have(3).elements
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'maps to the year array [1667, 1668, 1670, 1671, 1672]' do
|
67
|
+
set.map(&:year).should == [1667, 1668, 1670, 1671, 1672]
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: edtf
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2011-11-09 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
|
-
requirement: &
|
16
|
+
requirement: &70355024984460 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ~>
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '3.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70355024984460
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rake
|
27
|
-
requirement: &
|
27
|
+
requirement: &70355024983720 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ~>
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0.9'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70355024983720
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: racc
|
38
|
-
requirement: &
|
38
|
+
requirement: &70355024982860 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '1.4'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70355024982860
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: cucumber
|
49
|
-
requirement: &
|
49
|
+
requirement: &70355024981980 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '1.0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70355024981980
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: rspec
|
60
|
-
requirement: &
|
60
|
+
requirement: &70355024981220 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ~>
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '2.6'
|
66
66
|
type: :development
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *70355024981220
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: ZenTest
|
71
|
-
requirement: &
|
71
|
+
requirement: &70355024980360 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ~>
|
@@ -76,7 +76,7 @@ dependencies:
|
|
76
76
|
version: '4.6'
|
77
77
|
type: :development
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *70355024980360
|
80
80
|
description: A Ruby implementation of the Extended Date/Time Format (EDTF).
|
81
81
|
email:
|
82
82
|
- http://sylvester.keil.or.at
|
@@ -115,6 +115,7 @@ files:
|
|
115
115
|
- lib/edtf/interval.rb
|
116
116
|
- lib/edtf/parser.y
|
117
117
|
- lib/edtf/season.rb
|
118
|
+
- lib/edtf/set.rb
|
118
119
|
- lib/edtf/uncertainty.rb
|
119
120
|
- lib/edtf/version.rb
|
120
121
|
- spec/edtf/date_spec.rb
|
@@ -122,6 +123,7 @@ files:
|
|
122
123
|
- spec/edtf/interval_spec.rb
|
123
124
|
- spec/edtf/parser_spec.rb
|
124
125
|
- spec/edtf/season_spec.rb
|
126
|
+
- spec/edtf/set_spec.rb
|
125
127
|
- spec/edtf/uncertainty_spec.rb
|
126
128
|
- spec/spec_helper.rb
|
127
129
|
- lib/edtf/parser.rb
|
@@ -147,7 +149,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
147
149
|
version: '0'
|
148
150
|
segments:
|
149
151
|
- 0
|
150
|
-
hash: -
|
152
|
+
hash: -1918843685167052448
|
151
153
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
152
154
|
none: false
|
153
155
|
requirements:
|
@@ -156,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
158
|
version: '0'
|
157
159
|
segments:
|
158
160
|
- 0
|
159
|
-
hash: -
|
161
|
+
hash: -1918843685167052448
|
160
162
|
requirements: []
|
161
163
|
rubyforge_project:
|
162
164
|
rubygems_version: 1.8.10
|
@@ -181,5 +183,6 @@ test_files:
|
|
181
183
|
- spec/edtf/interval_spec.rb
|
182
184
|
- spec/edtf/parser_spec.rb
|
183
185
|
- spec/edtf/season_spec.rb
|
186
|
+
- spec/edtf/set_spec.rb
|
184
187
|
- spec/edtf/uncertainty_spec.rb
|
185
188
|
- spec/spec_helper.rb
|