or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cardinal-pluralization.mdcore-pluralization.mdexample-values.mdindex.mdordinal-pluralization.mdplural-categories.mdrange-pluralization.md

range-pluralization.mddocs/

0

# Range Pluralization

1

2

Functions for determining the pluralization of numerical ranges (e.g., "1-5 items", "3-7 books"). Only 91 of the 217 supported languages have specific range pluralization rules.

3

4

## Capabilities

5

6

### Range Functions

7

8

Languages with range rules provide functions that determine the appropriate plural category for a numerical range based on the plural categories of the start and end values.

9

10

```typescript { .api }

11

/**

12

* Determines the plural category for a numerical range

13

* @param start - Plural category of the range start value

14

* @param end - Plural category of the range end value

15

* @returns The appropriate plural category for the range

16

*/

17

(start: PluralCategory, end: PluralCategory) => PluralCategory;

18

19

type PluralCategory = "zero" | "one" | "two" | "few" | "many" | "other";

20

```

21

22

### Import Pattern

23

24

```javascript { .api }

25

import { en, ro, pl, ar } from "make-plural/ranges";

26

```

27

28

### Language Coverage

29

30

**93 languages with range rules include:**

31

32

**Simple Range Rules:**

33

- `en` - English: Always returns `"other"`

34

- `de` - German: Always returns `"other"`

35

- `es` - Spanish: Always returns `"other"`

36

- `fr` - French: Always returns `"other"`

37

38

**Complex Range Rules:**

39

- `ro` - Romanian: Complex logic based on end category

40

- `pl` - Polish: Returns `"one" | "few" | "many" | "other"`

41

- `ru` - Russian: Complex Slavic range rules

42

- `uk` - Ukrainian: Complex Slavic range rules

43

44

**Variable Range Rules:**

45

- `lt` - Lithuanian: 5 different possible outcomes

46

- `lv` - Latvian: Complex range calculations

47

- `cs` - Czech: Slavic range patterns

48

49

### Usage Examples

50

51

**English Range Pluralization:**

52

```javascript

53

import { en } from "make-plural/ranges";

54

55

// English always uses 'other' for ranges

56

en('one', 'one'); // 'other' (1-1 items)

57

en('one', 'other'); // 'other' (1-5 items)

58

en('other', 'other'); // 'other' (2-10 items)

59

en('other', 'one'); // 'other' (5-1 items - unusual but possible)

60

```

61

62

**Romanian Range Pluralization:**

63

```javascript

64

import { ro } from "make-plural/ranges";

65

66

// Romanian has complex range rules based on end category

67

ro('one', 'few'); // 'few' (1-3 items)

68

ro('few', 'one'); // 'few' (3-1 items)

69

ro('one', 'other'); // 'other' (1-20 items)

70

ro('few', 'other'); // 'other' (3-20 items)

71

ro('other', 'other'); // 'other' (20-100 items)

72

```

73

74

**Polish Range Pluralization:**

75

```javascript

76

import { pl } from "make-plural/ranges";

77

78

// Polish range rules follow specific patterns

79

pl('one', 'few'); // 'few' (1-3 items)

80

pl('few', 'few'); // 'few' (2-4 items)

81

pl('few', 'many'); // 'many' (3-10 items)

82

pl('many', 'many'); // 'many' (5-20 items)

83

pl('one', 'many'); // 'many' (1-10 items)

84

```

85

86

**Lithuanian Range Pluralization:**

87

```javascript

88

import { lt } from "make-plural/ranges";

89

90

// Lithuanian has complex 5-outcome range rules

91

lt('one', 'one'); // 'one'

92

lt('one', 'few'); // 'few'

93

lt('few', 'many'); // 'many'

94

lt('many', 'other'); // 'other'

95

lt('other', 'one'); // 'many' // Complex rule

96

```

97

98

### Practical Range Usage

99

100

**Building Localized Range Messages:**

101

```javascript

102

import { en, ro, pl } from "make-plural/ranges";

103

import { en as enPlural, ro as roPlural, pl as plPlural } from "make-plural";

104

105

function formatRange(start, end, language) {

106

// Get plural categories for start and end

107

const startCategory = language.plural(start);

108

const endCategory = language.plural(end);

109

110

// Get range category

111

const rangeCategory = language.range(startCategory, endCategory);

112

113

// Use appropriate translation based on range category

114

return language.translations.range[rangeCategory]

115

.replace('{start}', start)

116

.replace('{end}', end);

117

}

118

119

// Example with different languages

120

const languages = {

121

en: {

122

plural: enPlural,

123

range: en,

124

translations: {

125

range: {

126

other: '{start}-{end} items'

127

}

128

}

129

},

130

ro: {

131

plural: roPlural,

132

range: ro,

133

translations: {

134

range: {

135

one: '{start}-{end} element',

136

few: '{start}-{end} elemente',

137

other: '{start}-{end} de elemente'

138

}

139

}

140

}

141

};

142

143

console.log(formatRange(1, 3, languages.en)); // "1-3 items"

144

console.log(formatRange(1, 3, languages.ro)); // "1-3 elemente"

145

```

146

147

**Range Category Calculation:**

148

```javascript

149

import { en, ro, pl } from "make-plural/ranges";

150

import { en as enPlural, ro as roPlural, pl as plPlural } from "make-plural";

151

152

function getRangeInfo(start, end, rangeFn, pluralFn) {

153

const startCategory = pluralFn(start);

154

const endCategory = pluralFn(end);

155

const rangeCategory = rangeFn(startCategory, endCategory);

156

157

return {

158

start,

159

end,

160

startCategory,

161

endCategory,

162

rangeCategory

163

};

164

}

165

166

// English examples

167

console.log(getRangeInfo(1, 5, en, enPlural));

168

// { start: 1, end: 5, startCategory: 'one', endCategory: 'other', rangeCategory: 'other' }

169

170

// Romanian examples

171

console.log(getRangeInfo(1, 3, ro, roPlural));

172

// { start: 1, end: 3, startCategory: 'one', endCategory: 'few', rangeCategory: 'few' }

173

174

// Polish examples

175

console.log(getRangeInfo(2, 4, pl, plPlural));

176

// { start: 2, end: 4, startCategory: 'few', endCategory: 'few', rangeCategory: 'few' }

177

```

178

179

### Language-Specific Range Rules

180

181

**English Range Rules:**

182

- All ranges return `"other"` regardless of input categories

183

- Simple rule: ranges are always plural

184

185

**Romanian Range Rules:**

186

- If end is `"few"`, return `"few"`

187

- If end is `"other"`, return `"other"`

188

- Otherwise return start category

189

190

**Polish Range Rules:**

191

- Complex logic based on both start and end categories

192

- Generally returns the "more plural" of the two categories

193

- Special handling for `"one"` to `"few"` transitions

194

195

**Lithuanian Range Rules (Most Complex):**

196

- 5 possible outcomes: `"one"`, `"few"`, `"many"`, `"other"`

197

- Complex matrix-based rules considering all combinations

198

- Different outcomes for different start/end combinations

199

200

### Error Handling

201

202

Range functions expect valid plural categories as input:

203

204

```javascript

205

import { en, ro } from "make-plural/ranges";

206

207

// Valid usage

208

en('one', 'other'); // 'other'

209

ro('few', 'many'); // 'other'

210

211

// Invalid usage (will cause errors)

212

// en('invalid', 'other'); // Error: invalid category

213

// ro('one', 'seven'); // Error: invalid category

214

```

215

216

### When to Use Ranges

217

218

Use range pluralization when:

219

220

1. **Range Messages**: Displaying ranges like "1-5 items", "3-10 results"

221

2. **Localization**: Building internationalized range displays

222

3. **Complex Languages**: Working with languages that have specific range rules

223

4. **Comprehensive Support**: Need full CLDR compliance for range pluralization

224

225

Common applications:

226

- Search result counts ("Showing 1-10 of 100 results")

227

- Pagination displays ("Items 21-30")

228

- Quantity ranges ("Select 2-5 options")

229

- Date ranges with counts ("1-3 days remaining")

230

231

### Limitations

232

233

**Language Coverage:**

234

- Only 93 of 219 languages have specific range rules

235

- Languages without range rules are not included in this module

236

- Use main plurals module for fallback behavior

237

238

**Range Logic:**

239

- Range functions operate on plural categories, not raw numbers

240

- You must calculate start/end categories first using pluralization functions

241

- Range direction (start > end) may produce unexpected results in some languages

242

243

**Fallback Strategy:**

244

```javascript

245

import { en } from "make-plural/ranges";

246

import { fr } from "make-plural";

247

248

// For languages without range rules, use a fallback

249

function getRangeCategory(start, end, language) {

250

try {

251

// Try to use range function if available

252

const rangeFn = require(`make-plural/ranges`)[language];

253

const startCat = require(`make-plural`)[language](start);

254

const endCat = require(`make-plural`)[language](end);

255

return rangeFn(startCat, endCat);

256

} catch (e) {

257

// Fallback: ranges are typically 'other' or use end category

258

const endCat = require(`make-plural`)[language](end);

259

return endCat === 'one' ? 'other' : endCat;

260

}

261

}

262

```