[california/wip/725792-quick-add] Cleanup. Make life easier for translators.



commit 55ffb13d484d06b1232cf04adfa7d20292e5722e
Author: Jim Nelson <jim yorba org>
Date:   Mon Apr 21 16:44:42 2014 -0700

    Cleanup.  Make life easier for translators.

 src/calendar/calendar-day-of-week.vala         |   29 ++++++------
 src/calendar/calendar-month.vala               |   30 +++++++------
 src/calendar/calendar.vala                     |   15 +++----
 src/collection/collection-lookahead-stack.vala |    4 +-
 src/component/component-details-parser.vala    |   20 +++++---
 src/component/component.vala                   |   58 ++++++++++++------------
 src/util/util-string.vala                      |    8 +++
 7 files changed, 89 insertions(+), 75 deletions(-)
---
diff --git a/src/calendar/calendar-day-of-week.vala b/src/calendar/calendar-day-of-week.vala
index dae4e05..4c2024c 100644
--- a/src/calendar/calendar-day-of-week.vala
+++ b/src/calendar/calendar-day-of-week.vala
@@ -59,6 +59,8 @@ public class DayOfWeek : BaseObject, Gee.Hashable<DayOfWeek> {
     private static DayOfWeek[]? days_of_week_monday = null;
     private static DayOfWeek[]? days_of_week_sunday = null;
     
+    private static Gee.Map<string, DayOfWeek> parse_map;
+    
     /**
      * The abbreviated locale-specific name for the day of the week.
      */
@@ -110,10 +112,18 @@ public class DayOfWeek : BaseObject, Gee.Hashable<DayOfWeek> {
             date.add_days(1);
         }
         
+        parse_map = new Gee.HashMap<string, DayOfWeek>(String.ci_hash, String.ci_equal);
+        
         // Following GLib's lead, days of week Monday-first is straightforward
         days_of_week_monday = new DayOfWeek[COUNT];
-        for (int ctr = MIN; ctr <= MAX; ctr++)
-            days_of_week_monday[ctr - MIN] = new DayOfWeek(ctr, abbrevs[ctr - MIN], fulls[ctr - MIN]);
+        for (int ctr = MIN; ctr <= MAX; ctr++) {
+            DayOfWeek dow = new DayOfWeek(ctr, abbrevs[ctr - MIN], fulls[ctr - MIN]);
+            days_of_week_monday[ctr - MIN] = dow;
+            
+            // add to parse map by abbreivated and full name
+            parse_map.set(dow.abbrev_name, dow);
+            parse_map.set(dow.full_name, dow);
+        }
         
         MON = days_of_week_monday[0];
         TUE = days_of_week_monday[1];
@@ -182,20 +192,11 @@ public class DayOfWeek : BaseObject, Gee.Hashable<DayOfWeek> {
     /**
      * Parses the string looking for a match with any of the { link DayOfWeek}'s { link abbrev_name}
      * or { link full_name}.
+     *
+     * parse() is case-insensitive.
      */
     public static DayOfWeek? parse(string str) {
-        string token = str.strip().casefold();
-        
-        // a lookup map may make sense here
-        foreach (DayOfWeek dow in days_of_week_monday) {
-            if (dow.abbrev_name.casefold() == token)
-                return dow;
-            
-            if (dow.full_name.casefold() == token)
-                return dow;
-        }
-        
-        return null;
+        return parse_map.get(str);
     }
     
     /**
diff --git a/src/calendar/calendar-month.vala b/src/calendar/calendar-month.vala
index ffdca5a..536cad9 100644
--- a/src/calendar/calendar-month.vala
+++ b/src/calendar/calendar-month.vala
@@ -24,6 +24,8 @@ public class Month : BaseObject, Gee.Comparable<Month>, Gee.Hashable<Month> {
     public static Month NOV;
     public static Month DEC;
     
+    private static Gee.Map<string, Month> parse_map;
+    
     public const int MIN = 1;
     public const int MAX = 12;
     public const int COUNT = MAX - MIN + 1;
@@ -78,9 +80,17 @@ public class Month : BaseObject, Gee.Comparable<Month>, Gee.Hashable<Month> {
     }
     
     internal static void init() {
+        parse_map = new Gee.HashMap<string, Month>(String.ci_hash, String.ci_equal);
+        
         months = new Month[COUNT];
-        for (int ctr = MIN; ctr <= MAX; ctr++)
-            months[ctr - MIN] = new Month(ctr);
+        for (int ctr = MIN; ctr <= MAX; ctr++) {
+            Month month = new Month(ctr);
+            months[ctr - MIN] = month;
+            
+            // build parse map of abbreviated and full name to the Month
+            parse_map.set(month.abbrev_name, month);
+            parse_map.set(month.full_name, month);
+        }
         
         JAN = months[0];
         FEB = months[1];
@@ -97,6 +107,7 @@ public class Month : BaseObject, Gee.Comparable<Month>, Gee.Hashable<Month> {
     }
     
     internal static void terminate() {
+        parse_map = null;
         months = null;
         JAN = FEB = MAR = APR = MAY = JUN = JUL = AUG = SEP = OCT = NOV = DEC = null;
     }
@@ -134,20 +145,11 @@ public class Month : BaseObject, Gee.Comparable<Month>, Gee.Hashable<Month> {
     /**
      * Compares the supplied string with all translated { link Month} names, both { link abbrev_name}
      * and { link full_name}.
+     *
+     * parse() is case-insensitive.
      */
     public static Month? parse(string str) {
-        string casefolded = str.casefold();
-        
-        // a lookup map may make sense here
-        foreach (Month month in months) {
-            if (month.full_name.casefold() == casefolded)
-                return month;
-            
-            if (month.abbrev_name.casefold() == casefolded)
-                return month;
-        }
-        
-        return null;
+        return parse_map.get(str);
     }
     
     internal inline DateMonth to_date_month() {
diff --git a/src/calendar/calendar.vala b/src/calendar/calendar.vala
index 7f0d1b5..112066e 100644
--- a/src/calendar/calendar.vala
+++ b/src/calendar/calendar.vala
@@ -137,19 +137,16 @@ public void init() throws Error {
     FMT_24HOUR_MIN_SEC = _("%d:%02d:%02d");
     
     // Used by quick-add to convert a user's day unit into an internal value.  Common abbreviations
-    // (without punctuation) should be included.  Each word must be separated by semi-colons and
-    // casefolded (lowercase).
-    UNIT_DAYS = _("day;days;").split(";");
+    // (without punctuation) should be included.  Each word must be separated by semi-colons.
+    UNIT_DAYS = _("day;days;").casefold().split(";");
     
     // Used by quick-add to convert a user's hours unit into an internal value.  Common abbreviations
-    // (without punctuation) should be included.  Each word must be separated by semi-colons and
-    // casefolded (lowercase).
-    UNIT_HOURS = _("hour;hours;hr;hrs").split(";");
+    // (without punctuation) should be included.  Each word must be separated by semi-colons.
+    UNIT_HOURS = _("hour;hours;hr;hrs").casefold().split(";");
     
     // Used by quick-add to convert a user's minute unit into an internal value.  Common abbreviations
-    // (without punctuation) should be included.  Each word must be separated by semi-colons and
-    // casefolded (lowercase).
-    UNIT_MINS = _("minute;minutes;min;mins").split(";");
+    // (without punctuation) should be included.  Each word must be separated by semi-colons.
+    UNIT_MINS = _("minute;minutes;min;mins").casefold().split(";");
     
     // return LC_MESSAGES back to proper locale and return LANGUAGE environment variable
     if (messages_locale != null)
diff --git a/src/collection/collection-lookahead-stack.vala b/src/collection/collection-lookahead-stack.vala
index 0b996ce..88bcf24 100644
--- a/src/collection/collection-lookahead-stack.vala
+++ b/src/collection/collection-lookahead-stack.vala
@@ -26,7 +26,7 @@ public class LookaheadStack<G> : BaseObject {
     public int size { get { return stack.size; } }
     
     /**
-     * Returns true if the stack is marked.
+     * Returns number of saved markpoints.
      *
      * @see mark
      */
@@ -112,7 +112,7 @@ public class LookaheadStack<G> : BaseObject {
      *
      * @see mark
      */
-    public void clear_marks() {
+    public void clear_markpoints() {
         markpoint = null;
         markpoints.clear();
     }
diff --git a/src/component/component-details-parser.vala b/src/component/component-details-parser.vala
index 7454ce6..6e6a722 100644
--- a/src/component/component-details-parser.vala
+++ b/src/component/component-details-parser.vala
@@ -43,6 +43,8 @@ public class DetailsParser : BaseObject {
     
     /**
      * The original string of text generating the { link event}.
+     *
+     * If null is passed to constructor, this will be the empty string.
      */
     public string details { get; private set; }
     
@@ -71,10 +73,10 @@ public class DetailsParser : BaseObject {
      * If the details string is empty, a blank Event is generated.
      */
     public DetailsParser(string? details) {
-        this.details = details;
+        this.details = details ?? "";
         
         // tokenize the string and arrange as a stack for the parser
-        string[] tokenized = String.reduce_whitespace(details ?? "").split(" ");
+        string[] tokenized = String.reduce_whitespace(this.details).split(" ");
         Gee.LinkedList<Token> list = new Gee.LinkedList<Token>();
         foreach (string token in tokenized)
             list.add(new Token(token));
@@ -123,7 +125,9 @@ public class DetailsParser : BaseObject {
             
             // only look for location prepositions if not already adding text to the location field
             if (!adding_location && token.casefolded in LOCATION_PREPOSITIONS) {
-                // add current token (the preposition) to summary but not location
+                // add current token (the preposition) to summary but not location (because location
+                // tokens are added to summary, i.e. "dinner at John's" yields "John's" for location
+                // and "dinner at John's" for summary)
                 add_text(token);
                 
                 // now adding to both summary and location
@@ -190,7 +194,7 @@ public class DetailsParser : BaseObject {
         debug("summary: \"%s\"", summary.str);
         debug("location: \"%s\"", location.str);
         
-        // Specify event start/end time, if specified
+        // Event start/end time, if specified
         if (start_time != null && end_time != null) {
             assert(start_date != null);
             assert(end_date != null);
@@ -209,14 +213,15 @@ public class DetailsParser : BaseObject {
         
         if (!String.is_empty(location.str))
             event.location = location.str;
+        
+        event.description = details;
     }
     
     private bool parse_time(Token? specifier, bool strict) {
         if (specifier == null)
             return false;
         
-        // go for the gusto and look for 2 or 3 specifiers in total, month and day or month/day/year
-        // in any order
+        // look for day/month specifiers, in any order
         stack.mark();
         {
             Token? second = stack.pop();
@@ -231,6 +236,7 @@ public class DetailsParser : BaseObject {
         }
         stack.restore();
         
+        // look for day/month/year specifiers
         stack.mark();
         {
             Token? second = stack.pop();
@@ -391,7 +397,7 @@ public class DetailsParser : BaseObject {
         // a *sane* year
         int year = int.parse(yr.casefolded);
         int current_year = Calendar.System.today.year.value;
-        if (year < (current_year - 1) || (year > current_year + 6))
+        if (year < (current_year - 1) || (year > current_year + 10))
             return null;
         
         return parse_day_month(day, mon, new Calendar.Year(year));
diff --git a/src/component/component.vala b/src/component/component.vala
index e929eda..850e897 100644
--- a/src/component/component.vala
+++ b/src/component/component.vala
@@ -17,9 +17,9 @@ namespace California.Component {
 
 private int init_count = 0;
 
-private unowned string TODAY;
-private unowned string TOMORROW;
-private unowned string YESTERDAY;
+private string TODAY;
+private string TOMORROW;
+private string YESTERDAY;
 private string[] TIME_PREPOSITIONS;
 private string[] LOCATION_PREPOSITIONS;
 private string[] DURATION_PREPOSITIONS;
@@ -34,62 +34,62 @@ public void init() throws Error {
     Collection.init();
     Calendar.init();
     
-    // Used by quick-add to indicate the user wants to create an event for today.  Should be
-    // casefolded (lowercase).
-    TODAY = _("today");
+    // Used by quick-add to indicate the user wants to create an event for today.
+    TODAY = _("today").casefold();
     
-    // Used by quick-add to indicate the user wants to create an event for tomorrow.  Should be
-    // casefolded (lowercase).
-    TOMORROW = _("tomorrow");
+    // Used by quick-add to indicate the user wants to create an event for tomorrow.
+    TOMORROW = _("tomorrow").casefold();
     
-    // Used by quick-add to indicate the user wants to create an event for yesterday.  Should be
-    // casefolded (lowercase).
-    YESTERDAY = _("yesterday");
+    // Used by quick-add to indicate the user wants to create an event for yesterday.
+    YESTERDAY = _("yesterday").casefold();
     
     // Used by quick-add to determine if the word is a time-based preposition (indicating a
-    // specific time, not a duration).  Each word must be separated by semi-colons.  All
-    // words should be casefolded (lowercase).  It's allowable for some or all of these words to
+    // specific time, not a duration).  Each word must be separated by semi-colons.
+    // It's allowable for some or all of these words to
     // be duplicated in the location prepositions list (elsewhere) but not another time list.
     // The list can be empty, but that will limit the parser.
     // Examples: "at 9am", "from 10pm to 11:30pm", "on monday"
-    TIME_PREPOSITIONS = _("at;from;to;on;").split(";");
+    TIME_PREPOSITIONS = _("at;from;to;on;").casefold().split(";");
     
     // Used by quick-add to determine if the word is a duration-based preposition (indicating a
-    // a duration, not a specific time).  Each word must be separated by semi-colons.  All
-    // words should be casefolded (lowercase).  It's allowable for some or all of these words to
+    // a duration, not a specific time).  Each word must be separated by semi-colons.
+    // It's allowable for some or all of these words to
     // be duplicated in the location prepositions list (elsewhere) but not another time list.
     // The list can be empty, but that will limit the parser.
     // Examples: "for 3 hours", "for 90 minutes"
-    DURATION_PREPOSITIONS = _("for;").split(";");
+    DURATION_PREPOSITIONS = _("for;").casefold().split(";");
     
     // Used by quick-add to determine if the word is a delay preposition (indicating a specific
-    // time from the current moment).  Each word must be separated by semi-colons.  All
-    // words should be casefolded (lowercase).  It's allowable for some or all of these words to
+    // time from the current moment).  Each word must be separated by semi-colons.
+    // It's allowable for some or all of these words to
     // be duplicated in the location prepositions list (elsewhere) but not another time list.
     // The list can be empty, but that will limit the parser.
     // Example: "in 3 hours" (meaning 3 hours from now)
-    DELAY_PREPOSITIONS = _("in;").split(";");
+    DELAY_PREPOSITIONS = _("in;").casefold().split(";");
     
     // Used by quick-add to determine if the word is a location-based preposition (indicating a
-    // specific place).  Each word must be separated by semi-colons.  All words should be
-    // casefolded (lowercase).  It's allowable for some or all of these words to be duplicated in
+    // specific place).  Each word must be separated by semi-colons.
+    // It's allowable for some or all of these words to be duplicated in
     // the time prepositions list (elsewhere).  The list can be empty, but that will limit the
     // parser.
     // Example: "at supermarket", "at Eiffel Tower"
-    LOCATION_PREPOSITIONS = _("at;").split(";");
+    LOCATION_PREPOSITIONS = _("at;").casefold().split(";");
     
-    // Used by quick-add to strip date numbers of common ordinal suffices.  All suffixes should
-    // be casefolded (lowercase) and delimited by semi-colons.  The list can be empty, but that
-    // will limit the parser if your language supports ordinal suffixes.
+    // Used by quick-add to strip date numbers of common ordinal suffices.  Each word must be
+    // separated by semi-colons.
+    // The list can be empty, but that will limit the parser if your language supports ordinal
+    // suffixes.
     // Example: "1st", "2nd", "3rd", "4th"
-    ORDINAL_SUFFIXES = _("st;nd;rd;th").split(";");
+    ORDINAL_SUFFIXES = _("st;nd;rd;th").casefold().split(";");
 }
 
 public void terminate() {
     if (!Unit.do_terminate(ref init_count))
         return;
     
-    TIME_PREPOSITIONS = LOCATION_PREPOSITIONS = DURATION_PREPOSITIONS = ORDINAL_SUFFIXES = null;
+    TIME_PREPOSITIONS = LOCATION_PREPOSITIONS = DURATION_PREPOSITIONS = ORDINAL_SUFFIXES =
+        DELAY_PREPOSITIONS =null;
+    TODAY = TOMORROW = YESTERDAY = null;
     
     Calendar.terminate();
     Collection.terminate();
diff --git a/src/util/util-string.vala b/src/util/util-string.vala
index 781b236..b9561af 100644
--- a/src/util/util-string.vala
+++ b/src/util/util-string.vala
@@ -16,6 +16,14 @@ public int stricmp(string a, string b) {
     return strcmp(a.casefold(), b.casefold());
 }
 
+public uint ci_hash(string str) {
+    return str.casefold().hash();
+}
+
+public bool ci_equal(string a, string b) {
+    return stricmp(a, b) == 0;
+}
+
 /**
  * Removes redundant whitespace (including tabs and newlines) and strips whitespace from beginning
  * and end of string.


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]