roddeh / i18njs

Internationalisation library for JS projects
MIT License
64 stars 17 forks source link

Pluralization rules #8

Closed r-aamir closed 5 years ago

r-aamir commented 5 years ago

Is it planned to include ability to specify pluralization rules for a language such as Russian, where there are much more word forms depending on the count of objects, such as:

{
  values:{
    "%d results": {
        zero: "нет результатов",
        one: "1 результат",
        few: "%n результата",
        many: "%n результатов",
        other: "%n результаты"
    }
  }
}

// English
{
  values:{
    "%d results": {
        zero: "No results",
        one: "1 result",
        other: "%n results"
    }
  }
}

Russian pluralization rules:

function (value) {
  if (!value) {
    return "zero";
  }
  if (value % 10 == 1 && value % 100 != 11) {
    return "one";
  }
  if ([2, 3, 4].indexOf(value % 10) >= 0 && [12, 13, 14].indexOf(value % 100) < 0) {
    return "few";
  }
  if (value % 10 == 0 || [5, 6, 7, 8, 9].indexOf(value % 10) >= 0 || [11, 12, 13, 14].indexOf(value % 100) >= 0) {
    return "many";
  }
  return "other";
}

Pluralization rules can be found at http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html

roddeh commented 5 years ago

Support for more complex pluralisation rules has been on my radar for a while. I will probably have a chance to implement something in the next couple of weeks. My initial thoughts would be to support the rules through a plugin interface rather than baking them into the core.

roddeh commented 5 years ago

Ok, just pushed an update. I implemented the more complex rules as an extension point. The implementation for Russian (based on your example) lives here.

https://github.com/roddeh/i18njs-ru

Then the usage would be something like

let ru = i18n.create({
  values:{
    "%n results":{
      "zero": "нет результатов",
      "one": "%n результат",
      "few": "%n результата",
      "many": "%n результатов",
      "other": "%n результаты"
    }
  }
)

const russianExt = require('i18njs-ru')

ru.extend(russianExt)
ru('%n results', 0)
ru('%n results', 1)
ru('%n results', 11)
ru('%n results', 101)
...
roddeh commented 5 years ago

Let me know if you think this will work. I am not so familiar with Russian ;)

Once you confirm I will publish both packages to npm.

roddeh commented 5 years ago

Just published to npm

r-aamir commented 5 years ago

Sorry for late response, just tested and it works great, thanks!