package ut import "math" // PluralRule denotes the type of plural rules type PluralRule int // TODO: change this to integer for efficiency and use stringify lib to generate string values. const ( PluralRuleZero PluralRule = iota // zero PluralRuleOne // one - singular PluralRuleTwo // two - dual PluralRuleFew // few - paucal PluralRuleMany // many - also used for fractions if they have a separate class PluralRuleOther // other - required—general plural form—also used if the language only has a single form ) func (p PluralRule) String() string { switch p { case PluralRuleZero: return "PluralRuleZero" case PluralRuleOne: return "PluralRuleOne" case PluralRuleTwo: return "PluralRuleTwo" case PluralRuleFew: return "PluralRuleFew" case PluralRuleMany: return "PluralRuleMany" case PluralRuleOther: return "PluralRuleOther" default: return "Unknown PluralRule" } } // NumberValue should be one of these types: // int, float type NumberValue interface{} // PluralRuler allows the plural rule to be found type PluralRuler interface { FindRule(n NumberValue) PluralRule } var pluralRules = map[string]PluralRuler{ "1": PluralRulerFunc(pluralRule1), "2A": PluralRulerFunc(pluralRule2A), "2B": PluralRulerFunc(pluralRule2B), "2C": PluralRulerFunc(pluralRule2C), "2D": PluralRulerFunc(pluralRule2D), "2E": PluralRulerFunc(pluralRule2E), "2F": PluralRulerFunc(pluralRule2F), "3A": PluralRulerFunc(pluralRule3A), "3B": PluralRulerFunc(pluralRule3B), "3C": PluralRulerFunc(pluralRule3C), "3D": PluralRulerFunc(pluralRule3D), "3E": PluralRulerFunc(pluralRule3E), "3F": PluralRulerFunc(pluralRule3F), "3G": PluralRulerFunc(pluralRule3G), "3H": PluralRulerFunc(pluralRule3H), "3I": PluralRulerFunc(pluralRule3I), "4A": PluralRulerFunc(pluralRule4A), "4B": PluralRulerFunc(pluralRule4B), "4C": PluralRulerFunc(pluralRule4C), "4D": PluralRulerFunc(pluralRule4D), "4E": PluralRulerFunc(pluralRule4E), "4F": PluralRulerFunc(pluralRule4F), "5A": PluralRulerFunc(pluralRule5A), "5B": PluralRulerFunc(pluralRule5B), "6A": PluralRulerFunc(pluralRule6A), "6B": PluralRulerFunc(pluralRule6B), } var pluralPluralRules = map[string][]PluralRule{ "1": {PluralRuleOther}, "2A": {PluralRuleOne, PluralRuleOther}, "2B": {PluralRuleOne, PluralRuleOther}, "2C": {PluralRuleOne, PluralRuleOther}, "2D": {PluralRuleOne, PluralRuleOther}, "2E": {PluralRuleOne, PluralRuleOther}, "2F": {PluralRuleOne, PluralRuleOther}, "3A": {PluralRuleZero, PluralRuleOne, PluralRuleOther}, "3B": {PluralRuleOne, PluralRuleTwo, PluralRuleOther}, "3C": {PluralRuleOne, PluralRuleFew, PluralRuleOther}, "3D": {PluralRuleOne, PluralRuleFew, PluralRuleOther}, "3E": {PluralRuleOne, PluralRuleFew, PluralRuleOther}, "3F": {PluralRuleZero, PluralRuleOne, PluralRuleOther}, "3G": {PluralRuleOne, PluralRuleFew, PluralRuleOther}, "3H": {PluralRuleZero, PluralRuleOne, PluralRuleOther}, "3I": {PluralRuleOne, PluralRuleFew, PluralRuleOther}, "4A": {PluralRuleOne, PluralRuleTwo, PluralRuleMany, PluralRuleOther}, "4B": {PluralRuleOne, PluralRuleFew, PluralRuleMany, PluralRuleOther}, "4C": {PluralRuleOne, PluralRuleFew, PluralRuleMany, PluralRuleOther}, "4D": {PluralRuleOne, PluralRuleTwo, PluralRuleFew, PluralRuleOther}, "4E": {PluralRuleOne, PluralRuleFew, PluralRuleMany, PluralRuleOther}, "4F": {PluralRuleOne, PluralRuleTwo, PluralRuleFew, PluralRuleOther}, "5A": {PluralRuleOne, PluralRuleTwo, PluralRuleFew, PluralRuleMany, PluralRuleOther}, "5B": {PluralRuleOne, PluralRuleTwo, PluralRuleFew, PluralRuleMany, PluralRuleOther}, "6A": {PluralRuleZero, PluralRuleOne, PluralRuleTwo, PluralRuleFew, PluralRuleMany, PluralRuleOther}, "6B": {PluralRuleZero, PluralRuleOne, PluralRuleTwo, PluralRuleFew, PluralRuleMany, PluralRuleOther}, } // func GetPluralInt(code string) int { // switch code { // case "": // } // } // func getPluralFunc(code string) PluralRulerFunc { // fn, ok := pluralRules[code] // if !ok { // return PluralRuleOther // } // return fn // } // func RegisterPluralRule(locale string, ruler PluralRuler) { // pluralRules[locale] = ruler // } // func FindRule(locale string, count NumberValue) (rule PluralRule) { // l, ok := GetLocale(locale) // if !ok { // return PluralRuleOther // } // ruler, ok := pluralRules[l.PluralRule] // if !ok { // return PluralRuleOther // } // return ruler.FindRule(count) // } // PluralRulerFunc for a given locale used to find the PluralRule for the given // NumberValue type PluralRulerFunc func(n NumberValue) PluralRule // FindRule finds the actual PluralRules func (p PluralRulerFunc) FindRule(n NumberValue) PluralRule { return p(n) } // func init() { // RegisterPluralRule("en", PluralRulerFunc(func(n NumberValue) PluralRule { // switch count.(type) { // case int, int32, int64, uint, uint32, uint64: // if count == 1 { // return PluralRuleOne // } // } // return PluralRuleOther // })) // } // pluralRule is a function that takes a single float64 and returns an int. Its // intended use is to return an int index for what plural form to use for the // given float // type pluralRule func(float64) int // // pluralRules contains the list of all pluralRule functions. The string map // // index is used when loading plural rules from yaml files // var pluralRules = map[string]pluralRule{ // "1": pluralRule1, // "2A": pluralRule2A, // "2B": pluralRule2B, // "2C": pluralRule2C, // "2D": pluralRule2D, // "2E": pluralRule2E, // "2F": pluralRule2F, // "3A": pluralRule3A, // "3B": pluralRule3B, // "3C": pluralRule3C, // "3D": pluralRule3D, // "3E": pluralRule3E, // "3F": pluralRule3F, // "3G": pluralRule3G, // "3H": pluralRule3H, // "3I": pluralRule3I, // "4A": pluralRule4A, // "4B": pluralRule4B, // "4C": pluralRule4C, // "4D": pluralRule4D, // "4E": pluralRule4E, // "4F": pluralRule4F, // "5A": pluralRule5A, // "5B": pluralRule5B, // "6A": pluralRule6A, // "6B": pluralRule6B, // } // isInt checks if a float64 is an integer value func isInt(n NumberValue) bool { switch n.(type) { case int, int16, int32, int64, uint, uint16, uint32, uint64: return true } return false } func toFloat64(n NumberValue) float64 { switch x := n.(type) { case int: return float64(x) case int16: return float64(x) case int32: return float64(x) case int64: return float64(x) case uint: return float64(x) case uint16: return float64(x) case uint32: return float64(x) case uint64: return float64(x) case float32: return float64(x) case float64: return x } return 0.0 } // pluralRule1: // Logic for calculating the nth plural for languages with no plurals // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 1 form: // - other: // - rule: everything // - examples: 0, 0.5, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, … // // Languages: // - ay: Aymara // - az: Azerbaijani // - bm: Bambara // - bo: Tibetan // - dz: Dzongkha // - fa: Persian // - id: Indonesian // - ig: Igbo // - ii: Sichuan Yi // - hu: Hungarian // - ja: Japanese // - jbo: Lojban // - jv: Javanese // - ka: Georgian // - kde: Makonde // - kea: Kabuverdianu // - km: Khmer // - kn: Kannada // - ko: Korean // - lo: Lao // - ms: Malay // - my: Burmese // - sah: Sakha // - ses: Koyraboro Senni // - sg: Sango // - su: Sundanese // - th: Thai // - to: Tongan // - tr: Turkish // - tt: Tatar // - ug: Uyghur // - vi: Vietnamese // - wo: Wolof // - yo: Yoruba // - zh: Chinese func pluralRule1(n NumberValue) PluralRule { return PluralRuleOther } // pluralRule2A: // Logic for calculating the nth plural for Spanish or languages who share the same rules as Spanish // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 2 forms: // - one: // - rule: is 1 // - examples: 1 // - other: // - rule: everythng else // - examples: 0, 0.5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, … // // Languages: // - af: Afrikaans // - an: Aragonese // - asa: Asu // - ast: Asturian // - bem: Bemba // - bez: Bena // - bg: Bulgarian // - bn: Bengali // - brx: Bodo // - ca: Catalan // - cgg: Chiga // - chr: Cherokee // - ckb: Sorani Kurdish // - da: Danish // - de: German // - doi: Dogri // - dv: Divehi // - ee: Ewe // - el: Greek // - en: English // - eo: Esperanto // - es: Spanish // - et: Estonian // - eu: Basque // - fi: Finnish // - fo: Faroese // - fur: Friulian // - fy: Western Frisian // - gl: Galician // - gsw: Swiss German // - gu: Gujarati // - ha: Hausa // - haw: Hawaiian // - hne: Chhattisgarhi // - hy: Armenian // - ia: Interlingua // - is: Icelandic // - it: Italian // - jgo: Ngomba // - jmc: Machame // - kaj: Jju // - kcg: Tyap // - kk: Kazakh // - kkj: Kako // - kl: Kalaallisut // - ks: Kashmiri // - ksb: Shambala // - ku: Kurdish // - ky: Kirghiz // - lb: Luxembourgish // - lg: Ganda // - mai: Maithili // - mas: Masai // - mgo: Meta' // - ml: Malayalam // - mn: Mongolian // - mni: Manipuri // - mr: Marathi // - nah: Nahuatl // - nap: Neapolitan // - nb: Norwegian Bokmål // - nd: North Ndebele // - ne: Nepali // - nl: Dutch // - nn: Norwegian Nynorsk // - nnh: Ngiemboon // - no: Norwegian // - nr: South Ndebele // - ny: Nyanja // - nyn: Nyankole // - om: Oromo // - or: Oriya // - os: Ossetic // - pa: Punjabi // - pap: Papiamento // - pms: Piemontese // - ps: Pashto // - pt: Portuguese // - rof: Rombo // - rm: Romansh // - rw: Kinyarwanda // - rwk: Rwa // - saq: Samburu // - sat: Santali // - sco: Scots // - sd: Sindhi // - seh: Sena // - si: Sinhala // - sn: Shona // - so: Somali // - son: Songhai // - sq: Albanian // - ss: Swati // - ssy: Saho // - st: Southern Sotho // - sv: Swedish // - sw: Swahili // - syr: Syriac // - ta: Tamil // - te: Telugu // - teo: Teso // - tig: Tigre // - tk: Turkmen // - tn: Tswana // - ts: Tsonga // - ur: Urdu // - ve: Venda // - vo: Volapük // - vun: Vunjo // - wae: Walser // - xh: Xhosa // - xog: Soga // - zu: Zulu func pluralRule2A(n NumberValue) PluralRule { // isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) switch { case isInt(n) && i == 1: return PluralRuleOne } return PluralRuleOther } // pluralRule2B: // Logic for calculating the nth plural for Hindi or languages who share the same rules as Hindi // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 2 forms: // - one: // - rule: is 0 or 1 // - examples: 0, 1 // - other: // - rule: everythng else // - examples: 0.5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, … // // Languages: // - ach: Acholi // - ak: Akan // - am: Amharic // - arn: Mapudungun // - bh: Bihari // - fil: Filipino // - guw: Gun // - hi: Hindi // - ln: Lingala // - mfe: Mauritian Creole // - mg: Malagasy // - mi: Maori // - nso: Northern Sotho // - oc: Occitan // - tg: Tajic // - ti: Tigrinya // - tl: Tagalog // - uz: Uzbek // - wa: Walloon func pluralRule2B(n NumberValue) PluralRule { // isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) switch { case isInt(n) && (i == 0 || i == 1): return PluralRuleOne } return PluralRuleOther } // pluralRule2C: // Logic for calculating the nth plural for French or languages who share the same rules as French // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 2 forms: // - one: // - rule: n within 0..2 and n is not 2 // - examples: 0, 0.5, 1, 1.5, … // - other: // - rule: everythng else // - examples: 2, 2.5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, … // // Languages: // - ff: Fulah // - fr: French // - kab: Kabyle func pluralRule2C(n NumberValue) PluralRule { abs := math.Abs(toFloat64(n)) switch { case abs >= 0 && abs < 2: return PluralRuleOne } return PluralRuleOther } // pluralRule2D: // Logic for calculating the nth plural for Macedonian or languages who share the same rules as // Macedonian // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 2 forms: // - one: // - rule: n mod 10 is 1 and n is not 11 // - examples: 1, 21, 31, 41, 51, 61, 71, 81, 91, 101, 111, 121, 131, 141, 151, 161, 171, … // - other: // - rule: everythng else // - examples: 0, 0.5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, … // // Languages: // - mk: Macedonian func pluralRule2D(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) mod10 := i % 10 switch { case isInt && mod10 == 1 && i != 11: return PluralRuleOne } return PluralRuleOther } // pluralRule2E: // Logic for calculating the nth plural for Central Atlas Tamazight or languages who share the same // rules as Central Atlas Tamazight // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 2 forms: // - one: // - rule: n in 0..1 or n in 11..99 // - examples: 0, 1, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, … // - other: // - rule: everythng else // - examples: 0.5, 1.5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100, 101, 102, 103, 104, 105, 106, … // // Languages: // - tzm: Central Atlas Tamazight func pluralRule2E(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) switch { case isInt && (i == 0 || i == 1 || (i >= 11 && i <= 99)): return PluralRuleOne } return PluralRuleOther } // pluralRule2F: // Logic for calculating the nth plural for Manx or languages who share the same rules as Manx // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 2 forms: // - one: // - rule: n mod 10 in 1..2 or n mod 20 is 0 // - examples: 0, 1, 2, 11, 12, 20, 21, 22, 31, 32, 40, 41, 42, 51, 52, 60, 61, 62, 71, … // - other: // - rule: everythng else // - examples: 0.5, 1.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18, 19, 23, 24, … // // Languages: // - gv: Manx func pluralRule2F(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) mod10 := i % 10 mod20 := i % 20 switch { case isInt && (mod10 == 1 || mod10 == 2 || mod20 == 0): return PluralRuleOne } return PluralRuleOther } // pluralRule3A: // Logic for calculating the nth plural for Latvian or languages who share the same rules as Latvian // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 3 forms: // - zero: // - rule: n is 0 // - examples: 0 // - one: // - rule: n mod 10 is 1 and n mod 100 is not 11 // - examples: 1, 21, 31, 41, 51, 61, 71, 81, 91, 101, 121, 131, 141, 151, 161, 171, 181, … // - other: // - rule: everythng else // - examples: 2, 2.5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, … // // Languages: // - lv: Latvian func pluralRule3A(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) switch { case isInt && i == 0: return PluralRuleZero case isInt && i%10 == 1 && i%100 != 11: return PluralRuleOne } return PluralRuleOther } // pluralRule3B: // Logic for calculating the nth plural for Nama or languages who share the same rules as Nama // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 3 forms: // - one: // - rule: n is 1 // - examples: 1 // - two: // - rule: n is 2 // - examples: 2 // - other: // - rule: everythng else // - examples: 0, 0.5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, … // // Languages: // - iu: Inuktitut // - kw: Cornish // - naq: Nama // - se: Northern Sami // - sma: Southern Sami // - smi: Sami Language // - smj: Lule Sami // - smn: Inari Sami // - sms: Skolt Sami func pluralRule3B(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) switch { case isInt && i == 1: return PluralRuleOne case isInt && i == 2: return PluralRuleTwo } return PluralRuleOther } // pluralRule3C: // Logic for calculating the nth plural for Romanian or languages who share the same rules as // Romanian // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 3 forms: // - one: // - rule: n is 1 // - examples: 1 // - few: // - rule: n is 0 OR n is not 1 AND n mod 100 in 1..19 // - examples: 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 101, … // - other: // - rule: everythng else // - examples: 0.5, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, … // // Languages: // - ro: Romanian // - mo: Moldavian func pluralRule3C(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) switch { case isInt && i == 1: return PluralRuleOne case isInt && (i == 0 || (i%100 >= 1 && i%100 <= 19)): return PluralRuleFew } return PluralRuleOther } // pluralRule3D: // Logic for calculating the nth plural for Lithuanian or languages who share the same rules as // Lithuanian // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 3 forms: // - one: // - rule: n mod 10 is 1 and n mod 100 not in 11..19 // - examples: 1, 21, 31, 41, 51, 61, 71, 81, 91, 101, 121, 131, 141, 151, 161 171, 181, … // - few: // - rule: n mod 10 in 2..9 and n mod 100 not in 11..19 // - examples: 2, 3, 4, 5, 6, 7, 8, 9, 22, 23, 24, 25, 26, 27, 28, 29, 32, 33, 34, 35, 36, … // - other: // - rule: everythng else // - examples: 0, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 30, 40, 50, 60, 70, 80, 90, … // // Languages: // - lt: Lithuanian func pluralRule3D(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) mod10 := i % 10 mod100 := i % 100 switch { // the part in the parentheses should be replaced with just mod100 !- 11, right? I've seen this // same logically expression so many places that I'm doubting my own logical thinking, so I've // implemented it like I've seen it implemented elsewhere. case isInt && mod10 == 1 && (mod100 < 11 || mod100 > 19): return PluralRuleOne case isInt && mod10 >= 2 && mod10 <= 9 && (mod100 < 11 || mod100 > 19): return PluralRuleFew } return PluralRuleOther } // pluralRule3E: // Logic for calculating the nth plural for Czech or languages who share the same rules as Czech // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 3 forms: // - one: // - rule: n is 1 // - examples: 1 // - few: // - rule: n in 2..4 // - examples: 2, 3, 4 // - other: // - rule: everythng else // - examples: 0, 0.5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, … // // Languages: // - cs: Czech // - sk: Slovak func pluralRule3E(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) switch { case isInt && i == 1: return PluralRuleOne case isInt && i >= 2 && i <= 4: return PluralRuleFew } return PluralRuleOther } // pluralRule3F: // Logic for calculating the nth plural for Langi or languages who share the same rules as Langi // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 3 forms: // - zero: // - rule: n is 0 // - examples: 0 // - one: // - rule: n within 0..2 and n is not 0 and n is not 2 // - examples: 0.5, 1, 1.5, … // - other: // - rule: everythng else // - examples: 2, 2.5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, … // // Languages: // - lag: Langi func pluralRule3F(n NumberValue) PluralRule { isInt := isInt(n) abs := math.Abs(toFloat64(n)) i := int64(abs) switch { case isInt && i == 0: return PluralRuleZero case abs > 0 && abs < 2: return PluralRuleOne } return PluralRuleOther } // pluralRule3G: // Logic for calculating the nth plural for Tachelhit or languages who share the same rules as // Tachelhit // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 3 forms: // - one: // - rule: n within 0..1 // - examples: 0, 0.5, 1 // - few: // - rule: n in 2..10 // - examples: 2, 3, 4, 5, 6, 7, 8, 9, 10 // - other: // - rule: everythng else // - examples: 1.5, 10.5, 11, 11.5, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, … // // Languages: // - shi: Tachelhit func pluralRule3G(n NumberValue) PluralRule { isInt := isInt(n) abs := math.Abs(toFloat64(n)) i := int64(abs) switch { case abs >= 0 && abs <= 1: return PluralRuleOne case isInt && i >= 2 && i <= 10: return PluralRuleFew } return PluralRuleOther } // pluralRule3H: // Logic for calculating the nth plural for Colognian or languages who share the same rules as // Colognian // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 3 forms: // - zero: // - rule: n is 0 // - examples: 0 // - one: // - rule: n is 1 // - examples: 1 // - other: // - rule: everythng else // - examples: 0.5, 1.5, 2, 2.5, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, … // // Languages: // - ksh: Colognian // - mnk: Mandinka func pluralRule3H(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) switch { case isInt && i == 0: return PluralRuleZero case isInt && i == 1: return PluralRuleOne } return PluralRuleOther } // pluralRule3I: // Logic for calculating the nth plural for Kashubian or languages who share the same rules as // Kashubian // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 3 forms: // - one: // - rule: n is 1 // - examples: 1 // - few: // - rule: n mod 10 in 2..4 and n mod 100 not in 10..19 // - examples: 2, 3, 4, 22, 23, 24, 32, 33, 34, 42, 43, 44, 52, 53, 54, 62, 63, 64, 72, … // - other: // - rule: everythng else // - examples: 0, 0.5, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 25, … // // Languages: // - csb: Kashubian func pluralRule3I(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) mod10 := i % 10 mod100 := i % 100 switch { case isInt && i == 1: return PluralRuleOne case isInt && (mod10 >= 2 && mod10 <= 4 && (mod100 < 10 || mod100 > 19)): return PluralRuleFew } return PluralRuleOther } // pluralRule4A: // Logic for calculating the nth plural for Hebrew or languages who share the same rules as Hebrew // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 4 forms: // - one: // - rule: n is 1 // - examples: 1 // - two: // - rule: n is 2 // - examples: 2 // - many: // - rule: n is not 0 AND n mod 10 is 0 // - examples: 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130, 140, 150, 160, 170, … // - other: // - rule: everythng else // - examples: 0, 0.5, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, … // // Languages: // - he: Hebrew func pluralRule4A(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) switch { case isInt && i == 1: return PluralRuleOne case isInt && i == 2: return PluralRuleTwo case isInt && i != 0 && i%10 == 0: return PluralRuleMany } return PluralRuleOther } // pluralRule4B: // Logic for calculating the nth plural for Russian or languages who share the same rules as Russian // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 4 forms: // - one: // - rule: n mod 10 is 1 and n mod 100 is not 11 // - examples: 1, 21, 31, 41, 51, 61, 71, 81, 91, 101, 121, 131, 141, 151, 161, 171, 181, … // - few: // - rule: n mod 10 in 2..4 and n mod 100 not in 12..14 // - examples: 2, 3, 4, 22, 23, 24, 32, 33, 34, 42, 43, 44, 52, 53, 54, 62, 63, 64, 72, … // - many: // - rule: n mod 10 is 0 or n mod 10 in 5..9 or n mod 100 in 11..14 // - examples: 0, 5, 6, 7, 8, 9, 11, 12, 13, 14, 25, 26, 27, 28, 29, 35, 36, 37, 38, 39, … // - other: // - rule: everythng else // - examples: 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, … // // Languages: // - be: Belarusian // - bs: Bosnian // - hr: Croatian // - ru: Russian // - sh: Serbo-Croatian // - sr: Serbian // - uk: Ukrainian func pluralRule4B(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) mod10 := i % 10 mod100 := i % 100 switch { case isInt && mod10 == 1 && mod100 != 11: return PluralRuleOne case isInt && (mod10 >= 2 && mod10 <= 4) && (mod100 < 12 || mod100 > 14): return PluralRuleFew case isInt && (mod10 == 0 || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 11 && mod100 <= 14)): return PluralRuleMany } return PluralRuleOther } // pluralRule4C: // Logic for calculating the nth plural for Polish or languages who share the same rules as Polish // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 4 forms: // - one: // - rule: n is 1 // - examples: 1 // - few: // - rule: n mod 10 in 2..4 and n mod 100 not in 12..14 // - examples: 2, 3, 4, 22, 23, 24, 32, 33, 34, 42, 43, 44, 52, 53, 54, 62, 63, 64, 72, … // - many: // - rule: n is not 1 and n mod 10 in 0..1 or n mod 10 in 5..9 or n mod 100 in 12..14 // - examples: 0, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 25, 26, … // - other: // - rule: everythng else // - examples: 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, … // // Languages: // - pl: Polish func pluralRule4C(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) mod10 := i % 10 mod100 := i % 100 switch { case isInt && i == 1: return PluralRuleOne case isInt && mod10 >= 2 && mod10 <= 4 && (mod100 < 12 || mod100 > 14): return PluralRuleFew case isInt && ((mod10 >= 0 && mod10 <= 1) || (mod10 >= 5 && mod10 <= 9) || (mod100 >= 12 && mod100 <= 14)): return PluralRuleMany } return PluralRuleOther } // pluralRule4D: // Logic for calculating the nth plural for Slovenian or languages who share the same rules as // Slovenian // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 4 forms: // - one: // - rule: n mod 100 is 1 // - examples: 1, 11, 21, 31, 41, 51, 61, 71, 81, 91, 101, 111, 121, 131, 141, 151, 161, … // - two: // - rule: n mod 100 is 2 // - examples: 2, 12, 22, 32, 42, 52, 62, 72, 82, 92, 102, 112, 122, 132, 142, 152, 162, … // - few: // - rule: n mod 100 in 3..4 // - examples: 3, 4, 13, 14, 23, 24 33, 34, 43, 44, 53, 54, 63, 64, 73, 74, 83, 84, 93, … // - other: // - rule: everythng else // - examples: 0, 0.5, 5, 6, 7, 8, 9, 10, 15, 16, 17, 18, 19, 20, 25, 26, 27, 28, 29, 30, … // // Languages: // - dsb: Lower Sorbian // - hsb: Upper Sorbian // - sl: Slovenian // - wen: Sorbian Language func pluralRule4D(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) mod100 := i % 100 switch { case isInt && mod100 == 1: return PluralRuleOne case isInt && mod100 == 2: return PluralRuleTwo case isInt && mod100 >= 3 && mod100 <= 4: return PluralRuleFew } return PluralRuleOther } // pluralRule4E: // Logic for calculating the nth plural for Maltese or languages who share the same rules as Maltese // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 4 forms: // - one: // - rule: n is 1 // - examples: 1 // - few: // - rule: n is 0 or n mod 100 in 2..10 // - examples: 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 102, 103, 104, 105, 106, 107, 108, 109, 110, … // - many: // - rule: n mod 100 in 11..19 // - examples: 11, 12, 13, 14, 15, 16, 17, 18, 19, 111, 112, 113, 114, 115, 116, 117, 118, … // - other: // - rule: everythng else // - examples: 0.5, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, … // // Languages: // - mt: Maltese func pluralRule4E(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) mod100 := i % 100 switch { case isInt && i == 1: return PluralRuleOne case isInt && (i == 0 || (mod100 >= 2 && mod100 <= 10)): return PluralRuleFew case isInt && mod100 >= 11 && mod100 <= 19: return PluralRuleMany } return PluralRuleOther } // pluralRule4F: // Logic for calculating the nth plural for Scottish Gaelic or languages who share the same rules as // Scottish Gaelic // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 4 forms: // - one: // - rule: n in 1,11 // - examples: 1, 11 // - two: // - rule: n in 2,12 // - examples: 2, 12 // - few: // - rule: n in 3..10,13..19 // - examples: 3, 4, 5, 6, 7, 8, 9, 10, 13, 14, 15, 16, 17, 18, 19 // - other: // - rule: everythng else // - examples: 0, 0.5, 1.5, 2, 2.5, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, … // // Languages: // - gd: Scottish Gaelic func pluralRule4F(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) switch { case isInt && (i == 1 || i == 11): return PluralRuleOne case isInt && (i == 2 || i == 12): return PluralRuleTwo case isInt && ((i >= 3 && i <= 10) || (i >= 13 && i <= 19)): return PluralRuleFew } return PluralRuleOther } // pluralRule5A: // Logic for calculating the nth plural for Irish or languages who share the same rules as Irish // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 5 forms: // - one: // - rule: n is 1 // - examples: 1 // - two: // - rule: n is 2 // - examples: 2 // - few: // - rule: n in 3..6 // - examples: 3, 4, 5, 6 // - many: // - rule: n in 7..10 // - examples: 7, 8, 9, 10 // - other: // - rule: everythng else // - examples: 0, 0.5, 5, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, … // // Languages: // - ga: Irish func pluralRule5A(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) switch { case isInt && i == 1: return PluralRuleOne case isInt && i == 2: return PluralRuleTwo case isInt && i >= 3 && i <= 6: return PluralRuleFew case isInt && i >= 7 && i <= 10: return PluralRuleMany } return PluralRuleOther } // pluralRule5B: // Logic for calculating the nth plural for Breton or languages who share the same rules as Breton // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 5 forms: // - one: // - rule: n mod 10 is 1 and n mod 100 not in 11,71,91 // - examples: 1, 21, 31, 41, 51, 61, 81, 101, 121, 131, 141, 151, 161, 181, 201, 221, … // - two: // - rule: n mod 10 is 2 and n mod 100 not in 12,72,92 // - examples: 2, 22, 32, 42, 52, 62, 82, 102, 122, 132, 142, 152, 162, 182, 202, 222, … // - few: // - rule: n mod 10 in 3..4,9 and n mod 100 not in 10..19,70..79,90..99 // - examples: 3, 4, 9, 23, 24, 29, 33, 34, 39, 43, 44, 49, 53, 54, 59, 63, 64, 69, 83, … // - many: // - rule: n is not 0 and n mod 1000000 is 0 // - examples: 1000000, 2000000, 3000000, 4000000, 5000000, 6000000, 7000000, 8000000, … // - other: // - rule: everythng else // - examples: 0, 0.5, 10, 50, 100, 500, 1000, 5000, 10000, 50000, 100000, 500000, … // // Languages: // - br: Breton func pluralRule5B(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) mod10 := i % 10 mod100 := i % 100 switch { case isInt && mod10 == 1 && mod100 != 11 && mod100 != 71 && mod100 != 91: return PluralRuleOne case isInt && mod10 == 2 && mod100 != 12 && mod100 != 72 && mod100 != 92: return PluralRuleTwo case isInt && (mod10 == 3 || mod10 == 4 || mod10 == 9) && (mod100 < 10 || mod100 > 19) && (mod100 < 70 || mod100 > 79) && (mod100 < 90 || mod100 > 99): return PluralRuleFew case isInt && i != 0 && i%1000000 == 0: return PluralRuleMany } return PluralRuleOther } // pluralRule6A: // Logic for calculating the nth plural for Arabic or languages who share the same rules as Arabic // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 6 forms: // - zero: // - rule: n is 0 // - examples: 0 // - one: // - rule: n is 1 // - examples: 1 // - two: // - rule: n is 2 // - examples: 2 // - few: // - rule: n mod 100 in 3..10 // - examples: 3, 4, 5, 6, 7, 8, 9, 10, 103, 104, 105, 106, 107, 108, 109, 110, 203, 204, … // - many: // - rule: n mod 100 in 11..99 // - examples: 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, … // - other: // - rule: everythng else // - examples: 0.5, 1.5, 100, 101, 102, 200, 201, 202, 300, 301, 302, 400, 401, 402, 500, … // // Languages: // - ar: Arabic func pluralRule6A(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) switch { case isInt && i == 0: return PluralRuleZero case isInt && i == 1: return PluralRuleOne case isInt && i == 2: return PluralRuleTwo case isInt && i%100 >= 3 && i%100 <= 10: return PluralRuleFew case isInt && i%100 >= 11: return PluralRuleMany } return PluralRuleOther } // pluralRule6B: // Logic for calculating the nth plural for Welsh or languages who share the same rules as Welsh // // Plural Forms Rules Documented here: // https://developer.mozilla.org/en/docs/Localization_and_Plurals // // This Plural Rule contains 6 forms: // - zero: // - rule: n is 0 // - examples: 0 // - one: // - rule: n is 1 // - examples: 1 // - two: // - rule: n is 2 // - examples: 2 // - few: // - rule: n is 3 // - examples: 3 // - many: // - rule: n is 6 // - examples: 6 // - other: // - rule: everythng else // - examples: 0.5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, … // // Languages: // - cy: Welsh func pluralRule6B(n NumberValue) PluralRule { isInt := isInt(n) i := int64(math.Abs(toFloat64(n))) switch { case isInt && i == 0: return PluralRuleZero case isInt && i == 1: return PluralRuleOne case isInt && i == 2: return PluralRuleTwo case isInt && i == 3: return PluralRuleFew case isInt && i == 6: return PluralRuleMany } return PluralRuleOther }