Modul:NumberToWords


Túto dokumentáciu [vytvoriť] [obnoviť]
Dokumentácia Dokumentácia

Dokumentácia pre tento modul zatiaľ neexistuje. Môžete ju vytvoriť na Modul:NumberToWords/Dokumentácia


Ak máte otázku k tomuto modulu, alebo potrebujete jeho rozšírenie a neviete ho správne naformátovať, pýtajte sa v diskusii k modulu. Pokiaľ je potrebné modul urgentne opraviť, obráťte sa na technickú podporu.

-- Lua implementation of https://github.com/lubosdz/number-to-words/blob/master/src/NumberToWords_SK.php

local p = {}

function p._convert(number, units, level)
    -- mw.log('_convert(number: ' .. number .. ', ' .. 'units: ' .. tostring(units) .. ', ' .. 'level: ' .. tostring(level) .. ')')

    level = level or -1
    level = level + 1

    local hyphen      = ''   -- in english "-", v slovencine ziadny
    local conjunction = ' '  -- in english ' and ' v slovencine nepouzivame
    local separator   = ' '
    local negative    = 'mínus '
    local decimal     = ' celé '
    local prefixOneX  = false  -- false: "tisíc", "milión"; true: "jeden tisíc", "jeden milión"
    local dictionary = {
        [0]                   = 'nula',
        [1]                   = 'jeden', -- jeden milion, jedna miliarda
        [2]                   = 'dva',   -- dvojtvar dve, dve - napr. [22000] - dvadsatDVA tisic, [200] = DVE sto
        [3]                   = 'tri',
        [4]                   = 'štyri',
        [5]                   = 'päť',
        [6]                   = 'šesť',
        [7]                   = 'sedem',
        [8]                   = 'osem',
        [9]                   = 'deväť',
        [10]                  = 'desať',
        [11]                  = 'jedenásť',
        [12]                  = 'dvanásť',
        [13]                  = 'trinásť',
        [14]                  = 'štrnásť',
        [15]                  = 'pätnásť',
        [16]                  = 'šestnásť',
        [17]                  = 'sedemnásť',
        [18]                  = 'osemnásť',
        [19]                  = 'devätnásť',
        [20]                  = 'dvadsať',
        [30]                  = 'tridsať',
        [40]                  = 'štyridsať',
        [50]                  = 'päťdesiat',
        [60]                  = 'šesťdesiat',
        [70]                  = 'sedemdesiat',
        [80]                  = 'osemdesiat',
        [90]                  = 'deväťdesiat',
        [100]                 = 'sto',
        [1000]                = 'tisíc',
        [1000000]             = 'milión',                    -- e[6]
        [1000000000]          = 'miliarda|miliardy|miliárd', -- e[9]
        [1000000000000]       = 'bilión',                    -- e[12]
        [1000000000000000]    = 'biliarda|biliardy|biliárd', -- e[15]
        [1000000000000000000] = 'trilión',                   -- e[18]
        -- https:--sk.wikipedia.org/wiki/Veľké_čísla
    }
    
    -- fix common typo [,] instead of dot
    number = mw.ustring.gsub(number, ",", ".")
    number = tonumber(number)

    -- if (!is_numeric(number)) {
    --   return false;
    -- }

    -- if ((number >= 0 && (int) number < 0) || (int) number < 0 - PHP_INT_MAX) {
    --  -- overflow
    --  throw new \Exception('Invalid number range - value must be between ' . PHP_INT_MAX . ' and ' . PHP_INT_MAX.'.');
    -- }

    local string = nil

    if (number < 0) then
        string = negative .. p._convert(- number)
    else
        local fraction = nil

        if (mw.ustring.find(number, "%.")) then
            number, fraction = mw.ustring.match(number, "^(%d+)%.(%d+)$")
            number = tonumber(number)
            fraction = tonumber(fraction)
        end

        if (number < 21) then
            local dict = dictionary[number]
            if (units) then
                if (number == 1) then
                    -- ludia chcu "jednosto"
                    dict = ''  -- nie jedentisic, jedensto
                    if (prefixOneX) then
                        if (level <= 1) then  -- first loop = 0, pridame "jedno"sto na zaciatku slova
                            if (units == 100) then
                                dict = 'jedno' -- jednosto
                            elseif (units == 1e3 or units == 1e6) then
                                dict = 'jeden' -- jedentisic
                            elseif (units == 1e9 or units == 1e15) then
                                dict = 'jedna' -- jedna miliarda
                            end
                        end
                    end
                elseif (number == 2 and (units == 1e3 or units == 1e9 or units == 1e15)) then
                    dict = 'dve'  -- dvetisic, nie dvatisic, dve miliardy nie dva miliardy
                end
            end
            string = dict
        elseif (number < 100) then
            local tens   = math.floor(number / 10) * 10
            local units  = number % 10
            string = dictionary[tens]
            if (units > 0) then
                string = string .. hyphen .. dictionary[units]
            end
        elseif (number < 1000) then
            local hundreds  = math.floor(number / 100)
            local remainder = number % 100
            if (hundreds == 1) then
                -- ludia chcu "jednosto"
                dict = ''  -- nie styritisic jedenstoosemdesiat, jedenstopatnast
                if (not level) then  -- jednosto na zaciatku slova
                    dict = dictionary[hundreds]  -- nie styritisic jedenstoosemdesiat, jedenstopatnast
                    if (number < 200) then
                        dict = 'jedno'  -- jednostodvanast, nie jedensto
                    end
                end
            elseif (hundreds == 2) then
                dict = 'dve'  -- dvesto, nie dvasto
            else
                dict = dictionary[hundreds]
            end
            string = dict .. dictionary[100]
            if (remainder > 0) then
                -- string = string .. separator .. p._convert(remainder, nil, level)
                string = string ..  p._convert(remainder, nil, level)
            end
        else
            local baseUnit = math.pow(1000, math.floor(math.log(number) / math.log(1000)))
            local numBaseUnits = math.floor(number / baseUnit)
            local remainder = number - (baseUnit * numBaseUnits)
            -- SK declination
            local append = dictionary[baseUnit]
            local bigNumSep = nil
            -- mw.log('baseUnit: ' .. tostring(baseUnit))
            -- mw.log('numBaseUnits: ' .. tostring(numBaseUnits))
            -- mw.log('remainder: ' .. tostring(remainder))

            -- if (baseUnit > 1000) then
            if (baseUnit >= 1e6) then
                bigNumSep = ' '
                -- nesklonujeme tisicky, len milion a vyssie
                if (baseUnit == 1e9 or baseUnit == 1e15) then
                    append = mw.text.split(append, '|', true)  -- explode('|', append)
                    if (numBaseUnits >= 2 and numBaseUnits <= 4) then
                        append = append[2] -- 2, 3, 4 miliardy, biliardy
                    elseif (numBaseUnits >= 5) then
                        append = append[3] -- 5,6 ... 99 miliárd, biliárd
                    else
                        append = append[1] -- 1 miliarda, 1 biliarda
                    end
                else
                    if (numBaseUnits >= 2 and numBaseUnits <= 4) then
                        append = append .. 'y'  -- 2, 3, 4 miliony, biliony, triliony, ..
                    elseif (numBaseUnits >= 5) then
                        append = append .. 'ov'  -- 5,6 ... 99 milionov
                    end
                end
            else
                bigNumSep = ''
            end
            -- mw.log('bigNumSep: "' .. tostring(bigNumSep) .. '"')
            -- mw.log('append: "' .. tostring(append) .. '"')
            string = p._convert(numBaseUnits, baseUnit, level)
            if (string ~= '') then
                string = string .. bigNumSep
            end
            string = string .. append
            if (remainder > 0) then
                if (baseUnit >= 1e6) then  -- pri variante spolu podľa PSP len zložky od milióna vyššie s oddeľovačom
                    if (remainder < 100) then
                        string = string .. conjunction
                    else
                        string = string .. separator
                    end
                end
                string = string .. p._convert(remainder, nil, level)
            end    
        end

        if (fraction ~= nil) then
            string = string .. decimal;
            if (fraction < 1000) then
                -- up to 3 decimals - full convert
                string = string .. p._convert(fraction)
            else
                -- 3+ decimals - spell out single digits
                local fractionStr = ''
                for ch in mw.ustring.gmatch(tostring(fraction), '.') do
                    if (fractionStr ~= '') then
                        fractionStr = fractionStr .. ' '
                    end
                    fractionStr = fractionStr .. dictionary[string.byte(ch) - string.byte('0')]
                end
                string = string .. fractionStr
            end
        end

    end

    -- mw.log('_convert(number: ' .. number .. ', ' .. 'units: ' .. tostring(units) .. ', ' .. 'level: ' .. tostring(level) .. ') = ' .. '"' .. string .. '"')

    return string
end

function p._convertTests(frame)

    p._convert(1001234, nil, nil)

    if (true) then 
        return
    end

    p._convert(-1, nil, nil)
    p._convert(0, nil, nil)
    p._convert(0.1, nil, nil)
    p._convert(0.99, nil, nil)
    p._convert(0.999, nil, nil)
    p._convert(0.9999, nil, nil)
    p._convert(1, nil, nil)
    p._convert(13, nil, nil)
    p._convert(21, nil, nil)
    p._convert(33, nil, nil)
    p._convert(90, nil, nil)
    p._convert(99, nil, nil)
    p._convert(100, nil, nil)
    p._convert(101, nil, nil)
    p._convert(121, nil, nil)
    p._convert(133, nil, nil)
    p._convert(199, nil, nil)
    p._convert(200, nil, nil)
    p._convert(999, nil, nil)
    p._convert(1000, nil, nil)
    p._convert(1234, nil, nil)
    p._convert(9876, nil, nil)
    p._convert(12345, nil, nil)
    p._convert(98765, nil, nil)
    p._convert(123456, nil, nil)
    p._convert(987654, nil, nil)
    p._convert(1234567, nil, nil)
    p._convert(9876543, nil, nil)
    p._convert(12345678, nil, nil)
    p._convert(98765432, nil, nil)
    p._convert(123456789, nil, nil)
    p._convert(987654321, nil, nil)
    p._convert(1234567890, nil, nil)
    p._convert(9876543210, nil, nil)
end

function p.test(frame)
    return p._convertTests(frame)
end

function p.convert(frame)
    return p._convert(frame.args[1], nil, nil)
end

return p