--- /dev/null
+#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 + "}";
+}
+
+};
--- /dev/null
+#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
PinyinParser.cc \
PinyinProperties.cc \
SimpTradConverter.cc \
- SpecialTable.cc \
+ DynamicSpecialPhrase.cc \
+ SpecialPhraseTable.cc \
$(NULL)
ibus_engine_built_h_sources = \
PinyinParserTable.h \
Property.h \
SimpTradConverter.h \
SimpTradConverterTable.h \
- SpecialTable.h \
+ SpecialPhrase.h \
+ StaticSpecialPhrase.h \
+ DynamicSpecialPhrase.h \
+ SpecialPhraseTable.h \
String.h \
Text.h \
Types.h \
#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:
m_special_phrases.clear ();
if (begin < end) {
- SpecialTable::instance ().lookup (
+ SpecialPhraseTable::instance ().lookup (
m_text.substr (begin, m_cursor - begin),
m_special_phrases);
}
#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:
};
-SpecialTable::SpecialTable (void)
+SpecialPhraseTable::SpecialPhraseTable (void)
{
gchar * path = g_build_filename (g_get_user_config_dir (),
"ibus", "ibus-pinyin", "phrases.txt", NULL);
}
gboolean
-SpecialTable::load (const gchar *file)
+SpecialPhraseTable::load (const gchar *file)
{
std::ifstream in (file);
if (in.fail ())
#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 ();
}
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 ();
--- /dev/null
+#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
--- /dev/null
+#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;
+}
+
+};
+
-#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);
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;
Map m_map;
private:
- static SpecialTable m_instance;
+ static SpecialPhraseTable m_instance;
};
};