Jump to content
Toggle menu
  • 8 articles
  • 75 files
  • 7 users
  • 37.8K edits
Neodyland Wiki
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:Formatnum: Difference between revisions

From Neodyland Wiki
Created page with '-- This module is intended to replace the functionality of Template:Formatnum and related templates. -- This module is in beta. Use with caution. local p = {}...'
 
revert my previous edit but keep the code formatting
 
(26 intermediate revisions by 6 users not shown)
Line 1: Line 1:
-- This module is intended to replace the functionality of Template:Formatnum and related templates.
-- This module is intended to replace the functionality of Template:Formatnum and related templates.
-- This module is in beta. Use with caution.
local p = {}
local p = {}


function p.main(frame)
function p.main(frame)
local pframe = frame:getParent()
    local args = frame:getParent().args
local config = frame.args
    local prec    = args.prec or ''
local args = pframe.args
    local sep    = args.sep or ''
    local number  = args[1] or args.number or ''
if tonumber(args.prec) ~= nil and tonumber(args.prec) > 0 and tonumber(args[1]) ~= nil then
    local lang    = args[2] or args.lang or ''
if string.find(tostring(args[1]), "%.") ~= nil then
    -- validate the language parameter within MediaWiki's caller frame
precnumber = string.sub(args[1], 1, (string.find(tostring(args[1]), "%.") + args.prec))
    if lang == "arabic-indic" then -- only for back-compatibility ("arabic-indic" is not a SupportedLanguage)
else
        lang = "fa" -- better support than "ks"
precnumber = "" .. args[1] .. "." .. string.rep("0", args.prec)
    elseif lang == '' or not mw.language.isSupportedLanguage(lang) then
end
        -- Note that 'SupportedLanguages' are not necessarily 'BuiltinValidCodes', and so they are not necessarily
number = "" .. precnumber .. "1"
        -- 'KnownLanguages' (with a language name defined at least in the default localisation of the local wiki).
precA = "true"
        -- But they all are ValidLanguageCodes (suitable as Wiki subpages or identifiers: no slash, colon, HTML tags, or entities)
else
        -- In addition, they do not contain any capital letter in order to be unique in page titles (restriction inexistant in BCP47),
number = args[1]
        -- but they may violate the standard format of BCP47 language tags for specific needs in MediaWiki.
end
        -- Empty/unspecified and unsupported languages are treated here in Commons using the user's language,
        -- instead of the local 'ContentLanguage' of the Wiki.
if tonumber(number) ~= nil and mw.language.isSupportedLanguage(args[2] or "") == true then
        lang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language
formatnum = mw.getLanguage( args[2] ):formatNum( tonumber(number) )
    end
elseif tonumber(number) ~= nil then
    return p.formatNum(number, lang, prec, sep ~= '')
formatnum = mw.getLanguage(frame:preprocess( "{{int:lang}}" )):formatNum(tonumber(number))
end
else
 
formatnum = ""
local digit = { -- substitution of decimal digits for languages not supported by mw.language:formatNum() in core Lua libraries for MediaWiki
end
    ["ml-old"] = { '൦', '൧', '൨', '൩', '൪', '൫', '൬', '൭', '൮', '൯' },
    ["mn"]    = { '᠐', '᠑', '᠒', '᠓', '᠔', '᠕', '᠖', '᠗', '᠘', '᠙' },
if precA == "true" then
    ["ta"]    = { '௦', '௧', '௨', '௩', '௪', '௫', '௬', '௭', '௮', '௯' },
postprec = string.sub(formatnum, 1, (string.len(formatnum) - 1))
    ["te"]    = { '౦', '౧', '౨', '౩', '౪', '౫', '౬', '౭', '౮', '౯' },
else
    ["th"]     = { '๐', '๑', '๒', '๓', '๔', '๕', '๖', '๗', '๘', '๙' }
postprec = formatnum
}
end
 
function p.formatNum(number, lang, prec, compact)
-- Eqvaluent functions to Template:FormatnumSigns
 
-- Table over what thousands seperator is used.
    -- Do not alter the specified value when it is not a valid number, return it as is
thousand = {
    local value = tonumber(number)
ckb="٫",
    if value == nil then
fa="٫",
        return number
glk="٫",
    end
ks="٫",
    -- Basic ASCII-only formatting (without paddings)
mzn="٫",
    number = tostring(value)
ur=",",
 
ca=".",
    -- Check the presence of an exponent (incorrectly managed in mw.language:FormatNum() and even forgotten due to an internal bug, e.g. in Hindi)
da=",",
    local exponent
de=",",
    local pos = string.find(number, '[Ee]')
gl=",",
    if pos ~= nil then
mk=",",
        exponent = string.sub(number, pos + 1, string.len(number))
nds=",",
        number = string.sub(number, 1, pos - 1)
nl=",",
    else
sl=",",
        exponent = ''
cs=",",
    end
fr=",",
 
hu=",",
    -- Check the minimum precision requested
ro=",",
    prec = tonumber(prec) -- nil if not specified as a true number
pl=",",
    if prec ~= nil then
nb=",",
        prec = math.floor(prec)
nn=",",
        if prec < 0 then
no=",",
            prec = nil -- discard an incorrect precision (not a positive integer)
sv=",",
        elseif prec > 14 then
bn=".",
            prec = 14 -- maximum precision supported by tostring(number)
ml=".",
        end
hi=".",
    end
sa=".",
 
ta=".",
    -- Preprocess the minimum precision in the ASCII string
kn=".",
    local dot
te=".",
    if (prec or 0) > 0 then
mr=".",
        pos = string.find(number, '.', 1, true) -- plain search, no regexp
["or"]=".",
        if pos ~= nil then
pa=".",
            prec = pos + prec - string.len(number) -- effective number of trailing decimals to add or remove
gu=".",
            dot = '' -- already present
bho=".",
        else
as="."
            dot = mw.ustring.sub (mw.language.new(lang):formatNum(0.1), 2, 2) -- must be added
}
        end
-- Table ends
    else
if args.sep ~= nil then
        dot = '' -- don't add dot
local replace = mw.ustring.gsub( "", "%%", "%%%%" )
        prec = 0 -- don't alter the precision
local pattern = mw.ustring.gsub( (thousand[args[2] or frame:preprocess( "{{int:lang}}" )] or "."), "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1" )
    end
return tostring(mw.ustring.gsub( postprec, pattern, replace ))
 
else
    if lang ~= nil and mw.language.isKnownLanguageTag(lang) == true then
return postprec
        -- Convert number to localized digits, decimal separator, and group separators
end
        local language = mw.getLanguage(lang)
        if compact then
            number = language:formatNum(tonumber(number), { noCommafy = 'y' }) -- caveat: can load localized resources for up to 20 languages
        else
            number = language:formatNum(tonumber(number)) -- caveat: can load localized resources for up to 20 languages
        end
        -- Postprocessing the precision
        if prec > 0 then
            local zero = language:formatNum(0)
            number = number .. dot .. mw.ustring.rep(zero, prec)
        elseif prec < 0 then
            -- TODO: rounding of last decimal; here only truncate decimals in excess
            number = mw.ustring.sub(number, 1, mw.ustring.len(number) + prec)
        end
 
        -- Append the localized base-10 exponent without grouping separators (there's no reliable way to detect a localized leading symbol 'E')
        if exponent ~= '' then
            number = number .. 'E' .. language:formatNum(tonumber(exponent),{noCommafy=true})
        end
    else -- not localized, ASCII only
        -- Postprocessing the precision
        if prec > 0 then
            number = number .. dot .. mw.string.rep('0', prec)
        elseif prec < 0 then
            -- TODO: rounding of last decimal; here only truncate decimals in excess
            number = mw.string.sub(number, 1, mw.string.len(number) + prec)
        end
 
        -- Append the base-10 exponent
        if exponent ~= '' then
            number = number .. 'E' .. exponent
        end
    end
 
    -- Special cases for substitution of ASCII digits (missing support in Lua core libraries for some languages)
    if digit[lang] then
        for i, v in ipairs(digit[lang]) do
            number = mw.ustring.gsub(number, tostring(i - 1), v)
        end
    end
 
    return number
end
end


return p
return p

Latest revision as of 10:30, 28 March 2024

Module documentation[ create · purge ]
This documentation is transcluded from Module:Formatnum/doc.
-- This module is intended to replace the functionality of Template:Formatnum and related templates.
local p = {}

function p.main(frame)
    local args = frame:getParent().args
    local prec    = args.prec or ''
    local sep     = args.sep or ''
    local number  = args[1] or args.number or ''
    local lang    = args[2] or args.lang or ''
    -- validate the language parameter within MediaWiki's caller frame
    if lang == "arabic-indic" then -- only for back-compatibility ("arabic-indic" is not a SupportedLanguage)
        lang = "fa" -- better support than "ks"
    elseif lang == '' or not mw.language.isSupportedLanguage(lang) then
        -- Note that 'SupportedLanguages' are not necessarily 'BuiltinValidCodes', and so they are not necessarily
        -- 'KnownLanguages' (with a language name defined at least in the default localisation of the local wiki).
        -- But they all are ValidLanguageCodes (suitable as Wiki subpages or identifiers: no slash, colon, HTML tags, or entities)
        -- In addition, they do not contain any capital letter in order to be unique in page titles (restriction inexistant in BCP47),
        -- but they may violate the standard format of BCP47 language tags for specific needs in MediaWiki.
        -- Empty/unspecified and unsupported languages are treated here in Commons using the user's language,
        -- instead of the local 'ContentLanguage' of the Wiki.
        lang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language
    end
    return p.formatNum(number, lang, prec, sep ~= '')
end

local digit = { -- substitution of decimal digits for languages not supported by mw.language:formatNum() in core Lua libraries for MediaWiki
    ["ml-old"] = { '൦', '൧', '൨', '൩', '൪', '൫', '൬', '൭', '൮', '൯' },
    ["mn"]     = { '᠐', '᠑', '᠒', '᠓', '᠔', '᠕', '᠖', '᠗', '᠘', '᠙' },
    ["ta"]     = { '௦', '௧', '௨', '௩', '௪', '௫', '௬', '௭', '௮', '௯' },
    ["te"]     = { '౦', '౧', '౨', '౩', '౪', '౫', '౬', '౭', '౮', '౯' },
    ["th"]     = { '๐', '๑', '๒', '๓', '๔', '๕', '๖', '๗', '๘', '๙' }
}

function p.formatNum(number, lang, prec, compact)

    -- Do not alter the specified value when it is not a valid number, return it as is
    local value = tonumber(number)
    if value == nil then
        return number
    end
    -- Basic ASCII-only formatting (without paddings)
    number = tostring(value)

    -- Check the presence of an exponent (incorrectly managed in mw.language:FormatNum() and even forgotten due to an internal bug, e.g. in Hindi)
    local exponent
    local pos = string.find(number, '[Ee]')
    if pos ~= nil then
        exponent = string.sub(number, pos + 1, string.len(number))
        number = string.sub(number, 1, pos - 1)
    else
        exponent = ''
    end

    -- Check the minimum precision requested
    prec = tonumber(prec) -- nil if not specified as a true number
    if prec ~= nil then
        prec = math.floor(prec)
        if prec < 0 then
            prec = nil -- discard an incorrect precision (not a positive integer)
        elseif prec > 14 then
            prec = 14 -- maximum precision supported by tostring(number)
        end
    end

    -- Preprocess the minimum precision in the ASCII string
    local dot
    if (prec or 0) > 0 then
        pos = string.find(number, '.', 1, true) -- plain search, no regexp
        if pos ~= nil then
            prec = pos + prec - string.len(number) -- effective number of trailing decimals to add or remove
            dot = '' -- already present
        else
            dot = mw.ustring.sub (mw.language.new(lang):formatNum(0.1), 2, 2) -- must be added
        end
    else
        dot = '' -- don't add dot
        prec = 0 -- don't alter the precision
    end

    if lang ~= nil and mw.language.isKnownLanguageTag(lang) == true then
        -- Convert number to localized digits, decimal separator, and group separators
        local language = mw.getLanguage(lang)
        if compact then
            number = language:formatNum(tonumber(number), { noCommafy = 'y' }) -- caveat: can load localized resources for up to 20 languages
        else
            number = language:formatNum(tonumber(number)) -- caveat: can load localized resources for up to 20 languages
        end
        -- Postprocessing the precision
        if prec > 0 then
            local zero = language:formatNum(0)
            number = number .. dot .. mw.ustring.rep(zero, prec)
        elseif prec < 0 then
            -- TODO: rounding of last decimal; here only truncate decimals in excess
            number = mw.ustring.sub(number, 1, mw.ustring.len(number) + prec)
        end

        -- Append the localized base-10 exponent without grouping separators (there's no reliable way to detect a localized leading symbol 'E')
        if exponent ~= '' then
            number = number .. 'E' .. language:formatNum(tonumber(exponent),{noCommafy=true})
        end
    else -- not localized, ASCII only
        -- Postprocessing the precision
        if prec > 0 then
            number = number .. dot .. mw.string.rep('0', prec)
        elseif prec < 0 then
            -- TODO: rounding of last decimal; here only truncate decimals in excess
            number = mw.string.sub(number, 1, mw.string.len(number) + prec)
        end

        -- Append the base-10 exponent
        if exponent ~= '' then
            number = number .. 'E' .. exponent
        end
    end

    -- Special cases for substitution of ASCII digits (missing support in Lua core libraries for some languages)
    if digit[lang] then
        for i, v in ipairs(digit[lang]) do
            number = mw.ustring.gsub(number, tostring(i - 1), v)
        end
    end

    return number
end

return p
Cookies help us deliver our services. By using our services, you agree to our use of cookies.