make-plural
Make-plural is a JavaScript module that translates
Unicode CLDR
pluralization rules
to JavaScript functions. It includes both a live parser (make-plural.js
) as
well as the generated output for the latest edition of the CLDR (plurals.js
);
the latter is just over 2kB in size when minified & gzipped, and covers 199
languages, so it's probably what you want unless you really know what you're
doing.
Make-plural is written in
ECMAScript 6 and
transpiled using Babel and
Browserify to CommonJS and AMD and ES6 module formats,
as well as being suitable for use in browser environments.
Installation
npm install make-plural
or
bower install make-plural
or
git clone https://github.com/eemeli/make-plural.js.git
cd make-plural.js
npm install
make all
or download the latest release from
here
Precompiled plurals
plurals.js
contains an UMD module that can be included with node's require
or AMD's define
. In a browser environment, it will populate a global object
plurals
. Said module contains 199 functions (one per
language),
each taking as a first parameter the value to be classified (either a number or
a string), and as an optional second parameter, a boolean that if true, applies
ordinal rather than cardinal rules.
pluralCategories.js
has a similar structure to plurals.js
, but contains an
array of the pluralization categories the cardinal and ordinal rules each
language's pluralization function may output.
If your language isn't directly included in either of the above, try removing
any trailing parts that are separated from the stem by -
or _
.
Precompiled use: Node
> plurals = require('make-plural/plurals')
{ af: [Function],
ak: [Function],
am: [Function],
yo: [Function],
zh: [Function],
zu: [Function] }
> plurals.en(1)
'one'
> plurals.en(2)
'other'
> plurals.en(2, true)
'two'
> console.log(plurals.en.toString())
function (n, ord) {
var s = String(n).split('.'), v0 = !s[1], t0 = Number(s[0]) == n,
n10 = t0 && s[0].slice(-1), n100 = t0 && s[0].slice(-2);
if (ord) return (n10 == 1 && n100 != 11) ? 'one'
: (n10 == 2 && n100 != 12) ? 'two'
: (n10 == 3 && n100 != 13) ? 'few'
: 'other';
return (n == 1 && v0) ? 'one' : 'other';
}
> pluralCategories = require('make-plural/pluralCategories')
{ af: { cardinal: [ 'one', 'other' ], ordinal: [ 'other' ] },
ak: { cardinal: [ 'one', 'other' ], ordinal: [ 'other' ] },
am: { cardinal: [ 'one', 'other' ], ordinal: [ 'other' ] },
ar:
{ cardinal: [ 'zero', 'one', 'two', 'few', 'many', 'other' ],
ordinal: [ 'other' ] },
zh: { cardinal: [ 'other' ], ordinal: [ 'other' ] },
zu: { cardinal: [ 'one', 'other' ], ordinal: [ 'other' ] } }
Precompiled use: Web
<script src="path/to/make-plural/plurals.min.js"></script>
<script>
var ru = plurals.ru
console.log('1: ' + plurals.ru(1) + ', 3.0: ' + plurals.ru(3.0) +
', "1.0": ' + plurals.ru('1.0') + ', "0": ' + plurals.ru('0'));
console.log(plurals.ru.toString());
</script>
With outputs:
1: one, 3.0: few, "1.0": other, "0": many
function(n, ord) {
var s = String(n).split('.'), i = s[0], v0 = !s[1], i10 = i.slice(-1),
i100 = i.slice(-2);
if (ord) return 'other';
return (v0 && i10 == 1 && i100 != 11) ? 'one'
: (v0 && (i10 >= 2 && i10 <= 4) && (i100 < 12
|| i100 > 14)) ? 'few'
: (v0 && i10 == 0 || v0 && (i10 >= 5 && i10 <= 9)
|| v0 && (i100 >= 11 && i100 <= 14)) ? 'many'
: 'other';
}
Note that with plurals.min.js
, the stringified function would be rendered as:
function (e,t){var r=String(e).split("."),n=r[0],o=!r[1],c=n.slice(-1),
i=n.slice(-2);return t?"other":o&&1==c&&11!=i?"one":o&&c>=2&&4>=c&&(12>i||i>14)?
"few":o&&0==c||o&&c>=5&&9>=c||o&&i>=11&&14>=i?"many":"other"}
Live compiler: make-plural.js
MakePlural.load(cldr, ...)
Loads CLDR rules from one or more cldr
variables, each of which must be an
object formatted like
this.
No plural data is included by default, so you'll need to call this at least
once, or otherwise fill the MakePlural.rules
object.
The default CLDR rules are included in make-plural, and may be loaded as seen
in the examples below.
new MakePlural(lc, { cardinals, ordinals })
Returns a function that takes an argument n
and returns its plural category
for the given locale lc
.
The returned function has an overloaded toString(name)
method that may be
used to generate a clean string representation of the function, with an
optional name name
.
The optional second parameter may contain the following boolean members:
cardinals
— if true, rules for cardinal values (1 day, 2 days, etc.) are
includedordinals
— if true, rules for ordinal values (1st, 2nd, etc.) are included
If both cardinals
and ordinals
are true, the returned function takes a
second parameter ord
. Then, if ord
is true, the function will return the
ordinal rather than cardinal category applicable to n
in locale lc
.
If the second parameter is undefined, the values are taken from
MakePlural.cardinals
(default true
) and MakePlural.ordinals
(default
false
).
Live use: Node
> MakePlural = require('make-plural/make-plural').load(
... require('make-plural/data/plurals.json'),
... require('make-plural/data/ordinals.json'))
{ [Function: MakePlural]
cardinals: true,
ordinals: false,
rules:
{ cardinal:
{ af: [Object],
ak: [Object],
am: [Object],
yo: [Object],
zh: [Object],
zu: [Object] },
ordinal:
{ af: [Object],
am: [Object],
ar: [Object],
vi: [Object],
zh: [Object],
zu: [Object] } } }
> sk = new MakePlural('sk')
{ [Function]
_obj:
{ lc: 'sk',
cardinals: true,
ordinals: false,
categories: { cardinal: [Object], ordinal: [] },
parser: { v0: 1, i: 1 },
tests: { obj: [Circular], ordinal: {}, cardinal: [Object] },
fn: [Circular] },
categories: { cardinal: [ 'one', 'few', 'many', 'other' ], ordinal: [] },
test: [Function],
toString: [Function] }
> sk(1)
'one'
> sk(3.0)
'few'
> sk('1.0')
'many'
> sk('0')
'other'
> console.log(sk.toString())
function(n) {
var s = String(n).split('.'), i = s[0], v0 = !s[1];
return (i == 1 && v0 ) ? 'one'
: ((i >= 2 && i <= 4) && v0 ) ? 'few'
: (!v0 ) ? 'many'
: 'other';
}
make-plural.js
may also be used in browser environments; see test/index.html
for an example of its use.
CLI Usage
$ ./bin/make-plural > plurals.js
$ ./bin/make-plural fr
function fr(n, ord) {
if (ord) return (n == 1) ? 'one' : 'other';
return (n >= 0 && n < 2) ? 'one' : 'other';
}
$ ./bin/make-plural --locale fr --value 1.5
one
$ ./bin/make-plural 1.5 -l fr --ordinal
other
Please see the source of src/index.js
for more details.
Dependencies
Make-plural has no required runtime dependencies. CLDR plural rule data is
included in JSON format; make-plural supports the
LDML Language Plural Rules
as used in CLDR release 24 and later.
The CLI binary bin/make-plural
does use
minimist as an argument parser, but
that is not required for any other use.
Using MakePlural.load()
, you may make use of external sources of CLDR data.
For example, the following works when using together with
cldr-data:
> cldr = require('cldr-data');
> MakePlural = require('make-plural/make-plural').load(
cldr('supplemental/plurals'),
cldr('supplemental/ordinals')
);
> en = new MakePlural('en');
> en(3, true)
'few'