edtf 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- 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
|