chronic 0.2.2 → 0.10.2
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 +7 -0
- data/.gitignore +6 -0
- data/.travis.yml +8 -0
- data/HISTORY.md +243 -0
- data/LICENSE +21 -0
- data/README.md +182 -0
- data/Rakefile +62 -15
- data/chronic.gemspec +23 -0
- data/lib/chronic/date.rb +82 -0
- data/lib/chronic/grabber.rb +24 -17
- data/lib/chronic/handler.rb +97 -0
- data/lib/chronic/handlers.rb +490 -312
- data/lib/chronic/mini_date.rb +38 -0
- data/lib/chronic/numerizer.rb +130 -0
- data/lib/chronic/ordinal.rb +33 -24
- data/lib/chronic/parser.rb +268 -0
- data/lib/chronic/pointer.rb +22 -17
- data/lib/chronic/repeater.rb +137 -107
- data/lib/chronic/repeaters/repeater_day.rb +51 -44
- data/lib/chronic/repeaters/repeater_day_name.rb +50 -43
- data/lib/chronic/repeaters/repeater_day_portion.rb +97 -81
- data/lib/chronic/repeaters/repeater_fortnight.rb +61 -54
- data/lib/chronic/repeaters/repeater_hour.rb +51 -44
- data/lib/chronic/repeaters/repeater_minute.rb +51 -44
- data/lib/chronic/repeaters/repeater_month.rb +79 -60
- data/lib/chronic/repeaters/repeater_month_name.rb +85 -83
- data/lib/chronic/repeaters/repeater_season.rb +110 -22
- data/lib/chronic/repeaters/repeater_season_name.rb +41 -22
- data/lib/chronic/repeaters/repeater_second.rb +41 -34
- data/lib/chronic/repeaters/repeater_time.rb +128 -104
- data/lib/chronic/repeaters/repeater_week.rb +65 -58
- data/lib/chronic/repeaters/repeater_weekday.rb +86 -0
- data/lib/chronic/repeaters/repeater_weekend.rb +59 -52
- data/lib/chronic/repeaters/repeater_year.rb +72 -52
- data/lib/chronic/scalar.rb +53 -46
- data/lib/chronic/season.rb +26 -0
- data/lib/chronic/separator.rb +174 -43
- data/lib/chronic/sign.rb +49 -0
- data/lib/chronic/span.rb +31 -0
- data/lib/chronic/tag.rb +37 -0
- data/lib/chronic/time.rb +40 -0
- data/lib/chronic/time_zone.rb +21 -11
- data/lib/chronic/token.rb +51 -0
- data/lib/chronic.rb +94 -69
- data/test/helper.rb +12 -0
- data/test/test_chronic.rb +183 -0
- data/test/test_daylight_savings.rb +118 -0
- data/test/{test_Handler.rb → test_handler.rb} +73 -55
- data/test/test_mini_date.rb +32 -0
- data/test/test_numerizer.rb +86 -0
- data/test/test_parsing.rb +891 -248
- data/test/{test_RepeaterDayName.rb → test_repeater_day_name.rb} +16 -17
- data/test/test_repeater_day_portion.rb +254 -0
- data/test/{test_RepeaterFortnight.rb → test_repeater_fortnight.rb} +17 -18
- data/test/{test_RepeaterHour.rb → test_repeater_hour.rb} +23 -20
- data/test/test_repeater_minute.rb +34 -0
- data/test/{test_RepeaterMonth.rb → test_repeater_month.rb} +21 -18
- data/test/{test_RepeaterMonthName.rb → test_repeater_month_name.rb} +18 -19
- data/test/test_repeater_season.rb +40 -0
- data/test/{test_RepeaterTime.rb → test_repeater_time.rb} +39 -23
- data/test/{test_RepeaterWeek.rb → test_repeater_week.rb} +17 -18
- data/test/test_repeater_weekday.rb +55 -0
- data/test/{test_RepeaterWeekend.rb → test_repeater_weekend.rb} +22 -23
- data/test/{test_RepeaterYear.rb → test_repeater_year.rb} +25 -19
- data/test/{test_Span.rb → test_span.rb} +7 -8
- data/test/{test_Token.rb → test_token.rb} +6 -7
- metadata +163 -85
- data/History.txt +0 -49
- data/Manifest.txt +0 -47
- data/README.txt +0 -149
- data/lib/chronic/chronic.rb +0 -239
- data/lib/numerizer/numerizer.rb +0 -103
- data/test/suite.rb +0 -9
- data/test/test_Chronic.rb +0 -50
- data/test/test_Numerizer.rb +0 -48
- data/test/test_Time.rb +0 -50
data/lib/chronic/separator.rb
CHANGED
|
@@ -1,76 +1,207 @@
|
|
|
1
1
|
module Chronic
|
|
2
|
+
class Separator < Tag
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
# Scan an Array of Token objects and apply any necessary Separator
|
|
5
|
+
# tags to each token.
|
|
6
|
+
#
|
|
7
|
+
# tokens - An Array of tokens to scan.
|
|
8
|
+
# options - The Hash of options specified in Chronic::parse.
|
|
9
|
+
#
|
|
10
|
+
# Returns an Array of tokens.
|
|
11
|
+
def self.scan(tokens, options)
|
|
12
|
+
tokens.each do |token|
|
|
13
|
+
if t = scan_for_commas(token) then token.tag(t); next end
|
|
14
|
+
if t = scan_for_dots(token) then token.tag(t); next end
|
|
15
|
+
if t = scan_for_colon(token) then token.tag(t); next end
|
|
16
|
+
if t = scan_for_space(token) then token.tag(t); next end
|
|
17
|
+
if t = scan_for_slash(token) then token.tag(t); next end
|
|
18
|
+
if t = scan_for_dash(token) then token.tag(t); next end
|
|
19
|
+
if t = scan_for_quote(token) then token.tag(t); next end
|
|
20
|
+
if t = scan_for_at(token) then token.tag(t); next end
|
|
21
|
+
if t = scan_for_in(token) then token.tag(t); next end
|
|
22
|
+
if t = scan_for_on(token) then token.tag(t); next end
|
|
23
|
+
if t = scan_for_and(token) then token.tag(t); next end
|
|
24
|
+
if t = scan_for_t(token) then token.tag(t); next end
|
|
25
|
+
if t = scan_for_w(token) then token.tag(t); next end
|
|
10
26
|
end
|
|
11
|
-
tokens
|
|
12
27
|
end
|
|
13
|
-
|
|
28
|
+
|
|
29
|
+
# token - The Token object we want to scan.
|
|
30
|
+
#
|
|
31
|
+
# Returns a new SeparatorComma object.
|
|
14
32
|
def self.scan_for_commas(token)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
33
|
+
scan_for token, SeparatorComma, { /^,$/ => :comma }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# token - The Token object we want to scan.
|
|
37
|
+
#
|
|
38
|
+
# Returns a new SeparatorDot object.
|
|
39
|
+
def self.scan_for_dots(token)
|
|
40
|
+
scan_for token, SeparatorDot, { /^\.$/ => :dot }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# token - The Token object we want to scan.
|
|
44
|
+
#
|
|
45
|
+
# Returns a new SeparatorColon object.
|
|
46
|
+
def self.scan_for_colon(token)
|
|
47
|
+
scan_for token, SeparatorColon, { /^:$/ => :colon }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# token - The Token object we want to scan.
|
|
51
|
+
#
|
|
52
|
+
# Returns a new SeparatorSpace object.
|
|
53
|
+
def self.scan_for_space(token)
|
|
54
|
+
scan_for token, SeparatorSpace, { /^ $/ => :space }
|
|
29
55
|
end
|
|
30
|
-
|
|
56
|
+
|
|
57
|
+
# token - The Token object we want to scan.
|
|
58
|
+
#
|
|
59
|
+
# Returns a new SeparatorSlash object.
|
|
60
|
+
def self.scan_for_slash(token)
|
|
61
|
+
scan_for token, SeparatorSlash, { /^\/$/ => :slash }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# token - The Token object we want to scan.
|
|
65
|
+
#
|
|
66
|
+
# Returns a new SeparatorDash object.
|
|
67
|
+
def self.scan_for_dash(token)
|
|
68
|
+
scan_for token, SeparatorDash, { /^-$/ => :dash }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# token - The Token object we want to scan.
|
|
72
|
+
#
|
|
73
|
+
# Returns a new SeparatorQuote object.
|
|
74
|
+
def self.scan_for_quote(token)
|
|
75
|
+
scan_for token, SeparatorQuote,
|
|
76
|
+
{
|
|
77
|
+
/^'$/ => :single_quote,
|
|
78
|
+
/^"$/ => :double_quote
|
|
79
|
+
}
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# token - The Token object we want to scan.
|
|
83
|
+
#
|
|
84
|
+
# Returns a new SeparatorAt object.
|
|
31
85
|
def self.scan_for_at(token)
|
|
32
|
-
|
|
33
|
-
scanner.keys.each do |scanner_item|
|
|
34
|
-
return SeparatorAt.new(scanner[scanner_item]) if scanner_item =~ token.word
|
|
35
|
-
end
|
|
36
|
-
return nil
|
|
86
|
+
scan_for token, SeparatorAt, { /^(at|@)$/ => :at }
|
|
37
87
|
end
|
|
38
|
-
|
|
88
|
+
|
|
89
|
+
# token - The Token object we want to scan.
|
|
90
|
+
#
|
|
91
|
+
# Returns a new SeparatorIn object.
|
|
39
92
|
def self.scan_for_in(token)
|
|
40
|
-
|
|
41
|
-
scanner.keys.each do |scanner_item|
|
|
42
|
-
return SeparatorIn.new(scanner[scanner_item]) if scanner_item =~ token.word
|
|
43
|
-
end
|
|
44
|
-
return nil
|
|
93
|
+
scan_for token, SeparatorIn, { /^in$/ => :in }
|
|
45
94
|
end
|
|
46
|
-
|
|
95
|
+
|
|
96
|
+
# token - The Token object we want to scan.
|
|
97
|
+
#
|
|
98
|
+
# Returns a new SeparatorOn object.
|
|
99
|
+
def self.scan_for_on(token)
|
|
100
|
+
scan_for token, SeparatorOn, { /^on$/ => :on }
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# token - The Token object we want to scan.
|
|
104
|
+
#
|
|
105
|
+
# Returns a new SeperatorAnd Object object.
|
|
106
|
+
def self.scan_for_and(token)
|
|
107
|
+
scan_for token, SeparatorAnd, { /^and$/ => :and }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# token - The Token object we want to scan.
|
|
111
|
+
#
|
|
112
|
+
# Returns a new SeperatorT Object object.
|
|
113
|
+
def self.scan_for_t(token)
|
|
114
|
+
scan_for token, SeparatorT, { /^t$/ => :T }
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# token - The Token object we want to scan.
|
|
118
|
+
#
|
|
119
|
+
# Returns a new SeperatorW Object object.
|
|
120
|
+
def self.scan_for_w(token)
|
|
121
|
+
scan_for token, SeparatorW, { /^w$/ => :W }
|
|
122
|
+
end
|
|
123
|
+
|
|
47
124
|
def to_s
|
|
48
125
|
'separator'
|
|
49
126
|
end
|
|
50
127
|
end
|
|
51
|
-
|
|
128
|
+
|
|
52
129
|
class SeparatorComma < Separator #:nodoc:
|
|
53
130
|
def to_s
|
|
54
131
|
super << '-comma'
|
|
55
132
|
end
|
|
56
133
|
end
|
|
57
|
-
|
|
58
|
-
class
|
|
134
|
+
|
|
135
|
+
class SeparatorDot < Separator #:nodoc:
|
|
136
|
+
def to_s
|
|
137
|
+
super << '-dot'
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
class SeparatorColon < Separator #:nodoc:
|
|
142
|
+
def to_s
|
|
143
|
+
super << '-colon'
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
class SeparatorSpace < Separator #:nodoc:
|
|
59
148
|
def to_s
|
|
60
|
-
super << '-
|
|
149
|
+
super << '-space'
|
|
61
150
|
end
|
|
62
151
|
end
|
|
63
|
-
|
|
152
|
+
|
|
153
|
+
class SeparatorSlash < Separator #:nodoc:
|
|
154
|
+
def to_s
|
|
155
|
+
super << '-slash'
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
class SeparatorDash < Separator #:nodoc:
|
|
160
|
+
def to_s
|
|
161
|
+
super << '-dash'
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
class SeparatorQuote < Separator #:nodoc:
|
|
166
|
+
def to_s
|
|
167
|
+
super << '-quote-' << @type.to_s
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
64
171
|
class SeparatorAt < Separator #:nodoc:
|
|
65
172
|
def to_s
|
|
66
173
|
super << '-at'
|
|
67
174
|
end
|
|
68
175
|
end
|
|
69
|
-
|
|
176
|
+
|
|
70
177
|
class SeparatorIn < Separator #:nodoc:
|
|
71
178
|
def to_s
|
|
72
179
|
super << '-in'
|
|
73
180
|
end
|
|
74
181
|
end
|
|
75
182
|
|
|
76
|
-
|
|
183
|
+
class SeparatorOn < Separator #:nodoc:
|
|
184
|
+
def to_s
|
|
185
|
+
super << '-on'
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
class SeparatorAnd < Separator #:nodoc:
|
|
190
|
+
def to_s
|
|
191
|
+
super << '-and'
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
class SeparatorT < Separator #:nodoc:
|
|
196
|
+
def to_s
|
|
197
|
+
super << '-T'
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
class SeparatorW < Separator #:nodoc:
|
|
202
|
+
def to_s
|
|
203
|
+
super << '-W'
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
end
|
data/lib/chronic/sign.rb
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Chronic
|
|
2
|
+
class Sign < Tag
|
|
3
|
+
|
|
4
|
+
# Scan an Array of Token objects and apply any necessary Sign
|
|
5
|
+
# tags to each token.
|
|
6
|
+
#
|
|
7
|
+
# tokens - An Array of tokens to scan.
|
|
8
|
+
# options - The Hash of options specified in Chronic::parse.
|
|
9
|
+
#
|
|
10
|
+
# Returns an Array of tokens.
|
|
11
|
+
def self.scan(tokens, options)
|
|
12
|
+
tokens.each do |token|
|
|
13
|
+
if t = scan_for_plus(token) then token.tag(t); next end
|
|
14
|
+
if t = scan_for_minus(token) then token.tag(t); next end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# token - The Token object we want to scan.
|
|
19
|
+
#
|
|
20
|
+
# Returns a new SignPlus object.
|
|
21
|
+
def self.scan_for_plus(token)
|
|
22
|
+
scan_for token, SignPlus, { /^\+$/ => :plus }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# token - The Token object we want to scan.
|
|
26
|
+
#
|
|
27
|
+
# Returns a new SignMinus object.
|
|
28
|
+
def self.scan_for_minus(token)
|
|
29
|
+
scan_for token, SignMinus, { /^-$/ => :minus }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def to_s
|
|
33
|
+
'sign'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class SignPlus < Sign #:nodoc:
|
|
38
|
+
def to_s
|
|
39
|
+
super << '-plus'
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class SignMinus < Sign #:nodoc:
|
|
44
|
+
def to_s
|
|
45
|
+
super << '-minus'
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
data/lib/chronic/span.rb
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module Chronic
|
|
2
|
+
# A Span represents a range of time. Since this class extends
|
|
3
|
+
# Range, you can use #begin and #end to get the beginning and
|
|
4
|
+
# ending times of the span (they will be of class Time)
|
|
5
|
+
class Span < Range
|
|
6
|
+
# Returns the width of this span in seconds
|
|
7
|
+
def width
|
|
8
|
+
(self.end - self.begin).to_i
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Add a number of seconds to this span, returning the
|
|
12
|
+
# resulting Span
|
|
13
|
+
def +(seconds)
|
|
14
|
+
Span.new(self.begin + seconds, self.end + seconds)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Subtract a number of seconds to this span, returning the
|
|
18
|
+
# resulting Span
|
|
19
|
+
def -(seconds)
|
|
20
|
+
self + -seconds
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Prints this span in a nice fashion
|
|
24
|
+
def to_s
|
|
25
|
+
'(' << self.begin.to_s << '..' << self.end.to_s << ')'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
alias :cover? :include? if RUBY_VERSION =~ /^1.8/
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
data/lib/chronic/tag.rb
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Chronic
|
|
2
|
+
# Tokens are tagged with subclassed instances of this class when
|
|
3
|
+
# they match specific criteria.
|
|
4
|
+
class Tag
|
|
5
|
+
|
|
6
|
+
attr_accessor :type
|
|
7
|
+
|
|
8
|
+
# type - The Symbol type of this tag.
|
|
9
|
+
def initialize(type, options = {})
|
|
10
|
+
@type = type
|
|
11
|
+
@options = options
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# time - Set the start Time for this Tag.
|
|
15
|
+
def start=(time)
|
|
16
|
+
@now = time
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def scan_for(token, klass, items={}, options = {})
|
|
23
|
+
case items
|
|
24
|
+
when Regexp
|
|
25
|
+
return klass.new(token.word, options) if items =~ token.word
|
|
26
|
+
when Hash
|
|
27
|
+
items.each do |item, symbol|
|
|
28
|
+
return klass.new(symbol, options) if item =~ token.word
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
nil
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/chronic/time.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Chronic
|
|
2
|
+
class Time
|
|
3
|
+
HOUR_SECONDS = 3600 # 60 * 60
|
|
4
|
+
MINUTE_SECONDS = 60
|
|
5
|
+
SECOND_SECONDS = 1 # haha, awesome
|
|
6
|
+
SUBSECOND_SECONDS = 0.001
|
|
7
|
+
|
|
8
|
+
# Checks if given number could be hour
|
|
9
|
+
def self.could_be_hour?(hour)
|
|
10
|
+
hour >= 0 && hour <= 24
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Checks if given number could be minute
|
|
14
|
+
def self.could_be_minute?(minute)
|
|
15
|
+
minute >= 0 && minute <= 60
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Checks if given number could be second
|
|
19
|
+
def self.could_be_second?(second)
|
|
20
|
+
second >= 0 && second <= 60
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Checks if given number could be subsecond
|
|
24
|
+
def self.could_be_subsecond?(subsecond)
|
|
25
|
+
subsecond >= 0 && subsecond <= 999999
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# normalize offset in seconds to offset as string +mm:ss or -mm:ss
|
|
29
|
+
def self.normalize_offset(offset)
|
|
30
|
+
return offset if offset.is_a?(String)
|
|
31
|
+
offset = Chronic.time_class.now.to_time.utc_offset unless offset # get current system's UTC offset if offset is nil
|
|
32
|
+
sign = '+'
|
|
33
|
+
sign = '-' if offset < 0
|
|
34
|
+
hours = (offset.abs / 3600).to_i.to_s.rjust(2,'0')
|
|
35
|
+
minutes = (offset.abs % 3600).to_s.rjust(2,'0')
|
|
36
|
+
sign + hours + minutes
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
end
|
|
40
|
+
end
|
data/lib/chronic/time_zone.rb
CHANGED
|
@@ -1,22 +1,32 @@
|
|
|
1
1
|
module Chronic
|
|
2
|
-
class TimeZone < Tag
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
class TimeZone < Tag
|
|
3
|
+
|
|
4
|
+
# Scan an Array of Token objects and apply any necessary TimeZone
|
|
5
|
+
# tags to each token.
|
|
6
|
+
#
|
|
7
|
+
# tokens - An Array of tokens to scan.
|
|
8
|
+
# options - The Hash of options specified in Chronic::parse.
|
|
9
|
+
#
|
|
10
|
+
# Returns an Array of tokens.
|
|
11
|
+
def self.scan(tokens, options)
|
|
12
|
+
tokens.each do |token|
|
|
13
|
+
if t = scan_for_all(token) then token.tag(t); next end
|
|
6
14
|
end
|
|
7
|
-
tokens
|
|
8
15
|
end
|
|
9
16
|
|
|
17
|
+
# token - The Token object we want to scan.
|
|
18
|
+
#
|
|
19
|
+
# Returns a new Pointer object.
|
|
10
20
|
def self.scan_for_all(token)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
21
|
+
scan_for token, self,
|
|
22
|
+
{
|
|
23
|
+
/[PMCE][DS]T|UTC/i => :tz,
|
|
24
|
+
/(tzminus)?\d{2}:?\d{2}/ => :tz
|
|
25
|
+
}
|
|
16
26
|
end
|
|
17
27
|
|
|
18
28
|
def to_s
|
|
19
29
|
'timezone'
|
|
20
30
|
end
|
|
21
31
|
end
|
|
22
|
-
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Chronic
|
|
2
|
+
class Token
|
|
3
|
+
|
|
4
|
+
attr_accessor :word
|
|
5
|
+
attr_accessor :tags
|
|
6
|
+
|
|
7
|
+
def initialize(word)
|
|
8
|
+
@word = word
|
|
9
|
+
@tags = []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# Tag this token with the specified tag.
|
|
13
|
+
#
|
|
14
|
+
# new_tag - The new Tag object.
|
|
15
|
+
#
|
|
16
|
+
# Returns nothing.
|
|
17
|
+
def tag(new_tag)
|
|
18
|
+
@tags << new_tag
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Remove all tags of the given class.
|
|
22
|
+
#
|
|
23
|
+
# tag_class - The tag Class to remove.
|
|
24
|
+
#
|
|
25
|
+
# Returns nothing.
|
|
26
|
+
def untag(tag_class)
|
|
27
|
+
@tags.delete_if { |m| m.kind_of? tag_class }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Returns true if this token has any tags.
|
|
31
|
+
def tagged?
|
|
32
|
+
@tags.size > 0
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# tag_class - The tag Class to search for.
|
|
36
|
+
#
|
|
37
|
+
# Returns The first Tag that matches the given class.
|
|
38
|
+
def get_tag(tag_class)
|
|
39
|
+
@tags.find { |m| m.kind_of? tag_class }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Print this Token in a pretty way
|
|
43
|
+
def to_s
|
|
44
|
+
@word << '(' << @tags.join(', ') << ') '
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def inspect
|
|
48
|
+
to_s
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|