initial repeater port. lots to sort out for architecture here
authorChuck Hagenbuch <chuck@horde.org>
Thu, 29 Jan 2009 05:36:42 +0000 (00:36 -0500)
committerChuck Hagenbuch <chuck@horde.org>
Thu, 29 Jan 2009 05:36:42 +0000 (00:36 -0500)
framework/Date_Parser/lib/Horde/Date/Parser/Locale/Base/Repeater.php

index 9f80daf..c84d77f 100644 (file)
-class Chronic::Repeater < Chronic::Tag #:nodoc:
-  def self.scan(tokens, options)
-    # for each token
-    tokens.each_index do |i|
-      if t = self.scan_for_month_names(tokens[i]) then tokens[i].tag(t); next end
-      if t = self.scan_for_day_names(tokens[i]) then tokens[i].tag(t); next end
-      if t = self.scan_for_day_portions(tokens[i]) then tokens[i].tag(t); next end
-      if t = self.scan_for_times(tokens[i], options) then tokens[i].tag(t); next end
-      if t = self.scan_for_units(tokens[i]) then tokens[i].tag(t); next end
-    end
-    tokens
-  end
-  
-  def self.scan_for_month_names(token)
-    scanner = {/^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}
-    scanner.keys.each do |scanner_item|
-      return Chronic::RepeaterMonthName.new(scanner[scanner_item]) if scanner_item =~ token.word
-    end
-    return nil
-  end
-  
-  def self.scan_for_day_names(token)
-    scanner = {/^m[ou]n(day)?$/ => :monday,
-               /^t(ue|eu|oo|u|)s(day)?$/ => :tuesday,
-               /^tue$/ => :tuesday,
-               /^we(dnes|nds|nns)day$/ => :wednesday,
-               /^wed$/ => :wednesday,
-               /^th(urs|ers)day$/ => :thursday,
-               /^thu$/ => :thursday,
-               /^fr[iy](day)?$/ => :friday,
-               /^sat(t?[ue]rday)?$/ => :saturday,
-               /^su[nm](day)?$/ => :sunday}
-    scanner.keys.each do |scanner_item|
-      return Chronic::RepeaterDayName.new(scanner[scanner_item]) if scanner_item =~ token.word
-    end
-    return nil
-  end
-  
-  def self.scan_for_day_portions(token)
-    scanner = {/^ams?$/ => :am,
-               /^pms?$/ => :pm,
-               /^mornings?$/ => :morning,
-               /^afternoons?$/ => :afternoon,
-               /^evenings?$/ => :evening,
-               /^(night|nite)s?$/ => :night}
-    scanner.keys.each do |scanner_item|
-      return Chronic::RepeaterDayPortion.new(scanner[scanner_item]) if scanner_item =~ token.word
-    end
-    return nil
-  end
-  
-  def self.scan_for_times(token, options)
-    if token.word =~ /^\d{1,2}(:?\d{2})?([\.:]?\d{2})?$/
-      return Chronic::RepeaterTime.new(token.word, options)
-    end
-    return nil
-  end
-  
-  def self.scan_for_units(token)
-    scanner = {/^years?$/ => :year,
-               /^seasons?$/ => :season,
-               /^months?$/ => :month,
-               /^fortnights?$/ => :fortnight,
-               /^weeks?$/ => :week,
-               /^weekends?$/ => :weekend,
-               /^days?$/ => :day,
-               /^hours?$/ => :hour,
-               /^minutes?$/ => :minute,
-               /^seconds?$/ => :second}
-    scanner.keys.each do |scanner_item|
-      if scanner_item =~ token.word
-        klass_name = 'Chronic::Repeater' + scanner[scanner_item].to_s.capitalize
-        klass = eval(klass_name)
-        return klass.new(scanner[scanner_item]) 
-      end
-    end
-    return nil
-  end
-  
+<?php
+class Horde_Date_Parser_Locale_Base_Repeater extends Horde_Date_Parser_Tag
+{
+    public $monthNameScanner = array(
+        '/^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',
+    );
+
+    public $dayNameScanner = array(
+        '/^jan\.?(uary)?$/' => 'january',
+        '/^m[ou]n(day)?$/' => 'monday',
+        '/^t(ue|eu|oo|u|)s(day)?$/' => 'tuesday',
+        '/^tue$/' => 'tuesday',
+        '/^we(dnes|nds|nns)day$/' => 'wednesday',
+        '/^wed$/' => 'wednesday',
+        '/^th(urs|ers)day$/' => 'thursday',
+        '/^thu$/' => 'thursday',
+        '/^fr[iy](day)?$/' => 'friday',
+        '/^sat(t?[ue]rday)?$/' => 'saturday',
+        '/^su[nm](day)?$/' => 'sunday',
+    );
+
+    public $dayPortionScanner = array(
+        '/^ams?$/' => 'am',
+        '/^pms?$/' => 'pm',
+        '/^mornings?$/' => 'morning',
+        '/^afternoons?$/' => 'afternoon',
+        '/^evenings?$/' => 'evening',
+        '/^(night|nite)s?$/' => 'night',
+    );
+
+    public $unitScanner = array(
+        '/^years?$/' => 'year',
+        '/^seasons?$/' => 'season',
+        '/^months?$/' => 'month',
+        '/^fortnights?$/' => 'fortnight',
+        '/^weeks?$/' => 'week',
+        '/^weekends?$/' => 'weekend',
+        '/^days?$/' => 'day',
+        '/^hours?$/' => 'hour',
+        '/^minutes?$/' => 'minute',
+        '/^seconds?$/' => 'second',
+    );
+
+    public $timeRegex = '/^\d{1,2}(:?\d{2})?([\.:]?\d{2})?$/';
+
+
+    public function scan($tokens, $options)
+    {
+        foreach ($tokens as &$token) {
+            if ($t = $this->scanForMonthNames($token)) {
+                $token->tag($t);
+            } elseif ($t = $this->scanForDayNames($token)) {
+                $token->tag($t);
+            } elseif ($t = $this->scanForDayPortions($token)) {
+                $token->tag($t);
+            } elseif ($t = $this->scanForTimes($token, $options)) {
+                $token->tag($t);
+            } elseif ($t = $this->scanForUnits($token)) {
+                $token->tag($t);
+            }
+        }
+        return $tokens;
+    }
+
+    public function scanForMonthNames($token)
+    {
+        foreach ($this->monthNameScanner as $scannerItem => $scannerTag) {
+            if (preg_match($scannerItem, $token->word)) {
+                return new Horde_Date_Parser_Locale_Base_Repeater_MonthName($scannerTag);
+            }
+        }
+    }
+
+    public function scanForDayNames($token)
+    {
+        foreach ($this->dayNameScanner as $scannerItem => $scannerTag) {
+            if (preg_match($scannerItem, $token->word)) {
+                return new Horde_Date_Parser_Locale_Base_Repeater_DayName($scannerTag);
+            }
+        }
+    }
+
+    public function scanForDayPortions($token)
+    {
+        foreach ($this->dayPortionScanner as $scannerItem => $scannerTag) {
+            if (preg_match($scannerItem, $token->word)) {
+                return new Horde_Date_Parser_Locale_Base_Repeater_DayPortion($scannerTag);
+            }
+        }
+    }
+
+    public function scanForTimes($token, $options)
+    {
+        if (preg_match($this->timeRegex, $token->word)) {
+            return new Horde_Date_Parser_Locale_Base_Repeater_Time($token->word, $options);
+        }
+    }
+
+    public function scanForUnits($token)
+    {
+        foreach ($this->uniScanner as $scannerItem => $scannerTag) {
+            if (preg_match($scannerItem, $token->word)) {
+                $class = 'Horde_Date_Parser_Locale_Base_Repeater_' . ucfirst($scannerTag);
+                return new $class($scannerTag);
+            }
+        }
+    }
+
+    /*
   def <=>(other)
     width <=> other.width
   end
-  
-  # returns the width (in seconds or months) of this repeatable.
-  def width
-    raise("Repeatable#width must be overridden in subclasses")
-  end
-  
-  # returns the next occurance of this repeatable.
-  def next(pointer)
-    !@now.nil? || raise("Start point must be set before calling #next")
-    [:future, :none, :past].include?(pointer) || raise("First argument 'pointer' must be one of :past or :future")
-    #raise("Repeatable#next must be overridden in subclasses")
-  end
-  
-  def this(pointer)
-    !@now.nil? || raise("Start point must be set before calling #this")
-    [:future, :past, :none].include?(pointer) || raise("First argument 'pointer' must be one of :past, :future, :none")
-  end
-  
-  def to_s
-    'repeater'
-  end
-end
\ No newline at end of file
+    */
+
+    /**
+     * returns the width (in seconds or months) of this repeatable.
+     */
+    public function width()
+    {
+        throw new Horde_Date_Parser_Exception('Repeatable#width must be overridden in subclasses');
+    }
+
+    /**
+     * returns the next occurance of this repeatable.
+     */
+    public function next($pointer)
+    {
+        if (is_null($this->now)) {
+            throw new Horde_Date_Parser_Exception('Start point must be set before calling next()');
+        }
+
+        if (!in_array($pointer, array('future', 'none', 'past'))) {
+            throw new Horde_Date_Parser_Exception("First argument 'pointer' must be one of 'past', 'future', 'none'");
+        }
+    }
+
+    public function this($pointer)
+    {
+        if (is_null($this->now)) {
+            throw new Horde_Date_Parser_Exception('Start point must be set before calling this()');
+        }
+
+        if (!in_array($pointer, array('future', 'none', 'past'))) {
+            throw new Horde_Date_Parser_Exception("First argument 'pointer' must be one of 'past', 'future', 'none'");
+        }
+    }
+
+    public function __toString()
+    {
+        return 'repeater';
+    }
+
+}