Parent

Stamp::Translator

Public Instance Methods

build_emitters(tokens) click to toggle source

Transforms tokens that look like date/time parts to emitter objects.

# File lib/stamp/translator.rb, line 88
def build_emitters(tokens)
  previous_part = nil
  tokens.map do |token|
    emitter = yield(token, previous_part)
    previous_part = emitter.field unless emitter.nil?

    emitter || Emitters::String.new(token)
  end
end
date_emitter(token, previous_part) click to toggle source
# File lib/stamp/translator.rb, line 123
def date_emitter(token, previous_part)
  case token
  when MONTHNAMES_REGEXP
    Emitters::Lookup.new(:month, Date::MONTHNAMES)

  when ABBR_MONTHNAMES_REGEXP
    Emitters::Lookup.new(:month, Date::ABBR_MONTHNAMES)

  when DAYNAMES_REGEXP
    Emitters::Lookup.new(:wday, Date::DAYNAMES)

  when ABBR_DAYNAMES_REGEXP
    Emitters::Lookup.new(:wday, Date::ABBR_DAYNAMES)

  when TIMEZONE_REGEXP
    Emitters::Delegate.new(:zone)

  when FOUR_DIGIT_REGEXP
    Emitters::Delegate.new(:year)

  when ORDINAL_DAY_REGEXP
    Emitters::Ordinal.new(:day)

  when TWO_DIGIT_REGEXP
    value = token.to_i

    obvious_mappings =
      OBVIOUS_DATE_MAP.reject { |k,v| v.field == previous_part }

    obvious_directive = obvious_mappings.find do |range, directive|
      break directive if range === value
    end

    # if the intent isn't obvious based on the example value, try to
    # disambiguate based on context
    obvious_directive ||
      TWO_DIGIT_DATE_SUCCESSION[previous_part] ||
      TWO_DIGIT_MONTH_EMITTER

  when ONE_DIGIT_REGEXP
    Emitters::Delegate.new(:day)
  end
end
time_emitter(token, previous_part) click to toggle source
# File lib/stamp/translator.rb, line 98
def time_emitter(token, previous_part)
  case token
  when MERIDIAN_LOWER_REGEXP
    Emitters::AmPm.new

  when MERIDIAN_UPPER_REGEXP
    Emitters::AmPm.new { |v| v.upcase }

  when TWO_DIGIT_REGEXP
    TWO_DIGIT_TIME_SUCCESSION[previous_part] ||
      case token.to_i
      when OBVIOUS_24_HOUR
        # 24-hour clock
        Emitters::TwoDigit.new(:hour)
      else
        # 12-hour clock with leading zero
        Emitters::TwoDigit.new(:hour, &HOUR_TO_12_HOUR)
      end

  when ONE_DIGIT_REGEXP
    # 12-hour clock without leading zero
    Emitters::Delegate.new(:hour, &HOUR_TO_12_HOUR)
  end
end
translate(example) click to toggle source
# File lib/stamp/translator.rb, line 64
def translate(example)
  # extract any substrings that look like times, like "23:59" or "8:37 am"
  before, time_example, after = example.partition(TIME_REGEXP)

  # build emitters from the example date
  emitters = Emitters::Composite.new
  emitters << build_emitters(before.split(/\b/)) do |token, previous_part|
    date_emitter(token, previous_part)
  end

  # build emitters from the example time
  unless time_example.empty?
    time_parts = time_example.scan(TIME_REGEXP).first
    emitters << build_emitters(time_parts) do |token, previous_part|
      time_emitter(token, previous_part)
    end
  end

  # recursively process any remaining text
  emitters << translate(after) unless after.empty?
  emitters
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.