Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

refactor(InputMacro): introduce InputMacro classes for grouping #99

Merged
merged 4 commits into from
Dec 18, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
refactor(InputMacro): provide formatWithPattern and formatWithStyle
* extract common tasks from formatDate and formatTime into formatWithStyle
  for more generic formatting.
* add a new formatWithPattern helper to format datetime with patterns
* implement THIS_YEAR/LAST_YEAR/NEXT_YEAR macros with formatWithPattern
  • Loading branch information
xatier committed Dec 18, 2023
commit 79b8ee03388069b8b293498457e59cdfc1f56f12
12 changes: 12 additions & 0 deletions data/data.txt
Original file line number Diff line number Diff line change
@@ -16788,6 +16788,10 @@ _punctuation_~ ~ 0.0
ㄇㄧㄥˊ-ㄋㄧㄢˊ 明年 -4.10407541
ㄇㄧㄥˊ-ㄋㄧㄢˊ MACRO@NEXT_YEAR_GANZHI -8
ㄇㄧㄥˊ-ㄋㄧㄢˊ MACRO@NEXT_YEAR_CHINESE_ZODIAC -8
ㄇㄧㄥˊ-ㄋㄧㄢˊ MACRO@NEXT_YEAR_PLAIN -8
ㄇㄧㄥˊ-ㄋㄧㄢˊ MACRO@NEXT_YEAR_PLAIN_WITH_ERA -8
ㄇㄧㄥˊ-ㄋㄧㄢˊ MACRO@NEXT_YEAR_ROC -8
ㄇㄧㄥˊ-ㄋㄧㄢˊ MACRO@NEXT_YEAR_JAPANESE -8
ㄇㄧㄥˊ-ㄋㄧㄢˊ-ㄉㄜ˙ 明年的 -5.22522481
ㄇㄧㄥˊ-ㄋㄧㄢˊ-ㄍㄢ-ㄓ 明年干支 -8
ㄇㄧㄥˊ-ㄋㄧㄢˊ-ㄍㄢ-ㄓ MACRO@NEXT_YEAR_GANZHI -8
@@ -77433,6 +77437,10 @@ _punctuation_~ ~ 0.0
ㄐㄧㄣ-ㄋㄧㄢˊ 今年 -3.57582376
ㄐㄧㄣ-ㄋㄧㄢˊ MACRO@THIS_YEAR_GANZHI -8
ㄐㄧㄣ-ㄋㄧㄢˊ MACRO@THIS_YEAR_CHINESE_ZODIAC -8
ㄐㄧㄣ-ㄋㄧㄢˊ MACRO@THIS_YEAR_PLAIN -8
ㄐㄧㄣ-ㄋㄧㄢˊ MACRO@THIS_YEAR_PLAIN_WITH_ERA -8
ㄐㄧㄣ-ㄋㄧㄢˊ MACRO@THIS_YEAR_ROC -8
ㄐㄧㄣ-ㄋㄧㄢˊ MACRO@THIS_YEAR_JAPANESE -8
ㄐㄧㄣ-ㄋㄧㄢˊ-ㄍㄢ-ㄓ 今年干支 -8
ㄐㄧㄣ-ㄋㄧㄢˊ-ㄍㄢ-ㄓ MACRO@THIS_YEAR_GANZHI -8
ㄐㄧㄣ-ㄋㄧㄢˊ-ㄕㄥ-ㄒㄧㄠˋ 今年生肖 -8
@@ -85996,6 +86004,10 @@ _punctuation_~ ~ 0.0
ㄑㄩˋ-ㄋㄧㄢˊ 去年 -3.80140572
ㄑㄩˋ-ㄋㄧㄢˊ MACRO@LAST_YEAR_GANZHI -8
ㄑㄩˋ-ㄋㄧㄢˊ MACRO@LAST_YEAR_CHINESE_ZODIAC -8
ㄑㄩˋ-ㄋㄧㄢˊ MACRO@LAST_YEAR_PLAIN -8
ㄑㄩˋ-ㄋㄧㄢˊ MACRO@LAST_YEAR_PLAIN_WITH_ERA -8
ㄑㄩˋ-ㄋㄧㄢˊ MACRO@LAST_YEAR_ROC -8
ㄑㄩˋ-ㄋㄧㄢˊ MACRO@LAST_YEAR_JAPANESE -8
ㄑㄩˋ-ㄋㄧㄢˊ-ㄉㄜ˙ 去年的 -5.08542540
ㄑㄩˋ-ㄋㄧㄢˊ-ㄉㄨˋ 去年度 -5.82182190
ㄑㄩˋ-ㄋㄧㄢˊ-ㄍㄢ-ㄓ 去年干支 -8
174 changes: 151 additions & 23 deletions src/InputMacro.cpp
Original file line number Diff line number Diff line change
@@ -11,8 +11,9 @@

namespace McBopomofo {

std::string formatDate(std::string calendarName, int DayOffset,
std::string formatDate(std::string calendarName, int dayOffset,
icu::DateFormat::EStyle dateStyle);
std::string formatWithPattern(std::string calendarName, int yearOffset, int dateOffset, icu::UnicodeString pattern);
std::string formatTime(icu::DateFormat::EStyle timeStyle);
std::string formatTimeZone(icu::TimeZone::EDisplayType type);
int currentYear();
@@ -25,20 +26,40 @@ class InputMacroDate : public InputMacro {
icu::DateFormat::EStyle style)
: name_(macroName),
calendarName_(calendar),
DayOffset_(offset),
dayOffset_(offset),
dateStyle_(style) {}
std::string name() const override { return name_; }
std::string replacement() const override {
return formatDate(calendarName_, DayOffset_, dateStyle_);
return formatDate(calendarName_, dayOffset_, dateStyle_);
}

private:
std::string name_;
std::string calendarName_;
int DayOffset_;
int dayOffset_;
icu::DateFormat::EStyle dateStyle_;
};

class InputMacroYear : public InputMacro {
public:
InputMacroYear(std::string macroName, std::string calendar, int offset, icu::UnicodeString pattern)
: name_(macroName),
calendarName_(calendar),
yearOffset_(offset),
pattern_(pattern) {}
std::string name() const override { return name_; }
std::string replacement() const override {
return formatWithPattern(calendarName_, yearOffset_, /*dateOffset*/ 0, pattern_) + "年";
}

private:
std::string name_;
std::string calendarName_;
int yearOffset_;
// ref: https://unicode-org.github.io/icu/userguide/format_parse/datetime/index#datetime-format-syntax
icu::UnicodeString pattern_;
};

class InputMacroDateTime : public InputMacro {
public:
InputMacroDateTime(std::string macroName, icu::DateFormat::EStyle style)
@@ -204,6 +225,78 @@ class InputMacroDateTomorrowMediumJapanese : public InputMacroDate {
icu::DateFormat::EStyle::kMedium) {}
};

class InputMacroThisYearPlain : public InputMacroYear {
public:
InputMacroThisYearPlain()
: InputMacroYear("MACRO@THIS_YEAR_PLAIN", "", 0, "y") {}
};

class InputMacroThisYearPlainWithEra : public InputMacroYear {
public:
InputMacroThisYearPlainWithEra()
: InputMacroYear("MACRO@THIS_YEAR_PLAIN_WITH_ERA", "", 0, "Gy") {}
};

class InputMacroThisYearRoc : public InputMacroYear {
public:
InputMacroThisYearRoc()
: InputMacroYear("MACRO@THIS_YEAR_ROC", "roc", 0, "Gy") {}
};

class InputMacroThisYearJapanese : public InputMacroYear {
public:
InputMacroThisYearJapanese()
: InputMacroYear("MACRO@THIS_YEAR_JAPANESE", "japanese", 0, "Gy") {}
};

class InputMacroLastYearPlain : public InputMacroYear {
public:
InputMacroLastYearPlain()
: InputMacroYear("MACRO@LAST_YEAR_PLAIN", "", -1, "y") {}
};

class InputMacroLastYearPlainWithEra : public InputMacroYear {
public:
InputMacroLastYearPlainWithEra()
: InputMacroYear("MACRO@LAST_YEAR_PLAIN_WITH_ERA", "", -1, "Gy") {}
};

class InputMacroLastYearRoc : public InputMacroYear {
public:
InputMacroLastYearRoc()
: InputMacroYear("MACRO@LAST_YEAR_ROC", "roc", -1, "Gy") {}
};

class InputMacroLastYearJapanese : public InputMacroYear {
public:
InputMacroLastYearJapanese()
: InputMacroYear("MACRO@LAST_YEAR_JAPANESE", "japanese", -1, "Gy") {}
};

class InputMacroNextYearPlain : public InputMacroYear {
public:
InputMacroNextYearPlain()
: InputMacroYear("MACRO@NEXT_YEAR_PLAIN", "", 1, "y") {}
};

class InputMacroNextYearPlainWithEra : public InputMacroYear {
public:
InputMacroNextYearPlainWithEra()
: InputMacroYear("MACRO@NEXT_YEAR_PLAIN_WITH_ERA", "", 1, "Gy") {}
};

class InputMacroNextYearRoc : public InputMacroYear {
public:
InputMacroNextYearRoc()
: InputMacroYear("MACRO@NEXT_YEAR_ROC", "roc", 1, "Gy") {}
};

class InputMacroNextYearJapanese : public InputMacroYear {
public:
InputMacroNextYearJapanese()
: InputMacroYear("MACRO@NEXT_YEAR_JAPANESE", "japanese", 1, "Gy") {}
};

class InputMacroDateTimeNowShort : public InputMacroDateTime {
public:
InputMacroDateTimeNowShort()
@@ -282,6 +375,18 @@ InputMacroController::InputMacroController() {
AddMacro(macros_, std::make_unique<InputMacroDateTodayMediumRoc>());
AddMacro(macros_, std::make_unique<InputMacroDateTodayMediumChinese>());
AddMacro(macros_, std::make_unique<InputMacroDateTodayMediumJapanese>());
AddMacro(macros_, std::make_unique<InputMacroThisYearPlain>());
AddMacro(macros_, std::make_unique<InputMacroThisYearPlainWithEra>());
AddMacro(macros_, std::make_unique<InputMacroThisYearRoc>());
AddMacro(macros_, std::make_unique<InputMacroThisYearJapanese>());
AddMacro(macros_, std::make_unique<InputMacroLastYearPlain>());
AddMacro(macros_, std::make_unique<InputMacroLastYearPlainWithEra>());
AddMacro(macros_, std::make_unique<InputMacroLastYearRoc>());
AddMacro(macros_, std::make_unique<InputMacroLastYearJapanese>());
AddMacro(macros_, std::make_unique<InputMacroNextYearPlain>());
AddMacro(macros_, std::make_unique<InputMacroNextYearPlainWithEra>());
AddMacro(macros_, std::make_unique<InputMacroNextYearRoc>());
AddMacro(macros_, std::make_unique<InputMacroNextYearJapanese>());
AddMacro(macros_, std::make_unique<InputMacroDateYesterdayShort>());
AddMacro(macros_, std::make_unique<InputMacroDateYesterdayMedium>());
AddMacro(macros_, std::make_unique<InputMacroDateYesterdayMediumRoc>());
@@ -314,49 +419,72 @@ std::string InputMacroController::handle(std::string input) {
return input;
}

std::string formatDate(std::string calendarName, int DayOffset,
icu::DateFormat::EStyle dateStyle) {
UErrorCode status = U_ZERO_ERROR;
icu::TimeZone* timezone = icu::TimeZone::createDefault();
icu::Locale createLocale(std::string calendarName) {
std::string calendarNameBase =
calendarName == "japanese" ? "ja_JP" : "zh_Hant_TW";
if (!calendarName.empty()) {
calendarNameBase += "@calendar=" + calendarName;
}
return icu::Locale::createCanonical(calendarNameBase.c_str());
}

const icu::Locale locale =
icu::Locale::createCanonical(calendarNameBase.c_str());
std::unique_ptr<icu::Calendar> createCalendar(icu::Locale locale) {
UErrorCode status = U_ZERO_ERROR;
icu::TimeZone* timezone = icu::TimeZone::createDefault();
std::unique_ptr<icu::Calendar> calendar(icu::Calendar::createInstance(timezone, locale, status));
calendar->setTime(icu::Calendar::getNow(), status);
calendar->add(icu::Calendar::DATE, DayOffset, status);
return calendar;
}

std::string formatWithStyle(std::string calendarName, int yearOffset, int dayOffset,
icu::DateFormat::EStyle dateStyle,
icu::DateFormat::EStyle timeStyle) {
UErrorCode status = U_ZERO_ERROR;

const icu::Locale locale = createLocale(calendarName);
std::unique_ptr<icu::Calendar> calendar = createCalendar(locale);

calendar->add(icu::Calendar::YEAR, yearOffset, status);
calendar->add(icu::Calendar::DATE, dayOffset, status);

std::unique_ptr<icu::DateFormat> dateFormatter(icu::DateFormat::createDateTimeInstance(
dateStyle, icu::DateFormat::EStyle::kNone, locale));
dateStyle, timeStyle, locale));
icu::UnicodeString formattedDate;
icu::FieldPosition fieldPosition;
dateFormatter->format(*calendar, formattedDate, fieldPosition);

std::string output;
formattedDate.toUTF8String(output);
return output;
}

std::string formatTime(icu::DateFormat::EStyle timeStyle) {
std::string formatWithPattern(std::string calendarName, int yearOffset, int dateOffset, icu::UnicodeString pattern) {
UErrorCode status = U_ZERO_ERROR;
icu::TimeZone* timezone = icu::TimeZone::createDefault();
std::string calendarNameBase = "zh_Hant_TW";
const icu::Locale locale =
icu::Locale::createCanonical(calendarNameBase.c_str());
std::unique_ptr<icu::Calendar> calendar(icu::Calendar::createInstance(timezone, locale, status));
calendar->setTime(icu::Calendar::getNow(), status);
std::unique_ptr<icu::DateFormat> dateFormatter(icu::DateFormat::createDateTimeInstance(
icu::DateFormat::EStyle::kNone, timeStyle, locale));

const icu::Locale locale = createLocale(calendarName);
std::unique_ptr<icu::Calendar> calendar = createCalendar(locale);

calendar->add(icu::Calendar::YEAR, yearOffset, status);
calendar->add(icu::Calendar::DATE, dateOffset, status);

icu::SimpleDateFormat dateFormatter(pattern, locale, status);
icu::UnicodeString formattedDate;
icu::FieldPosition fieldPosition;
dateFormatter->format(*calendar, formattedDate, fieldPosition);
dateFormatter.format(calendar->getTime(status), formattedDate, status);

std::string output;
formattedDate.toUTF8String(output);
return output;
}

std::string formatDate(std::string calendarName, int dayOffset,
icu::DateFormat::EStyle dateStyle) {
return formatWithStyle(calendarName, /*yearOffset*/ 0, dayOffset, dateStyle, /*timeStyle*/ icu::DateFormat::EStyle::kNone);
}

std::string formatTime(icu::DateFormat::EStyle timeStyle) {
return formatWithStyle(/*calendarName*/ "", /*yearOffset*/ 0, /*dayOffset*/ 0, /*dateStyle*/ icu::DateFormat::EStyle::kNone, timeStyle);
}

std::string formatTimeZone(icu::TimeZone::EDisplayType type) {
std::unique_ptr<icu::TimeZone> timezone(icu::TimeZone::createDefault());
const icu::Locale locale = icu::Locale::createCanonical("zh_Hant_TW");