or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-locales.mddate-time-formatting.mdindex.mdmessage-catalogs.mdnumber-currency-formatting.mdplural-language-data.mdunits-utilities.md

plural-language-data.mddocs/

0

# Plural Rules and Language Data

1

2

Plural rule handling for different languages, language territory information, and list formatting according to locale conventions. Babel provides comprehensive support for CLDR plural rules and language-specific data.

3

4

## Capabilities

5

6

### Plural Rule Class

7

8

Represents and evaluates CLDR plural rules for different languages.

9

10

```python { .api }

11

class PluralRule:

12

"""

13

Represents a set of language pluralization rules based on CLDR data.

14

15

Attributes:

16

rules (dict): Rules mapping plural tags to conditions

17

tags (set): Set of defined plural tags for this rule

18

"""

19

def __init__(self, rules):

20

"""

21

Initialize plural rule with rule definitions.

22

23

Args:

24

rules (dict): Mapping of plural tags to rule conditions

25

"""

26

27

@classmethod

28

def parse(cls, rules):

29

"""

30

Parse plural rules from various formats.

31

32

Args:

33

rules (str|dict|PluralRule): Rules in string, dict, or PluralRule format

34

35

Returns:

36

PluralRule: Parsed plural rule object

37

"""

38

39

def __call__(self, n):

40

"""

41

Get plural form for a number.

42

43

Args:

44

n (int|float|Decimal): Number to evaluate

45

46

Returns:

47

str: Plural form tag ('zero', 'one', 'two', 'few', 'many', 'other')

48

"""

49

```

50

51

Usage example:

52

53

```python

54

from babel.plural import PluralRule

55

56

# English plural rule (simple: one vs other)

57

en_rule = PluralRule({'one': 'n == 1'})

58

print(en_rule(1)) # 'one'

59

print(en_rule(2)) # 'other'

60

61

# French plural rule

62

fr_rule = PluralRule({'one': 'n >= 0 and n < 2'})

63

print(fr_rule(0)) # 'one'

64

print(fr_rule(1)) # 'one'

65

print(fr_rule(2)) # 'other'

66

```

67

68

### CLDR Operand Extraction

69

70

Extract operands from numbers for use in CLDR plural rule evaluation.

71

72

```python { .api }

73

def extract_operands(source):

74

"""

75

Extract CLDR operands from a number for plural rule evaluation.

76

77

Args:

78

source (float|Decimal): Number to extract operands from

79

80

Returns:

81

tuple: (n, i, v, w, f, t, c, e) operands where:

82

n: absolute value of the source number

83

i: integer digits of n

84

v: number of visible fraction digits in n

85

w: number of fraction digits in n without trailing zeros

86

f: visible fraction digits in n as an integer

87

t: fraction digits in n without trailing zeros as an integer

88

c: compact decimal exponent value

89

e: deprecated, use 'c'

90

"""

91

```

92

93

Usage example:

94

95

```python

96

from babel.plural import extract_operands

97

98

# Extract operands for different numbers

99

print(extract_operands(1.23)) # (1.23, 1, 2, 2, 23, 23, 0, 0)

100

print(extract_operands(5.00)) # (5.0, 5, 2, 0, 0, 0, 0, 0)

101

print(extract_operands(1000)) # (1000, 1000, 0, 0, 0, 0, 0, 0)

102

```

103

104

### Plural Rule Conversion

105

106

Convert plural rules to different formats for use in various systems.

107

108

```python { .api }

109

def to_javascript(rule):

110

"""

111

Convert plural rule to JavaScript function code.

112

113

Args:

114

rule (PluralRule): Plural rule to convert

115

116

Returns:

117

str: JavaScript function code for evaluating plural forms

118

"""

119

120

def to_python(rule):

121

"""

122

Convert plural rule to Python function.

123

124

Args:

125

rule (PluralRule): Plural rule to convert

126

127

Returns:

128

callable: Python function for evaluating plural forms

129

"""

130

131

def to_gettext(rule):

132

"""

133

Convert plural rule to gettext format.

134

135

Args:

136

rule (PluralRule): Plural rule to convert

137

138

Returns:

139

str: Gettext plural expression string

140

"""

141

```

142

143

Usage example:

144

145

```python

146

from babel.plural import PluralRule, to_javascript, to_python, to_gettext

147

148

rule = PluralRule({'one': 'n == 1'})

149

150

js_code = to_javascript(rule)

151

py_func = to_python(rule)

152

gettext_expr = to_gettext(rule)

153

154

print(py_func(1)) # 'one'

155

print(py_func(2)) # 'other'

156

```

157

158

### Range List Operations

159

160

Test if numbers fall within CLDR range specifications.

161

162

```python { .api }

163

def in_range_list(num, range_list):

164

"""

165

Test if integer is in a range list.

166

167

Args:

168

num (int): Integer to test

169

range_list (list): List of range specifications

170

171

Returns:

172

bool: True if number is in any of the ranges

173

"""

174

175

def within_range_list(num, range_list):

176

"""

177

Test if number is within a range list (including decimals).

178

179

Args:

180

num (float|Decimal): Number to test

181

range_list (list): List of range specifications

182

183

Returns:

184

bool: True if number is within any of the ranges

185

"""

186

187

def cldr_modulo(a, b):

188

"""

189

CLDR-compatible modulo operation.

190

191

Args:

192

a (float): Dividend

193

b (float): Divisor

194

195

Returns:

196

float: Modulo result following CLDR rules

197

"""

198

```

199

200

### Language Territory Information

201

202

Access information about languages used in different territories.

203

204

```python { .api }

205

def get_official_languages(territory, regional=False, de_facto=False):

206

"""

207

Get official languages for a territory.

208

209

Args:

210

territory (str): Territory code (e.g., 'US', 'CA', 'CH')

211

regional (bool): Include regional languages

212

de_facto (bool): Include de facto official languages

213

214

Returns:

215

tuple[str, ...]: Language codes in order of popularity/usage

216

"""

217

218

def get_territory_language_info(territory):

219

"""

220

Get detailed language information for a territory.

221

222

Args:

223

territory (str): Territory code

224

225

Returns:

226

dict: Mapping of language codes to detailed information including:

227

- population_percent: Percentage of population using language

228

- literacy_percent: Literacy rate for language

229

- writing_percent: Percentage using written form

230

- official_status: Official status information

231

"""

232

```

233

234

Usage example:

235

236

```python

237

from babel.languages import get_official_languages, get_territory_language_info

238

239

# Get official languages for territories

240

us_languages = get_official_languages('US') # ('en',)

241

ca_languages = get_official_languages('CA') # ('en', 'fr')

242

ch_languages = get_official_languages('CH') # ('de', 'fr', 'it')

243

244

# Get detailed language info

245

us_info = get_territory_language_info('US')

246

print(us_info['en']['population_percent']) # Population percentage for English in US

247

```

248

249

### List Formatting

250

251

Format sequences of items as lists according to locale conventions.

252

253

```python { .api }

254

def format_list(lst, style='standard', locale=default_locale()):

255

"""

256

Format a sequence of items as a list according to locale conventions.

257

258

Args:

259

lst (Sequence[str]): Sequence of string items to format

260

style (str): List style ('standard', 'standard-short', 'or', 'or-short', 'unit', 'unit-short', 'unit-narrow')

261

locale (Locale|str): Target locale for formatting

262

263

Returns:

264

str: Properly formatted list string

265

"""

266

```

267

268

Usage example:

269

270

```python

271

from babel.lists import format_list

272

from babel import Locale

273

274

items = ['apples', 'oranges', 'bananas']

275

276

# English formatting

277

en_result = format_list(items, locale='en_US')

278

print(en_result) # "apples, oranges, and bananas"

279

280

# Different styles

281

or_result = format_list(items, style='or', locale='en_US')

282

print(or_result) # "apples, oranges, or bananas"

283

284

# French formatting

285

fr_result = format_list(items, locale='fr_FR')

286

print(fr_result) # "apples, oranges et bananas"

287

288

# German formatting

289

de_result = format_list(items, locale='de_DE')

290

print(de_result) # "apples, oranges und bananas"

291

292

# Short styles

293

short_items = ['NYC', 'LA', 'CHI']

294

short_result = format_list(short_items, style='standard-short', locale='en_US')

295

print(short_result) # "NYC, LA, & CHI"

296

```

297

298

Different list styles:

299

- `'standard'`: Standard list with "and" (e.g., "A, B, and C")

300

- `'standard-short'`: Short standard list (e.g., "A, B, & C")

301

- `'or'`: Disjunctive list with "or" (e.g., "A, B, or C")

302

- `'or-short'`: Short disjunctive list (e.g., "A, B, or C")

303

- `'unit'`: Unit list for measurements (e.g., "A B C")

304

- `'unit-short'`: Short unit list

305

- `'unit-narrow'`: Narrow unit list

306

307

## Exception Classes

308

309

```python { .api }

310

class RuleError(Exception):

311

"""Raised when plural rule parsing or evaluation fails."""

312

```

313

314

## Advanced Plural Rule Examples

315

316

Different languages have varying plural rule complexity:

317

318

```python

319

from babel.plural import PluralRule

320

321

# English: Simple two-form rule

322

english_rule = PluralRule({

323

'one': 'n == 1',

324

'other': '' # default case

325

})

326

327

# Polish: Complex six-form rule

328

polish_rule = PluralRule({

329

'one': 'n == 1',

330

'few': 'n % 10 >= 2 and n % 10 <= 4 and (n % 100 < 12 or n % 100 > 14)',

331

'many': '(n % 10 == 0 or n % 10 == 1 or n % 10 >= 5 and n % 10 <= 9) and (n % 100 >= 12 and n % 100 <= 14)',

332

'other': ''

333

})

334

335

# Arabic: Six-form rule with zero

336

arabic_rule = PluralRule({

337

'zero': 'n == 0',

338

'one': 'n == 1',

339

'two': 'n == 2',

340

'few': 'n % 100 >= 3 and n % 100 <= 10',

341

'many': 'n % 100 >= 11 and n % 100 <= 99',

342

'other': ''

343

})

344

345

# Test different numbers

346

for num in [0, 1, 2, 3, 5, 11, 21, 101]:

347

print(f"{num}: {english_rule(num)} (en), {polish_rule(num)} (pl), {arabic_rule(num)} (ar)")

348

```