1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
module Chronic
class Repeater < Tag
# Scan an Array of {Token}s and apply any necessary Repeater tags to
# each token
#
# @param [Array<Token>] tokens Array of tokens to scan
# @param [Hash] options Options specified in {Chronic.parse}
# @return [Array] list of tokens
def self.scan(tokens, options)
tokens.each do |token|
if t = scan_for_season_names(token) then token.tag(t); next end
if t = scan_for_month_names(token) then token.tag(t); next end
if t = scan_for_day_names(token) then token.tag(t); next end
if t = scan_for_day_portions(token) then token.tag(t); next end
if t = scan_for_times(token) then token.tag(t); next end
if t = scan_for_units(token) then token.tag(t); next end
end
end
# @param [Token] token
# @return [RepeaterSeasonName, nil]
def self.scan_for_season_names(token)
scan_for token, RepeaterSeasonName,
{
/^springs?$/ => :spring,
/^summers?$/ => :summer,
/^(autumn)|(fall)s?$/ => :autumn,
/^winters?$/ => :winter
}
end
# @param [Token] token
# @return [RepeaterMonthName, nil]
def self.scan_for_month_names(token)
scan_for token, RepeaterMonthName,
{
/^jan\.?(uary)?$/ => :january,
/^feb\.?(ruary)?$/ => :february,
/^mar\.?(ch)?$/ => :march,
/^apr\.?(il)?$/ => :april,
/^may$/ => :may,
/^jun\.?e?$/ => :june,
/^jul\.?y?$/ => :july,
/^aug\.?(ust)?$/ => :august,
/^sep\.?(t\.?|tember)?$/ => :september,
/^oct\.?(ober)?$/ => :october,
/^nov\.?(ember)?$/ => :november,
/^dec\.?(ember)?$/ => :december
}
end
# @param [Token] token
# @return [RepeaterDayName, nil]
def self.scan_for_day_names(token)
scan_for token, RepeaterDayName,
{
/^m[ou]n(day)?$/ => :monday,
/^t(ue|eu|oo|u|)s?(day)?$/ => :tuesday,
/^we(d|dnes|nds|nns)(day)?$/ => :wednesday,
/^th(u|ur|urs|ers)(day)?$/ => :thursday,
/^fr[iy](day)?$/ => :friday,
/^sat(t?[ue]rday)?$/ => :saturday,
/^su[nm](day)?$/ => :sunday
}
end
# @param [Token] token
# @return [RepeaterDayPortion, nil]
def self.scan_for_day_portions(token)
scan_for token, RepeaterDayPortion,
{
/^ams?$/ => :am,
/^pms?$/ => :pm,
/^mornings?$/ => :morning,
/^afternoons?$/ => :afternoon,
/^evenings?$/ => :evening,
/^(night|nite)s?$/ => :night
}
end
# @param [Token] token
# @return [RepeaterTime, nil]
def self.scan_for_times(token)
scan_for token, RepeaterTime, /^\d{1,2}(:?\d{2})?([\.:]?\d{2})?$/
end
# @param [Token] token
# @return [Repeater] A new instance of a subclass of Repeater
def self.scan_for_units(token)
{
/^years?$/ => :year,
/^seasons?$/ => :season,
/^months?$/ => :month,
/^fortnights?$/ => :fortnight,
/^weeks?$/ => :week,
/^weekends?$/ => :weekend,
/^(week|business)days?$/ => :weekday,
/^days?$/ => :day,
/^hours?$/ => :hour,
/^minutes?$/ => :minute,
/^seconds?$/ => :second
}.each do |item, symbol|
if item =~ token.word
klass_name = 'Repeater' + symbol.to_s.capitalize
klass = Chronic.const_get(klass_name)
return klass.new(symbol)
end
end
return nil
end
def <=>(other)
width <=> other.width
end
# returns the width (in seconds or months) of this repeatable.
def width
raise("Repeater#width must be overridden in subclasses")
end
# returns the next occurance of this repeatable.
def next(pointer)
raise("Start point must be set before calling #next") unless @now
end
def this(pointer)
raise("Start point must be set before calling #this") unless @now
end
def to_s
'repeater'
end
end
end
|