1# -*- coding: utf-8 -*- 2""" 3 babel.messages.plurals 4 ~~~~~~~~~~~~~~~~~~~~~~ 5 6 Plural form definitions. 7 8 :copyright: (c) 2013-2021 by the Babel Team. 9 :license: BSD, see LICENSE for more details. 10""" 11 12from babel.core import default_locale, Locale 13from operator import itemgetter 14 15 16# XXX: remove this file, duplication with babel.plural 17 18 19LC_CTYPE = default_locale('LC_CTYPE') 20 21 22PLURALS = { 23 # Afar 24 # 'aa': (), 25 # Abkhazian 26 # 'ab': (), 27 # Avestan 28 # 'ae': (), 29 # Afrikaans - From Pootle's PO's 30 'af': (2, '(n != 1)'), 31 # Akan 32 # 'ak': (), 33 # Amharic 34 # 'am': (), 35 # Aragonese 36 # 'an': (), 37 # Arabic - From Pootle's PO's 38 'ar': (6, '(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=0 && n%100<=2 ? 4 : 5)'), 39 # Assamese 40 # 'as': (), 41 # Avaric 42 # 'av': (), 43 # Aymara 44 # 'ay': (), 45 # Azerbaijani 46 # 'az': (), 47 # Bashkir 48 # 'ba': (), 49 # Belarusian 50 'be': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), 51 # Bulgarian - From Pootle's PO's 52 'bg': (2, '(n != 1)'), 53 # Bihari 54 # 'bh': (), 55 # Bislama 56 # 'bi': (), 57 # Bambara 58 # 'bm': (), 59 # Bengali - From Pootle's PO's 60 'bn': (2, '(n != 1)'), 61 # Tibetan - as discussed in private with Andrew West 62 'bo': (1, '0'), 63 # Breton 64 'br': ( 65 6, 66 '(n==1 ? 0 : n%10==1 && n%100!=11 && n%100!=71 && n%100!=91 ? 1 : n%10==2 && n%100!=12 && n%100!=72 && ' 67 'n%100!=92 ? 2 : (n%10==3 || n%10==4 || n%10==9) && n%100!=13 && n%100!=14 && n%100!=19 && n%100!=73 && ' 68 'n%100!=74 && n%100!=79 && n%100!=93 && n%100!=94 && n%100!=99 ? 3 : n%1000000==0 ? 4 : 5)' 69 ), 70 # Bosnian 71 'bs': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), 72 # Catalan - From Pootle's PO's 73 'ca': (2, '(n != 1)'), 74 # Chechen 75 # 'ce': (), 76 # Chamorro 77 # 'ch': (), 78 # Corsican 79 # 'co': (), 80 # Cree 81 # 'cr': (), 82 # Czech 83 'cs': (3, '((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2)'), 84 # Church Slavic 85 # 'cu': (), 86 # Chuvash 87 'cv': (1, '0'), 88 # Welsh 89 'cy': (5, '(n==1 ? 1 : n==2 ? 2 : n==3 ? 3 : n==6 ? 4 : 0)'), 90 # Danish 91 'da': (2, '(n != 1)'), 92 # German 93 'de': (2, '(n != 1)'), 94 # Divehi 95 # 'dv': (), 96 # Dzongkha 97 'dz': (1, '0'), 98 # Greek 99 'el': (2, '(n != 1)'), 100 # English 101 'en': (2, '(n != 1)'), 102 # Esperanto 103 'eo': (2, '(n != 1)'), 104 # Spanish 105 'es': (2, '(n != 1)'), 106 # Estonian 107 'et': (2, '(n != 1)'), 108 # Basque - From Pootle's PO's 109 'eu': (2, '(n != 1)'), 110 # Persian - From Pootle's PO's 111 'fa': (1, '0'), 112 # Finnish 113 'fi': (2, '(n != 1)'), 114 # French 115 'fr': (2, '(n > 1)'), 116 # Friulian - From Pootle's PO's 117 'fur': (2, '(n > 1)'), 118 # Irish 119 'ga': (5, '(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)'), 120 # Galician - From Pootle's PO's 121 'gl': (2, '(n != 1)'), 122 # Hausa - From Pootle's PO's 123 'ha': (2, '(n != 1)'), 124 # Hebrew 125 'he': (2, '(n != 1)'), 126 # Hindi - From Pootle's PO's 127 'hi': (2, '(n != 1)'), 128 # Croatian 129 'hr': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), 130 # Hungarian 131 'hu': (1, '0'), 132 # Armenian - From Pootle's PO's 133 'hy': (1, '0'), 134 # Icelandic - From Pootle's PO's 135 'is': (2, '(n%10==1 && n%100!=11 ? 0 : 1)'), 136 # Italian 137 'it': (2, '(n != 1)'), 138 # Japanese 139 'ja': (1, '0'), 140 # Georgian - From Pootle's PO's 141 'ka': (1, '0'), 142 # Kongo - From Pootle's PO's 143 'kg': (2, '(n != 1)'), 144 # Khmer - From Pootle's PO's 145 'km': (1, '0'), 146 # Korean 147 'ko': (1, '0'), 148 # Kurdish - From Pootle's PO's 149 'ku': (2, '(n != 1)'), 150 # Lao - Another member of the Tai language family, like Thai. 151 'lo': (1, '0'), 152 # Lithuanian 153 'lt': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2)'), 154 # Latvian 155 'lv': (3, '(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2)'), 156 # Maltese - From Pootle's PO's 157 'mt': (4, '(n==1 ? 0 : n==0 || ( n%100=>1 && n%100<=10) ? 1 : (n%100>10 && n%100<20 ) ? 2 : 3)'), 158 # Norwegian Bokmål 159 'nb': (2, '(n != 1)'), 160 # Dutch 161 'nl': (2, '(n != 1)'), 162 # Norwegian Nynorsk 163 'nn': (2, '(n != 1)'), 164 # Norwegian 165 'no': (2, '(n != 1)'), 166 # Punjabi - From Pootle's PO's 167 'pa': (2, '(n != 1)'), 168 # Polish 169 'pl': (3, '(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), 170 # Portuguese 171 'pt': (2, '(n != 1)'), 172 # Brazilian 173 'pt_BR': (2, '(n > 1)'), 174 # Romanian - From Pootle's PO's 175 'ro': (3, '(n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2)'), 176 # Russian 177 'ru': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), 178 # Slovak 179 'sk': (3, '((n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2)'), 180 # Slovenian 181 'sl': (4, '(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3)'), 182 # Serbian - From Pootle's PO's 183 'sr': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), 184 # Southern Sotho - From Pootle's PO's 185 'st': (2, '(n != 1)'), 186 # Swedish 187 'sv': (2, '(n != 1)'), 188 # Thai 189 'th': (1, '0'), 190 # Turkish 191 'tr': (1, '0'), 192 # Ukrainian 193 'uk': (3, '(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)'), 194 # Venda - From Pootle's PO's 195 've': (2, '(n != 1)'), 196 # Vietnamese - From Pootle's PO's 197 'vi': (1, '0'), 198 # Xhosa - From Pootle's PO's 199 'xh': (2, '(n != 1)'), 200 # Chinese - From Pootle's PO's (modified) 201 'zh': (1, '0'), 202} 203 204 205DEFAULT_PLURAL = (2, '(n != 1)') 206 207 208class _PluralTuple(tuple): 209 """A tuple with plural information.""" 210 211 __slots__ = () 212 num_plurals = property(itemgetter(0), doc=""" 213 The number of plurals used by the locale.""") 214 plural_expr = property(itemgetter(1), doc=""" 215 The plural expression used by the locale.""") 216 plural_forms = property(lambda x: 'nplurals=%s; plural=%s;' % x, doc=""" 217 The plural expression used by the catalog or locale.""") 218 219 def __str__(self): 220 return self.plural_forms 221 222 223def get_plural(locale=LC_CTYPE): 224 """A tuple with the information catalogs need to perform proper 225 pluralization. The first item of the tuple is the number of plural 226 forms, the second the plural expression. 227 228 >>> get_plural(locale='en') 229 (2, '(n != 1)') 230 >>> get_plural(locale='ga') 231 (5, '(n==1 ? 0 : n==2 ? 1 : n>=3 && n<=6 ? 2 : n>=7 && n<=10 ? 3 : 4)') 232 233 The object returned is a special tuple with additional members: 234 235 >>> tup = get_plural("ja") 236 >>> tup.num_plurals 237 1 238 >>> tup.plural_expr 239 '0' 240 >>> tup.plural_forms 241 'nplurals=1; plural=0;' 242 243 Converting the tuple into a string prints the plural forms for a 244 gettext catalog: 245 246 >>> str(tup) 247 'nplurals=1; plural=0;' 248 """ 249 locale = Locale.parse(locale) 250 try: 251 tup = PLURALS[str(locale)] 252 except KeyError: 253 try: 254 tup = PLURALS[locale.language] 255 except KeyError: 256 tup = DEFAULT_PLURAL 257 return _PluralTuple(tup) 258