Skip to content

Instantly share code, notes, and snippets.

@iegik
Last active October 26, 2021 17:02
Show Gist options
  • Save iegik/fb82ec5fe11c70cb6c7a309a20ba9e7a to your computer and use it in GitHub Desktop.
Save iegik/fb82ec5fe11c70cb6c7a309a20ba9e7a to your computer and use it in GitHub Desktop.
Plural forms
{
"ru": {
"day": "день",
"%s days": ["%s день", "%s дня", "%s дней"]
}
}
function createText(lang) {
return function () {
return plural.bind(plural, dict, lang, null).apply(plural, arguments);
}
}
function createPluralText(lang) {
return function () {
return plural.bind(plural, dict, lang).apply(plural, arguments);
}
}
// Aliases
/**
* @returns {String} text translated to russian language
*/
var rutext = createText('ru');
// rutext('day') - 'день'
/**
* @param {String} slug/text for translation
* @returns {String} plural formatted text translated to russian language, based on dictionary
*/
var nrutext = createPluralText('ru');
// nrutext(2, '%s day', '%s days') - '%s дня'
// Example without dictionary
/**
* @param {String} formatted text
* @returns {String} plural formatted text in latvian form
*/
function nlvtext() {
return plural.bind(plural, null, 'lv').apply(plural, arguments);
}
// nlvtext(2, '%s diena', '%s dienas') - '%s dienas'
// _n = l10n('ru')
// ;[
// _n('today')
// _n('day', 5),
// _n('%d day', 5, 5),
// _n('%d page of %d', 1, 1, 10),
// _n('%0.2f second', 1/3, 1/3),
// _n('%4dth', 1, 1),
// _n('%4dth', 4, 4),
// _n('%4dth', 125, 125),
// ]
const l10n = lang => {
form = forms[lang]
dict = dicts[lang]
return (str, n, ...values) => dict[str][form(n)].replaceAll(/(%d|%0.2f|%4d)/g, (k) => {
const val = values.shift()
switch (k) {
case '%d': return parseInt(val)
case '%0.2f': return parseFloat(val).toFixed(2)
case '%4d': return `${val}`.padStart(4, '0')
default: return val
}
})
}
// _n = l10n(dicts, 'ru')
// ;[
// _n`today`,
// _n`day`(5),
// _n`${5} day`(5),
// _n`${1} page of ${10}`(1),
// _n`${parseFloat(1/3).toFixed(2)} second`(1/3),
// _n`${1}th`(1),
// _n`${`${4}`.padStart(4, '0')}th`(4),
// _n`${`${125}`.padStart(4, '0')}th`(125),
// ]
const l10n = lang => {
const form = forms[lang]
const dict = dicts[lang]
return (parts, ...values) => {
const replacer = k => values.shift()
const str = dict[parts.join('%s')]
return (n) => str[form(n)]
.replaceAll(/%s/g, replacer)
}
}
// http://rextester.com/OMF52875
public class Program
{
public static string N(Match m) {
return "{" + m.Captures.Count + "}";
}
public static string Get(string str) {
Dictionary<string, string> obj = new Dictionary<string, string>();
obj.Add("%n day", "%n день");
obj.Add("%n days0", "%n дня");
obj.Add("%n days1", "%n дней");
obj.Add("%n day in %s", "%n день в %s");
obj.Add("%n days in %s0", "%n дня в %s");
obj.Add("%n days in %s1", "%n дней в %s");
return obj[str];
}
public static string ToSharp(string str) {
string pattern = @"%[ns]";
Regex rgx = new Regex(pattern);
int i = 0;
str = rgx.Replace(str, m => "{" + (i++) + "}");
return str;
}
public static string Get(string str, params object[] list) {
str = Get(str);
str = String.Format(ToSharp(str), list);
return str;
}
public static int pluralRU(int n) {
return n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
}
public static string NGet(string str, string strs, int count) {
int form = pluralRU(count);
str = form == 0 ? Get(str) : Get(strs + (form - 1));
return str;
}
public static string NGet(string str, string strs, int count, params object[] list) {
int form = pluralRU(count);
str = form == 0 ? Get(str) : Get(strs + (form - 1));
str = String.Format(ToSharp(str), list);
return str;
}
public static void Main(string[] args)
{
String str;
int n;
n = 1;
str = NGet("%n day", "%n days", n, n);
Console.WriteLine(str);
n = 2;
str = NGet("%n day", "%n days", n, n);
Console.WriteLine(str);
n = 5;
str = NGet("%n day", "%n days", n, n);
Console.WriteLine(str);
n = 7;
str = NGet("%n day in %s", "%n days in %s", n, n, "неделе");
Console.WriteLine(str);
}
}
plural.prototype.ru = function (n){
return n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
}
plural.prototype.lv = function(n){
return n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;
}
/**
* @param {Object} dict Dictionary:
* {
* en: {
* 'day': 'day',
* '%s days': ['%s day', '%s days']
* }
* }
* @param {String} lang Language of the word
* @param {Number} n Base number of form
* @param {String} ... #n form of text
* @return {String} translated plural text
*/
function plural(dict, lang, n){
var form = this.prototype[lang](n),
x = 3;
return dict ? (typeof n === 'number' ? dict[lang][arguments[x + 1]][form] : dict[lang][arguments[x]]) : arguments[form + x];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment