OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # Copyright 2013 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. |
| 5 |
| 6 """ |
| 7 localize.py -- Generates an output file from the given template replacing |
| 8 variables and localizing strings. |
| 9 |
| 10 The script uses Jinja2 template processing library (src/third_party/jinja2). |
| 11 Variables available to the templates: |
| 12 - |languages| - the list of languages passed on the command line. ('-l'). |
| 13 - Each KEY=VALUE define ('-d') can be accesses as |KEY|. |
| 14 - |official_build| is set to '1' when CHROME_BUILD_TYPE environment variable |
| 15 is set to "_official". |
| 16 |
| 17 Filters: |
| 18 - GetCodepage - returns the code page for the given language. |
| 19 - GetCodepageDecimal same as GetCodepage, but returns a decimal value. |
| 20 - GetLangId - returns Win32 LANGID. |
| 21 - GetPrimaryLanguage - returns a named Win32 constant specifing the primary |
| 22 language ID. |
| 23 - GetSublanguage - returns a named Win32 constant specifing the sublanguage |
| 24 ID. |
| 25 |
| 26 Globals: |
| 27 - SelectLanguage(language) - allows to select the language to the used by |
| 28 {% trans %}{% endtrans %} statements. |
| 29 |
| 30 """ |
| 31 |
| 32 import io |
| 33 import json |
| 34 from optparse import OptionParser |
| 35 import os |
| 36 import sys |
| 37 |
| 38 # Win32 primary languages IDs. |
| 39 _LANGUAGE_PRIMARY = { |
| 40 'LANG_NEUTRAL' : 0x00, |
| 41 'LANG_INVARIANT' : 0x7f, |
| 42 'LANG_AFRIKAANS' : 0x36, |
| 43 'LANG_ALBANIAN' : 0x1c, |
| 44 'LANG_ALSATIAN' : 0x84, |
| 45 'LANG_AMHARIC' : 0x5e, |
| 46 'LANG_ARABIC' : 0x01, |
| 47 'LANG_ARMENIAN' : 0x2b, |
| 48 'LANG_ASSAMESE' : 0x4d, |
| 49 'LANG_AZERI' : 0x2c, |
| 50 'LANG_BASHKIR' : 0x6d, |
| 51 'LANG_BASQUE' : 0x2d, |
| 52 'LANG_BELARUSIAN' : 0x23, |
| 53 'LANG_BENGALI' : 0x45, |
| 54 'LANG_BRETON' : 0x7e, |
| 55 'LANG_BOSNIAN' : 0x1a, |
| 56 'LANG_BULGARIAN' : 0x02, |
| 57 'LANG_CATALAN' : 0x03, |
| 58 'LANG_CHINESE' : 0x04, |
| 59 'LANG_CORSICAN' : 0x83, |
| 60 'LANG_CROATIAN' : 0x1a, |
| 61 'LANG_CZECH' : 0x05, |
| 62 'LANG_DANISH' : 0x06, |
| 63 'LANG_DARI' : 0x8c, |
| 64 'LANG_DIVEHI' : 0x65, |
| 65 'LANG_DUTCH' : 0x13, |
| 66 'LANG_ENGLISH' : 0x09, |
| 67 'LANG_ESTONIAN' : 0x25, |
| 68 'LANG_FAEROESE' : 0x38, |
| 69 'LANG_FILIPINO' : 0x64, |
| 70 'LANG_FINNISH' : 0x0b, |
| 71 'LANG_FRENCH' : 0x0c, |
| 72 'LANG_FRISIAN' : 0x62, |
| 73 'LANG_GALICIAN' : 0x56, |
| 74 'LANG_GEORGIAN' : 0x37, |
| 75 'LANG_GERMAN' : 0x07, |
| 76 'LANG_GREEK' : 0x08, |
| 77 'LANG_GREENLANDIC' : 0x6f, |
| 78 'LANG_GUJARATI' : 0x47, |
| 79 'LANG_HAUSA' : 0x68, |
| 80 'LANG_HEBREW' : 0x0d, |
| 81 'LANG_HINDI' : 0x39, |
| 82 'LANG_HUNGARIAN' : 0x0e, |
| 83 'LANG_ICELANDIC' : 0x0f, |
| 84 'LANG_IGBO' : 0x70, |
| 85 'LANG_INDONESIAN' : 0x21, |
| 86 'LANG_INUKTITUT' : 0x5d, |
| 87 'LANG_IRISH' : 0x3c, |
| 88 'LANG_ITALIAN' : 0x10, |
| 89 'LANG_JAPANESE' : 0x11, |
| 90 'LANG_KANNADA' : 0x4b, |
| 91 'LANG_KASHMIRI' : 0x60, |
| 92 'LANG_KAZAK' : 0x3f, |
| 93 'LANG_KHMER' : 0x53, |
| 94 'LANG_KICHE' : 0x86, |
| 95 'LANG_KINYARWANDA' : 0x87, |
| 96 'LANG_KONKANI' : 0x57, |
| 97 'LANG_KOREAN' : 0x12, |
| 98 'LANG_KYRGYZ' : 0x40, |
| 99 'LANG_LAO' : 0x54, |
| 100 'LANG_LATVIAN' : 0x26, |
| 101 'LANG_LITHUANIAN' : 0x27, |
| 102 'LANG_LOWER_SORBIAN' : 0x2e, |
| 103 'LANG_LUXEMBOURGISH' : 0x6e, |
| 104 'LANG_MACEDONIAN' : 0x2f, |
| 105 'LANG_MALAY' : 0x3e, |
| 106 'LANG_MALAYALAM' : 0x4c, |
| 107 'LANG_MALTESE' : 0x3a, |
| 108 'LANG_MANIPURI' : 0x58, |
| 109 'LANG_MAORI' : 0x81, |
| 110 'LANG_MAPUDUNGUN' : 0x7a, |
| 111 'LANG_MARATHI' : 0x4e, |
| 112 'LANG_MOHAWK' : 0x7c, |
| 113 'LANG_MONGOLIAN' : 0x50, |
| 114 'LANG_NEPALI' : 0x61, |
| 115 'LANG_NORWEGIAN' : 0x14, |
| 116 'LANG_OCCITAN' : 0x82, |
| 117 'LANG_ORIYA' : 0x48, |
| 118 'LANG_PASHTO' : 0x63, |
| 119 'LANG_PERSIAN' : 0x29, |
| 120 'LANG_POLISH' : 0x15, |
| 121 'LANG_PORTUGUESE' : 0x16, |
| 122 'LANG_PUNJABI' : 0x46, |
| 123 'LANG_QUECHUA' : 0x6b, |
| 124 'LANG_ROMANIAN' : 0x18, |
| 125 'LANG_ROMANSH' : 0x17, |
| 126 'LANG_RUSSIAN' : 0x19, |
| 127 'LANG_SAMI' : 0x3b, |
| 128 'LANG_SANSKRIT' : 0x4f, |
| 129 'LANG_SCOTTISH_GAELIC' : 0x91, |
| 130 'LANG_SERBIAN' : 0x1a, |
| 131 'LANG_SINDHI' : 0x59, |
| 132 'LANG_SINHALESE' : 0x5b, |
| 133 'LANG_SLOVAK' : 0x1b, |
| 134 'LANG_SLOVENIAN' : 0x24, |
| 135 'LANG_SOTHO' : 0x6c, |
| 136 'LANG_SPANISH' : 0x0a, |
| 137 'LANG_SWAHILI' : 0x41, |
| 138 'LANG_SWEDISH' : 0x1d, |
| 139 'LANG_SYRIAC' : 0x5a, |
| 140 'LANG_TAJIK' : 0x28, |
| 141 'LANG_TAMAZIGHT' : 0x5f, |
| 142 'LANG_TAMIL' : 0x49, |
| 143 'LANG_TATAR' : 0x44, |
| 144 'LANG_TELUGU' : 0x4a, |
| 145 'LANG_THAI' : 0x1e, |
| 146 'LANG_TIBETAN' : 0x51, |
| 147 'LANG_TIGRIGNA' : 0x73, |
| 148 'LANG_TSWANA' : 0x32, |
| 149 'LANG_TURKISH' : 0x1f, |
| 150 'LANG_TURKMEN' : 0x42, |
| 151 'LANG_UIGHUR' : 0x80, |
| 152 'LANG_UKRAINIAN' : 0x22, |
| 153 'LANG_UPPER_SORBIAN' : 0x2e, |
| 154 'LANG_URDU' : 0x20, |
| 155 'LANG_UZBEK' : 0x43, |
| 156 'LANG_VIETNAMESE' : 0x2a, |
| 157 'LANG_WELSH' : 0x52, |
| 158 'LANG_WOLOF' : 0x88, |
| 159 'LANG_XHOSA' : 0x34, |
| 160 'LANG_YAKUT' : 0x85, |
| 161 'LANG_YI' : 0x78, |
| 162 'LANG_YORUBA' : 0x6a, |
| 163 'LANG_ZULU' : 0x35, |
| 164 } |
| 165 |
| 166 |
| 167 # Win32 sublanguage IDs. |
| 168 _LANGUAGE_SUB = { |
| 169 'SUBLANG_NEUTRAL' : 0x00, |
| 170 'SUBLANG_DEFAULT' : 0x01, |
| 171 'SUBLANG_SYS_DEFAULT' : 0x02, |
| 172 'SUBLANG_CUSTOM_DEFAULT' : 0x03, |
| 173 'SUBLANG_CUSTOM_UNSPECIFIED' : 0x04, |
| 174 'SUBLANG_UI_CUSTOM_DEFAULT' : 0x05, |
| 175 'SUBLANG_AFRIKAANS_SOUTH_AFRICA' : 0x01, |
| 176 'SUBLANG_ALBANIAN_ALBANIA' : 0x01, |
| 177 'SUBLANG_ALSATIAN_FRANCE' : 0x01, |
| 178 'SUBLANG_AMHARIC_ETHIOPIA' : 0x01, |
| 179 'SUBLANG_ARABIC_SAUDI_ARABIA' : 0x01, |
| 180 'SUBLANG_ARABIC_IRAQ' : 0x02, |
| 181 'SUBLANG_ARABIC_EGYPT' : 0x03, |
| 182 'SUBLANG_ARABIC_LIBYA' : 0x04, |
| 183 'SUBLANG_ARABIC_ALGERIA' : 0x05, |
| 184 'SUBLANG_ARABIC_MOROCCO' : 0x06, |
| 185 'SUBLANG_ARABIC_TUNISIA' : 0x07, |
| 186 'SUBLANG_ARABIC_OMAN' : 0x08, |
| 187 'SUBLANG_ARABIC_YEMEN' : 0x09, |
| 188 'SUBLANG_ARABIC_SYRIA' : 0x0a, |
| 189 'SUBLANG_ARABIC_JORDAN' : 0x0b, |
| 190 'SUBLANG_ARABIC_LEBANON' : 0x0c, |
| 191 'SUBLANG_ARABIC_KUWAIT' : 0x0d, |
| 192 'SUBLANG_ARABIC_UAE' : 0x0e, |
| 193 'SUBLANG_ARABIC_BAHRAIN' : 0x0f, |
| 194 'SUBLANG_ARABIC_QATAR' : 0x10, |
| 195 'SUBLANG_ARMENIAN_ARMENIA' : 0x01, |
| 196 'SUBLANG_ASSAMESE_INDIA' : 0x01, |
| 197 'SUBLANG_AZERI_LATIN' : 0x01, |
| 198 'SUBLANG_AZERI_CYRILLIC' : 0x02, |
| 199 'SUBLANG_BASHKIR_RUSSIA' : 0x01, |
| 200 'SUBLANG_BASQUE_BASQUE' : 0x01, |
| 201 'SUBLANG_BELARUSIAN_BELARUS' : 0x01, |
| 202 'SUBLANG_BENGALI_INDIA' : 0x01, |
| 203 'SUBLANG_BENGALI_BANGLADESH' : 0x02, |
| 204 'SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN' : 0x05, |
| 205 'SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC' : 0x08, |
| 206 'SUBLANG_BRETON_FRANCE' : 0x01, |
| 207 'SUBLANG_BULGARIAN_BULGARIA' : 0x01, |
| 208 'SUBLANG_CATALAN_CATALAN' : 0x01, |
| 209 'SUBLANG_CHINESE_TRADITIONAL' : 0x01, |
| 210 'SUBLANG_CHINESE_SIMPLIFIED' : 0x02, |
| 211 'SUBLANG_CHINESE_HONGKONG' : 0x03, |
| 212 'SUBLANG_CHINESE_SINGAPORE' : 0x04, |
| 213 'SUBLANG_CHINESE_MACAU' : 0x05, |
| 214 'SUBLANG_CORSICAN_FRANCE' : 0x01, |
| 215 'SUBLANG_CZECH_CZECH_REPUBLIC' : 0x01, |
| 216 'SUBLANG_CROATIAN_CROATIA' : 0x01, |
| 217 'SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN' : 0x04, |
| 218 'SUBLANG_DANISH_DENMARK' : 0x01, |
| 219 'SUBLANG_DARI_AFGHANISTAN' : 0x01, |
| 220 'SUBLANG_DIVEHI_MALDIVES' : 0x01, |
| 221 'SUBLANG_DUTCH' : 0x01, |
| 222 'SUBLANG_DUTCH_BELGIAN' : 0x02, |
| 223 'SUBLANG_ENGLISH_US' : 0x01, |
| 224 'SUBLANG_ENGLISH_UK' : 0x02, |
| 225 'SUBLANG_ENGLISH_AUS' : 0x03, |
| 226 'SUBLANG_ENGLISH_CAN' : 0x04, |
| 227 'SUBLANG_ENGLISH_NZ' : 0x05, |
| 228 'SUBLANG_ENGLISH_EIRE' : 0x06, |
| 229 'SUBLANG_ENGLISH_SOUTH_AFRICA' : 0x07, |
| 230 'SUBLANG_ENGLISH_JAMAICA' : 0x08, |
| 231 'SUBLANG_ENGLISH_CARIBBEAN' : 0x09, |
| 232 'SUBLANG_ENGLISH_BELIZE' : 0x0a, |
| 233 'SUBLANG_ENGLISH_TRINIDAD' : 0x0b, |
| 234 'SUBLANG_ENGLISH_ZIMBABWE' : 0x0c, |
| 235 'SUBLANG_ENGLISH_PHILIPPINES' : 0x0d, |
| 236 'SUBLANG_ENGLISH_INDIA' : 0x10, |
| 237 'SUBLANG_ENGLISH_MALAYSIA' : 0x11, |
| 238 'SUBLANG_ENGLISH_SINGAPORE' : 0x12, |
| 239 'SUBLANG_ESTONIAN_ESTONIA' : 0x01, |
| 240 'SUBLANG_FAEROESE_FAROE_ISLANDS' : 0x01, |
| 241 'SUBLANG_FILIPINO_PHILIPPINES' : 0x01, |
| 242 'SUBLANG_FINNISH_FINLAND' : 0x01, |
| 243 'SUBLANG_FRENCH' : 0x01, |
| 244 'SUBLANG_FRENCH_BELGIAN' : 0x02, |
| 245 'SUBLANG_FRENCH_CANADIAN' : 0x03, |
| 246 'SUBLANG_FRENCH_SWISS' : 0x04, |
| 247 'SUBLANG_FRENCH_LUXEMBOURG' : 0x05, |
| 248 'SUBLANG_FRENCH_MONACO' : 0x06, |
| 249 'SUBLANG_FRISIAN_NETHERLANDS' : 0x01, |
| 250 'SUBLANG_GALICIAN_GALICIAN' : 0x01, |
| 251 'SUBLANG_GEORGIAN_GEORGIA' : 0x01, |
| 252 'SUBLANG_GERMAN' : 0x01, |
| 253 'SUBLANG_GERMAN_SWISS' : 0x02, |
| 254 'SUBLANG_GERMAN_AUSTRIAN' : 0x03, |
| 255 'SUBLANG_GERMAN_LUXEMBOURG' : 0x04, |
| 256 'SUBLANG_GERMAN_LIECHTENSTEIN' : 0x05, |
| 257 'SUBLANG_GREEK_GREECE' : 0x01, |
| 258 'SUBLANG_GREENLANDIC_GREENLAND' : 0x01, |
| 259 'SUBLANG_GUJARATI_INDIA' : 0x01, |
| 260 'SUBLANG_HAUSA_NIGERIA_LATIN' : 0x01, |
| 261 'SUBLANG_HEBREW_ISRAEL' : 0x01, |
| 262 'SUBLANG_HINDI_INDIA' : 0x01, |
| 263 'SUBLANG_HUNGARIAN_HUNGARY' : 0x01, |
| 264 'SUBLANG_ICELANDIC_ICELAND' : 0x01, |
| 265 'SUBLANG_IGBO_NIGERIA' : 0x01, |
| 266 'SUBLANG_INDONESIAN_INDONESIA' : 0x01, |
| 267 'SUBLANG_INUKTITUT_CANADA' : 0x01, |
| 268 'SUBLANG_INUKTITUT_CANADA_LATIN' : 0x02, |
| 269 'SUBLANG_IRISH_IRELAND' : 0x02, |
| 270 'SUBLANG_ITALIAN' : 0x01, |
| 271 'SUBLANG_ITALIAN_SWISS' : 0x02, |
| 272 'SUBLANG_JAPANESE_JAPAN' : 0x01, |
| 273 'SUBLANG_KANNADA_INDIA' : 0x01, |
| 274 'SUBLANG_KASHMIRI_SASIA' : 0x02, |
| 275 'SUBLANG_KASHMIRI_INDIA' : 0x02, |
| 276 'SUBLANG_KAZAK_KAZAKHSTAN' : 0x01, |
| 277 'SUBLANG_KHMER_CAMBODIA' : 0x01, |
| 278 'SUBLANG_KICHE_GUATEMALA' : 0x01, |
| 279 'SUBLANG_KINYARWANDA_RWANDA' : 0x01, |
| 280 'SUBLANG_KONKANI_INDIA' : 0x01, |
| 281 'SUBLANG_KOREAN' : 0x01, |
| 282 'SUBLANG_KYRGYZ_KYRGYZSTAN' : 0x01, |
| 283 'SUBLANG_LAO_LAO' : 0x01, |
| 284 'SUBLANG_LATVIAN_LATVIA' : 0x01, |
| 285 'SUBLANG_LITHUANIAN' : 0x01, |
| 286 'SUBLANG_LOWER_SORBIAN_GERMANY' : 0x02, |
| 287 'SUBLANG_LUXEMBOURGISH_LUXEMBOURG' : 0x01, |
| 288 'SUBLANG_MACEDONIAN_MACEDONIA' : 0x01, |
| 289 'SUBLANG_MALAY_MALAYSIA' : 0x01, |
| 290 'SUBLANG_MALAY_BRUNEI_DARUSSALAM' : 0x02, |
| 291 'SUBLANG_MALAYALAM_INDIA' : 0x01, |
| 292 'SUBLANG_MALTESE_MALTA' : 0x01, |
| 293 'SUBLANG_MAORI_NEW_ZEALAND' : 0x01, |
| 294 'SUBLANG_MAPUDUNGUN_CHILE' : 0x01, |
| 295 'SUBLANG_MARATHI_INDIA' : 0x01, |
| 296 'SUBLANG_MOHAWK_MOHAWK' : 0x01, |
| 297 'SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA' : 0x01, |
| 298 'SUBLANG_MONGOLIAN_PRC' : 0x02, |
| 299 'SUBLANG_NEPALI_INDIA' : 0x02, |
| 300 'SUBLANG_NEPALI_NEPAL' : 0x01, |
| 301 'SUBLANG_NORWEGIAN_BOKMAL' : 0x01, |
| 302 'SUBLANG_NORWEGIAN_NYNORSK' : 0x02, |
| 303 'SUBLANG_OCCITAN_FRANCE' : 0x01, |
| 304 'SUBLANG_ORIYA_INDIA' : 0x01, |
| 305 'SUBLANG_PASHTO_AFGHANISTAN' : 0x01, |
| 306 'SUBLANG_PERSIAN_IRAN' : 0x01, |
| 307 'SUBLANG_POLISH_POLAND' : 0x01, |
| 308 'SUBLANG_PORTUGUESE' : 0x02, |
| 309 'SUBLANG_PORTUGUESE_BRAZILIAN' : 0x01, |
| 310 'SUBLANG_PUNJABI_INDIA' : 0x01, |
| 311 'SUBLANG_QUECHUA_BOLIVIA' : 0x01, |
| 312 'SUBLANG_QUECHUA_ECUADOR' : 0x02, |
| 313 'SUBLANG_QUECHUA_PERU' : 0x03, |
| 314 'SUBLANG_ROMANIAN_ROMANIA' : 0x01, |
| 315 'SUBLANG_ROMANSH_SWITZERLAND' : 0x01, |
| 316 'SUBLANG_RUSSIAN_RUSSIA' : 0x01, |
| 317 'SUBLANG_SAMI_NORTHERN_NORWAY' : 0x01, |
| 318 'SUBLANG_SAMI_NORTHERN_SWEDEN' : 0x02, |
| 319 'SUBLANG_SAMI_NORTHERN_FINLAND' : 0x03, |
| 320 'SUBLANG_SAMI_LULE_NORWAY' : 0x04, |
| 321 'SUBLANG_SAMI_LULE_SWEDEN' : 0x05, |
| 322 'SUBLANG_SAMI_SOUTHERN_NORWAY' : 0x06, |
| 323 'SUBLANG_SAMI_SOUTHERN_SWEDEN' : 0x07, |
| 324 'SUBLANG_SAMI_SKOLT_FINLAND' : 0x08, |
| 325 'SUBLANG_SAMI_INARI_FINLAND' : 0x09, |
| 326 'SUBLANG_SANSKRIT_INDIA' : 0x01, |
| 327 'SUBLANG_SCOTTISH_GAELIC' : 0x01, |
| 328 'SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN' : 0x06, |
| 329 'SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC' : 0x07, |
| 330 'SUBLANG_SERBIAN_MONTENEGRO_LATIN' : 0x0b, |
| 331 'SUBLANG_SERBIAN_MONTENEGRO_CYRILLIC' : 0x0c, |
| 332 'SUBLANG_SERBIAN_SERBIA_LATIN' : 0x09, |
| 333 'SUBLANG_SERBIAN_SERBIA_CYRILLIC' : 0x0a, |
| 334 'SUBLANG_SERBIAN_CROATIA' : 0x01, |
| 335 'SUBLANG_SERBIAN_LATIN' : 0x02, |
| 336 'SUBLANG_SERBIAN_CYRILLIC' : 0x03, |
| 337 'SUBLANG_SINDHI_INDIA' : 0x01, |
| 338 'SUBLANG_SINDHI_PAKISTAN' : 0x02, |
| 339 'SUBLANG_SINDHI_AFGHANISTAN' : 0x02, |
| 340 'SUBLANG_SINHALESE_SRI_LANKA' : 0x01, |
| 341 'SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA' : 0x01, |
| 342 'SUBLANG_SLOVAK_SLOVAKIA' : 0x01, |
| 343 'SUBLANG_SLOVENIAN_SLOVENIA' : 0x01, |
| 344 'SUBLANG_SPANISH' : 0x01, |
| 345 'SUBLANG_SPANISH_MEXICAN' : 0x02, |
| 346 'SUBLANG_SPANISH_MODERN' : 0x03, |
| 347 'SUBLANG_SPANISH_GUATEMALA' : 0x04, |
| 348 'SUBLANG_SPANISH_COSTA_RICA' : 0x05, |
| 349 'SUBLANG_SPANISH_PANAMA' : 0x06, |
| 350 'SUBLANG_SPANISH_DOMINICAN_REPUBLIC' : 0x07, |
| 351 'SUBLANG_SPANISH_VENEZUELA' : 0x08, |
| 352 'SUBLANG_SPANISH_COLOMBIA' : 0x09, |
| 353 'SUBLANG_SPANISH_PERU' : 0x0a, |
| 354 'SUBLANG_SPANISH_ARGENTINA' : 0x0b, |
| 355 'SUBLANG_SPANISH_ECUADOR' : 0x0c, |
| 356 'SUBLANG_SPANISH_CHILE' : 0x0d, |
| 357 'SUBLANG_SPANISH_URUGUAY' : 0x0e, |
| 358 'SUBLANG_SPANISH_PARAGUAY' : 0x0f, |
| 359 'SUBLANG_SPANISH_BOLIVIA' : 0x10, |
| 360 'SUBLANG_SPANISH_EL_SALVADOR' : 0x11, |
| 361 'SUBLANG_SPANISH_HONDURAS' : 0x12, |
| 362 'SUBLANG_SPANISH_NICARAGUA' : 0x13, |
| 363 'SUBLANG_SPANISH_PUERTO_RICO' : 0x14, |
| 364 'SUBLANG_SPANISH_US' : 0x15, |
| 365 'SUBLANG_SWAHILI_KENYA' : 0x01, |
| 366 'SUBLANG_SWEDISH' : 0x01, |
| 367 'SUBLANG_SWEDISH_FINLAND' : 0x02, |
| 368 'SUBLANG_SYRIAC_SYRIA' : 0x01, |
| 369 'SUBLANG_TAJIK_TAJIKISTAN' : 0x01, |
| 370 'SUBLANG_TAMAZIGHT_ALGERIA_LATIN' : 0x02, |
| 371 'SUBLANG_TAMIL_INDIA' : 0x01, |
| 372 'SUBLANG_TATAR_RUSSIA' : 0x01, |
| 373 'SUBLANG_TELUGU_INDIA' : 0x01, |
| 374 'SUBLANG_THAI_THAILAND' : 0x01, |
| 375 'SUBLANG_TIBETAN_PRC' : 0x01, |
| 376 'SUBLANG_TIGRIGNA_ERITREA' : 0x02, |
| 377 'SUBLANG_TSWANA_SOUTH_AFRICA' : 0x01, |
| 378 'SUBLANG_TURKISH_TURKEY' : 0x01, |
| 379 'SUBLANG_TURKMEN_TURKMENISTAN' : 0x01, |
| 380 'SUBLANG_UIGHUR_PRC' : 0x01, |
| 381 'SUBLANG_UKRAINIAN_UKRAINE' : 0x01, |
| 382 'SUBLANG_UPPER_SORBIAN_GERMANY' : 0x01, |
| 383 'SUBLANG_URDU_PAKISTAN' : 0x01, |
| 384 'SUBLANG_URDU_INDIA' : 0x02, |
| 385 'SUBLANG_UZBEK_LATIN' : 0x01, |
| 386 'SUBLANG_UZBEK_CYRILLIC' : 0x02, |
| 387 'SUBLANG_VIETNAMESE_VIETNAM' : 0x01, |
| 388 'SUBLANG_WELSH_UNITED_KINGDOM' : 0x01, |
| 389 'SUBLANG_WOLOF_SENEGAL' : 0x01, |
| 390 'SUBLANG_XHOSA_SOUTH_AFRICA' : 0x01, |
| 391 'SUBLANG_YAKUT_RUSSIA' : 0x01, |
| 392 'SUBLANG_YI_PRC' : 0x01, |
| 393 'SUBLANG_YORUBA_NIGERIA' : 0x01, |
| 394 'SUBLANG_ZULU_SOUTH_AFRICA' : 0x01, |
| 395 } |
| 396 |
| 397 |
| 398 ''' |
| 399 This dictionary defines the language lookup table. The key is the language ISO |
| 400 country code, and the value specifies the corresponding code page, primary |
| 401 language and sublanguage. |
| 402 |
| 403 LCID resource: http://msdn.microsoft.com/en-us/library/ms776294.aspx |
| 404 Codepage resource: http://www.science.co.il/language/locale-codes.asp |
| 405 Language ID resource: http://msdn.microsoft.com/en-us/library/ms776294.aspx |
| 406 |
| 407 There is no appropriate sublang for Spanish (Latin America) [es-419], so we |
| 408 use Mexico. SUBLANG_DEFAULT would incorrectly map to Spain. Unlike other |
| 409 Latin American countries, Mexican Spanish is supported by VERSIONINFO: |
| 410 http://msdn.microsoft.com/en-us/library/aa381058.aspx |
| 411 |
| 412 ''' |
| 413 _LANGUAGE_MAP = { |
| 414 # Language neutral LCID, unicode(1200) code page. |
| 415 'neutral' : [ 1200, 'LANG_NEUTRAL', 'SUBLANG_NEUTRAL' ], |
| 416 # LANG_USER_DEFAULT LCID, unicode(1200) code page. |
| 417 'userdefault' : [ 1200, 'LANG_NEUTRAL', 'SUBLANG_DEFAULT' ], |
| 418 'fake-bidi' : [ 1255, 'LANG_HEBREW', 'SUBLANG_DEFAULT' ], |
| 419 'af' : [ 1252, 'LANG_AFRIKAANS', 'SUBLANG_DEFAULT' ], |
| 420 'am' : [ 1200, 'LANG_AMHARIC', 'SUBLANG_DEFAULT' ], |
| 421 'ar' : [ 1256, 'LANG_ARABIC', 'SUBLANG_DEFAULT' ], |
| 422 'bg' : [ 1251, 'LANG_BULGARIAN', 'SUBLANG_DEFAULT' ], |
| 423 'bn' : [ 1200, 'LANG_BENGALI', 'SUBLANG_DEFAULT' ], |
| 424 'ca' : [ 1252, 'LANG_CATALAN', 'SUBLANG_DEFAULT' ], |
| 425 'cs' : [ 1250, 'LANG_CZECH', 'SUBLANG_DEFAULT' ], |
| 426 'da' : [ 1252, 'LANG_DANISH', 'SUBLANG_DEFAULT' ], |
| 427 'de' : [ 1252, 'LANG_GERMAN', 'SUBLANG_GERMAN' ], |
| 428 'el' : [ 1253, 'LANG_GREEK', 'SUBLANG_DEFAULT' ], |
| 429 'en' : [ 1200, 'LANG_ENGLISH', 'SUBLANG_ENGLISH_US' ], |
| 430 'en-GB' : [ 1038, 'LANG_ENGLISH', 'SUBLANG_ENGLISH_UK' ], |
| 431 'es' : [ 1252, 'LANG_SPANISH', 'SUBLANG_SPANISH_MODERN' ], |
| 432 # LCID for Mexico; Windows does not support L.A. LCID. |
| 433 'es-419' : [ 1252, 'LANG_SPANISH', 'SUBLANG_SPANISH_MEXICAN' ], |
| 434 'et' : [ 1257, 'LANG_ESTONIAN', 'SUBLANG_DEFAULT' ], |
| 435 'eu' : [ 1252, 'LANG_BASQUE', 'SUBLANG_DEFAULT' ], |
| 436 'fa' : [ 1256, 'LANG_PERSIAN', 'SUBLANG_DEFAULT' ], |
| 437 'fi' : [ 1252, 'LANG_FINNISH', 'SUBLANG_DEFAULT' ], |
| 438 'fil' : [ 1252, 'LANG_FILIPINO', 'SUBLANG_DEFAULT' ], |
| 439 'fr' : [ 1252, 'LANG_FRENCH', 'SUBLANG_FRENCH' ], |
| 440 'fr-CA' : [ 1252, 'LANG_FRENCH', 'SUBLANG_FRENCH_CANADIAN' ], |
| 441 'gl' : [ 1252, 'LANG_GALICIAN', 'SUBLANG_DEFAULT' ], |
| 442 'gu' : [ 1200, 'LANG_GUJARATI', 'SUBLANG_DEFAULT' ], |
| 443 'he' : [ 1255, 'LANG_HEBREW', 'SUBLANG_DEFAULT' ], |
| 444 'hi' : [ 1200, 'LANG_HINDI', 'SUBLANG_DEFAULT' ], |
| 445 'hr' : [ 1252, 'LANG_CROATIAN', 'SUBLANG_DEFAULT' ], |
| 446 'hu' : [ 1250, 'LANG_HUNGARIAN', 'SUBLANG_DEFAULT' ], |
| 447 'id' : [ 1252, 'LANG_INDONESIAN', 'SUBLANG_DEFAULT' ], |
| 448 'is' : [ 1252, 'LANG_ICELANDIC', 'SUBLANG_DEFAULT' ], |
| 449 'it' : [ 1252, 'LANG_ITALIAN', 'SUBLANG_DEFAULT' ], |
| 450 'iw' : [ 1255, 'LANG_HEBREW', 'SUBLANG_DEFAULT' ], |
| 451 'ja' : [ 932, 'LANG_JAPANESE', 'SUBLANG_DEFAULT' ], |
| 452 'kn' : [ 1200, 'LANG_KANNADA', 'SUBLANG_DEFAULT' ], |
| 453 'ko' : [ 949, 'LANG_KOREAN', 'SUBLANG_KOREAN' ], |
| 454 'lt' : [ 1257, 'LANG_LITHUANIAN', 'SUBLANG_LITHUANIAN' ], |
| 455 'lv' : [ 1257, 'LANG_LATVIAN', 'SUBLANG_DEFAULT' ], |
| 456 'ml' : [ 1200, 'LANG_MALAYALAM', 'SUBLANG_DEFAULT' ], |
| 457 'mr' : [ 1200, 'LANG_MARATHI', 'SUBLANG_DEFAULT' ], |
| 458 # Malay (Malaysia) [ms-MY] |
| 459 'ms' : [ 1252, 'LANG_MALAY', 'SUBLANG_DEFAULT' ], |
| 460 'nb' : [ 1252, 'LANG_NORWEGIAN', 'SUBLANG_NORWEGIAN_BOKMAL' ], |
| 461 'ne' : [ 1200, 'LANG_NEPALI', 'SUBLANG_NEPALI_NEPAL' ], |
| 462 'nl' : [ 1252, 'LANG_DUTCH', 'SUBLANG_DEFAULT' ], |
| 463 'nn' : [ 1252, 'LANG_NORWEGIAN', 'SUBLANG_NORWEGIAN_NYNORSK' ], |
| 464 'no' : [ 1252, 'LANG_NORWEGIAN', 'SUBLANG_DEFAULT' ], |
| 465 'or' : [ 1200, 'LANG_ORIYA', 'SUBLANG_DEFAULT' ], |
| 466 'pa' : [ 1200, 'LANG_PUNJABI', 'SUBLANG_PUNJABI_INDIA' ], |
| 467 'pl' : [ 1250, 'LANG_POLISH', 'SUBLANG_DEFAULT' ], |
| 468 'pt-BR' : [ 1252, 'LANG_PORTUGUESE', 'SUBLANG_DEFAULT' ], |
| 469 'pt-PT' : [ 1252, 'LANG_PORTUGUESE', 'SUBLANG_PORTUGUESE' ], |
| 470 'ro' : [ 1250, 'LANG_ROMANIAN', 'SUBLANG_DEFAULT' ], |
| 471 'ru' : [ 1251, 'LANG_RUSSIAN', 'SUBLANG_DEFAULT' ], |
| 472 'sa' : [ 1200, 'LANG_SANSKRIT', 'SUBLANG_SANSKRIT_INDIA' ], |
| 473 'si' : [ 1200, 'LANG_SINHALESE', 'SUBLANG_SINHALESE_SRI_LANKA' ], |
| 474 'sk' : [ 1250, 'LANG_SLOVAK', 'SUBLANG_DEFAULT' ], |
| 475 'sl' : [ 1250, 'LANG_SLOVENIAN', 'SUBLANG_DEFAULT' ], |
| 476 'sr' : [ 1250, 'LANG_SERBIAN', 'SUBLANG_SERBIAN_LATIN' ], |
| 477 'sv' : [ 1252, 'LANG_SWEDISH', 'SUBLANG_SWEDISH' ], |
| 478 'sw' : [ 1252, 'LANG_SWAHILI', 'SUBLANG_DEFAULT' ], |
| 479 'ta' : [ 1200, 'LANG_TAMIL', 'SUBLANG_DEFAULT' ], |
| 480 'te' : [ 1200, 'LANG_TELUGU', 'SUBLANG_DEFAULT' ], |
| 481 'th' : [ 874, 'LANG_THAI', 'SUBLANG_DEFAULT' ], |
| 482 'ti' : [ 1200, 'LANG_TIGRIGNA', 'SUBLANG_TIGRIGNA_ERITREA' ], |
| 483 'tr' : [ 1254, 'LANG_TURKISH', 'SUBLANG_DEFAULT' ], |
| 484 'uk' : [ 1251, 'LANG_UKRAINIAN', 'SUBLANG_DEFAULT' ], |
| 485 'ur' : [ 1200, 'LANG_URDU', 'SUBLANG_DEFAULT' ], |
| 486 'vi' : [ 1258, 'LANG_VIETNAMESE', 'SUBLANG_DEFAULT' ], |
| 487 'zh-CN' : [ 936, 'LANG_CHINESE', 'SUBLANG_CHINESE_SIMPLIFIED' ], |
| 488 'zh-HK' : [ 950, 'LANG_CHINESE', 'SUBLANG_CHINESE_HONGKONG' ], |
| 489 'zh-TW' : [ 950, 'LANG_CHINESE', 'SUBLANG_CHINESE_TRADITIONAL' ], |
| 490 'zu' : [ 1200, 'LANG_ZULU', 'SUBLANG_DEFAULT' ], |
| 491 } |
| 492 |
| 493 |
| 494 # Right-To-Left languages |
| 495 _RTL_LANGUAGES = ( |
| 496 'ar', # Arabic |
| 497 'fa', # Farsi |
| 498 'iw', # Hebrew |
| 499 'ks', # Kashmiri |
| 500 'ku', # Kurdish |
| 501 'ps', # Pashto |
| 502 'ur', # Urdu |
| 503 'yi', # Yiddish |
| 504 ) |
| 505 |
| 506 |
| 507 def GetCodepage(language): |
| 508 """ Returns the codepage for the given |language|. """ |
| 509 lang = _LANGUAGE_MAP[language] |
| 510 return "%04x" % lang[0] |
| 511 |
| 512 |
| 513 def GetCodepageDecimal(language): |
| 514 """ Returns the codepage for the given |language| as a decimal value. """ |
| 515 lang = _LANGUAGE_MAP[language] |
| 516 return "%d" % lang[0] |
| 517 |
| 518 |
| 519 def GetLangId(language): |
| 520 """ Returns the language id for the given |language|. """ |
| 521 lang = _LANGUAGE_MAP[language] |
| 522 return "%04x" % (_LANGUAGE_PRIMARY[lang[1]] | (_LANGUAGE_SUB[lang[2]] << 10)) |
| 523 |
| 524 |
| 525 def GetPrimaryLanguage(language): |
| 526 """ Returns the primary language ID for the given |language|. """ |
| 527 lang = _LANGUAGE_MAP[language] |
| 528 return _LANGUAGE_PRIMARY[lang[1]] |
| 529 |
| 530 |
| 531 def GetSublanguage(language): |
| 532 """ Returns the sublanguage ID for the given |language|. """ |
| 533 lang = _LANGUAGE_MAP[language] |
| 534 return _LANGUAGE_SUB[lang[2]] |
| 535 |
| 536 |
| 537 def IsRtlLanguage(language): |
| 538 return language in _RTL_LANGUAGES; |
| 539 |
| 540 |
| 541 def NormalizeLanguageCode(language): |
| 542 return language.replace('_', '-', 1) |
| 543 |
| 544 |
| 545 def ReadValuesFromFile(values_dict, file_name): |
| 546 """ |
| 547 Reads KEYWORD=VALUE settings from the specified file. |
| 548 |
| 549 Everything to the left of the first '=' is the keyword, |
| 550 everything to the right is the value. No stripping of |
| 551 white space, so beware. |
| 552 |
| 553 The file must exist, otherwise you get the Python exception from open(). |
| 554 """ |
| 555 for line in open(file_name, 'r').readlines(): |
| 556 key, val = line.rstrip('\r\n').split('=', 1) |
| 557 values_dict[key] = val |
| 558 |
| 559 |
| 560 def ReadMessagesFromFile(file_name): |
| 561 """ |
| 562 Reads messages from a 'chrome_messages_json' file. |
| 563 |
| 564 The file must exist, otherwise you get the Python exception from open(). |
| 565 """ |
| 566 messages_file = io.open(file_name, encoding='utf-8-sig') |
| 567 messages = json.load(messages_file) |
| 568 messages_file.close() |
| 569 |
| 570 values = {} |
| 571 for key in messages.keys(): |
| 572 values[key] = unicode(messages[key]['message']); |
| 573 return values |
| 574 |
| 575 |
| 576 def WriteIfChanged(file_name, contents, encoding='utf-16'): |
| 577 """ |
| 578 Writes the specified contents to the specified file_name |
| 579 iff the contents are different than the current contents. |
| 580 """ |
| 581 try: |
| 582 target = io.open(file_name, 'r') |
| 583 old_contents = target.read() |
| 584 except EnvironmentError: |
| 585 pass |
| 586 except UnicodeDecodeError: |
| 587 target.close() |
| 588 os.unlink(file_name) |
| 589 else: |
| 590 if contents == old_contents: |
| 591 return |
| 592 target.close() |
| 593 os.unlink(file_name) |
| 594 io.open(file_name, 'w', encoding=encoding).write(contents) |
| 595 |
| 596 |
| 597 class MessageMap: |
| 598 """ Provides a dictionary of localized messages for each language.""" |
| 599 def __init__(self, languages, messages_path): |
| 600 self.language = None |
| 601 self.message_map = {} |
| 602 |
| 603 # Populate the message map |
| 604 if messages_path: |
| 605 for language in languages: |
| 606 file_name = os.path.join(messages_path, |
| 607 language.replace('-', '_', 1), |
| 608 'messages.json') |
| 609 self.message_map[language] = ReadMessagesFromFile(file_name) |
| 610 |
| 611 def GetText(self, message): |
| 612 """ Returns a localized message for the current language. """ |
| 613 return self.message_map[self.language][message] |
| 614 |
| 615 def SelectLanguage(self, language): |
| 616 """ Selects the language to be used when retrieving localized messages. """ |
| 617 self.language = language |
| 618 |
| 619 def MakeSelectLanguage(self): |
| 620 """ Returns a function that can be used to select the current language. """ |
| 621 return lambda language: self.SelectLanguage(language) |
| 622 |
| 623 def MakeGetText(self): |
| 624 """ Returns a function that can be used to retrieve a localized message. """ |
| 625 return lambda message: self.GetText(message) |
| 626 |
| 627 |
| 628 def Localize(source, target, options): |
| 629 # Load jinja2 library. |
| 630 if options.jinja2: |
| 631 jinja2_path = os.path.normpath(options.jinja2) |
| 632 else: |
| 633 jinja2_path = os.path.normpath(os.path.join(os.path.abspath(__file__), |
| 634 '../../../third_party/jinja2')) |
| 635 sys.path.append(os.path.split(jinja2_path)[0]) |
| 636 from jinja2 import Environment, FileSystemLoader |
| 637 |
| 638 # Create jinja2 environment. |
| 639 (template_path, template_name) = os.path.split(source) |
| 640 env = Environment(loader=FileSystemLoader(template_path), |
| 641 extensions=['jinja2.ext.do', 'jinja2.ext.i18n']) |
| 642 |
| 643 # Register custom filters. |
| 644 env.filters['GetCodepage'] = GetCodepage |
| 645 env.filters['GetCodepageDecimal'] = GetCodepageDecimal |
| 646 env.filters['GetLangId'] = GetLangId |
| 647 env.filters['GetPrimaryLanguage'] = GetPrimaryLanguage |
| 648 env.filters['GetSublanguage'] = GetSublanguage |
| 649 |
| 650 # Set the list of languages to use |
| 651 languages = map(NormalizeLanguageCode, options.languages) |
| 652 context = { 'languages' : languages } |
| 653 env.globals['IsRtlLanguage'] = IsRtlLanguage |
| 654 |
| 655 # Load the localized messages and register the message map with jinja2.i18n |
| 656 # extension. |
| 657 message_map = MessageMap(languages, options.messages_path) |
| 658 env.globals['SelectLanguage'] = message_map.MakeSelectLanguage() |
| 659 env.install_gettext_callables(message_map.MakeGetText(), |
| 660 message_map.MakeGetText()); |
| 661 |
| 662 # Add OFFICIAL_BUILD variable the same way chrome/tools/build/version.py |
| 663 # does. |
| 664 if os.environ.get('CHROME_BUILD_TYPE') == '_official': |
| 665 context['official_build'] = '1' |
| 666 else: |
| 667 context['official_build'] = '0' |
| 668 |
| 669 # Add all variables defined in the command line. |
| 670 if options.define: |
| 671 for define in options.define: |
| 672 context.update(dict([define.split('=', 1)])); |
| 673 |
| 674 # Read KEYWORD=VALUE variables from file. |
| 675 if options.input: |
| 676 for file_name in options.input: |
| 677 ReadValuesFromFile(context, file_name) |
| 678 |
| 679 template = env.get_template(template_name) |
| 680 WriteIfChanged(target, template.render(context), options.encoding); |
| 681 return 0; |
| 682 |
| 683 |
| 684 def main(): |
| 685 usage = "Usage: localize [options] <input> <output>" |
| 686 parser = OptionParser(usage=usage) |
| 687 parser.add_option( |
| 688 '-d', '--define', dest='define', action='append', type='string', |
| 689 help='define a variable (VAR=VALUE).') |
| 690 parser.add_option( |
| 691 '-i', '--input', dest='input', action='append', type='string', |
| 692 help='read variables from INPUT.') |
| 693 parser.add_option( |
| 694 '-l', '--language', dest='languages', action='append', type='string', |
| 695 help='add LANGUAGE to the list of languages to use.') |
| 696 parser.add_option( |
| 697 '--encoding', dest='encoding', type='string', default='utf-16', |
| 698 help="set the encoding of <output>. 'utf-16' is the default.") |
| 699 parser.add_option( |
| 700 '--jinja2', dest='jinja2', type='string', |
| 701 help="specifies path to the jinja2 library.") |
| 702 parser.add_option( |
| 703 '--messages_path', dest='messages_path', type='string', |
| 704 help="set path to localized messages.") |
| 705 |
| 706 options, args = parser.parse_args() |
| 707 if len(args) != 2: |
| 708 parser.error('Two positional arguments (<input> and <output>) are expected') |
| 709 if not options.languages: |
| 710 parser.error('At least one language must be specified') |
| 711 if not options.messages_path: |
| 712 parser.error('--messages_path is required') |
| 713 |
| 714 return Localize(args[0], args[1], options) |
| 715 |
| 716 if __name__ == '__main__': |
| 717 sys.exit(main()) |
| 718 |
OLD | NEW |