| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/common/spellcheck_common.h" |
| |
| #include "base/file_path.h" |
| |
| namespace SpellCheckCommon { |
| |
| static const struct { |
| // The language. |
| const char* language; |
| |
| // The corresponding language and region, used by the dictionaries. |
| const char* language_region; |
| } g_supported_spellchecker_languages[] = { |
| // Several languages are not to be included in the spellchecker list: |
| // th-TH, uk-UA |
| {"bg", "bg-BG"}, |
| {"ca", "ca-ES"}, |
| {"cs", "cs-CZ"}, |
| {"da", "da-DK"}, |
| {"de", "de-DE"}, |
| {"el", "el-GR"}, |
| {"en-AU", "en-AU"}, |
| {"en-CA", "en-CA"}, |
| {"en-GB", "en-GB"}, |
| {"en-US", "en-US"}, |
| {"es", "es-ES"}, |
| {"et", "et-EE"}, |
| {"fr", "fr-FR"}, |
| {"he", "he-IL"}, |
| {"hi", "hi-IN"}, |
| {"hr", "hr-HR"}, |
| {"hu", "hu-HU"}, |
| {"id", "id-ID"}, |
| {"it", "it-IT"}, |
| {"lt", "lt-LT"}, |
| {"lv", "lv-LV"}, |
| {"nb", "nb-NO"}, |
| {"nl", "nl-NL"}, |
| {"pl", "pl-PL"}, |
| {"pt-BR", "pt-BR"}, |
| {"pt-PT", "pt-PT"}, |
| {"ro", "ro-RO"}, |
| {"ru", "ru-RU"}, |
| {"sk", "sk-SK"}, |
| {"sl", "sl-SI"}, |
| {"sh", "sh"}, |
| {"sr", "sr"}, |
| {"sv", "sv-SE"}, |
| {"tr", "tr-TR"}, |
| {"uk", "uk-UA"}, |
| {"vi", "vi-VN"}, |
| }; |
| |
| // This function returns the language-region version of language name. |
| // e.g. returns hi-IN for hi. |
| std::string GetSpellCheckLanguageRegion(const std::string& input_language) { |
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(g_supported_spellchecker_languages); |
| ++i) { |
| if (g_supported_spellchecker_languages[i].language == input_language) { |
| return std::string( |
| g_supported_spellchecker_languages[i].language_region); |
| } |
| } |
| |
| return input_language; |
| } |
| |
| FilePath GetVersionedFileName(const std::string& input_language, |
| const FilePath& dict_dir) { |
| // The default dictionary version is 1-2. These versions have been augmented |
| // with additional words found by the translation team. |
| static const char kDefaultVersionString[] = "-1-2"; |
| |
| static const struct { |
| // The language input. |
| const char* language; |
| |
| // The corresponding version. |
| const char* version; |
| } special_version_string[] = { |
| {"es-ES", "-1-1"}, // 1-1: Have not been augmented with addtional words. |
| {"nl-NL", "-1-1"}, |
| {"sv-SE", "-1-1"}, |
| {"he-IL", "-1-1"}, |
| {"el-GR", "-1-1"}, |
| {"hi-IN", "-1-1"}, |
| {"tr-TR", "-1-1"}, |
| {"et-EE", "-1-1"}, |
| {"lt-LT", "-1-3"}, // 1-3 (Feb 2009): new words, as well as an upgraded |
| // dictionary. |
| {"pl-PL", "-1-3"}, |
| {"fr-FR", "-2-0"}, // 2-0 (2010): upgraded dictionaries. |
| {"hu-HU", "-2-0"}, |
| {"ro-RO", "-2-0"}, |
| {"ru-RU", "-2-0"}, |
| {"bg-BG", "-2-0"}, |
| {"sr", "-2-0"}, |
| {"uk-UA", "-2-0"}, |
| {"en-US", "-2-1"}, // 2-1 (Mar 2011): upgraded dictionaries. |
| {"en-CA", "-2-1"}, |
| {"pt-BR", "-2-2"}, // 2-2 (Mar 2011): upgraded a dictionary. |
| {"sh", "-2-2"}, // 2-2 (Mar 2011): added a dictionary. |
| }; |
| |
| // Generate the bdict file name using default version string or special |
| // version string, depending on the language. |
| std::string language = GetSpellCheckLanguageRegion(input_language); |
| std::string versioned_bdict_file_name(language + kDefaultVersionString + |
| ".bdic"); |
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(special_version_string); ++i) { |
| if (language == special_version_string[i].language) { |
| versioned_bdict_file_name = |
| language + special_version_string[i].version + ".bdic"; |
| break; |
| } |
| } |
| |
| return dict_dir.AppendASCII(versioned_bdict_file_name); |
| } |
| |
| std::string GetCorrespondingSpellCheckLanguage(const std::string& language) { |
| // Look for exact match in the Spell Check language list. |
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(g_supported_spellchecker_languages); |
| ++i) { |
| // First look for exact match in the language region of the list. |
| std::string spellcheck_language( |
| g_supported_spellchecker_languages[i].language); |
| if (spellcheck_language == language) |
| return language; |
| |
| // Next, look for exact match in the language_region part of the list. |
| std::string spellcheck_language_region( |
| g_supported_spellchecker_languages[i].language_region); |
| if (spellcheck_language_region == language) |
| return g_supported_spellchecker_languages[i].language; |
| } |
| |
| // Look for a match by comparing only language parts. All the 'en-RR' |
| // except for 'en-GB' exactly matched in the above loop, will match |
| // 'en-US'. This is not ideal because 'en-ZA', 'en-NZ' had |
| // better be matched with 'en-GB'. This does not handle cases like |
| // 'az-Latn-AZ' vs 'az-Arab-AZ', either, but we don't use 3-part |
| // locale ids with a script code in the middle, yet. |
| // TODO(jungshik): Add a better fallback. |
| std::string language_part(language, 0, language.find('-')); |
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(g_supported_spellchecker_languages); |
| ++i) { |
| std::string spellcheck_language( |
| g_supported_spellchecker_languages[i].language_region); |
| if (spellcheck_language.substr(0, spellcheck_language.find('-')) == |
| language_part) { |
| return spellcheck_language; |
| } |
| } |
| |
| // No match found - return blank. |
| return std::string(); |
| } |
| |
| |
| void SpellCheckLanguages(std::vector<std::string>* languages) { |
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(g_supported_spellchecker_languages); |
| ++i) { |
| languages->push_back(g_supported_spellchecker_languages[i].language); |
| } |
| } |
| |
| } // namespace SpellCheckCommon |