module Chronic
def definitions(options={})
-
(Hash)
- A Hash of Handler definitions
Other tags:
- See: parse -
def definitions(options={}) options[:endian_precedence] ||= [:middle, :little] @definitions ||= { :time => [ Handler.new([:repeater_time, :repeater_day_portion?], nil) ], :date => [ Handler.new([:repeater_day_name, :repeater_month_name, :scalar_day, :repeater_time, :separator_slash_or_dash?, :time_zone, :scalar_year], :handle_rdn_rmn_sd_t_tz_sy), Handler.new([:repeater_month_name, :scalar_day, :scalar_year], :handle_rmn_sd_sy), Handler.new([:repeater_month_name, :ordinal_day, :scalar_year], :handle_rmn_od_sy), Handler.new([:repeater_month_name, :scalar_day, :scalar_year, :separator_at?, 'time?'], :handle_rmn_sd_sy), Handler.new([:repeater_month_name, :ordinal_day, :scalar_year, :separator_at?, 'time?'], :handle_rmn_od_sy), Handler.new([:repeater_month_name, :scalar_day, :separator_at?, 'time?'], :handle_rmn_sd), Handler.new([:repeater_time, :repeater_day_portion?, :separator_on?, :repeater_month_name, :scalar_day], :handle_rmn_sd_on), Handler.new([:repeater_month_name, :ordinal_day, :separator_at?, 'time?'], :handle_rmn_od), Handler.new([:repeater_time, :repeater_day_portion?, :separator_on?, :repeater_month_name, :ordinal_day], :handle_rmn_od_on), Handler.new([:repeater_month_name, :scalar_year], :handle_rmn_sy), Handler.new([:scalar_day, :repeater_month_name, :scalar_year, :separator_at?, 'time?'], :handle_sd_rmn_sy), Handler.new([:scalar_year, :separator_slash_or_dash, :scalar_month, :separator_slash_or_dash, :scalar_day, :separator_at?, 'time?'], :handle_sy_sm_sd), Handler.new([:scalar_month, :separator_slash_or_dash, :scalar_year], :handle_sm_sy) ], # tonight at 7pm :anchor => [ Handler.new([:grabber?, :repeater, :separator_at?, :repeater?, :repeater?], :handle_r), Handler.new([:grabber?, :repeater, :repeater, :separator_at?, :repeater?, :repeater?], :handle_r), Handler.new([:repeater, :grabber, :repeater], :handle_r_g_r) ], # 3 weeks from now, in 2 months :arrow => [ Handler.new([:scalar, :repeater, :pointer], :handle_s_r_p), Handler.new([:pointer, :scalar, :repeater], :handle_p_s_r), Handler.new([:scalar, :repeater, :pointer, 'anchor'], :handle_s_r_p_a) ], # 3rd week in march :narrow => [ Handler.new([:ordinal, :repeater, :separator_in, :repeater], :handle_o_r_s_r), Handler.new([:ordinal, :repeater, :grabber, :repeater], :handle_o_r_g_r) ] } endians = [ Handler.new([:scalar_month, :separator_slash_or_dash, :scalar_day, :separator_slash_or_dash, :scalar_year, :separator_at?, 'time?'], :handle_sm_sd_sy), Handler.new([:scalar_day, :separator_slash_or_dash, :scalar_month, :separator_slash_or_dash, :scalar_year, :separator_at?, 'time?'], :handle_sd_sm_sy) ] case endian = Array(options[:endian_precedence]).first when :little @definitions[:endian] = endians.reverse when :middle @definitions[:endian] = endians else raise InvalidArgumentException, "Unknown endian option '#{endian}'" end @definitions end
def guess(span)
-
(Time)
-
Parameters:
-
span
(Span
) --
def guess(span) return nil if span.nil? if span.width > 1 span.begin + (span.width / 2) else span.begin end end
def numericize_numbers(text)
-
(String)
- A new string with words converted to numbers
Parameters:
-
text
(String
) -- The string to convert
Other tags:
- See: Numerizer.numerize -
def numericize_numbers(text) Numerizer.numerize(text) end
def parse(text, opts={})
-
(Time, Chronic::Span, nil)
-
Options Hash:
(**opts)
-
:ambiguous_year_future_bias
(Integer
) -- -
:endian_precedence
(Array
) -- -
:ambiguous_time_range
(Integer
) -- -
:guess
(Boolean
) -- -
:now
(Object
) -- -
:context
(Symbol
) --
def parse(text, opts={}) @text = text options = DEFAULT_OPTIONS.merge opts # ensure the specified options are valid (opts.keys - DEFAULT_OPTIONS.keys).each do |key| raise InvalidArgumentException, "#{key} is not a valid option key." end unless [:past, :future, :none].include?(options[:context]) raise InvalidArgumentException, "Invalid context, :past/:future only" end options[:text] = text options[:now] ||= Chronic.time_class.now Chronic.now = options[:now] # tokenize words tokens = tokenize(text, options) if Chronic.debug puts "+#{'-' * 51}\n| #{tokens}\n+#{'-' * 51}" end span = tokens_to_span(tokens, options) if options[:guess] guess span else span end end
def pre_normalize(text) #:nodoc:
-
(String)
- A new string ready for Chronic to parse
Parameters:
-
text
(String
) -- The string to normalize
def pre_normalize(text) #:nodoc: text = text.to_s.downcase text.gsub!(/['"\.,]/, '') text.gsub!(/\bsecond (of|day|month|hour|minute|second)\b/, '2nd \1') text = numericize_numbers(text) text.gsub!(/ \-(\d{4})\b/, ' tzminus\1') text.gsub!(/([\/\-\,\@])/) { ' ' + $1 + ' ' } text.gsub!(/\b0(\d+:\d+\s*pm?\b)/, '\1') text.gsub!(/\btoday\b/, 'this day') text.gsub!(/\btomm?orr?ow\b/, 'next day') text.gsub!(/\byesterday\b/, 'last day') text.gsub!(/\bnoon\b/, '12:00') text.gsub!(/\bmidnight\b/, '24:00') text.gsub!(/\bbefore now\b/, 'past') text.gsub!(/\bnow\b/, 'this second') text.gsub!(/\b(ago|before)\b/, 'past') text.gsub!(/\bthis past\b/, 'last') text.gsub!(/\bthis last\b/, 'last') text.gsub!(/\b(?:in|during) the (morning)\b/, '\1') text.gsub!(/\b(?:in the|during the|at) (afternoon|evening|night)\b/, '\1') text.gsub!(/\btonight\b/, 'this night') text.gsub!(/\b\d+:?\d*[ap]\b/,'\0m') text.gsub!(/(\d)([ap]m|oclock)\b/, '\1 \2') text.gsub!(/\b(hence|after|from)\b/, 'future') text end
def tokenize(text, options)
def tokenize(text, options) text = pre_normalize(text) tokens = text.split(' ').map { |word| Token.new(word) } [Repeater, Grabber, Pointer, Scalar, Ordinal, Separator, TimeZone].each do |tok| tokens = tok.scan(tokens, options) end tokens.select { |token| token.tagged? } end
def tokens_to_span(tokens, options) #:nodoc:
def tokens_to_span(tokens, options) #:nodoc: definitions = definitions(options) (definitions[:date] + definitions[:endian]).each do |handler| if handler.match(tokens, definitions) puts "-date" if Chronic.debug good_tokens = tokens.select { |o| !o.get_tag Separator } return Handlers.send(handler.handler_method, good_tokens, options) end end definitions[:anchor].each do |handler| if handler.match(tokens, definitions) puts "-anchor" if Chronic.debug good_tokens = tokens.select { |o| !o.get_tag Separator } return Handlers.send(handler.handler_method, good_tokens, options) end end definitions[:arrow].each do |handler| if handler.match(tokens, definitions) puts "-arrow" if Chronic.debug tags = [SeparatorAt, SeparatorSlashOrDash, SeparatorComma] good_tokens = tokens.reject { |o| tags.any? { |t| o.get_tag(t) } } return Handlers.send(handler.handler_method, good_tokens, options) end end definitions[:narrow].each do |handler| if handler.match(tokens, definitions) puts "-narrow" if Chronic.debug good_tokens = tokens.select { |o| !o.get_tag Separator } return Handlers.send(handler.handler_method, tokens, options) end end puts "-none" if Chronic.debug return nil end