|
|
Line 1: |
Line 1: |
| -- Credit to https://dev.fandom.com/wiki/Module:Plural
| | local p = {} |
|
| |
|
| ------------------------------------------------------------------
| | function p.ru_pluralize(count, one, few, many) |
| -- Lua script, that replaces {{plural:}} magic word
| | local mod10 = count % 10 |
| -- Some languages have specific plural logic, but the {{plural:}} can't provide it on English wikis (such as Dev Wiki)
| | local mod100 = count % 100 |
| --
| |
| -- Feel free to add more languages
| |
| -- The logic was based on localization guide
| |
| ---- Source: https://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html
| |
| ------------------------------------------------------------------
| |
| local plural = {} | |
|
| |
|
| local i18n = require('Dev:i18n').loadMessages('Plural')
| | if mod10 == 1 and mod100 ~= 11 then |
| ------------------------------------------------------------------ | | return one -- singular |
| -- Logic realization
| | elseif mod10 >= 2 and mod10 <= 4 and (mod100 < 10 or mod100 >= 20) then |
| ------------------------------------------------------------------
| | return few -- few |
| -- Plural logic with 2 forms
| | else |
| -- If the amount is not 1 then second form, else the first one
| | return many -- many |
| -- @param {number} n — the amout of items | | end |
| -- @param {stirng} f — first form
| |
| -- @param {stirng} s — second form
| |
| -- @return {sting} $f or $s | |
| local function plural_not_one(n, f, s)
| |
| return n ~= 1 and s or f
| |
| end | | end |
|
| |
|
| | | function p.Plural(frame) |
| -- Plural logic with 2 forms
| | local args = frame.args |
| -- If the amount is more than 1 then second form, else the first one
| | local lang = args["lang"] or "ru" |
| -- @param {number} n — the amout of items
| | local count = tonumber(args[1]) or 0 |
| -- @param {stirng} f — first form
| | |
| -- @param {stirng} s — second form
| | if lang == "ru" then |
| -- @return {sting} $f or $s
| | return p.ru_pluralize(count, args[2], args[3], args[4]) |
| local function plural_more_than_one(n, f, s)
| | else |
| return n > 1 and s or f
| | return "[Only these lang values are supported: ru]" |
| end
| | end |
| | |
| -- Plural logic for Russian, Serbian, and Ukrainian
| |
| -- These languages have 3 plural forms
| |
| -- First form — if the amount ends with 1, but is not 11
| |
| -- Second form — if the amount ends with 2, 3, or 4, but is not 12, 13, or 14.
| |
| -- Third form — anything else
| |
| -- @param {number} n — the amout of items
| |
| -- @param {stirng} f — first form
| |
| -- @param {stirng} s — second form
| |
| -- @param {stirng} t — third form
| |
| -- @return {sting} $f, $s, or $t
| |
| local function plural_rus_and_serb(n, f, s, t)
| |
| if n % 10 == 1 and n % 100 ~= 11 then
| |
| return f
| |
| elseif (n % 10 >= 2 and n % 10 <= 4) and (n % 100 < 10 or n % 100 >= 20) then
| |
| return s
| |
| else
| |
| return t
| |
| end
| |
| end
| |
| | |
| -- Plural logic for Polish
| |
| -- This language has 3 plural forms
| |
| -- First form — if the amount is 1
| |
| -- Second form — if the amount ends with 2, 3, or 4, but is not 12, 13, or 14.
| |
| -- Third form — anything else
| |
| -- @param {number} n — the amout of items
| |
| -- @param {stirng} f — first form
| |
| -- @param {stirng} s — second form
| |
| -- @param {stirng} t — third form
| |
| -- @return {sting} $f, $s, or $t
| |
| local function plural_polish(n, f, s, t)
| |
| if n == 1 then
| |
| return f
| |
| elseif (n % 10 >= 2 and n % 10 <= 4) and (n % 100 < 10 or n % 100 >= 20) then
| |
| return s
| |
| else
| |
| return t
| |
| end
| |
| end
| |
| | |
| -- Plural logic for Romanian
| |
| -- This language has 3 plural forms
| |
| -- First form — if the amount is 1
| |
| -- Second form — if the amount is between 2 and 20 or equals 0
| |
| -- Third form — anything else
| |
| -- @param {number} n — the amout of items
| |
| -- @param {stirng} f — first form
| |
| -- @param {stirng} s — second form
| |
| -- @param {stirng} t — third form
| |
| -- @return {sting} $f, $s, or $t
| |
| local function plural_romanian(n, f, s, t) | |
| if n == 1 then
| |
| return f
| |
| elseif n == 0 or (n % 100 > 0 and n % 100 < 20) then
| |
| return s
| |
| else
| |
| return t
| |
| end
| |
| end
| |
| | |
| -- Plural logic for Slovenian
| |
| -- This language has 3 plural forms
| |
| -- First form — if the amount is 1
| |
| -- Second form — if the amount is between 2 and 20 or equals 0
| |
| -- Third form — anything else
| |
| -- @param {number} n — the amout of items
| |
| -- @param {stirng} f — first form
| |
| -- @param {stirng} s — second form
| |
| -- @param {stirng} t — third form
| |
| -- @param {stirng} fo — fourth form
| |
| -- @return {sting} $f, $s, or $t
| |
| local function plural_slovenian(n, f, s, t, fo)
| |
| if n % 100 == 1 then
| |
| return f
| |
| elseif n % 100 == 2 then
| |
| return s
| |
| elseif n % 100 == 3 or n % 100 == 4 then
| |
| return t
| |
| else
| |
| return fo
| |
| end
| |
| end
| |
| | |
| -- Plural logic for Arabic
| |
| -- This language has 6 plural forms
| |
| -- First form — if the amount is 0
| |
| -- Second form — if the amount is 1
| |
| -- Third form — if the amount is 2
| |
| -- Fourth form — if the amount ends with 3, 4 ... 9, or 10
| |
| -- Fifth form — if the amount ends with 11, 12 ... 98, or 99
| |
| -- Sixth form — anything else
| |
| -- @param {number} n — the amout of items
| |
| -- @param {stirng} first — first form
| |
| -- @param {stirng} second — second form
| |
| -- @param {stirng} third — third form
| |
| -- @param {stirng} fourth — fourth form
| |
| -- @param {stirng} fifth — fifth form
| |
| -- @param {stirng} sixth — sixth form
| |
| -- @return {sting} $first, $second, $third, $fourth, $fifth, or $sixth
| |
| local function plural_arabic(n, first, second, third, fourth, fifth, sixth) | |
| if n == 0 then
| |
| return first
| |
| elseif n == 1 then
| |
| return second
| |
| elseif n == 2 then
| |
| return third
| |
| elseif n % 100 >= 3 and n % 100 <= 10 then
| |
| return fourth
| |
| elseif n % 100 >= 11 then
| |
| return fifth
| |
| else
| |
| return sixth
| |
| end
| |
| end
| |
| | |
| | |
| ------------------------------------------------------------------
| |
| -- Tables
| |
| ------------------------------------------------------------------
| |
| -- Table with language codes and functions, associated with them
| |
| local langcodes = {
| |
| ["af"] = plural_not_one,
| |
| ["az"] = plural_not_one,
| |
| ["be"] = plural_rus_and_serb,
| |
| ["ar"] = plural_arabic,
| |
| ["de"] = plural_not_one,
| |
| ["en"] = plural_not_one,
| |
| ["es"] = plural_not_one,
| |
| ["et"] = plural_not_one,
| |
| ["fa"] = plural_more_than_one,
| |
| ["fi"] = plural_not_one,
| |
| ["fr"] = plural_more_than_one,
| |
| ["hi"] = plural_not_one,
| |
| ["it"] = plural_not_one,
| |
| ["kk"] = plural_not_one,
| |
| ["ku"] = plural_not_one,
| |
| ["nl"] = plural_not_one,
| |
| ["pl"] = plural_polish,
| |
| ["pt"] = plural_not_one,
| |
| ["pt-br"] = plural_more_than_one,
| |
| ["ro"] = plural_romanian,
| |
| ["ru"] = plural_rus_and_serb,
| |
| ["sl"] = plural_slovenian,
| |
| ["sr"] = plural_rus_and_serb,
| |
| ["tg"] = plural_more_than_one,
| |
| ["tr"] = plural_more_than_one,
| |
| ["uk"] = plural_rus_and_serb,
| |
| ["zh"] = plural_more_than_one, -- Mandarin Chinese doesn't have plural forms in general, however the personal pronounses have plural forms
| |
| ["zh-hans"] = plural_more_than_one, -- Mandarin Chinese doesn't have plural forms in general, however the personal pronounses have plural forms
| |
| ["zh-hant"] = plural_more_than_one, -- Mandarin Chinese doesn't have plural forms in general, however the personal pronounses have plural forms
| |
| }
| |
| | |
| -- Table with language codes that have 3 plural forms
| |
| -- Table lookup is slightly faster and looks compact than comparing all values
| |
| -- {{if three_forms[lang_code] then}} is better than {{if lang_code = "ru" or lang_code = "ro" or lang_code = "pl" then}}
| |
| local three_forms = {
| |
| ["pl"] = true,
| |
| ["ro"] = true,
| |
| ["ru"] = true,
| |
| ["sr"] = true,
| |
| ["uk"] = true,
| |
| }
| |
| | |
| local abs = math.abs | |
| ------------------------------------------------------------------
| |
| -- Invocation of logic's functions
| |
| ------------------------------------------------------------------
| |
| -- The main function that calls functions from "langcodes" table
| |
| -- @param {table} args — table with all args
| |
| -- @param {string} args.lang — language code (optional, content language by default)
| |
| -- @param {number} args[1] — the amount of items
| |
| -- @param {string} args[2] — first form
| |
| -- @param {string} args[3] — second form
| |
| -- @param {string} args[4] — third form (optional, depends on $lang parameter)
| |
| -- @param {string} args[5] — fourth form (optional, depends on $lang parameter)
| |
| -- @param {string} args[6] — fifth form (optional, depends on $lang parameter)
| |
| -- @param {string} args[7] — sixth form (optional, depends on $lang parameter)
| |
| -- @return {string} the plural form
| |
| function plural.getPlural(args)
| |
| local lang_code = args["lang"] or mw.getContentLanguage().code
| |
|
| |
| local number = abs(tonumber(args[1]))
| |
| local first = args[2] or ""
| |
| local second = args[3] or ""
| |
|
| |
| if three_forms[lang_code] then
| |
| local third = args[4] or ""
| |
| return langcodes[lang_code](number, first, second, third)
| |
| elseif lang_code == "sl" then
| |
| local third = args[4] or ""
| |
| local fourth = args[5] or ""
| |
| return langcodes[lang_code](number, first, second, third, fourth)
| |
| elseif lang_code == "ar" then
| |
| local third = args[4] or ""
| |
| local fourth = args[5] or ""
| |
| local fifth = args[6] or ""
| |
| local sixth = args[7] or ""
| |
|
| |
| return plural_arabic(number, first, second, third, fouth, fifth, sixth)
| |
| elseif langcodes[lang_code] then
| |
| return langcodes[lang_code](number, first, second)
| |
| end
| |
|
| |
| error(i18n:msg('error', lang_code))
| |
| end
| |
| | |
| | |
| -- The function to call plural.getPlural() from {{#invoke}}
| |
| -- @param {table} frame — the frame object
| |
| -- @return {string} the plural form
| |
| function plural.main(frame)
| |
| local args = frame:getParent().args
| |
| return plural.getPlural(args)
| |
| end | | end |
|
| |
|
| return plural | | return p |