diff --git a/McBopomofo.xcodeproj/project.pbxproj b/McBopomofo.xcodeproj/project.pbxproj index 64f9430c..38c42854 100644 --- a/McBopomofo.xcodeproj/project.pbxproj +++ b/McBopomofo.xcodeproj/project.pbxproj @@ -23,6 +23,10 @@ 6A2E40F9253A6AA000D1AE1D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6A2E40F5253A69DA00D1AE1D /* Images.xcassets */; }; 6A38BC1515FC117A00A8A51F /* data.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6A38BBF615FC117A00A8A51F /* data.txt */; }; 6A38BC2815FC158A00A8A51F /* InputMethodKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A38BC2715FC158A00A8A51F /* InputMethodKit.framework */; }; + 6A6ED16B2797650A0012872E /* template-phrases-replacement.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6A6ED1632797650A0012872E /* template-phrases-replacement.txt */; }; + 6A6ED16C2797650A0012872E /* template-data.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6A6ED1652797650A0012872E /* template-data.txt */; }; + 6A6ED16D2797650A0012872E /* template-exclude-phrases-plain-bpmf.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6A6ED1672797650A0012872E /* template-exclude-phrases-plain-bpmf.txt */; }; + 6A6ED16E2797650A0012872E /* template-exclude-phrases.txt in Resources */ = {isa = PBXBuildFile; fileRef = 6A6ED1692797650A0012872E /* template-exclude-phrases.txt */; }; 6ACA41CD15FC1D7500935EF6 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6A0D4EA615FC0D2D00ABF4B3 /* Cocoa.framework */; }; 6ACA41F915FC1D9000935EF6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6ACA41E915FC1D9000935EF6 /* AppDelegate.m */; }; 6ACA41FA15FC1D9000935EF6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6ACA41EA15FC1D9000935EF6 /* InfoPlist.strings */; }; @@ -146,6 +150,14 @@ 6A2E40F5253A69DA00D1AE1D /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 6A38BBF615FC117A00A8A51F /* data.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = data.txt; sourceTree = ""; }; 6A38BC2715FC158A00A8A51F /* InputMethodKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = InputMethodKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/InputMethodKit.framework; sourceTree = DEVELOPER_DIR; }; + 6A6ED1642797650A0012872E /* Base */ = {isa = PBXFileReference; lastKnownFileType = text; name = Base; path = "Base.lproj/template-phrases-replacement.txt"; sourceTree = ""; }; + 6A6ED1662797650A0012872E /* Base */ = {isa = PBXFileReference; lastKnownFileType = text; name = Base; path = "Base.lproj/template-data.txt"; sourceTree = ""; }; + 6A6ED1682797650A0012872E /* Base */ = {isa = PBXFileReference; lastKnownFileType = text; name = Base; path = "Base.lproj/template-exclude-phrases-plain-bpmf.txt"; sourceTree = ""; }; + 6A6ED16A2797650A0012872E /* Base */ = {isa = PBXFileReference; lastKnownFileType = text; name = Base; path = "Base.lproj/template-exclude-phrases.txt"; sourceTree = ""; }; + 6A6ED16F279765100012872E /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text; name = "zh-Hant"; path = "zh-Hant.lproj/template-data.txt"; sourceTree = ""; }; + 6A6ED170279765140012872E /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text; name = "zh-Hant"; path = "zh-Hant.lproj/template-exclude-phrases-plain-bpmf.txt"; sourceTree = ""; }; + 6A6ED171279765170012872E /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text; name = "zh-Hant"; path = "zh-Hant.lproj/template-exclude-phrases.txt"; sourceTree = ""; }; + 6A6ED1722797651A0012872E /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text; name = "zh-Hant"; path = "zh-Hant.lproj/template-phrases-replacement.txt"; sourceTree = ""; }; 6ACA41CB15FC1D7500935EF6 /* McBopomofoInstaller.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = McBopomofoInstaller.app; sourceTree = BUILT_PRODUCTS_DIR; }; 6ACA41E815FC1D9000935EF6 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = Source/Installer/AppDelegate.h; sourceTree = SOURCE_ROOT; }; 6ACA41E915FC1D9000935EF6 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = Source/Installer/AppDelegate.m; sourceTree = SOURCE_ROOT; }; @@ -379,6 +391,7 @@ 6A0D4F4715FC0EB900ABF4B3 /* Resources */ = { isa = PBXGroup; children = ( + 6A6ED162279764CD0012872E /* Custom Phrase Templates */, 6AFF97F0253B299E007F1C49 /* NonModalAlertWindowController.xib */, 6A0D4EEE15FC0DA600ABF4B3 /* Images */, 6A0D4EF515FC0DA600ABF4B3 /* McBopomofo-Info.plist */, @@ -399,6 +412,17 @@ path = Data; sourceTree = ""; }; + 6A6ED162279764CD0012872E /* Custom Phrase Templates */ = { + isa = PBXGroup; + children = ( + 6A6ED1652797650A0012872E /* template-data.txt */, + 6A6ED1672797650A0012872E /* template-exclude-phrases-plain-bpmf.txt */, + 6A6ED1692797650A0012872E /* template-exclude-phrases.txt */, + 6A6ED1632797650A0012872E /* template-phrases-replacement.txt */, + ); + name = "Custom Phrase Templates"; + sourceTree = ""; + }; 6ACA41E715FC1D9000935EF6 /* Installer */ = { isa = PBXGroup; children = ( @@ -540,15 +564,19 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 6A6ED16E2797650A0012872E /* template-exclude-phrases.txt in Resources */, 6A0D4F0815FC0DA600ABF4B3 /* Bopomofo.tiff in Resources */, 6A0D4F0915FC0DA600ABF4B3 /* Bopomofo@2x.tiff in Resources */, + 6A6ED16D2797650A0012872E /* template-exclude-phrases-plain-bpmf.txt in Resources */, 6A0D4F5315FC0EE100ABF4B3 /* preferences.xib in Resources */, 6A0D4F5715FC0EF900ABF4B3 /* InfoPlist.strings in Resources */, 6A0D4F5815FC0EF900ABF4B3 /* Localizable.strings in Resources */, 6A2E40F6253A69DA00D1AE1D /* Images.xcassets in Resources */, 6A38BC1515FC117A00A8A51F /* data.txt in Resources */, + 6A6ED16B2797650A0012872E /* template-phrases-replacement.txt in Resources */, 6AFF97F2253B299E007F1C49 /* NonModalAlertWindowController.xib in Resources */, 6AE210B215FC63CC003659FE /* PlainBopomofo.tiff in Resources */, + 6A6ED16C2797650A0012872E /* template-data.txt in Resources */, 6AE210B315FC63CC003659FE /* PlainBopomofo@2x.tiff in Resources */, 6AD7CBC815FE555000691B5B /* data-plain-bpmf.txt in Resources */, 6A187E2616004C5900466B2E /* MainMenu.xib in Resources */, @@ -680,6 +708,42 @@ name = MainMenu.xib; sourceTree = ""; }; + 6A6ED1632797650A0012872E /* template-phrases-replacement.txt */ = { + isa = PBXVariantGroup; + children = ( + 6A6ED1642797650A0012872E /* Base */, + 6A6ED1722797651A0012872E /* zh-Hant */, + ); + name = "template-phrases-replacement.txt"; + sourceTree = ""; + }; + 6A6ED1652797650A0012872E /* template-data.txt */ = { + isa = PBXVariantGroup; + children = ( + 6A6ED1662797650A0012872E /* Base */, + 6A6ED16F279765100012872E /* zh-Hant */, + ); + name = "template-data.txt"; + sourceTree = ""; + }; + 6A6ED1672797650A0012872E /* template-exclude-phrases-plain-bpmf.txt */ = { + isa = PBXVariantGroup; + children = ( + 6A6ED1682797650A0012872E /* Base */, + 6A6ED170279765140012872E /* zh-Hant */, + ); + name = "template-exclude-phrases-plain-bpmf.txt"; + sourceTree = ""; + }; + 6A6ED1692797650A0012872E /* template-exclude-phrases.txt */ = { + isa = PBXVariantGroup; + children = ( + 6A6ED16A2797650A0012872E /* Base */, + 6A6ED171279765170012872E /* zh-Hant */, + ); + name = "template-exclude-phrases.txt"; + sourceTree = ""; + }; 6ACA41EA15FC1D9000935EF6 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( diff --git a/Source/Base.lproj/template-data.txt b/Source/Base.lproj/template-data.txt new file mode 100644 index 00000000..29b95587 --- /dev/null +++ b/Source/Base.lproj/template-data.txt @@ -0,0 +1,11 @@ +# Custom Phrases or Characters. +# +# See https://github.com/openvanilla/McBopomofo/wiki/使用手冊#手動加詞 for usage. +# +# Add your phrases and their respective Bopomofo reading below. Use hyphen ("-") +# to connect the Bopomofo syllables. +# +# 小麥注音 ㄒㄧㄠˇ-ㄇㄞˋ-ㄓㄨˋ-ㄧㄣ +# +# Any line that starts with "#" is treated as comment. + diff --git a/Source/Base.lproj/template-exclude-phrases-plain-bpmf.txt b/Source/Base.lproj/template-exclude-phrases-plain-bpmf.txt new file mode 100644 index 00000000..d12c9c79 --- /dev/null +++ b/Source/Base.lproj/template-exclude-phrases-plain-bpmf.txt @@ -0,0 +1,12 @@ +# Custom Exculded Characters or Symbols (for Plain Bopomofo). +# +# See https://github.com/openvanilla/McBopomofo/wiki/使用手冊#手動刪詞 for usage. +# +# For example, the two lines below will remove the punctuations 〈 and 《 whenever +# you type the character <: +# +# 〈 _punctuation_Standard_< +# 《 _punctuation_Standard_< +# +# Any line that starts with "#" is treated as comment. + diff --git a/Source/Base.lproj/template-exclude-phrases.txt b/Source/Base.lproj/template-exclude-phrases.txt new file mode 100644 index 00000000..9ee1e861 --- /dev/null +++ b/Source/Base.lproj/template-exclude-phrases.txt @@ -0,0 +1,13 @@ +# Custom Exculded Phrases or Characters. +# +# See https://github.com/openvanilla/McBopomofo/wiki/使用手冊#手動刪詞 for usage. +# +# For example, the line below will prevent the phrase "家祠" from showing up anywhere +# whenever you type "ㄐㄧㄚ ㄘˊ": +# +# 家祠 ㄐㄧㄚ-ㄘˊ +# +# Note that you need to use a hyphen ("-") between Bopomofo syllables. +# +# Any line that starts with "#" is treated as comment. + diff --git a/Source/Base.lproj/template-phrases-replacement.txt b/Source/Base.lproj/template-phrases-replacement.txt new file mode 100644 index 00000000..4d792e3f --- /dev/null +++ b/Source/Base.lproj/template-phrases-replacement.txt @@ -0,0 +1,12 @@ +# Custom Replacements File. +# +# See https://github.com/openvanilla/McBopomofo/wiki/使用手冊#手動換詞 for usage. +# +# This is an advanced feature. For example, if you add this line: +# +# 這個 呢個 +# +# All instances of 這個 will be replaced with 呢個. +# +# Any line that starts with "#" is treated as comment. + diff --git a/Source/LanguageModelManager.mm b/Source/LanguageModelManager.mm index bdf0ac9f..4ae80481 100644 --- a/Source/LanguageModelManager.mm +++ b/Source/LanguageModelManager.mm @@ -21,6 +21,13 @@ McBopomofoLM gLanguageModelMcBopomofo; McBopomofoLM gLanguageModelPlainBopomofo; UserOverrideModel gUserOverrideModel(kUserOverrideModelCapacity, kObservedOverrideHalflife); +NSString *const kUserDataTemplateName = @"template-data"; +NSString *const kExcludedPhrasesMcBopomofoTemplateName = @"template-exclude-phrases"; +NSString *const kExcludedPhrasesPlainBopomofoTemplateName = @"template-exclude-phrases-plain-bpmf"; +NSString *const kPhraseReplacementTemplateName = @"template-phrases-replacement"; +NSString *const kTemplateExtension = @".txt"; + + @implementation LanguageModelManager static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, McBopomofoLM &lm) @@ -97,10 +104,19 @@ static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, McBopomo return YES; } -+ (BOOL)checkIfFileExist:(NSString *)filePath ++ (BOOL)ensureFileExists:(NSString *)filePath populateWithTemplate:(NSString *)templateBasename extension:(NSString *)ext { if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) { - BOOL result = [[@"" dataUsingEncoding:NSUTF8StringEncoding] writeToFile:filePath atomically:YES]; + + NSURL *templateURL = [[NSBundle mainBundle] URLForResource:templateBasename withExtension:ext]; + NSData *templateData; + if (templateURL) { + templateData = [NSData dataWithContentsOfURL:templateURL]; + } else { + templateData = [@"" dataUsingEncoding:NSUTF8StringEncoding]; + } + + BOOL result = [templateData writeToFile:filePath atomically:YES]; if (!result) { NSLog(@"Failed to write file"); return NO; @@ -114,16 +130,16 @@ static void LTLoadLanguageModelFile(NSString *filenameWithoutExtension, McBopomo if (![self checkIfUserDataFolderExists]) { return NO; } - if (![self checkIfFileExist:[self userPhrasesDataPathMcBopomofo]]) { + if (![self ensureFileExists:[self userPhrasesDataPathMcBopomofo] populateWithTemplate:kUserDataTemplateName extension:kTemplateExtension]) { return NO; } - if (![self checkIfFileExist:[self excludedPhrasesDataPathMcBopomofo]]) { + if (![self ensureFileExists:[self excludedPhrasesDataPathMcBopomofo] populateWithTemplate:kExcludedPhrasesMcBopomofoTemplateName extension:kTemplateExtension]) { return NO; } - if (![self checkIfFileExist:[self excludedPhrasesDataPathPlainBopomofo]]) { + if (![self ensureFileExists:[self excludedPhrasesDataPathPlainBopomofo] populateWithTemplate:kExcludedPhrasesPlainBopomofoTemplateName extension:kTemplateExtension]) { return NO; } - if (![self checkIfFileExist:[self phraseReplacementDataPathMcBopomofo]]) { + if (![self ensureFileExists:[self phraseReplacementDataPathMcBopomofo] populateWithTemplate:kPhraseReplacementTemplateName extension:kTemplateExtension]) { return NO; } return YES; diff --git a/Source/zh-Hant.lproj/template-data.txt b/Source/zh-Hant.lproj/template-data.txt new file mode 100644 index 00000000..6a0d7084 --- /dev/null +++ b/Source/zh-Hant.lproj/template-data.txt @@ -0,0 +1,11 @@ +# 手動加詞資料檔 +# +# 使用方式請參考 https://github.com/openvanilla/McBopomofo/wiki/使用手冊#手動加詞 +# +# 請在下方加入用戶自訂字詞。每個詞後面要有字詞的讀音。注音音節之間要用減 +# 號 ("-") 分隔。例如,以下範例加入「小麥注音」一詞: +# +# 小麥注音 ㄒㄧㄠˇ-ㄇㄞˋ-ㄓㄨˋ-ㄧㄣ +# +# 如果任何一行以 "#" 開頭,該行將被當作註解忽略。 + diff --git a/Source/zh-Hant.lproj/template-exclude-phrases-plain-bpmf.txt b/Source/zh-Hant.lproj/template-exclude-phrases-plain-bpmf.txt new file mode 100644 index 00000000..aeadfdce --- /dev/null +++ b/Source/zh-Hant.lproj/template-exclude-phrases-plain-bpmf.txt @@ -0,0 +1,11 @@ +# 手動刪詞資料檔(傳統注音) +# +# 使用方式請參考 https://github.com/openvanilla/McBopomofo/wiki/使用手冊#手動刪詞 +# +# 以下範例刪除輸入 < 時在選字窗出現的 〈 及 《 兩個標點符號: +# +# 〈 _punctuation_Standard_< +# 《 _punctuation_Standard_< +# +# 如果任何一行以 "#" 開頭,該行將被當作註解忽略。 + diff --git a/Source/zh-Hant.lproj/template-exclude-phrases.txt b/Source/zh-Hant.lproj/template-exclude-phrases.txt new file mode 100644 index 00000000..d1a61c8d --- /dev/null +++ b/Source/zh-Hant.lproj/template-exclude-phrases.txt @@ -0,0 +1,12 @@ +# 手動刪詞資料檔 +# +# 使用方式請參考 https://github.com/openvanilla/McBopomofo/wiki/使用手冊#手動刪詞 +# +# 如果將下面這行範例加入資料檔中,輸入 "ㄐㄧㄚ ㄘˊ" 時不會再看到「家祠」一詞: +# +# 家祠 ㄐㄧㄚ-ㄘˊ +# +# 請注意,注音音節之間要用減號 ("-") 分隔。 +# +# 如果任何一行以 "#" 開頭,該行將被當作註解忽略。 + diff --git a/Source/zh-Hant.lproj/template-phrases-replacement.txt b/Source/zh-Hant.lproj/template-phrases-replacement.txt new file mode 100644 index 00000000..898a9e09 --- /dev/null +++ b/Source/zh-Hant.lproj/template-phrases-replacement.txt @@ -0,0 +1,11 @@ +# 手動換詞資料檔 +# +# 使用方式請參考 https://github.com/openvanilla/McBopomofo/wiki/使用手冊#手動換詞 +# +# +# 這是進階功能。如果加入以下範例的換詞規則,「這個」會被替換成「呢個」: +# +# 這個 呢個 +# +# 如果任何一行以 "#" 開頭,該行將被當作註解忽略。 +