Skip to content

Commit 583ae45

Browse files
committed
Plural: Support ordinals
Fixes #403
1 parent 0eebc18 commit 583ae45

File tree

6 files changed

+112
-21
lines changed

6 files changed

+112
-21
lines changed

README.md

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ requirements. See table below.
205205
| Currency module | cldr/main/`locale`/currencies.json<br>cldr/supplemental/currencyData.json<br>+CLDR JSON files from number module<br>+CLDR JSON files from plural module for name style support |
206206
| Date module | cldr/main/`locale`/ca-gregorian.json<br>cldr/main/`locale`/timeZoneNames.json<br>cldr/supplemental/timeData.json<br>cldr/supplemental/weekData.json<br>+CLDR JSON files from number module |
207207
| Number module | cldr/main/`locale`/numbers.json<br>cldr/supplemental/numberingSystems.json |
208-
| Plural module | cldr/supplemental/plurals.json |
208+
| Plural module | cldr/supplemental/plurals.json (for cardinals)<br>cldr/supplemental/ordinals.json (for ordinals) |
209209

210210
*(b) How am I supposed to get and load CLDR content?*
211211

@@ -433,24 +433,32 @@ to you in different flavors):
433433

434434
### Plural module
435435

436-
- **`.pluralGenerator()`**
436+
- **`.pluralGenerator( [options] )`**
437437

438438
Return a function that returns the value's corresponding plural group: `zero`,
439439
`one`, `two`, `few`, `many`, or `other`.
440440

441+
The function may be used for cardinals or ordinals.
442+
441443
```javascript
442444
.pluralGenerator()( 0 )
443445
// > "other"
444446

445447
.pluralGenerator()( 1 )
446448
// > "one"
449+
450+
.pluralGenerator({ type: "ordinal" })( 1 )
451+
// > "one"
452+
453+
.pluralGenerator({ type: "ordinal" })( 2 )
454+
// > "two"
447455
```
448456

449457
[Read more...](doc/api/plural/plural-generator.md)
450458

451-
- **`.plural( value )`**
459+
- **`.plural( value[, options ] )`**
452460

453-
Alias for `.pluralGenerator()( value )`.
461+
Alias for `.pluralGenerator( [options] )( value )`.
454462

455463

456464
## Error reference

doc/api/plural/plural-generator.md

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
## .pluralGenerator() ➜ function( value )
1+
## .pluralGenerator( [options] ) ➜ function( value )
22

33
It supports the creation of internationalized messages with plural inflection by
44
returning a function that returns the value's plural group: `zero`, `one`,
@@ -9,13 +9,24 @@ to return the plural group.
99

1010
### Parameters
1111

12+
**options** Optional
13+
14+
A JSON object including none or any of the following options.
15+
16+
> **type** Optional
17+
>
18+
> String `cardinal` (default), or `ordinal`.
19+
1220
**value**
1321

1422
A Number for which to return the plural group.
1523

1624
### Example
1725

18-
Prior to using any plural method, you must load `supplemental/plurals.json`.
26+
Prior to using any plural method, you must load either
27+
`supplemental/plurals.json` for cardinals or `supplemental/ordinals.json` for
28+
ordinals.
29+
1930
Read [CLDR content][] if you need more information.
2031

2132
[CLDR content]: ../../../README.md#2-cldr-content
@@ -27,6 +38,8 @@ default locale.
2738
var plural;
2839

2940
Globalize.locale( "en" );
41+
42+
// Cardinals
3043
plural = Globalize.pluralGenerator();
3144

3245
plural( 0 );
@@ -37,6 +50,18 @@ plural( 1 );
3750

3851
plural( 2 );
3952
// > "other"
53+
54+
// Ordinals
55+
plural = Globalize.pluralGenerator({ type: "ordinal" });
56+
57+
plural( 0 );
58+
// > "other"
59+
60+
plural( 1 );
61+
// > "one"
62+
63+
plural( 2 );
64+
// > "two"
4065
```
4166

4267
You can use the instance method `.pluralGenerator()`, which uses the instance
@@ -49,7 +74,7 @@ plural( 1 );
4974
// > "other"
5075
```
5176

52-
For comparison:
77+
For comparison (cardinals):
5378

5479
| | en (English) | ru (Russian) | ar (Arabic) |
5580
| --- | --- | --- | --- |
@@ -58,3 +83,13 @@ For comparison:
5883
| `plural( 2 )` | `other` | `few` | `two` |
5984
| `plural( 3 )` | `other` | `few` | `few` |
6085
| `plural( 5 )` | `other` | `many` | `few` |
86+
87+
For comparison (ordinals):
88+
89+
| | en (English) | ru (Russian) | ar (Arabic) |
90+
| --- | --- | --- | --- |
91+
| `plural( 0, { type: "ordinal" } )` | `other` | `other` | `other` |
92+
| `plural( 1, { type: "ordinal" } )` | `one` | `other` | `other` |
93+
| `plural( 2, { type: "ordinal" } )` | `two` | `other` | `other` |
94+
| `plural( 3, { type: "ordinal" } )` | `few` | `other` | `other` |
95+
| `plural( 5, { type: "ordinal" } )` | `other` | `other` | `other` |

src/build/intro-plural.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,5 @@
3939
var validateCldr = Globalize._validateCldr,
4040
validateDefaultLocale = Globalize._validateDefaultLocale,
4141
validateParameterPresence = Globalize._validateParameterPresence,
42-
validateParameterType = Globalize._validateParameterType;
42+
validateParameterType = Globalize._validateParameterType,
43+
validateParameterTypePlainObject = Globalize._validateParameterTypePlainObject;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
define([
2+
"../parameter-type"
3+
], function( validateParameterType ) {
4+
5+
return function( value, name ) {
6+
validateParameterType(
7+
value,
8+
name,
9+
value === undefined || value === "cardinal" || value === "ordinal",
10+
"String \"cardinal\" or \"ordinal\""
11+
);
12+
};
13+
14+
});

src/plural.js

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,14 @@ define([
77
"./common/validate/parameter-presence",
88
"./common/validate/parameter-type",
99
"./common/validate/parameter-type/number",
10+
"./common/validate/parameter-type/plain-object",
11+
"./common/validate/parameter-type/plural-type",
1012

1113
"cldr/event",
1214
"cldr/supplemental"
1315
], function( Cldr, MakePlural, Globalize, validateCldr, validateDefaultLocale,
14-
validateParameterPresence, validateParameterType, validateParameterTypeNumber ) {
16+
validateParameterPresence, validateParameterType, validateParameterTypeNumber,
17+
validateParameterTypePlainObject, validateParameterTypePluralType ) {
1518

1619
/**
1720
* .plural( value )
@@ -22,14 +25,14 @@ define([
2225
* value given locale.
2326
*/
2427
Globalize.plural =
25-
Globalize.prototype.plural = function( value ) {
28+
Globalize.prototype.plural = function( value, options ) {
2629
validateParameterPresence( value, "value" );
2730
validateParameterTypeNumber( value, "value" );
28-
return this.pluralGenerator()( value );
31+
return this.pluralGenerator( options )( value );
2932
};
3033

3134
/**
32-
* .pluralGenerator()
35+
* .pluralGenerator( [options] )
3336
*
3437
* Return a plural function (of the form below).
3538
*
@@ -41,23 +44,33 @@ Globalize.prototype.plural = function( value ) {
4144
* default/instance locale.
4245
*/
4346
Globalize.pluralGenerator =
44-
Globalize.prototype.pluralGenerator = function() {
45-
var cldr, plural;
47+
Globalize.prototype.pluralGenerator = function( options ) {
48+
var cldr, plural, isOrdinal, type;
4649

50+
validateParameterTypePlainObject( options, "options" );
51+
52+
options = options || {};
53+
type = options.type || "cardinal";
4754
cldr = this.cldr;
4855

56+
validateParameterTypePluralType( options.type, "options.type" );
57+
4958
validateDefaultLocale( cldr );
5059

60+
isOrdinal = type === "ordinal";
61+
5162
cldr.on( "get", validateCldr );
52-
cldr.supplemental( "plurals-type-cardinal/{language}" );
63+
cldr.supplemental([ "plurals-type-" + type, "{language}" ]);
5364
cldr.off( "get", validateCldr );
5465

55-
// Set CLDR data
56-
MakePlural.rules = {
57-
cardinal: cldr.supplemental( "plurals-type-cardinal" )
58-
};
66+
MakePlural.rules = {};
67+
MakePlural.rules[type] = cldr.supplemental( "plurals-type-" + type );
5968

60-
plural = MakePlural( cldr.attributes.language, { "no_tests": true } );
69+
plural = MakePlural( cldr.attributes.language, {
70+
"no_tests": true,
71+
"ordinals": isOrdinal,
72+
"no_cardinals": isOrdinal
73+
} );
6174

6275
return function( value ) {
6376
validateParameterPresence( value, "value" );

test/functional/plural/plural.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,15 @@ define([
22
"globalize",
33
"json!cldr-data/supplemental/likelySubtags.json",
44
"json!cldr-data/supplemental/plurals.json",
5+
"json!cldr-data/supplemental/ordinals.json",
56
"../../util",
67

78
"globalize/plural"
8-
], function( Globalize, likelySubtags, plurals, util ) {
9+
], function( Globalize, likelySubtags, plurals, ordinals, util ) {
910

1011
function extraSetup() {
1112
Globalize.load( plurals );
13+
Globalize.load( ordinals );
1214

1315
// Temporary fix due to CLDR v26 regression about pt_BR plural
1416
// http://unicode.org/cldr/trac/ticket/7178
@@ -47,6 +49,12 @@ QUnit.test( "should validate parameters", function( assert ) {
4749
Globalize.plural( invalidValue );
4850
};
4951
});
52+
53+
util.assertPlainObjectParameter( assert, "options", function( invalidOptions ) {
54+
return function() {
55+
Globalize.plural( 0, invalidOptions );
56+
};
57+
});
5058
});
5159

5260
QUnit.test( "should validate CLDR content", function( assert ) {
@@ -67,6 +75,14 @@ QUnit.test( "should return plural form", function( assert ) {
6775
assert.equal( Globalize( "en" ).plural( 0.14 ), "other" );
6876
assert.equal( Globalize( "en" ).plural( 3.14 ), "other" );
6977

78+
assert.equal( Globalize( "en" ).plural( 0, { type: "ordinal" } ), "other" );
79+
assert.equal( Globalize( "en" ).plural( 1, { type: "ordinal" } ), "one" );
80+
assert.equal( Globalize( "en" ).plural( 2, { type: "ordinal" } ), "two" );
81+
assert.equal( Globalize( "en" ).plural( 3, { type: "ordinal" } ), "few" );
82+
assert.equal( Globalize( "en" ).plural( 1412, { type: "ordinal" } ), "other" );
83+
assert.equal( Globalize( "en" ).plural( 0.14, { type: "ordinal" } ), "other" );
84+
assert.equal( Globalize( "en" ).plural( 3.14, { type: "ordinal" } ), "other" );
85+
7086
assert.equal( Globalize( "ar" ).plural( 0 ), "zero" );
7187
assert.equal( Globalize( "ar" ).plural( 1 ), "one" );
7288
assert.equal( Globalize( "ar" ).plural( 2 ), "two" );
@@ -87,6 +103,10 @@ QUnit.test( "should return plural form", function( assert ) {
87103
assert.equal( Globalize( "ar" ).plural( 199 ), "many" );
88104
assert.equal( Globalize( "ar" ).plural( 3.14 ), "other" );
89105

106+
[ 0, 1, 2, 3, 9, 10, 11, 99, 100, 101, 3.14 ].forEach(function( value ) {
107+
assert.equal( Globalize( "ar" ).plural( value, { type: "ordinal" } ), "other" );
108+
});
109+
90110
assert.equal( Globalize( "ja" ).plural( 0 ), "other" );
91111
assert.equal( Globalize( "ja" ).plural( 1 ), "other" );
92112
assert.equal( Globalize( "ja" ).plural( 2 ), "other" );

0 commit comments

Comments
 (0)