summaryrefslogtreecommitdiffstats
path: root/remoting/tools/build/remoting_localize.py
diff options
context:
space:
mode:
Diffstat (limited to 'remoting/tools/build/remoting_localize.py')
-rwxr-xr-xremoting/tools/build/remoting_localize.py773
1 files changed, 773 insertions, 0 deletions
diff --git a/remoting/tools/build/remoting_localize.py b/remoting/tools/build/remoting_localize.py
new file mode 100755
index 0000000..8dc0538
--- /dev/null
+++ b/remoting/tools/build/remoting_localize.py
@@ -0,0 +1,773 @@
+#!/usr/bin/env python
+# Copyright 2013 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.
+
+"""
+localize.py -- Generates an output file from the given template replacing
+variables and localizing strings.
+
+The script uses Jinja2 template processing library (src/third_party/jinja2).
+Variables available to the templates:
+ - |languages| - the list of languages passed on the command line. ('-l').
+ - Each NAME=VALUE define ('-d') can be accesses as {{ NAME }}.
+ - |official_build| is set to '1' when CHROME_BUILD_TYPE environment variable
+ is set to "_official".
+
+Filters:
+ - GetCodepage - returns the code page for the given language.
+ - GetCodepageDecimal same as GetCodepage, but returns a decimal value.
+ - GetLangId - returns Win32 LANGID.
+ - GetPrimaryLanguage - returns a named Win32 constant specifing the primary
+ language ID.
+ - GetSublanguage - returns a named Win32 constant specifing the sublanguage
+ ID.
+
+Globals:
+ - IsRtlLanguage(language) - returns True if the language is right-to-left.
+ - SelectLanguage(language) - allows to select the language to the used by
+ {% trans %}{% endtrans %} statements.
+
+"""
+
+import io
+import json
+from optparse import OptionParser
+import os
+import sys
+from string import Template
+
+
+# Win32 primary languages IDs.
+_LANGUAGE_PRIMARY = {
+ 'LANG_NEUTRAL' : 0x00,
+ 'LANG_INVARIANT' : 0x7f,
+ 'LANG_AFRIKAANS' : 0x36,
+ 'LANG_ALBANIAN' : 0x1c,
+ 'LANG_ALSATIAN' : 0x84,
+ 'LANG_AMHARIC' : 0x5e,
+ 'LANG_ARABIC' : 0x01,
+ 'LANG_ARMENIAN' : 0x2b,
+ 'LANG_ASSAMESE' : 0x4d,
+ 'LANG_AZERI' : 0x2c,
+ 'LANG_BASHKIR' : 0x6d,
+ 'LANG_BASQUE' : 0x2d,
+ 'LANG_BELARUSIAN' : 0x23,
+ 'LANG_BENGALI' : 0x45,
+ 'LANG_BRETON' : 0x7e,
+ 'LANG_BOSNIAN' : 0x1a,
+ 'LANG_BULGARIAN' : 0x02,
+ 'LANG_CATALAN' : 0x03,
+ 'LANG_CHINESE' : 0x04,
+ 'LANG_CORSICAN' : 0x83,
+ 'LANG_CROATIAN' : 0x1a,
+ 'LANG_CZECH' : 0x05,
+ 'LANG_DANISH' : 0x06,
+ 'LANG_DARI' : 0x8c,
+ 'LANG_DIVEHI' : 0x65,
+ 'LANG_DUTCH' : 0x13,
+ 'LANG_ENGLISH' : 0x09,
+ 'LANG_ESTONIAN' : 0x25,
+ 'LANG_FAEROESE' : 0x38,
+ 'LANG_FILIPINO' : 0x64,
+ 'LANG_FINNISH' : 0x0b,
+ 'LANG_FRENCH' : 0x0c,
+ 'LANG_FRISIAN' : 0x62,
+ 'LANG_GALICIAN' : 0x56,
+ 'LANG_GEORGIAN' : 0x37,
+ 'LANG_GERMAN' : 0x07,
+ 'LANG_GREEK' : 0x08,
+ 'LANG_GREENLANDIC' : 0x6f,
+ 'LANG_GUJARATI' : 0x47,
+ 'LANG_HAUSA' : 0x68,
+ 'LANG_HEBREW' : 0x0d,
+ 'LANG_HINDI' : 0x39,
+ 'LANG_HUNGARIAN' : 0x0e,
+ 'LANG_ICELANDIC' : 0x0f,
+ 'LANG_IGBO' : 0x70,
+ 'LANG_INDONESIAN' : 0x21,
+ 'LANG_INUKTITUT' : 0x5d,
+ 'LANG_IRISH' : 0x3c,
+ 'LANG_ITALIAN' : 0x10,
+ 'LANG_JAPANESE' : 0x11,
+ 'LANG_KANNADA' : 0x4b,
+ 'LANG_KASHMIRI' : 0x60,
+ 'LANG_KAZAK' : 0x3f,
+ 'LANG_KHMER' : 0x53,
+ 'LANG_KICHE' : 0x86,
+ 'LANG_KINYARWANDA' : 0x87,
+ 'LANG_KONKANI' : 0x57,
+ 'LANG_KOREAN' : 0x12,
+ 'LANG_KYRGYZ' : 0x40,
+ 'LANG_LAO' : 0x54,
+ 'LANG_LATVIAN' : 0x26,
+ 'LANG_LITHUANIAN' : 0x27,
+ 'LANG_LOWER_SORBIAN' : 0x2e,
+ 'LANG_LUXEMBOURGISH' : 0x6e,
+ 'LANG_MACEDONIAN' : 0x2f,
+ 'LANG_MALAY' : 0x3e,
+ 'LANG_MALAYALAM' : 0x4c,
+ 'LANG_MALTESE' : 0x3a,
+ 'LANG_MANIPURI' : 0x58,
+ 'LANG_MAORI' : 0x81,
+ 'LANG_MAPUDUNGUN' : 0x7a,
+ 'LANG_MARATHI' : 0x4e,
+ 'LANG_MOHAWK' : 0x7c,
+ 'LANG_MONGOLIAN' : 0x50,
+ 'LANG_NEPALI' : 0x61,
+ 'LANG_NORWEGIAN' : 0x14,
+ 'LANG_OCCITAN' : 0x82,
+ 'LANG_ORIYA' : 0x48,
+ 'LANG_PASHTO' : 0x63,
+ 'LANG_PERSIAN' : 0x29,
+ 'LANG_POLISH' : 0x15,
+ 'LANG_PORTUGUESE' : 0x16,
+ 'LANG_PUNJABI' : 0x46,
+ 'LANG_QUECHUA' : 0x6b,
+ 'LANG_ROMANIAN' : 0x18,
+ 'LANG_ROMANSH' : 0x17,
+ 'LANG_RUSSIAN' : 0x19,
+ 'LANG_SAMI' : 0x3b,
+ 'LANG_SANSKRIT' : 0x4f,
+ 'LANG_SCOTTISH_GAELIC' : 0x91,
+ 'LANG_SERBIAN' : 0x1a,
+ 'LANG_SINDHI' : 0x59,
+ 'LANG_SINHALESE' : 0x5b,
+ 'LANG_SLOVAK' : 0x1b,
+ 'LANG_SLOVENIAN' : 0x24,
+ 'LANG_SOTHO' : 0x6c,
+ 'LANG_SPANISH' : 0x0a,
+ 'LANG_SWAHILI' : 0x41,
+ 'LANG_SWEDISH' : 0x1d,
+ 'LANG_SYRIAC' : 0x5a,
+ 'LANG_TAJIK' : 0x28,
+ 'LANG_TAMAZIGHT' : 0x5f,
+ 'LANG_TAMIL' : 0x49,
+ 'LANG_TATAR' : 0x44,
+ 'LANG_TELUGU' : 0x4a,
+ 'LANG_THAI' : 0x1e,
+ 'LANG_TIBETAN' : 0x51,
+ 'LANG_TIGRIGNA' : 0x73,
+ 'LANG_TSWANA' : 0x32,
+ 'LANG_TURKISH' : 0x1f,
+ 'LANG_TURKMEN' : 0x42,
+ 'LANG_UIGHUR' : 0x80,
+ 'LANG_UKRAINIAN' : 0x22,
+ 'LANG_UPPER_SORBIAN' : 0x2e,
+ 'LANG_URDU' : 0x20,
+ 'LANG_UZBEK' : 0x43,
+ 'LANG_VIETNAMESE' : 0x2a,
+ 'LANG_WELSH' : 0x52,
+ 'LANG_WOLOF' : 0x88,
+ 'LANG_XHOSA' : 0x34,
+ 'LANG_YAKUT' : 0x85,
+ 'LANG_YI' : 0x78,
+ 'LANG_YORUBA' : 0x6a,
+ 'LANG_ZULU' : 0x35,
+}
+
+
+# Win32 sublanguage IDs.
+_LANGUAGE_SUB = {
+ 'SUBLANG_NEUTRAL' : 0x00,
+ 'SUBLANG_DEFAULT' : 0x01,
+ 'SUBLANG_SYS_DEFAULT' : 0x02,
+ 'SUBLANG_CUSTOM_DEFAULT' : 0x03,
+ 'SUBLANG_CUSTOM_UNSPECIFIED' : 0x04,
+ 'SUBLANG_UI_CUSTOM_DEFAULT' : 0x05,
+ 'SUBLANG_AFRIKAANS_SOUTH_AFRICA' : 0x01,
+ 'SUBLANG_ALBANIAN_ALBANIA' : 0x01,
+ 'SUBLANG_ALSATIAN_FRANCE' : 0x01,
+ 'SUBLANG_AMHARIC_ETHIOPIA' : 0x01,
+ 'SUBLANG_ARABIC_SAUDI_ARABIA' : 0x01,
+ 'SUBLANG_ARABIC_IRAQ' : 0x02,
+ 'SUBLANG_ARABIC_EGYPT' : 0x03,
+ 'SUBLANG_ARABIC_LIBYA' : 0x04,
+ 'SUBLANG_ARABIC_ALGERIA' : 0x05,
+ 'SUBLANG_ARABIC_MOROCCO' : 0x06,
+ 'SUBLANG_ARABIC_TUNISIA' : 0x07,
+ 'SUBLANG_ARABIC_OMAN' : 0x08,
+ 'SUBLANG_ARABIC_YEMEN' : 0x09,
+ 'SUBLANG_ARABIC_SYRIA' : 0x0a,
+ 'SUBLANG_ARABIC_JORDAN' : 0x0b,
+ 'SUBLANG_ARABIC_LEBANON' : 0x0c,
+ 'SUBLANG_ARABIC_KUWAIT' : 0x0d,
+ 'SUBLANG_ARABIC_UAE' : 0x0e,
+ 'SUBLANG_ARABIC_BAHRAIN' : 0x0f,
+ 'SUBLANG_ARABIC_QATAR' : 0x10,
+ 'SUBLANG_ARMENIAN_ARMENIA' : 0x01,
+ 'SUBLANG_ASSAMESE_INDIA' : 0x01,
+ 'SUBLANG_AZERI_LATIN' : 0x01,
+ 'SUBLANG_AZERI_CYRILLIC' : 0x02,
+ 'SUBLANG_BASHKIR_RUSSIA' : 0x01,
+ 'SUBLANG_BASQUE_BASQUE' : 0x01,
+ 'SUBLANG_BELARUSIAN_BELARUS' : 0x01,
+ 'SUBLANG_BENGALI_INDIA' : 0x01,
+ 'SUBLANG_BENGALI_BANGLADESH' : 0x02,
+ 'SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN' : 0x05,
+ 'SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC' : 0x08,
+ 'SUBLANG_BRETON_FRANCE' : 0x01,
+ 'SUBLANG_BULGARIAN_BULGARIA' : 0x01,
+ 'SUBLANG_CATALAN_CATALAN' : 0x01,
+ 'SUBLANG_CHINESE_TRADITIONAL' : 0x01,
+ 'SUBLANG_CHINESE_SIMPLIFIED' : 0x02,
+ 'SUBLANG_CHINESE_HONGKONG' : 0x03,
+ 'SUBLANG_CHINESE_SINGAPORE' : 0x04,
+ 'SUBLANG_CHINESE_MACAU' : 0x05,
+ 'SUBLANG_CORSICAN_FRANCE' : 0x01,
+ 'SUBLANG_CZECH_CZECH_REPUBLIC' : 0x01,
+ 'SUBLANG_CROATIAN_CROATIA' : 0x01,
+ 'SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN' : 0x04,
+ 'SUBLANG_DANISH_DENMARK' : 0x01,
+ 'SUBLANG_DARI_AFGHANISTAN' : 0x01,
+ 'SUBLANG_DIVEHI_MALDIVES' : 0x01,
+ 'SUBLANG_DUTCH' : 0x01,
+ 'SUBLANG_DUTCH_BELGIAN' : 0x02,
+ 'SUBLANG_ENGLISH_US' : 0x01,
+ 'SUBLANG_ENGLISH_UK' : 0x02,
+ 'SUBLANG_ENGLISH_AUS' : 0x03,
+ 'SUBLANG_ENGLISH_CAN' : 0x04,
+ 'SUBLANG_ENGLISH_NZ' : 0x05,
+ 'SUBLANG_ENGLISH_EIRE' : 0x06,
+ 'SUBLANG_ENGLISH_SOUTH_AFRICA' : 0x07,
+ 'SUBLANG_ENGLISH_JAMAICA' : 0x08,
+ 'SUBLANG_ENGLISH_CARIBBEAN' : 0x09,
+ 'SUBLANG_ENGLISH_BELIZE' : 0x0a,
+ 'SUBLANG_ENGLISH_TRINIDAD' : 0x0b,
+ 'SUBLANG_ENGLISH_ZIMBABWE' : 0x0c,
+ 'SUBLANG_ENGLISH_PHILIPPINES' : 0x0d,
+ 'SUBLANG_ENGLISH_INDIA' : 0x10,
+ 'SUBLANG_ENGLISH_MALAYSIA' : 0x11,
+ 'SUBLANG_ENGLISH_SINGAPORE' : 0x12,
+ 'SUBLANG_ESTONIAN_ESTONIA' : 0x01,
+ 'SUBLANG_FAEROESE_FAROE_ISLANDS' : 0x01,
+ 'SUBLANG_FILIPINO_PHILIPPINES' : 0x01,
+ 'SUBLANG_FINNISH_FINLAND' : 0x01,
+ 'SUBLANG_FRENCH' : 0x01,
+ 'SUBLANG_FRENCH_BELGIAN' : 0x02,
+ 'SUBLANG_FRENCH_CANADIAN' : 0x03,
+ 'SUBLANG_FRENCH_SWISS' : 0x04,
+ 'SUBLANG_FRENCH_LUXEMBOURG' : 0x05,
+ 'SUBLANG_FRENCH_MONACO' : 0x06,
+ 'SUBLANG_FRISIAN_NETHERLANDS' : 0x01,
+ 'SUBLANG_GALICIAN_GALICIAN' : 0x01,
+ 'SUBLANG_GEORGIAN_GEORGIA' : 0x01,
+ 'SUBLANG_GERMAN' : 0x01,
+ 'SUBLANG_GERMAN_SWISS' : 0x02,
+ 'SUBLANG_GERMAN_AUSTRIAN' : 0x03,
+ 'SUBLANG_GERMAN_LUXEMBOURG' : 0x04,
+ 'SUBLANG_GERMAN_LIECHTENSTEIN' : 0x05,
+ 'SUBLANG_GREEK_GREECE' : 0x01,
+ 'SUBLANG_GREENLANDIC_GREENLAND' : 0x01,
+ 'SUBLANG_GUJARATI_INDIA' : 0x01,
+ 'SUBLANG_HAUSA_NIGERIA_LATIN' : 0x01,
+ 'SUBLANG_HEBREW_ISRAEL' : 0x01,
+ 'SUBLANG_HINDI_INDIA' : 0x01,
+ 'SUBLANG_HUNGARIAN_HUNGARY' : 0x01,
+ 'SUBLANG_ICELANDIC_ICELAND' : 0x01,
+ 'SUBLANG_IGBO_NIGERIA' : 0x01,
+ 'SUBLANG_INDONESIAN_INDONESIA' : 0x01,
+ 'SUBLANG_INUKTITUT_CANADA' : 0x01,
+ 'SUBLANG_INUKTITUT_CANADA_LATIN' : 0x02,
+ 'SUBLANG_IRISH_IRELAND' : 0x02,
+ 'SUBLANG_ITALIAN' : 0x01,
+ 'SUBLANG_ITALIAN_SWISS' : 0x02,
+ 'SUBLANG_JAPANESE_JAPAN' : 0x01,
+ 'SUBLANG_KANNADA_INDIA' : 0x01,
+ 'SUBLANG_KASHMIRI_SASIA' : 0x02,
+ 'SUBLANG_KASHMIRI_INDIA' : 0x02,
+ 'SUBLANG_KAZAK_KAZAKHSTAN' : 0x01,
+ 'SUBLANG_KHMER_CAMBODIA' : 0x01,
+ 'SUBLANG_KICHE_GUATEMALA' : 0x01,
+ 'SUBLANG_KINYARWANDA_RWANDA' : 0x01,
+ 'SUBLANG_KONKANI_INDIA' : 0x01,
+ 'SUBLANG_KOREAN' : 0x01,
+ 'SUBLANG_KYRGYZ_KYRGYZSTAN' : 0x01,
+ 'SUBLANG_LAO_LAO' : 0x01,
+ 'SUBLANG_LATVIAN_LATVIA' : 0x01,
+ 'SUBLANG_LITHUANIAN' : 0x01,
+ 'SUBLANG_LOWER_SORBIAN_GERMANY' : 0x02,
+ 'SUBLANG_LUXEMBOURGISH_LUXEMBOURG' : 0x01,
+ 'SUBLANG_MACEDONIAN_MACEDONIA' : 0x01,
+ 'SUBLANG_MALAY_MALAYSIA' : 0x01,
+ 'SUBLANG_MALAY_BRUNEI_DARUSSALAM' : 0x02,
+ 'SUBLANG_MALAYALAM_INDIA' : 0x01,
+ 'SUBLANG_MALTESE_MALTA' : 0x01,
+ 'SUBLANG_MAORI_NEW_ZEALAND' : 0x01,
+ 'SUBLANG_MAPUDUNGUN_CHILE' : 0x01,
+ 'SUBLANG_MARATHI_INDIA' : 0x01,
+ 'SUBLANG_MOHAWK_MOHAWK' : 0x01,
+ 'SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA' : 0x01,
+ 'SUBLANG_MONGOLIAN_PRC' : 0x02,
+ 'SUBLANG_NEPALI_INDIA' : 0x02,
+ 'SUBLANG_NEPALI_NEPAL' : 0x01,
+ 'SUBLANG_NORWEGIAN_BOKMAL' : 0x01,
+ 'SUBLANG_NORWEGIAN_NYNORSK' : 0x02,
+ 'SUBLANG_OCCITAN_FRANCE' : 0x01,
+ 'SUBLANG_ORIYA_INDIA' : 0x01,
+ 'SUBLANG_PASHTO_AFGHANISTAN' : 0x01,
+ 'SUBLANG_PERSIAN_IRAN' : 0x01,
+ 'SUBLANG_POLISH_POLAND' : 0x01,
+ 'SUBLANG_PORTUGUESE' : 0x02,
+ 'SUBLANG_PORTUGUESE_BRAZILIAN' : 0x01,
+ 'SUBLANG_PUNJABI_INDIA' : 0x01,
+ 'SUBLANG_QUECHUA_BOLIVIA' : 0x01,
+ 'SUBLANG_QUECHUA_ECUADOR' : 0x02,
+ 'SUBLANG_QUECHUA_PERU' : 0x03,
+ 'SUBLANG_ROMANIAN_ROMANIA' : 0x01,
+ 'SUBLANG_ROMANSH_SWITZERLAND' : 0x01,
+ 'SUBLANG_RUSSIAN_RUSSIA' : 0x01,
+ 'SUBLANG_SAMI_NORTHERN_NORWAY' : 0x01,
+ 'SUBLANG_SAMI_NORTHERN_SWEDEN' : 0x02,
+ 'SUBLANG_SAMI_NORTHERN_FINLAND' : 0x03,
+ 'SUBLANG_SAMI_LULE_NORWAY' : 0x04,
+ 'SUBLANG_SAMI_LULE_SWEDEN' : 0x05,
+ 'SUBLANG_SAMI_SOUTHERN_NORWAY' : 0x06,
+ 'SUBLANG_SAMI_SOUTHERN_SWEDEN' : 0x07,
+ 'SUBLANG_SAMI_SKOLT_FINLAND' : 0x08,
+ 'SUBLANG_SAMI_INARI_FINLAND' : 0x09,
+ 'SUBLANG_SANSKRIT_INDIA' : 0x01,
+ 'SUBLANG_SCOTTISH_GAELIC' : 0x01,
+ 'SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN' : 0x06,
+ 'SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC' : 0x07,
+ 'SUBLANG_SERBIAN_MONTENEGRO_LATIN' : 0x0b,
+ 'SUBLANG_SERBIAN_MONTENEGRO_CYRILLIC' : 0x0c,
+ 'SUBLANG_SERBIAN_SERBIA_LATIN' : 0x09,
+ 'SUBLANG_SERBIAN_SERBIA_CYRILLIC' : 0x0a,
+ 'SUBLANG_SERBIAN_CROATIA' : 0x01,
+ 'SUBLANG_SERBIAN_LATIN' : 0x02,
+ 'SUBLANG_SERBIAN_CYRILLIC' : 0x03,
+ 'SUBLANG_SINDHI_INDIA' : 0x01,
+ 'SUBLANG_SINDHI_PAKISTAN' : 0x02,
+ 'SUBLANG_SINDHI_AFGHANISTAN' : 0x02,
+ 'SUBLANG_SINHALESE_SRI_LANKA' : 0x01,
+ 'SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA' : 0x01,
+ 'SUBLANG_SLOVAK_SLOVAKIA' : 0x01,
+ 'SUBLANG_SLOVENIAN_SLOVENIA' : 0x01,
+ 'SUBLANG_SPANISH' : 0x01,
+ 'SUBLANG_SPANISH_MEXICAN' : 0x02,
+ 'SUBLANG_SPANISH_MODERN' : 0x03,
+ 'SUBLANG_SPANISH_GUATEMALA' : 0x04,
+ 'SUBLANG_SPANISH_COSTA_RICA' : 0x05,
+ 'SUBLANG_SPANISH_PANAMA' : 0x06,
+ 'SUBLANG_SPANISH_DOMINICAN_REPUBLIC' : 0x07,
+ 'SUBLANG_SPANISH_VENEZUELA' : 0x08,
+ 'SUBLANG_SPANISH_COLOMBIA' : 0x09,
+ 'SUBLANG_SPANISH_PERU' : 0x0a,
+ 'SUBLANG_SPANISH_ARGENTINA' : 0x0b,
+ 'SUBLANG_SPANISH_ECUADOR' : 0x0c,
+ 'SUBLANG_SPANISH_CHILE' : 0x0d,
+ 'SUBLANG_SPANISH_URUGUAY' : 0x0e,
+ 'SUBLANG_SPANISH_PARAGUAY' : 0x0f,
+ 'SUBLANG_SPANISH_BOLIVIA' : 0x10,
+ 'SUBLANG_SPANISH_EL_SALVADOR' : 0x11,
+ 'SUBLANG_SPANISH_HONDURAS' : 0x12,
+ 'SUBLANG_SPANISH_NICARAGUA' : 0x13,
+ 'SUBLANG_SPANISH_PUERTO_RICO' : 0x14,
+ 'SUBLANG_SPANISH_US' : 0x15,
+ 'SUBLANG_SWAHILI_KENYA' : 0x01,
+ 'SUBLANG_SWEDISH' : 0x01,
+ 'SUBLANG_SWEDISH_FINLAND' : 0x02,
+ 'SUBLANG_SYRIAC_SYRIA' : 0x01,
+ 'SUBLANG_TAJIK_TAJIKISTAN' : 0x01,
+ 'SUBLANG_TAMAZIGHT_ALGERIA_LATIN' : 0x02,
+ 'SUBLANG_TAMIL_INDIA' : 0x01,
+ 'SUBLANG_TATAR_RUSSIA' : 0x01,
+ 'SUBLANG_TELUGU_INDIA' : 0x01,
+ 'SUBLANG_THAI_THAILAND' : 0x01,
+ 'SUBLANG_TIBETAN_PRC' : 0x01,
+ 'SUBLANG_TIGRIGNA_ERITREA' : 0x02,
+ 'SUBLANG_TSWANA_SOUTH_AFRICA' : 0x01,
+ 'SUBLANG_TURKISH_TURKEY' : 0x01,
+ 'SUBLANG_TURKMEN_TURKMENISTAN' : 0x01,
+ 'SUBLANG_UIGHUR_PRC' : 0x01,
+ 'SUBLANG_UKRAINIAN_UKRAINE' : 0x01,
+ 'SUBLANG_UPPER_SORBIAN_GERMANY' : 0x01,
+ 'SUBLANG_URDU_PAKISTAN' : 0x01,
+ 'SUBLANG_URDU_INDIA' : 0x02,
+ 'SUBLANG_UZBEK_LATIN' : 0x01,
+ 'SUBLANG_UZBEK_CYRILLIC' : 0x02,
+ 'SUBLANG_VIETNAMESE_VIETNAM' : 0x01,
+ 'SUBLANG_WELSH_UNITED_KINGDOM' : 0x01,
+ 'SUBLANG_WOLOF_SENEGAL' : 0x01,
+ 'SUBLANG_XHOSA_SOUTH_AFRICA' : 0x01,
+ 'SUBLANG_YAKUT_RUSSIA' : 0x01,
+ 'SUBLANG_YI_PRC' : 0x01,
+ 'SUBLANG_YORUBA_NIGERIA' : 0x01,
+ 'SUBLANG_ZULU_SOUTH_AFRICA' : 0x01,
+}
+
+
+'''
+This dictionary defines the language lookup table. The key is the language ISO
+country code, and the value specifies the corresponding code page, primary
+language and sublanguage.
+
+LCID resource: http://msdn.microsoft.com/en-us/library/ms776294.aspx
+Codepage resource: http://www.science.co.il/language/locale-codes.asp
+Language ID resource: http://msdn.microsoft.com/en-us/library/ms776294.aspx
+
+There is no appropriate sublang for Spanish (Latin America) [es-419], so we
+use Mexico. SUBLANG_DEFAULT would incorrectly map to Spain. Unlike other
+Latin American countries, Mexican Spanish is supported by VERSIONINFO:
+http://msdn.microsoft.com/en-us/library/aa381058.aspx
+
+'''
+_LANGUAGE_MAP = {
+ # Language neutral LCID, unicode(1200) code page.
+ 'neutral' : [ 1200, 'LANG_NEUTRAL', 'SUBLANG_NEUTRAL' ],
+ # LANG_USER_DEFAULT LCID, unicode(1200) code page.
+ 'userdefault' : [ 1200, 'LANG_NEUTRAL', 'SUBLANG_DEFAULT' ],
+ 'fake-bidi' : [ 1255, 'LANG_HEBREW', 'SUBLANG_DEFAULT' ],
+ 'af' : [ 1252, 'LANG_AFRIKAANS', 'SUBLANG_DEFAULT' ],
+ 'am' : [ 1200, 'LANG_AMHARIC', 'SUBLANG_DEFAULT' ],
+ 'ar' : [ 1256, 'LANG_ARABIC', 'SUBLANG_DEFAULT' ],
+ 'bg' : [ 1251, 'LANG_BULGARIAN', 'SUBLANG_DEFAULT' ],
+ 'bn' : [ 1200, 'LANG_BENGALI', 'SUBLANG_DEFAULT' ],
+ 'ca' : [ 1252, 'LANG_CATALAN', 'SUBLANG_DEFAULT' ],
+ 'cs' : [ 1250, 'LANG_CZECH', 'SUBLANG_DEFAULT' ],
+ 'da' : [ 1252, 'LANG_DANISH', 'SUBLANG_DEFAULT' ],
+ 'de' : [ 1252, 'LANG_GERMAN', 'SUBLANG_GERMAN' ],
+ 'el' : [ 1253, 'LANG_GREEK', 'SUBLANG_DEFAULT' ],
+ 'en' : [ 1200, 'LANG_ENGLISH', 'SUBLANG_ENGLISH_US' ],
+ 'en-GB' : [ 1038, 'LANG_ENGLISH', 'SUBLANG_ENGLISH_UK' ],
+ 'es' : [ 1252, 'LANG_SPANISH', 'SUBLANG_SPANISH_MODERN' ],
+ # LCID for Mexico; Windows does not support L.A. LCID.
+ 'es-419' : [ 1252, 'LANG_SPANISH', 'SUBLANG_SPANISH_MEXICAN' ],
+ 'et' : [ 1257, 'LANG_ESTONIAN', 'SUBLANG_DEFAULT' ],
+ 'eu' : [ 1252, 'LANG_BASQUE', 'SUBLANG_DEFAULT' ],
+ 'fa' : [ 1256, 'LANG_PERSIAN', 'SUBLANG_DEFAULT' ],
+ 'fi' : [ 1252, 'LANG_FINNISH', 'SUBLANG_DEFAULT' ],
+ 'fil' : [ 1252, 'LANG_FILIPINO', 'SUBLANG_DEFAULT' ],
+ 'fr' : [ 1252, 'LANG_FRENCH', 'SUBLANG_FRENCH' ],
+ 'fr-CA' : [ 1252, 'LANG_FRENCH', 'SUBLANG_FRENCH_CANADIAN' ],
+ 'gl' : [ 1252, 'LANG_GALICIAN', 'SUBLANG_DEFAULT' ],
+ 'gu' : [ 1200, 'LANG_GUJARATI', 'SUBLANG_DEFAULT' ],
+ 'he' : [ 1255, 'LANG_HEBREW', 'SUBLANG_DEFAULT' ],
+ 'hi' : [ 1200, 'LANG_HINDI', 'SUBLANG_DEFAULT' ],
+ 'hr' : [ 1252, 'LANG_CROATIAN', 'SUBLANG_DEFAULT' ],
+ 'hu' : [ 1250, 'LANG_HUNGARIAN', 'SUBLANG_DEFAULT' ],
+ 'id' : [ 1252, 'LANG_INDONESIAN', 'SUBLANG_DEFAULT' ],
+ 'is' : [ 1252, 'LANG_ICELANDIC', 'SUBLANG_DEFAULT' ],
+ 'it' : [ 1252, 'LANG_ITALIAN', 'SUBLANG_DEFAULT' ],
+ 'iw' : [ 1255, 'LANG_HEBREW', 'SUBLANG_DEFAULT' ],
+ 'ja' : [ 932, 'LANG_JAPANESE', 'SUBLANG_DEFAULT' ],
+ 'kn' : [ 1200, 'LANG_KANNADA', 'SUBLANG_DEFAULT' ],
+ 'ko' : [ 949, 'LANG_KOREAN', 'SUBLANG_KOREAN' ],
+ 'lt' : [ 1257, 'LANG_LITHUANIAN', 'SUBLANG_LITHUANIAN' ],
+ 'lv' : [ 1257, 'LANG_LATVIAN', 'SUBLANG_DEFAULT' ],
+ 'ml' : [ 1200, 'LANG_MALAYALAM', 'SUBLANG_DEFAULT' ],
+ 'mr' : [ 1200, 'LANG_MARATHI', 'SUBLANG_DEFAULT' ],
+ # Malay (Malaysia) [ms-MY]
+ 'ms' : [ 1252, 'LANG_MALAY', 'SUBLANG_DEFAULT' ],
+ 'nb' : [ 1252, 'LANG_NORWEGIAN', 'SUBLANG_NORWEGIAN_BOKMAL' ],
+ 'ne' : [ 1200, 'LANG_NEPALI', 'SUBLANG_NEPALI_NEPAL' ],
+ 'nl' : [ 1252, 'LANG_DUTCH', 'SUBLANG_DEFAULT' ],
+ 'nn' : [ 1252, 'LANG_NORWEGIAN', 'SUBLANG_NORWEGIAN_NYNORSK' ],
+ 'no' : [ 1252, 'LANG_NORWEGIAN', 'SUBLANG_DEFAULT' ],
+ 'or' : [ 1200, 'LANG_ORIYA', 'SUBLANG_DEFAULT' ],
+ 'pa' : [ 1200, 'LANG_PUNJABI', 'SUBLANG_PUNJABI_INDIA' ],
+ 'pl' : [ 1250, 'LANG_POLISH', 'SUBLANG_DEFAULT' ],
+ 'pt-BR' : [ 1252, 'LANG_PORTUGUESE', 'SUBLANG_DEFAULT' ],
+ 'pt-PT' : [ 1252, 'LANG_PORTUGUESE', 'SUBLANG_PORTUGUESE' ],
+ 'ro' : [ 1250, 'LANG_ROMANIAN', 'SUBLANG_DEFAULT' ],
+ 'ru' : [ 1251, 'LANG_RUSSIAN', 'SUBLANG_DEFAULT' ],
+ 'sa' : [ 1200, 'LANG_SANSKRIT', 'SUBLANG_SANSKRIT_INDIA' ],
+ 'si' : [ 1200, 'LANG_SINHALESE', 'SUBLANG_SINHALESE_SRI_LANKA' ],
+ 'sk' : [ 1250, 'LANG_SLOVAK', 'SUBLANG_DEFAULT' ],
+ 'sl' : [ 1250, 'LANG_SLOVENIAN', 'SUBLANG_DEFAULT' ],
+ 'sr' : [ 1250, 'LANG_SERBIAN', 'SUBLANG_SERBIAN_LATIN' ],
+ 'sv' : [ 1252, 'LANG_SWEDISH', 'SUBLANG_SWEDISH' ],
+ 'sw' : [ 1252, 'LANG_SWAHILI', 'SUBLANG_DEFAULT' ],
+ 'ta' : [ 1200, 'LANG_TAMIL', 'SUBLANG_DEFAULT' ],
+ 'te' : [ 1200, 'LANG_TELUGU', 'SUBLANG_DEFAULT' ],
+ 'th' : [ 874, 'LANG_THAI', 'SUBLANG_DEFAULT' ],
+ 'ti' : [ 1200, 'LANG_TIGRIGNA', 'SUBLANG_TIGRIGNA_ERITREA' ],
+ 'tr' : [ 1254, 'LANG_TURKISH', 'SUBLANG_DEFAULT' ],
+ 'uk' : [ 1251, 'LANG_UKRAINIAN', 'SUBLANG_DEFAULT' ],
+ 'ur' : [ 1200, 'LANG_URDU', 'SUBLANG_DEFAULT' ],
+ 'vi' : [ 1258, 'LANG_VIETNAMESE', 'SUBLANG_DEFAULT' ],
+ 'zh-CN' : [ 936, 'LANG_CHINESE', 'SUBLANG_CHINESE_SIMPLIFIED' ],
+ 'zh-HK' : [ 950, 'LANG_CHINESE', 'SUBLANG_CHINESE_HONGKONG' ],
+ 'zh-TW' : [ 950, 'LANG_CHINESE', 'SUBLANG_CHINESE_TRADITIONAL' ],
+ 'zu' : [ 1200, 'LANG_ZULU', 'SUBLANG_DEFAULT' ],
+}
+
+
+# Right-To-Left languages
+_RTL_LANGUAGES = (
+ 'ar', # Arabic
+ 'fa', # Farsi
+ 'iw', # Hebrew
+ 'ks', # Kashmiri
+ 'ku', # Kurdish
+ 'ps', # Pashto
+ 'ur', # Urdu
+ 'yi', # Yiddish
+)
+
+
+def GetCodepage(language):
+ """ Returns the codepage for the given |language|. """
+ lang = _LANGUAGE_MAP[language]
+ return "%04x" % lang[0]
+
+
+def GetCodepageDecimal(language):
+ """ Returns the codepage for the given |language| as a decimal value. """
+ lang = _LANGUAGE_MAP[language]
+ return "%d" % lang[0]
+
+
+def GetLangId(language):
+ """ Returns the language id for the given |language|. """
+ lang = _LANGUAGE_MAP[language]
+ return "%04x" % (_LANGUAGE_PRIMARY[lang[1]] | (_LANGUAGE_SUB[lang[2]] << 10))
+
+
+def GetPrimaryLanguage(language):
+ """ Returns the primary language ID for the given |language|. """
+ lang = _LANGUAGE_MAP[language]
+ return _LANGUAGE_PRIMARY[lang[1]]
+
+
+def GetSublanguage(language):
+ """ Returns the sublanguage ID for the given |language|. """
+ lang = _LANGUAGE_MAP[language]
+ return _LANGUAGE_SUB[lang[2]]
+
+
+def IsRtlLanguage(language):
+ return language in _RTL_LANGUAGES;
+
+
+def NormalizeLanguageCode(language):
+ return language.replace('_', '-', 1)
+
+
+def GetDataPackageSuffix(language):
+ lang = NormalizeLanguageCode(language)
+ if lang == 'en':
+ lang = 'en-US'
+ return lang
+
+
+def GetJsonSuffix(language):
+ return language.replace('-', '_', 1)
+
+
+def ReadValuesFromFile(values_dict, file_name):
+ """
+ Reads NAME=VALUE settings from the specified file.
+
+ Everything to the left of the first '=' is the keyword,
+ everything to the right is the value. No stripping of
+ white space, so beware.
+
+ The file must exist, otherwise you get the Python exception from open().
+ """
+ for line in open(file_name, 'r').readlines():
+ key, val = line.rstrip('\r\n').split('=', 1)
+ values_dict[key] = val
+
+
+def ReadMessagesFromFile(file_name):
+ """
+ Reads messages from a 'chrome_messages_json' file.
+
+ The file must exist, otherwise you get the Python exception from open().
+ """
+ messages_file = io.open(file_name, encoding='utf-8-sig')
+ messages = json.load(messages_file)
+ messages_file.close()
+
+ values = {}
+ for key in messages.keys():
+ values[key] = unicode(messages[key]['message']);
+ return values
+
+
+def WriteIfChanged(file_name, contents, encoding='utf-16'):
+ """
+ Writes the specified contents to the specified file_name
+ iff the contents are different than the current contents.
+ """
+ try:
+ target = io.open(file_name, 'r')
+ old_contents = target.read()
+ except EnvironmentError:
+ pass
+ except UnicodeDecodeError:
+ target.close()
+ os.unlink(file_name)
+ else:
+ if contents == old_contents:
+ return
+ target.close()
+ os.unlink(file_name)
+ io.open(file_name, 'w', encoding=encoding).write(contents)
+
+
+class MessageMap:
+ """ Provides a dictionary of localized messages for each language."""
+ def __init__(self, languages, locale_dir):
+ self.language = None
+ self.message_map = {}
+
+ # Populate the message map
+ if locale_dir:
+ for language in languages:
+ file_name = os.path.join(locale_dir,
+ GetJsonSuffix(language),
+ 'messages.json')
+ self.message_map[language] = ReadMessagesFromFile(file_name)
+
+ def GetText(self, message):
+ """ Returns a localized message for the current language. """
+ return self.message_map[self.language][message]
+
+ def SelectLanguage(self, language):
+ """ Selects the language to be used when retrieving localized messages. """
+ self.language = language
+
+ def MakeSelectLanguage(self):
+ """ Returns a function that can be used to select the current language. """
+ return lambda language: self.SelectLanguage(language)
+
+ def MakeGetText(self):
+ """ Returns a function that can be used to retrieve a localized message. """
+ return lambda message: self.GetText(message)
+
+
+def Localize(source, locales, options):
+ # Set the list of languages to use.
+ languages = map(NormalizeLanguageCode, locales)
+ context = { 'languages' : languages }
+
+ # Load the localized messages.
+ message_map = MessageMap(languages, options.locale_dir)
+
+ # Add OFFICIAL_BUILD variable the same way chrome/tools/build/version.py
+ # does.
+ if os.environ.get('CHROME_BUILD_TYPE') == '_official':
+ context['official_build'] = '1'
+ else:
+ context['official_build'] = '0'
+
+ # Add all variables defined in the command line.
+ if options.define:
+ for define in options.define:
+ context.update(dict([define.split('=', 1)]));
+
+ # Read NAME=VALUE variables from file.
+ if options.variables:
+ for file_name in options.variables:
+ ReadValuesFromFile(context, file_name)
+
+ env = None
+ template = None
+
+ if source:
+ # Load jinja2 library.
+ if options.jinja2:
+ jinja2_path = os.path.normpath(options.jinja2)
+ else:
+ jinja2_path = os.path.normpath(
+ os.path.join(os.path.abspath(__file__),
+ '../../../../third_party/jinja2'))
+ sys.path.append(os.path.split(jinja2_path)[0])
+ from jinja2 import Environment, FileSystemLoader
+
+ # Create jinja2 environment.
+ (template_path, template_name) = os.path.split(source)
+ env = Environment(loader=FileSystemLoader(template_path),
+ extensions=['jinja2.ext.do', 'jinja2.ext.i18n'])
+
+ # Register custom filters.
+ env.filters['GetCodepage'] = GetCodepage
+ env.filters['GetCodepageDecimal'] = GetCodepageDecimal
+ env.filters['GetLangId'] = GetLangId
+ env.filters['GetPrimaryLanguage'] = GetPrimaryLanguage
+ env.filters['GetSublanguage'] = GetSublanguage
+
+ # Register the message map with jinja2.i18n extension.
+ env.globals['IsRtlLanguage'] = IsRtlLanguage
+ env.globals['SelectLanguage'] = message_map.MakeSelectLanguage()
+ env.install_gettext_callables(message_map.MakeGetText(),
+ message_map.MakeGetText());
+
+ template = env.get_template(template_name)
+
+ # Generate a separate file per each locale if requested.
+ outputs = []
+ if options.locale_output:
+ target = Template(options.locale_output)
+ for lang in languages:
+ context['languages'] = [ lang ]
+ context['language'] = lang
+ context['pak_suffix'] = GetDataPackageSuffix(lang)
+ context['json_suffix'] = GetJsonSuffix(lang)
+
+ template_file_name = target.safe_substitute(context)
+ outputs.append(template_file_name)
+ if not options.print_only:
+ WriteIfChanged(template_file_name, template.render(context),
+ options.encoding)
+ else:
+ outputs.append(options.output)
+ if not options.print_only:
+ WriteIfChanged(options.output, template.render(context), options.encoding)
+
+ if options.print_only:
+ # Quote each element so filename spaces don't mess up gyp's attempt to parse
+ # it into a list.
+ return " ".join(['"%s"' % x for x in outputs])
+
+ return
+
+
+def DoMain(argv):
+ usage = "Usage: localize [options] locales"
+ parser = OptionParser(usage=usage)
+ parser.add_option(
+ '-d', '--define', dest='define', action='append', type='string',
+ help='define a variable (NAME=VALUE).')
+ parser.add_option(
+ '--encoding', dest='encoding', type='string', default='utf-16',
+ help="set the encoding of <output>. 'utf-16' is the default.")
+ parser.add_option(
+ '--jinja2', dest='jinja2', type='string',
+ help="specifies path to the jinja2 library.")
+ parser.add_option(
+ '--locale_dir', dest='locale_dir', type='string',
+ help="set path to localized message files.")
+ parser.add_option(
+ '--locale_output', dest='locale_output', type='string',
+ help='specify the per-locale output file name.')
+ parser.add_option(
+ '-o', '--output', dest='output', type='string',
+ help="specify the output file name.")
+ parser.add_option(
+ '--print_only', dest='print_only', action='store_true',
+ default=False, help='print the output file names only.')
+ parser.add_option(
+ '-t', '--template', dest='template', type='string',
+ help="specify the template file name.")
+ parser.add_option(
+ '--variables', dest='variables', action='append', type='string',
+ help='read variables (NAME=VALUE) from file.')
+
+ options, locales = parser.parse_args(argv)
+ if not locales:
+ parser.error('At least one locale must be specified')
+ if bool(options.output) == bool(options.locale_output):
+ parser.error(
+ 'Either --output or --locale_output must be specified but not both')
+ if not options.template and not options.print_only:
+ parser.error('The template name is required unless --print_only is used')
+
+ return Localize(options.template, locales, options)
+
+if __name__ == '__main__':
+ sys.exit(DoMain(sys.argv[1:]))
+