Skip to content

Instantly share code, notes, and snippets.

@WebFreak001
Last active July 20, 2019 14:40
Show Gist options
  • Save WebFreak001/b0dd5a55376709de825bfbe86b2545e8 to your computer and use it in GitHub Desktop.
Save WebFreak001/b0dd5a55376709de825bfbe86b2545e8 to your computer and use it in GitHub Desktop.
Implements Mozilla's localization and plurals site in D for i18n
/// Implements mozilla's plural forms.
/// See_Also: https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_and_Plurals
/// Returns: the index which plural word to use. For each rule from top to bottom.
int resolvePlural(int form, int n)
{
import std.algorithm : among;
switch (form)
{
// Asian, Persian, Turkic/Altaic, Thai, Lao
case 0:
return 0;
// Germanic, Finno-Ugric, Language isolate, Latin/Greek, Semitic, Romanic, Vietnamese
case 1:
return n == 1 ? 0 : 1;
// Romanic, Lingala
case 2:
return n == 0 || n == 1 ? 0 : 1;
// Baltic
case 3:
if (n % 10 == 0)
return 0;
else if (n != 11 && n % 10 == 1)
return 1;
else
return 2;
// Celtic
case 4:
if (n == 1 || n == 11)
return 0;
else if (n == 2 || n == 12)
return 1;
else if ((n >= 3 && n <= 10) || (n >= 13 && n <= 19))
return 2;
else
return 3;
// Romanic
case 5:
if (n == 1)
return 0;
else if ((n % 100) >= 0 && (n % 100) <= 19)
return 1;
else
return 2;
// Baltic
case 6:
if (n != 11 && n % 10 == 1)
return 0;
else if (n % 10 == 0 || (n % 100 >= 11 && n % 100 <= 19))
return 1;
else
return 2;
// Belarusian, Russian, Ukrainian
case 7:
// Slavic
case 19:
if (n != 11 && n % 10 == 1)
return 0;
else if (n != 12 && n != 13 && n != 14 && (n % 10 >= 2 && n % 10 <= 4))
return 1;
else
return 2;
// Slavic
case 8:
if (n == 1)
return 0;
else if (n >= 2 && n <= 4)
return 1;
else
return 2;
// Slavic
case 9:
if (n == 1)
return 0;
else if (n >= 2 && n <= 4 && !(n >= 12 && n <= 14))
return 1;
else
return 2;
// Slavic
case 10:
if (n % 100 == 1)
return 0;
else if (n % 100 == 2)
return 1;
else if (n % 100 == 3 || n % 100 == 4)
return 2;
else
return 3;
// Celtic
case 11:
if (n == 1)
return 0;
else if (n == 2)
return 1;
else if (n >= 3 && n <= 6)
return 2;
else if (n >= 7 && n <= 10)
return 3;
else
return 4;
// Semitic
case 12:
if (n == 1)
return 0;
else if (n == 2)
return 1;
else if (n == 0)
return 5;
else
{
const d = n % 100;
if (d >= 0 && d <= 2)
return 4;
else if (d >= 3 && d <= 10)
return 2;
else
return 3;
}
// Semitic
case 13:
if (n == 1)
return 0;
else
{
const d = n % 100;
if (d >= 1 && d <= 10)
return 1;
else if (d >= 11 && d <= 19)
return 2;
else
return 3;
}
// unused
case 14:
if (n % 10 == 1)
return 0;
else if (n % 10 == 2)
return 1;
else
return 2;
// Icelandic, Macedonian
case 15:
if (n != 11 && n % 10 == 1)
return 0;
else
return 1;
// Celtic
case 16:
const a = n % 10;
const b = n % 100;
if (a == 1 && b != 11 && b != 71 && b != 91)
return 0;
else if (a == 2 && b != 12 && b != 72 && b != 92)
return 1;
else if (a.among!(3, 4, 9) && !b.among!(13, 14, 19, 73, 74, 79, 93, 94, 99))
return 2;
else if (n % 1_000_000 == 0)
return 3;
else
return 4;
// Ecuador indigenous languages
case 17:
return (n == 0) ? 0 : 1;
// Welsh
case 18:
switch (n)
{
case 0:
return 0;
case 1:
return 1;
case 2:
return 2;
case 3:
return 3;
case 6:
return 4;
default:
return 5;
}
default:
throw new Exception("Unknown plural form");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment