palgarvio@51: # -*- coding: utf-8 -*- palgarvio@51: # palgarvio@51: # Copyright (C) 2007 Edgewall Software palgarvio@51: # All rights reserved. palgarvio@51: # palgarvio@51: # This software is licensed as described in the file COPYING, which palgarvio@51: # you should have received as part of this distribution. The terms palgarvio@51: # are also available at http://babel.edgewall.org/wiki/License. palgarvio@51: # palgarvio@51: # This software consists of voluntary contributions made by many palgarvio@51: # individuals. For the exact contribution history, see the revision palgarvio@51: # history and logs, available at http://babel.edgewall.org/log/. palgarvio@51: cmlenz@56: """Plural form definitions.""" cmlenz@56: cmlenz@379: from babel.core import default_locale, Locale fschwarz@507: from babel.util import itemgetter cmlenz@379: cmlenz@379: cmlenz@379: LC_CTYPE = default_locale('LC_CTYPE') cmlenz@379: cmlenz@379: palgarvio@51: PLURALS = { cmlenz@318: # Afar cmlenz@318: # 'aa': (), cmlenz@318: # Abkhazian cmlenz@318: # 'ab': (), cmlenz@318: # Avestan cmlenz@318: # 'ae': (), palgarvio@51: # Afrikaans - From Pootle's PO's palgarvio@51: 'af': (2, '(n != 1)'), cmlenz@318: # Akan cmlenz@318: # 'ak': (), cmlenz@318: # Amharic cmlenz@318: # 'am': (), cmlenz@318: # Aragonese cmlenz@318: # 'an': (), palgarvio@51: # Arabic - From Pootle's PO's palgarvio@51: 'ar': (6, '(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n>=3 && n<=10 ? 3 : n>=11 && n<=99 ? 4 : 5)'), cmlenz@318: # Assamese cmlenz@318: # 'as': (), cmlenz@318: # Avaric cmlenz@318: # 'av': (), cmlenz@318: # Aymara cmlenz@318: # 'ay': (), cmlenz@318: # Azerbaijani cmlenz@318: # 'az': (), cmlenz@318: # Bashkir cmlenz@318: # 'ba': (), cmlenz@318: # Belarusian cmlenz@318: # 'be': (), palgarvio@51: # Bulgarian - From Pootle's PO's palgarvio@51: 'bg': (2, '(n != 1)'), cmlenz@318: # Bihari cmlenz@318: # 'bh': (), cmlenz@318: # Bislama cmlenz@318: # 'bi': (), cmlenz@318: # Bambara cmlenz@318: # 'bm': (), palgarvio@51: # Bengali - From Pootle's PO's palgarvio@51: 'bn': (2, '(n != 1)'), cmlenz@300: # Tibetan - as discussed in private with Andrew West cmlenz@300: 'bo': (1, '0'), cmlenz@318: # Breton cmlenz@318: # 'br': (), cmlenz@318: # Bosnian cmlenz@318: # 'bs': (), palgarvio@51: # Catalan - From Pootle's PO's palgarvio@51: 'ca': (2, '(n != 1)'), cmlenz@318: # Chechen cmlenz@318: # 'ce': (), cmlenz@318: # Chamorro cmlenz@318: # 'ch': (), cmlenz@318: # Corsican cmlenz@318: # 'co': (), cmlenz@318: # Cree cmlenz@318: # 'cr': (), palgarvio@51: # Czech palgarvio@51: 'cs': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), cmlenz@318: # Church Slavic cmlenz@318: # 'cu': (), cmlenz@318: # Chuvash cmlenz@318: 'cv': (1, '0'), cmlenz@318: # Welsh cmlenz@346: 'cy': (5, '(n==1 ? 1 : n==2 ? 2 : n==3 ? 3 : n==6 ? 4 : 0)'), palgarvio@51: # Danish palgarvio@51: 'da': (2, '(n != 1)'), palgarvio@51: # German palgarvio@51: 'de': (2, '(n != 1)'), cmlenz@318: # Divehi cmlenz@318: # 'dv': (), cmlenz@318: # Dzongkha cmlenz@318: 'dz': (1, '0'), palgarvio@51: # Greek palgarvio@51: 'el': (2, '(n != 1)'), palgarvio@51: # English palgarvio@51: 'en': (2, '(n != 1)'), palgarvio@51: # Esperanto palgarvio@51: 'eo': (2, '(n != 1)'), palgarvio@51: # Spanish palgarvio@51: 'es': (2, '(n != 1)'), palgarvio@51: # Estonian palgarvio@51: 'et': (2, '(n != 1)'), palgarvio@51: # Basque - From Pootle's PO's palgarvio@51: 'eu': (2, '(n != 1)'), palgarvio@51: # Persian - From Pootle's PO's palgarvio@51: 'fa': (1, '0'), palgarvio@51: # Finnish palgarvio@51: 'fi': (2, '(n != 1)'), palgarvio@51: # French palgarvio@51: 'fr': (2, '(n > 1)'), cmlenz@300: # Friulian - From Pootle's PO's palgarvio@51: 'fur': (2, '(n > 1)'), palgarvio@51: # Irish cmlenz@346: 'ga': (3, '(n==1 ? 0 : n==2 ? 1 : 2)'), cmlenz@300: # Galician - From Pootle's PO's palgarvio@51: 'gl': (2, '(n != 1)'), palgarvio@51: # Hausa - From Pootle's PO's cmlenz@346: 'ha': (2, '(n != 1)'), palgarvio@51: # Hebrew palgarvio@51: 'he': (2, '(n != 1)'), palgarvio@51: # Hindi - From Pootle's PO's cmlenz@346: 'hi': (2, '(n != 1)'), palgarvio@51: # Croatian palgarvio@51: 'hr': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), palgarvio@51: # Hungarian palgarvio@51: 'hu': (1, '0'), palgarvio@51: # Armenian - From Pootle's PO's palgarvio@51: 'hy': (1, '0'), palgarvio@51: # Icelandic - From Pootle's PO's palgarvio@51: 'is': (2, '(n != 1)'), palgarvio@51: # Italian palgarvio@51: 'it': (2, '(n != 1)'), palgarvio@51: # Japanese palgarvio@51: 'ja': (1, '0'), palgarvio@51: # Georgian - From Pootle's PO's palgarvio@51: 'ka': (1, '0'), palgarvio@51: # Kongo - From Pootle's PO's palgarvio@51: 'kg': (2, '(n != 1)'), palgarvio@51: # Khmer - From Pootle's PO's palgarvio@51: 'km': (1, '0'), palgarvio@51: # Korean palgarvio@51: 'ko': (1, '0'), cmlenz@300: # Kurdish - From Pootle's PO's palgarvio@51: 'ku': (2, '(n != 1)'), cmlenz@318: # Lao - Another member of the Tai language family, like Thai. cmlenz@318: 'lo': (1, '0'), palgarvio@51: # Lithuanian palgarvio@51: 'lt': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2)'), palgarvio@51: # Latvian palgarvio@51: 'lv': (3, '(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2)'), palgarvio@51: # Maltese - From Pootle's PO's palgarvio@51: 'mt': (4, '(n==1 ? 0 : n==0 || ( n%100>1 && n%100<11) ? 1 : (n%100>10 && n%100<20 ) ? 2 : 3)'), cmlenz@300: # Norwegian Bokmål palgarvio@51: 'nb': (2, '(n != 1)'), palgarvio@51: # Dutch palgarvio@51: 'nl': (2, '(n != 1)'), palgarvio@51: # Norwegian Nynorsk palgarvio@51: 'nn': (2, '(n != 1)'), palgarvio@51: # Norwegian palgarvio@51: 'no': (2, '(n != 1)'), palgarvio@51: # Punjabi - From Pootle's PO's palgarvio@51: 'pa': (2, '(n != 1)'), palgarvio@51: # Polish palgarvio@51: 'pl': (3, '(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), palgarvio@51: # Portuguese palgarvio@51: 'pt': (2, '(n != 1)'), palgarvio@51: # Brazilian palgarvio@51: 'pt_BR': (2, '(n > 1)'), palgarvio@51: # Romanian - From Pootle's PO's palgarvio@51: 'ro': (3, '(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2)'), palgarvio@51: # Russian palgarvio@51: 'ru': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), palgarvio@51: # Slovak palgarvio@51: 'sk': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), palgarvio@51: # Slovenian palgarvio@51: 'sl': (4, '(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3)'), palgarvio@51: # Serbian - From Pootle's PO's jruigrok@490: 'sr': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), cmlenz@300: # Southern Sotho - From Pootle's PO's palgarvio@51: 'st': (2, '(n != 1)'), palgarvio@51: # Swedish palgarvio@51: 'sv': (2, '(n != 1)'), cmlenz@300: # Thai cmlenz@300: 'th': (1, '0'), palgarvio@51: # Turkish palgarvio@51: 'tr': (1, '0'), palgarvio@51: # Ukrainian palgarvio@51: 'uk': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), palgarvio@51: # Venda - From Pootle's PO's palgarvio@51: 've': (2, '(n != 1)'), palgarvio@51: # Vietnamese - From Pootle's PO's palgarvio@51: 'vi': (1, '0'), palgarvio@51: # Xhosa - From Pootle's PO's palgarvio@51: 'xh': (2, '(n != 1)'), palgarvio@51: # Chinese - From Pootle's PO's palgarvio@51: 'zh_CN': (1, '0'), palgarvio@51: 'zh_HK': (1, '0'), palgarvio@51: 'zh_TW': (1, '0'), palgarvio@51: } cmlenz@379: cmlenz@379: cmlenz@379: DEFAULT_PLURAL = (2, '(n != 1)') cmlenz@379: cmlenz@379: cmlenz@379: class _PluralTuple(tuple): cmlenz@379: """A tuple with plural information.""" cmlenz@379: cmlenz@379: __slots__ = () cmlenz@379: num_plurals = property(itemgetter(0), doc=""" cmlenz@379: The number of plurals used by the locale.""") cmlenz@379: plural_expr = property(itemgetter(1), doc=""" cmlenz@379: The plural expression used by the locale.""") cmlenz@379: plural_forms = property(lambda x: 'npurals=%s; plural=%s' % x, doc=""" cmlenz@379: The plural expression used by the catalog or locale.""") cmlenz@379: cmlenz@379: def __str__(self): cmlenz@379: return self.plural_forms cmlenz@379: cmlenz@379: cmlenz@379: def get_plural(locale=LC_CTYPE): cmlenz@379: """A tuple with the information catalogs need to perform proper cmlenz@379: pluralization. The first item of the tuple is the number of plural cmlenz@379: forms, the second the plural expression. cmlenz@379: cmlenz@379: >>> get_plural(locale='en') cmlenz@379: (2, '(n != 1)') cmlenz@379: >>> get_plural(locale='ga') cmlenz@379: (3, '(n==1 ? 0 : n==2 ? 1 : 2)') cmlenz@379: cmlenz@379: The object returned is a special tuple with additional members: cmlenz@379: cmlenz@379: >>> tup = get_plural("ja") cmlenz@379: >>> tup.num_plurals cmlenz@379: 1 cmlenz@379: >>> tup.plural_expr cmlenz@379: '0' cmlenz@379: >>> tup.plural_forms cmlenz@379: 'npurals=1; plural=0' cmlenz@379: cmlenz@379: Converting the tuple into a string prints the plural forms for a cmlenz@379: gettext catalog: cmlenz@379: cmlenz@379: >>> str(tup) cmlenz@379: 'npurals=1; plural=0' cmlenz@379: """ cmlenz@379: locale = Locale.parse(locale) cmlenz@379: try: cmlenz@379: tup = PLURALS[str(locale)] cmlenz@379: except KeyError: cmlenz@379: try: cmlenz@379: tup = PLURALS[locale.language] cmlenz@379: except KeyError: cmlenz@379: tup = DEFAULT_PLURAL cmlenz@379: return _PluralTuple(tup)