• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "chrome/common/spellcheck_common.h"
6 
7 #include "base/file_path.h"
8 
9 namespace SpellCheckCommon {
10 
11 static const struct {
12   // The language.
13   const char* language;
14 
15   // The corresponding language and region, used by the dictionaries.
16   const char* language_region;
17 } g_supported_spellchecker_languages[] = {
18   // Several languages are not to be included in the spellchecker list:
19   // th-TH, uk-UA
20   {"bg", "bg-BG"},
21   {"ca", "ca-ES"},
22   {"cs", "cs-CZ"},
23   {"da", "da-DK"},
24   {"de", "de-DE"},
25   {"el", "el-GR"},
26   {"en-AU", "en-AU"},
27   {"en-CA", "en-CA"},
28   {"en-GB", "en-GB"},
29   {"en-US", "en-US"},
30   {"es", "es-ES"},
31   {"et", "et-EE"},
32   {"fr", "fr-FR"},
33   {"he", "he-IL"},
34   {"hi", "hi-IN"},
35   {"hr", "hr-HR"},
36   {"hu", "hu-HU"},
37   {"id", "id-ID"},
38   {"it", "it-IT"},
39   {"lt", "lt-LT"},
40   {"lv", "lv-LV"},
41   {"nb", "nb-NO"},
42   {"nl", "nl-NL"},
43   {"pl", "pl-PL"},
44   {"pt-BR", "pt-BR"},
45   {"pt-PT", "pt-PT"},
46   {"ro", "ro-RO"},
47   {"ru", "ru-RU"},
48   {"sk", "sk-SK"},
49   {"sl", "sl-SI"},
50   {"sh", "sh"},
51   {"sr", "sr"},
52   {"sv", "sv-SE"},
53   {"tr", "tr-TR"},
54   {"uk", "uk-UA"},
55   {"vi", "vi-VN"},
56 };
57 
58 // This function returns the language-region version of language name.
59 // e.g. returns hi-IN for hi.
GetSpellCheckLanguageRegion(const std::string & input_language)60 std::string GetSpellCheckLanguageRegion(const std::string& input_language) {
61   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(g_supported_spellchecker_languages);
62        ++i) {
63     if (g_supported_spellchecker_languages[i].language == input_language) {
64       return std::string(
65           g_supported_spellchecker_languages[i].language_region);
66     }
67   }
68 
69   return input_language;
70 }
71 
GetVersionedFileName(const std::string & input_language,const FilePath & dict_dir)72 FilePath GetVersionedFileName(const std::string& input_language,
73                               const FilePath& dict_dir) {
74   // The default dictionary version is 1-2. These versions have been augmented
75   // with additional words found by the translation team.
76   static const char kDefaultVersionString[] = "-1-2";
77 
78   static const struct {
79     // The language input.
80     const char* language;
81 
82     // The corresponding version.
83     const char* version;
84   } special_version_string[] = {
85     {"es-ES", "-1-1"},  // 1-1: Have not been augmented with addtional words.
86     {"nl-NL", "-1-1"},
87     {"sv-SE", "-1-1"},
88     {"he-IL", "-1-1"},
89     {"el-GR", "-1-1"},
90     {"hi-IN", "-1-1"},
91     {"tr-TR", "-1-1"},
92     {"et-EE", "-1-1"},
93     {"lt-LT", "-1-3"},  // 1-3 (Feb 2009): new words, as well as an upgraded
94                         // dictionary.
95     {"pl-PL", "-1-3"},
96     {"fr-FR", "-2-0"},  // 2-0 (2010): upgraded dictionaries.
97     {"hu-HU", "-2-0"},
98     {"ro-RO", "-2-0"},
99     {"ru-RU", "-2-0"},
100     {"bg-BG", "-2-0"},
101     {"sr",    "-2-0"},
102     {"uk-UA", "-2-0"},
103     {"en-US", "-2-1"},  // 2-1 (Mar 2011): upgraded dictionaries.
104     {"en-CA", "-2-1"},
105     {"pt-BR", "-2-2"},  // 2-2 (Mar 2011): upgraded a dictionary.
106     {"sh",    "-2-2"},  // 2-2 (Mar 2011): added a dictionary.
107   };
108 
109   // Generate the bdict file name using default version string or special
110   // version string, depending on the language.
111   std::string language = GetSpellCheckLanguageRegion(input_language);
112   std::string versioned_bdict_file_name(language + kDefaultVersionString +
113                                         ".bdic");
114   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(special_version_string); ++i) {
115     if (language == special_version_string[i].language) {
116       versioned_bdict_file_name =
117           language + special_version_string[i].version + ".bdic";
118       break;
119     }
120   }
121 
122   return dict_dir.AppendASCII(versioned_bdict_file_name);
123 }
124 
GetCorrespondingSpellCheckLanguage(const std::string & language)125 std::string GetCorrespondingSpellCheckLanguage(const std::string& language) {
126   // Look for exact match in the Spell Check language list.
127   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(g_supported_spellchecker_languages);
128        ++i) {
129     // First look for exact match in the language region of the list.
130     std::string spellcheck_language(
131         g_supported_spellchecker_languages[i].language);
132     if (spellcheck_language == language)
133       return language;
134 
135     // Next, look for exact match in the language_region part of the list.
136     std::string spellcheck_language_region(
137         g_supported_spellchecker_languages[i].language_region);
138     if (spellcheck_language_region == language)
139       return g_supported_spellchecker_languages[i].language;
140   }
141 
142   // Look for a match by comparing only language parts. All the 'en-RR'
143   // except for 'en-GB' exactly matched in the above loop, will match
144   // 'en-US'. This is not ideal because 'en-ZA', 'en-NZ' had
145   // better be matched with 'en-GB'. This does not handle cases like
146   // 'az-Latn-AZ' vs 'az-Arab-AZ', either, but we don't use 3-part
147   // locale ids with a script code in the middle, yet.
148   // TODO(jungshik): Add a better fallback.
149   std::string language_part(language, 0, language.find('-'));
150   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(g_supported_spellchecker_languages);
151        ++i) {
152     std::string spellcheck_language(
153         g_supported_spellchecker_languages[i].language_region);
154     if (spellcheck_language.substr(0, spellcheck_language.find('-')) ==
155         language_part) {
156       return spellcheck_language;
157     }
158   }
159 
160   // No match found - return blank.
161   return std::string();
162 }
163 
164 
SpellCheckLanguages(std::vector<std::string> * languages)165 void SpellCheckLanguages(std::vector<std::string>* languages) {
166   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(g_supported_spellchecker_languages);
167        ++i) {
168     languages->push_back(g_supported_spellchecker_languages[i].language);
169   }
170 }
171 
172 }  // namespace SpellCheckCommon
173