chronic 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README +1 -0
- data/lib/chronic.rb +2 -1
- data/lib/chronic/chronic.rb +2 -2
- data/lib/chronic/handlers.rb +19 -5
- data/lib/chronic/repeater.rb +4 -4
- data/lib/chronic/repeaters/repeater_day.rb +3 -0
- data/lib/chronic/repeaters/repeater_day_name.rb +1 -0
- data/lib/chronic/repeaters/repeater_fortnight.rb +2 -1
- data/lib/chronic/repeaters/repeater_minute.rb +23 -2
- data/lib/chronic/repeaters/repeater_month.rb +3 -0
- data/lib/chronic/repeaters/repeater_month_name.rb +2 -0
- data/lib/chronic/repeaters/repeater_second.rb +2 -0
- data/lib/chronic/repeaters/repeater_time.rb +4 -1
- data/lib/chronic/repeaters/repeater_week.rb +6 -0
- data/lib/chronic/repeaters/repeater_year.rb +3 -0
- data/lib/chronic/scalar.rb +1 -1
- data/test/test_parsing.rb +21 -6
- metadata +2 -2
data/README
CHANGED
data/lib/chronic.rb
CHANGED
data/lib/chronic/chronic.rb
CHANGED
@@ -50,7 +50,7 @@ module Chronic
|
|
50
50
|
specified_options.keys.each do |key|
|
51
51
|
default_options.keys.include?(key) || raise(InvalidArgumentException, "#{key} is not a valid option key.")
|
52
52
|
end
|
53
|
-
[:past, :future].include?(options[:context]) || raise(InvalidArgumentException, "Invalid value '
|
53
|
+
[:past, :future, :none].include?(options[:context]) || raise(InvalidArgumentException, "Invalid value ':#{options[:context]}' for :context specified. Valid values are :past and :future.")
|
54
54
|
|
55
55
|
# store now for later =)
|
56
56
|
@now = options[:now]
|
@@ -73,7 +73,7 @@ module Chronic
|
|
73
73
|
# strip any non-tagged tokens
|
74
74
|
@tokens = @tokens.select { |token| token.tagged? }
|
75
75
|
|
76
|
-
if
|
76
|
+
if true
|
77
77
|
puts "+---------------------------------------------------"
|
78
78
|
puts "| " + @tokens.to_s
|
79
79
|
puts "+---------------------------------------------------"
|
data/lib/chronic/handlers.rb
CHANGED
@@ -35,6 +35,7 @@ module Chronic
|
|
35
35
|
self.definitions[:date].each do |handler|
|
36
36
|
if handler.match(tokens, self.definitions)
|
37
37
|
good_tokens = tokens.select { |o| !o.get_tag Separator }
|
38
|
+
puts "--#{handler}"
|
38
39
|
return self.send(handler.handler_method, good_tokens, options)
|
39
40
|
end
|
40
41
|
end
|
@@ -67,6 +68,7 @@ module Chronic
|
|
67
68
|
end
|
68
69
|
|
69
70
|
# I guess you're out of luck!
|
71
|
+
puts "--SUCKY"
|
70
72
|
return nil
|
71
73
|
end
|
72
74
|
|
@@ -282,14 +284,25 @@ module Chronic
|
|
282
284
|
|
283
285
|
head = repeaters.shift
|
284
286
|
head.start = @now
|
285
|
-
|
287
|
+
|
286
288
|
case grabber.type
|
287
|
-
when :last
|
288
|
-
|
289
|
-
when :
|
289
|
+
when :last
|
290
|
+
outer_span = head.next(:past)
|
291
|
+
when :this
|
292
|
+
puts "--THIS"
|
293
|
+
puts "--#{repeaters}"
|
294
|
+
if repeaters.size > 0
|
295
|
+
puts "--NONE"
|
296
|
+
outer_span = head.this(:none)
|
297
|
+
else
|
298
|
+
outer_span = head.this(options[:context])
|
299
|
+
end
|
300
|
+
when :next
|
301
|
+
outer_span = head.next(:future)
|
290
302
|
else raise(ChronicPain, "Invalid grabber")
|
291
303
|
end
|
292
304
|
|
305
|
+
puts "--#{outer_span}"
|
293
306
|
anchor = find_within(repeaters, outer_span, pointer)
|
294
307
|
end
|
295
308
|
|
@@ -307,11 +320,12 @@ module Chronic
|
|
307
320
|
# Returns a Span representing the innermost time span
|
308
321
|
# or nil if no repeater union could be found
|
309
322
|
def find_within(tags, span, pointer) #:nodoc:
|
323
|
+
puts "--#{span}"
|
310
324
|
return span if tags.empty?
|
311
325
|
|
312
326
|
head, *rest = tags
|
313
327
|
head.start = pointer == :future ? span.begin : span.end
|
314
|
-
h = head.this(
|
328
|
+
h = head.this(:none)
|
315
329
|
|
316
330
|
if span.include?(h.begin) || span.include?(h.end)
|
317
331
|
return find_within(rest, h, pointer)
|
data/lib/chronic/repeater.rb
CHANGED
@@ -6,7 +6,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
|
|
6
6
|
if t = self.scan_for_day_names(tokens[i]) then tokens[i].tag(t); next end
|
7
7
|
if t = self.scan_for_day_portions(tokens[i]) then tokens[i].tag(t); next end
|
8
8
|
if t = self.scan_for_times(tokens[i], options) then tokens[i].tag(t); next end
|
9
|
-
if t = self.scan_for_units(tokens[i]) then tokens[i].tag(t); next end
|
9
|
+
if t = self.scan_for_units(tokens[i]) then tokens[i].tag(t); next end
|
10
10
|
end
|
11
11
|
tokens
|
12
12
|
end
|
@@ -20,7 +20,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
|
|
20
20
|
/^jun\.?e?$/ => :june,
|
21
21
|
/^jul\.?y?$/ => :july,
|
22
22
|
/^aug\.?(ust)?$/ => :august,
|
23
|
-
/^sep\.?(tember)?$/ => :september,
|
23
|
+
/^sep\.?(t\.?|tember)?$/ => :september,
|
24
24
|
/^oct\.?(ober)?$/ => :october,
|
25
25
|
/^nov\.?(ember)?$/ => :november,
|
26
26
|
/^dec\.?(ember)?$/ => :december}
|
@@ -52,7 +52,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
|
|
52
52
|
/^mornings?$/ => :morning,
|
53
53
|
/^afternoons?$/ => :afternoon,
|
54
54
|
/^evenings?$/ => :evening,
|
55
|
-
/^
|
55
|
+
/^(night|nite)s?$/ => :night}
|
56
56
|
scanner.keys.each do |scanner_item|
|
57
57
|
return Chronic::RepeaterDayPortion.new(scanner[scanner_item]) if scanner_item =~ token.word
|
58
58
|
end
|
@@ -105,7 +105,7 @@ class Chronic::Repeater < Chronic::Tag #:nodoc:
|
|
105
105
|
|
106
106
|
def this(pointer)
|
107
107
|
!@now.nil? || raise("Start point must be set before calling #next")
|
108
|
-
[:future, :past].include?(pointer) || raise("First argument 'pointer' must be one of :past
|
108
|
+
[:future, :past, :none].include?(pointer) || raise("First argument 'pointer' must be one of :past, :future, :none")
|
109
109
|
end
|
110
110
|
|
111
111
|
def to_s
|
@@ -24,6 +24,9 @@ class Chronic::RepeaterDay < Chronic::Repeater #:nodoc:
|
|
24
24
|
when :past
|
25
25
|
day_begin = Time.local(@now.year, @now.month, @now.day)
|
26
26
|
day_end = Time.local(@now.year, @now.month, @now.day, @now.hour)
|
27
|
+
when :none
|
28
|
+
day_begin = Time.local(@now.year, @now.month, @now.day)
|
29
|
+
day_end = Time.local(@now.year, @now.month, @now.day) + DAY_SECONDS
|
27
30
|
end
|
28
31
|
|
29
32
|
Chronic::Span.new(day_begin, day_end)
|
@@ -29,6 +29,8 @@ class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
|
|
29
29
|
def this(pointer = :future)
|
30
30
|
super
|
31
31
|
|
32
|
+
pointer = :future if pointer == :none
|
33
|
+
|
32
34
|
case pointer
|
33
35
|
when :future
|
34
36
|
this_fortnight_start = Time.local(@now.year, @now.month, @now.day, @now.hour) + Chronic::RepeaterHour::HOUR_SECONDS
|
@@ -42,7 +44,6 @@ class Chronic::RepeaterFortnight < Chronic::Repeater #:nodoc:
|
|
42
44
|
this_fortnight_end = Time.local(@now.year, @now.month, @now.day, @now.hour)
|
43
45
|
sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
|
44
46
|
sunday_repeater.start = @now
|
45
|
-
#sunday_repeater.next(:past)
|
46
47
|
last_sunday_span = sunday_repeater.next(:past)
|
47
48
|
this_fortnight_start = last_sunday_span.begin
|
48
49
|
Chronic::Span.new(this_fortnight_start, this_fortnight_end)
|
@@ -1,9 +1,30 @@
|
|
1
1
|
class Chronic::RepeaterMinute < Chronic::Repeater #:nodoc:
|
2
2
|
MINUTE_SECONDS = 60
|
3
3
|
|
4
|
+
def next(pointer = :future)
|
5
|
+
super
|
6
|
+
|
7
|
+
direction = pointer == :future ? 1 : -1
|
8
|
+
|
9
|
+
raise 'not implemented'
|
10
|
+
end
|
11
|
+
|
4
12
|
def this(pointer = :future)
|
5
|
-
|
6
|
-
|
13
|
+
super
|
14
|
+
|
15
|
+
case pointer
|
16
|
+
when :future
|
17
|
+
minute_begin = @now
|
18
|
+
minute_end = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
|
19
|
+
when :past
|
20
|
+
minute_begin = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
|
21
|
+
minute_end = @now
|
22
|
+
when :none
|
23
|
+
minute_begin = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min)
|
24
|
+
minute_end = Time.local(@now.year, @now.month, @now.day, @now.hour, @now.min) + MINUTE_SECONDS
|
25
|
+
end
|
26
|
+
|
27
|
+
Chronic::Span.new(minute_begin, minute_end)
|
7
28
|
end
|
8
29
|
|
9
30
|
def offset(span, amount, pointer)
|
@@ -24,6 +24,9 @@ class Chronic::RepeaterMonth < Chronic::Repeater #:nodoc:
|
|
24
24
|
when :past
|
25
25
|
month_start = Time.local(@now.year, @now.month)
|
26
26
|
month_end = Time.local(@now.year, @now.month, @now.day)
|
27
|
+
when :none
|
28
|
+
month_start = Time.local(@now.year, @now.month)
|
29
|
+
month_end = self.offset_by(Time.local(@now.year, @now.month), 1, :future)
|
27
30
|
end
|
28
31
|
|
29
32
|
Chronic::Span.new(month_start, month_end)
|
@@ -92,7 +92,10 @@ class Chronic::RepeaterTime < Chronic::Repeater #:nodoc:
|
|
92
92
|
end
|
93
93
|
|
94
94
|
def this(context = :future)
|
95
|
-
|
95
|
+
super
|
96
|
+
|
97
|
+
context = :future if context == :none
|
98
|
+
|
96
99
|
self.next(context)
|
97
100
|
end
|
98
101
|
|
@@ -44,6 +44,12 @@ class Chronic::RepeaterWeek < Chronic::Repeater #:nodoc:
|
|
44
44
|
last_sunday_span = sunday_repeater.next(:past)
|
45
45
|
this_week_start = last_sunday_span.begin
|
46
46
|
Chronic::Span.new(this_week_start, this_week_end)
|
47
|
+
when :none
|
48
|
+
sunday_repeater = Chronic::RepeaterDayName.new(:sunday)
|
49
|
+
sunday_repeater.start = @now
|
50
|
+
last_sunday_span = sunday_repeater.next(:past)
|
51
|
+
this_week_start = last_sunday_span.begin
|
52
|
+
Chronic::Span.new(this_week_start, this_week_start + WEEK_SECONDS)
|
47
53
|
end
|
48
54
|
end
|
49
55
|
|
@@ -28,6 +28,9 @@ class Chronic::RepeaterYear < Chronic::Repeater #:nodoc:
|
|
28
28
|
when :past
|
29
29
|
this_year_start = Time.local(@now.year, 1, 1)
|
30
30
|
this_year_end = Time.local(@now.year, @now.month, @now.day)
|
31
|
+
when :none
|
32
|
+
this_year_start = Time.local(@now.year, 1, 1)
|
33
|
+
this_year_end = Time.local(@now.year + 1, 1, 1)
|
31
34
|
end
|
32
35
|
|
33
36
|
Chronic::Span.new(this_year_start, this_year_end)
|
data/lib/chronic/scalar.rb
CHANGED
@@ -40,7 +40,7 @@ module Chronic
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def self.scan_for_years(token, post_token)
|
43
|
-
if token.word =~
|
43
|
+
if token.word =~ /^([1-9]\d)?\d\d?$/
|
44
44
|
unless post_token && %w{am pm morning afternoon evening night}.include?(post_token)
|
45
45
|
return ScalarYear.new(token.word.to_i)
|
46
46
|
end
|
data/test/test_parsing.rb
CHANGED
@@ -300,10 +300,22 @@ class TestParsing < Test::Unit::TestCase
|
|
300
300
|
assert_equal Time.local(2006, 8, 16, 13, 59, 59), time
|
301
301
|
end
|
302
302
|
|
303
|
-
def test_parse_guess_grr
|
303
|
+
def test_parse_guess_grr
|
304
304
|
time = Chronic.parse("yesterday at 4:00", :now => @time_2006_08_16_14_00_00)
|
305
305
|
assert_equal Time.local(2006, 8, 15, 16), time
|
306
306
|
|
307
|
+
time = Chronic.parse("today at 9:00", :now => @time_2006_08_16_14_00_00)
|
308
|
+
assert_equal Time.local(2006, 8, 16, 9), time
|
309
|
+
|
310
|
+
time = Chronic.parse("today at 2100", :now => @time_2006_08_16_14_00_00)
|
311
|
+
assert_equal Time.local(2006, 8, 16, 21), time
|
312
|
+
|
313
|
+
time = Chronic.parse("this day at 0900", :now => @time_2006_08_16_14_00_00)
|
314
|
+
assert_equal Time.local(2006, 8, 16, 9), time
|
315
|
+
|
316
|
+
time = Chronic.parse("tomorrow at 0900", :now => @time_2006_08_16_14_00_00)
|
317
|
+
assert_equal Time.local(2006, 8, 17, 9), time
|
318
|
+
|
307
319
|
time = Chronic.parse("yesterday at 4:00", :now => @time_2006_08_16_14_00_00, :ambiguous_time_range => :none)
|
308
320
|
assert_equal Time.local(2006, 8, 15, 4), time
|
309
321
|
|
@@ -324,6 +336,9 @@ class TestParsing < Test::Unit::TestCase
|
|
324
336
|
time = Chronic.parse("today at 6:00pm", :now => @time_2006_08_16_14_00_00)
|
325
337
|
assert_equal Time.local(2006, 8, 16, 18), time
|
326
338
|
|
339
|
+
time = Chronic.parse("today at 6:00am", :now => @time_2006_08_16_14_00_00)
|
340
|
+
assert_equal Time.local(2006, 8, 16, 6), time
|
341
|
+
|
327
342
|
time = Chronic.parse("this day 1800", :now => @time_2006_08_16_14_00_00)
|
328
343
|
assert_equal Time.local(2006, 8, 16, 18), time
|
329
344
|
|
@@ -358,7 +373,7 @@ class TestParsing < Test::Unit::TestCase
|
|
358
373
|
assert_equal Time.local(2006, 7, 26, 14, 30, 30), time
|
359
374
|
|
360
375
|
time = Chronic.parse("3 days ago", :now => @time_2006_08_16_14_00_00)
|
361
|
-
assert_equal Time.local(2006, 8, 13, 14
|
376
|
+
assert_equal Time.local(2006, 8, 13, 14), time
|
362
377
|
|
363
378
|
#time = Chronic.parse("1 monday ago", :now => @time_2006_08_16_14_00_00)
|
364
379
|
#assert_equal Time.local(2006, 8, 14, 12), time
|
@@ -367,7 +382,7 @@ class TestParsing < Test::Unit::TestCase
|
|
367
382
|
assert_equal Time.local(2006, 8, 12, 9), time
|
368
383
|
|
369
384
|
time = Chronic.parse("7 hours ago", :now => @time_2006_08_16_14_00_00)
|
370
|
-
assert_equal Time.local(2006, 8, 16, 7
|
385
|
+
assert_equal Time.local(2006, 8, 16, 7), time
|
371
386
|
|
372
387
|
time = Chronic.parse("3 minutes ago", :now => @time_2006_08_16_14_00_00)
|
373
388
|
assert_equal Time.local(2006, 8, 16, 13, 57), time
|
@@ -390,13 +405,13 @@ class TestParsing < Test::Unit::TestCase
|
|
390
405
|
assert_equal Time.local(2006, 8, 23, 14, 30, 30), time
|
391
406
|
|
392
407
|
time = Chronic.parse("1 day hence", :now => @time_2006_08_16_14_00_00)
|
393
|
-
assert_equal Time.local(2006, 8, 17, 14
|
408
|
+
assert_equal Time.local(2006, 8, 17, 14), time
|
394
409
|
|
395
410
|
time = Chronic.parse("5 mornings hence", :now => @time_2006_08_16_14_00_00)
|
396
411
|
assert_equal Time.local(2006, 8, 21, 9), time
|
397
412
|
|
398
413
|
time = Chronic.parse("1 hour from now", :now => @time_2006_08_16_14_00_00)
|
399
|
-
assert_equal Time.local(2006, 8, 16, 15
|
414
|
+
assert_equal Time.local(2006, 8, 16, 15), time
|
400
415
|
|
401
416
|
time = Chronic.parse("20 minutes hence", :now => @time_2006_08_16_14_00_00)
|
402
417
|
assert_equal Time.local(2006, 8, 16, 14, 20), time
|
@@ -407,7 +422,7 @@ class TestParsing < Test::Unit::TestCase
|
|
407
422
|
|
408
423
|
def test_parse_guess_p_s_r
|
409
424
|
time = Chronic.parse("in 3 hours", :now => @time_2006_08_16_14_00_00)
|
410
|
-
assert_equal Time.local(2006, 8, 16, 17
|
425
|
+
assert_equal Time.local(2006, 8, 16, 17), time
|
411
426
|
end
|
412
427
|
|
413
428
|
def test_parse_guess_s_r_p_a
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.8.11
|
|
3
3
|
specification_version: 1
|
4
4
|
name: chronic
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.1.
|
7
|
-
date: 2006-
|
6
|
+
version: 0.1.3
|
7
|
+
date: 2006-10-20 00:00:00 -07:00
|
8
8
|
summary: A natural language date parser
|
9
9
|
require_paths:
|
10
10
|
- lib
|