plurals.py 7.0 KB

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