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
```