Split SpecialTable.{h, cc}
authorPeng Huang <shawn.p.huang@gmail.com>
Thu, 15 Apr 2010 03:02:07 +0000 (11:02 +0800)
committerPeng Huang <shawn.p.huang@gmail.com>
Thu, 15 Apr 2010 03:02:07 +0000 (11:02 +0800)
src/DynamicSpecialPhrase.cc [new file with mode: 0644]
src/DynamicSpecialPhrase.h [new file with mode: 0644]
src/Makefile.am
src/PinyinEditor.h
src/SpecialPhrase.cc [moved from src/SpecialTable.cc with 94% similarity]
src/SpecialPhrase.h [new file with mode: 0644]
src/SpecialPhraseTable.cc [new file with mode: 0644]
src/SpecialPhraseTable.h [moved from src/SpecialTable.h with 52% similarity]

diff --git a/src/DynamicSpecialPhrase.cc b/src/DynamicSpecialPhrase.cc
new file mode 100644 (file)
index 0000000..f7b6b4f
--- /dev/null
@@ -0,0 +1,183 @@
+#include <ctime>
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+#include "DynamicSpecialPhrase.h"
+
+namespace PY {
+
+std::string
+DynamicSpecialPhrase::text (void)
+{
+    /* get the current time */
+    std::time (&m_time);
+
+    std::string result;
+
+    size_t pos = 0;
+    size_t pnext;
+    gint s = 0;
+    while (s != 2) {
+        switch (s) {
+        case 0:
+            pnext = m_text.find ("${", pos);
+            if (pnext == m_text.npos) {
+                result += m_text.substr (pos);
+                s = 2;
+            }
+            else {
+                result += m_text.substr (pos, pnext - pos);
+                pos = pnext + 2;
+                s = 1;
+            }
+            break;
+        case 1:
+            pnext = m_text.find ("}", pos);
+            if (pnext == m_text.npos) {
+                result += "${";
+                result += m_text.substr (pos);
+                s = 2;
+            }
+            else {
+                result += variable (m_text.substr(pos, pnext - pos));
+                pos = pnext + 1;
+                s = 0;
+            }
+            break;
+        default:
+            g_assert_not_reached ();
+        }
+    }
+    return result;
+}
+
+inline const std::string
+DynamicSpecialPhrase::dec (gint d, const gchar *fmt)
+{
+    char string [32];
+    std::snprintf (string, sizeof (string), fmt, d);
+    return string;
+}
+
+inline const std::string
+DynamicSpecialPhrase::year_cn (gboolean yy)
+{
+    static const gchar * digits[] = {
+        "〇", "一", "二", "三", "四",
+        "五", "六", "七", "八", "九"
+    };
+
+    gint year = localtime (&m_time)->tm_year + 1900;
+    gint bit = 0;
+    if (yy) {
+        year %= 100;
+        bit = 2;
+    }
+
+    std::string result;
+    while (year != 0 || bit > 0) {
+        result.insert(0, digits[year % 10]);
+        year /= 10;
+        bit -= 1;
+    }
+    return result;
+}
+
+inline const std::string
+DynamicSpecialPhrase::month_cn (void)
+{
+    static const gchar *month_num[] = {
+        "一", "二", "三", "四", "五", "六", "七", "八",
+        "九", "十", "十一", "十二"
+    };
+    return month_num[localtime (&m_time)->tm_mon];
+}
+
+inline const std::string
+DynamicSpecialPhrase::weekday_cn (void)
+{
+    static const gchar *week_num[] = {
+        "日", "一", "二", "三", "四", "五", "六"
+    };
+    return week_num[localtime (&m_time)->tm_wday];
+}
+
+inline const std::string
+DynamicSpecialPhrase::hour_cn (guint i)
+{
+    static const gchar *hour_num[] = {
+        "零", "一", "二", "三", "四",
+        "五", "六", "七", "八", "九",
+        "十", "十一", "十二", "十三", "十四",
+        "十五", "十六", "十七", "十八", "十九",
+        "二十", "二十一", "二十二", "二十三",
+    };
+    return hour_num[i];
+}
+
+inline const std::string
+DynamicSpecialPhrase::fullhour_cn (void)
+{
+    return hour_cn (localtime (&m_time)->tm_hour);
+}
+
+inline const std::string
+DynamicSpecialPhrase::halfhour_cn (void)
+{
+    return hour_cn (localtime (&m_time)->tm_hour % 12);
+}
+
+inline const std::string
+DynamicSpecialPhrase::day_cn (void)
+{
+    static const gchar *day_num[] = {
+        "", "一", "二", "三", "四",
+        "五", "六", "七", "八", "九",
+        "", "十","二十", "三十"
+    };
+    guint day = localtime (&m_time)->tm_mday;
+    return std::string (day_num[day / 10 + 10]) + day_num[day % 10];
+}
+
+inline const std::string
+DynamicSpecialPhrase::minsec_cn (guint i)
+{
+    static const gchar *num[] = {
+        "", "一", "二", "三", "四",
+        "五", "六", "七", "八", "九",
+        "零", "十","二十", "三十", "四十"
+        "五十", "六十"
+    };
+    return std::string (num[i / 10 + 10]) + num[i % 10];
+}
+
+inline const std::string
+DynamicSpecialPhrase::variable (const std::string &name)
+{
+    if (name == "year")     return dec (localtime (&m_time)->tm_year + 1900);
+    if (name == "year_yy")  return dec ((localtime (&m_time)->tm_year + 1900) % 100, "%02d");
+    if (name == "month")    return dec (localtime (&m_time)->tm_mon + 1);
+    if (name == "month_mm") return dec (localtime (&m_time)->tm_mon + 1, "%02d");
+    if (name == "day")      return dec (localtime (&m_time)->tm_mday);
+    if (name == "day_dd")   return dec (localtime (&m_time)->tm_mday, "%02d");
+    if (name == "weekday")  return dec (localtime (&m_time)->tm_wday + 1);
+    if (name == "fullhour") return dec (localtime (&m_time)->tm_hour, "%02d");
+    if (name == "falfhour") return dec (localtime (&m_time)->tm_hour % 12, "%02d");
+    if (name == "ampm")     return localtime (&m_time)->tm_hour < 12 ? "AM" : "PM";
+    if (name == "minute")   return dec (localtime (&m_time)->tm_min, "%02d");
+    if (name == "second")   return dec (localtime (&m_time)->tm_sec, "%02d");
+    if (name == "year_cn")      return year_cn ();
+    if (name == "year_yy_cn")   return year_cn (TRUE);
+    if (name == "month_cn")     return month_cn ();
+    if (name == "day_cn")       return day_cn ();
+    if (name == "weekday_cn")   return weekday_cn ();
+    if (name == "fullhour_cn")  return fullhour_cn ();
+    if (name == "halfhour_cn")  return halfhour_cn ();
+    if (name == "ampm_cn")      return localtime (&m_time)->tm_hour < 12 ? "上午" : "下午";
+    if (name == "minute_cn")    return minsec_cn (localtime (&m_time)->tm_min);
+    if (name == "second_cn")    return minsec_cn (localtime (&m_time)->tm_sec);
+
+    return "${" + name + "}";
+}
+
+};
diff --git a/src/DynamicSpecialPhrase.h b/src/DynamicSpecialPhrase.h
new file mode 100644 (file)
index 0000000..5ffe49c
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef __DYNAMIC_SPECIAL_PHRASE_H_
+#define __DYNAMIC_SPECIAL_PHRASE_H_
+
+#include <ctime>
+#include <string>
+#include <glib.h>
+#include "SpecialPhrase.h"
+
+namespace PY {
+
+class DynamicSpecialPhrase : public SpecialPhrase {
+public:
+    DynamicSpecialPhrase (const std::string &text, guint pos) :
+        SpecialPhrase (pos), m_text (text) { }
+
+    std::string text (void);
+    const std::string dec (gint d, const gchar *fmt = "%d");
+    const std::string year_cn (gboolean yy = FALSE);
+    const std::string month_cn (void);
+    const std::string weekday_cn (void);
+    const std::string hour_cn (guint i);
+    const std::string fullhour_cn (void);
+    const std::string halfhour_cn (void);
+    const std::string day_cn (void);
+    const std::string minsec_cn (guint i);
+    const std::string variable (const std::string &name);
+
+private:
+    std::string m_text;
+    time_t m_time;
+};
+
+};
+#endif
index bd3329a..1bdbb29 100644 (file)
@@ -51,7 +51,8 @@ ibus_engine_c_sources = \
        PinyinParser.cc \
        PinyinProperties.cc \
        SimpTradConverter.cc \
-       SpecialTable.cc \
+       DynamicSpecialPhrase.cc \
+       SpecialPhraseTable.cc \
        $(NULL)
 ibus_engine_built_h_sources = \
        PinyinParserTable.h \
@@ -86,7 +87,10 @@ ibus_engine_h_sources = \
        Property.h \
        SimpTradConverter.h \
        SimpTradConverterTable.h \
-       SpecialTable.h \
+       SpecialPhrase.h \
+       StaticSpecialPhrase.h \
+       DynamicSpecialPhrase.h \
+       SpecialPhraseTable.h \
        String.h \
        Text.h \
        Types.h \
index aaa2f8a..1ae3fb0 100644 (file)
@@ -6,13 +6,13 @@
 #include "Database.h"
 #include "PinyinParser.h"
 #include "PhraseEditor.h"
-#include "SpecialTable.h"
+#include "SpecialPhraseTable.h"
 
 namespace PY {
 
 #define MAX_PINYIN_LEN 64
 
-class SpecialTable;
+class SpecialPhraseTable;
 
 class PinyinEditor : public Editor {
 public:
@@ -56,7 +56,7 @@ protected:
 
         m_special_phrases.clear ();
         if (begin < end) {
-            SpecialTable::instance ().lookup (
+            SpecialPhraseTable::instance ().lookup (
                 m_text.substr (begin, m_cursor - begin),
                 m_special_phrases);
         }
similarity index 94%
rename from src/SpecialTable.cc
rename to src/SpecialPhrase.cc
index 2cd6be9..125078d 100644 (file)
@@ -3,11 +3,11 @@
 #include <iostream>
 #include <fstream>
 #include <string>
-#include "SpecialTable.h"
+#include "SpecialPhraseTable.h"
 
 namespace PY {
 
-SpecialTable SpecialTable::m_instance;
+SpecialPhraseTable SpecialPhraseTable::m_instance;
 
 class StaticPhrase : public SpecialPhrase {
 public:
@@ -183,7 +183,7 @@ private:
 
 };
 
-SpecialTable::SpecialTable (void)
+SpecialPhraseTable::SpecialPhraseTable (void)
 {
     gchar * path = g_build_filename (g_get_user_config_dir (),
                         "ibus", "ibus-pinyin", "phrases.txt", NULL);
@@ -195,7 +195,7 @@ SpecialTable::SpecialTable (void)
 }
 
 gboolean
-SpecialTable::load (const gchar *file)
+SpecialPhraseTable::load (const gchar *file)
 {
     std::ifstream in (file);
     if (in.fail ())
@@ -235,8 +235,8 @@ phraseCmp (const SpecialPhrase *first,
 #endif
 
 void
-SpecialTable::insert (const std::string   &command,
-                      SpecialPhrase       *phrase)
+SpecialPhraseTable::insert (const std::string   &command,
+                            SpecialPhrase       *phrase)
 {
     if (m_map.find (command) == m_map.end ()) {
         m_map[command] = List ();
@@ -249,8 +249,8 @@ SpecialTable::insert (const std::string   &command,
 }
 
 gboolean
-SpecialTable::lookup (const std::string         &command,
-                      std::vector<std::string>  &result)
+SpecialPhraseTable::lookup (const std::string         &command,
+                            std::vector<std::string>  &result)
 {
     result.clear ();
 
diff --git a/src/SpecialPhrase.h b/src/SpecialPhrase.h
new file mode 100644 (file)
index 0000000..9126c6d
--- /dev/null
@@ -0,0 +1,24 @@
+#ifndef __PY_SPECIAL_PHRASE_H_
+#define __PY_SPECIAL_PHRASE_H_
+
+#include <string>
+#include <glib.h>
+
+namespace PY {
+
+class SpecialPhrase {
+public:
+    SpecialPhrase (guint pos) : m_position (pos) { }
+
+    guint position (void) const {
+        return m_position;
+    }
+
+    virtual std::string text (void) = 0;
+private:
+    guint m_position;
+};
+
+};
+
+#endif
diff --git a/src/SpecialPhraseTable.cc b/src/SpecialPhraseTable.cc
new file mode 100644 (file)
index 0000000..ca4c9b7
--- /dev/null
@@ -0,0 +1,270 @@
+#include <ctime>
+#include <cstdio>
+#include <iostream>
+#include <fstream>
+#include <string>
+#include "DynamicSpecialPhrase.h"
+#include "SpecialPhraseTable.h"
+
+namespace PY {
+
+SpecialPhraseTable SpecialPhraseTable::m_instance;
+
+class StaticSpecialPhrase : public SpecialPhrase {
+public:
+    StaticSpecialPhrase (const std::string &text, guint pos) :
+        SpecialPhrase (pos), m_text (text) { }
+
+    std::string text (void) { return m_text; }
+
+private:
+    std::string m_text;
+};
+
+class DynamicPhrase : public SpecialPhrase {
+public:
+    DynamicPhrase (const std::string &text, guint pos) :
+        SpecialPhrase (pos), m_text (text) { }
+
+    std::string text (void) {
+        /* get the current time */
+        std::time (&m_time);
+
+        std::string result;
+
+        size_t pos = 0;
+        size_t pnext;
+        gint s = 0;
+        while (s != 2) {
+            switch (s) {
+            case 0:
+                pnext = m_text.find ("${", pos);
+                if (pnext == m_text.npos) {
+                    result += m_text.substr (pos);
+                    s = 2;
+                }
+                else {
+                    result += m_text.substr (pos, pnext - pos);
+                    pos = pnext + 2;
+                    s = 1;
+                }
+                break;
+            case 1:
+                pnext = m_text.find ("}", pos);
+                if (pnext == m_text.npos) {
+                    result += "${";
+                    result += m_text.substr (pos);
+                    s = 2;
+                }
+                else {
+                    result += variable (m_text.substr(pos, pnext - pos));
+                    pos = pnext + 1;
+                    s = 0;
+                }
+                break;
+            default:
+                g_assert_not_reached ();
+            }
+        }
+        return result;
+    }
+
+    const std::string dec (gint d, const gchar *fmt = "%d") {
+        char string [32];
+        std::snprintf (string, sizeof (string), fmt, d);
+        return string;
+    }
+
+    const std::string year_cn (gboolean yy = FALSE) {
+        static const gchar * digits[] = {
+            "〇", "一", "二", "三", "四",
+            "五", "六", "七", "八", "九"
+        };
+
+        gint year = localtime (&m_time)->tm_year + 1900;
+        gint bit = 0;
+        if (yy) {
+            year %= 100;
+            bit = 2;
+        }
+
+        std::string result;
+        while (year != 0 || bit > 0) {
+            result.insert(0, digits[year % 10]);
+            year /= 10;
+            bit -= 1;
+        }
+        return result;
+    }
+
+    const std::string month_cn (void) {
+        static const gchar *month_num[] = {
+            "一", "二", "三", "四", "五", "六", "七", "八",
+            "九", "十", "十一", "十二"
+        };
+        return month_num[localtime (&m_time)->tm_mon];
+    }
+
+    const std::string weekday_cn (void) {
+        static const gchar *week_num[] = {
+            "日", "一", "二", "三", "四", "五", "六"
+        };
+        return week_num[localtime (&m_time)->tm_wday];
+    }
+
+    const std::string hour_cn (guint i) {
+        static const gchar *hour_num[] = {
+            "零", "一", "二", "三", "四",
+            "五", "六", "七", "八", "九",
+            "十", "十一", "十二", "十三", "十四",
+            "十五", "十六", "十七", "十八", "十九",
+            "二十", "二十一", "二十二", "二十三",
+        };
+        return hour_num[i];
+    }
+
+    const std::string fullhour_cn (void) {
+        return hour_cn (localtime (&m_time)->tm_hour);
+    }
+
+    const std::string halfhour_cn (void) {
+        return hour_cn (localtime (&m_time)->tm_hour % 12);
+    }
+
+    const std::string day_cn (void) {
+        static const gchar *day_num[] = {
+            "", "一", "二", "三", "四",
+            "五", "六", "七", "八", "九",
+            "", "十","二十", "三十"
+        };
+        guint day = localtime (&m_time)->tm_mday;
+        return std::string (day_num[day / 10 + 10]) + day_num[day % 10];
+    }
+
+    const std::string minsec_cn (guint i) {
+        static const gchar *num[] = {
+            "", "一", "二", "三", "四",
+            "五", "六", "七", "八", "九",
+            "零", "十","二十", "三十", "四十"
+            "五十", "六十"
+        };
+        return std::string (num[i / 10 + 10]) + num[i % 10];
+    }
+
+    const std::string variable (const std::string &name) {
+        if (name == "year")     return dec (localtime (&m_time)->tm_year + 1900);
+        if (name == "year_yy")  return dec ((localtime (&m_time)->tm_year + 1900) % 100, "%02d");
+        if (name == "month")    return dec (localtime (&m_time)->tm_mon + 1);
+        if (name == "month_mm") return dec (localtime (&m_time)->tm_mon + 1, "%02d");
+        if (name == "day")      return dec (localtime (&m_time)->tm_mday);
+        if (name == "day_dd")   return dec (localtime (&m_time)->tm_mday, "%02d");
+        if (name == "weekday")  return dec (localtime (&m_time)->tm_wday + 1);
+        if (name == "fullhour") return dec (localtime (&m_time)->tm_hour, "%02d");
+        if (name == "falfhour") return dec (localtime (&m_time)->tm_hour % 12, "%02d");
+        if (name == "ampm")     return localtime (&m_time)->tm_hour < 12 ? "AM" : "PM";
+        if (name == "minute")   return dec (localtime (&m_time)->tm_min, "%02d");
+        if (name == "second")   return dec (localtime (&m_time)->tm_sec, "%02d");
+        if (name == "year_cn")      return year_cn ();
+        if (name == "year_yy_cn")   return year_cn (TRUE);
+        if (name == "month_cn")     return month_cn ();
+        if (name == "day_cn")       return day_cn ();
+        if (name == "weekday_cn")   return weekday_cn ();
+        if (name == "fullhour_cn")  return fullhour_cn ();
+        if (name == "halfhour_cn")  return halfhour_cn ();
+        if (name == "ampm_cn")      return localtime (&m_time)->tm_hour < 12 ? "上午" : "下午";
+        if (name == "minute_cn")    return minsec_cn (localtime (&m_time)->tm_min);
+        if (name == "second_cn")    return minsec_cn (localtime (&m_time)->tm_sec);
+
+        return "${" + name + "}";
+    }
+
+private:
+    std::string m_text;
+    time_t m_time;
+
+};
+
+SpecialPhraseTable::SpecialPhraseTable (void)
+{
+    gchar * path = g_build_filename (g_get_user_config_dir (),
+                        "ibus", "ibus-pinyin", "phrases.txt", NULL);
+
+    load ("phrases.txt") ||
+    load (path) ||
+    load (PKGDATADIR G_DIR_SEPARATOR_S "phrases.txt");
+    g_free (path);
+}
+
+gboolean
+SpecialPhraseTable::load (const gchar *file)
+{
+    std::ifstream in (file);
+    if (in.fail ())
+        return FALSE;
+
+    std::string line;
+    while (!in.eof ()) {
+        getline (in, line);
+        if (line.size () == 0 || line[0] == ';')
+            continue;
+        size_t pos = line.find ('=');
+        if (pos == line.npos)
+            continue;
+
+        std::string command = line.substr(0, pos);
+        std::string phrase = line.substr(pos + 1);
+        if (command.empty () || phrase.empty ())
+            continue;
+
+        if (phrase[0] != '#') {
+            insert (command, new StaticSpecialPhrase (phrase, 0));
+        }
+        else if (phrase.size () > 1) {
+            insert (command, new DynamicPhrase (phrase.substr (1), 0));
+        }
+    }
+    return TRUE;
+}
+
+#if 0
+static bool
+phraseCmp (const SpecialPhrase *first,
+           const SpecialPhrase *second)
+{
+    return first->position () <= second->position ();
+}
+#endif
+
+void
+SpecialPhraseTable::insert (const std::string   &command,
+                            SpecialPhrase       *phrase)
+{
+    if (m_map.find (command) == m_map.end ()) {
+        m_map[command] = List ();
+    }
+    List & list = m_map[command];
+    list.push_back (phrase);
+#if 0
+    list.sort (phraseCmp);
+#endif
+}
+
+gboolean
+SpecialPhraseTable::lookup (const std::string         &command,
+                            std::vector<std::string>  &result)
+{
+    result.clear ();
+
+    if (m_map.find (command) == m_map.end ())
+        return FALSE;
+
+    List list = m_map[command];
+    for (List::iterator it = list.begin (); it != list.end (); it ++) {
+        result.push_back ((*it)->text ());
+    }
+
+    return result.size () > 0;
+}
+
+};
+
similarity index 52%
rename from src/SpecialTable.h
rename to src/SpecialPhraseTable.h
index 851d32e..f2da1c5 100644 (file)
@@ -1,30 +1,18 @@
-#ifndef __PY_SPECIAL_TABLE_H_
-#define __PY_SPECIAL_TABLE_H_
+#ifndef __PY_SPECIAL_PHRASE_TABLE_H_
+#define __PY_SPECIAL_PHRASE_TABLE_H_
 
 #include <map>
 #include <list>
 #include <string>
 #include <vector>
 #include <glib.h>
+#include "SpecialPhrase.h"
 
 namespace PY {
 
-class SpecialPhrase {
-public:
-    SpecialPhrase (guint pos) : m_position (pos) { }
-
-    guint position (void) const {
-        return m_position;
-    }
-
-    virtual std::string text (void) = 0;
-private:
-    guint m_position;
-};
-
-class SpecialTable {
+class SpecialPhraseTable {
 private:
-    SpecialTable (void);
+    SpecialPhraseTable (void);
 
 public:
     void insert (const std::string & command, SpecialPhrase *phrase);
@@ -34,7 +22,7 @@ private:
     gboolean load (const gchar *file);
 
 public:
-    static SpecialTable & instance (void) { return m_instance; }
+    static SpecialPhraseTable & instance (void) { return m_instance; }
 
 private:
     typedef std::list<SpecialPhrase *> List;
@@ -42,7 +30,7 @@ private:
     Map m_map;
 
 private:
-    static SpecialTable m_instance;
+    static SpecialPhraseTable m_instance;
 };
 
 };