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
m minor fixes
revert my previous edit but keep the code formatting
 
(24 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 ''
-- Preprocessing prec
    local lang    = args[2] or args.lang or ''
if tonumber(args.prec) ~= nil and tonumber(args.prec) > 0 and tonumber(args[1]) ~= nil then
    -- validate the language parameter within MediaWiki's caller frame
if string.find(tostring(args[1]), "%.") ~= nil then
    if lang == "arabic-indic" then -- only for back-compatibility ("arabic-indic" is not a SupportedLanguage)
if (string.len(args[1]) - string.find(tostring(args[1]), "%.")) < tonumber(args.prec) then
        lang = "fa" -- better support than "ks"
precnumber = "" .. args[1] .. string.rep("0", tonumber(args.prec) - (string.len(args[1]) - string.find(tostring(args[1]), "%.")))
    elseif lang == '' or not mw.language.isSupportedLanguage(lang) then
elseif (string.len(args[1]) - string.find(tostring(args[1]), "%.")) > tonumber(args.prec) then
        -- Note that 'SupportedLanguages' are not necessarily 'BuiltinValidCodes', and so they are not necessarily
local proc = string.gsub(args[1], "0+$", "")
        -- 'KnownLanguages' (with a language name defined at least in the default localisation of the local wiki).
if (string.len(proc) - string.find(tostring(proc), "%.")) < tonumber(args.prec) then
        -- But they all are ValidLanguageCodes (suitable as Wiki subpages or identifiers: no slash, colon, HTML tags, or entities)
precnumber = proc .. string.rep("0", tonumber(args.prec) - (string.len(proc) - string.find(tostring(proc), "%.")))
        -- In addition, they do not contain any capital letter in order to be unique in page titles (restriction inexistant in BCP47),
else
        -- but they may violate the standard format of BCP47 language tags for specific needs in MediaWiki.
precnumber = proc
        -- Empty/unspecified and unsupported languages are treated here in Commons using the user's language,
end
        -- instead of the local 'ContentLanguage' of the Wiki.
elseif (string.len(args[1]) - string.find(tostring(args[1]), "%.")) == tonumber(args.prec) then
        lang = frame:callParserFunction( "int", "lang" ) -- get user's chosen language
precnumber = args[1]
    end
end
    return p.formatNum(number, lang, prec, sep ~= '')
else
end
precnumber = "" .. args[1] .. "." .. string.rep("0", args.prec)
 
end
local digit = { -- substitution of decimal digits for languages not supported by mw.language:formatNum() in core Lua libraries for MediaWiki
number = precnumber .. "1"
    ["ml-old"] = { '൦', '൧', '൨', '൩', '൪', '൫', '൬', '൭', '൮', '൯' },
precA = "true"
    ["mn"]     = { '᠐', '᠑', '᠒', '᠓', '᠔', '᠕', '᠖', '᠗', '᠘', '᠙' },
else
    ["ta"]     = { '௦', '௧', '௨', '௩', '௪', '௫', '௬', '௭', '௮', '௯' },
number = args[1]
    ["te"]     = { '౦', '౧', '౨', '౩', '౪', '౫', '౬', '౭', '౮', '౯' },
end
    ["th"]     = { '๐', '๑', '๒', '๓', '๔', '๕', '๖', '๗', '๘', '๙' }
local digitml = {
["0"] = '൦',
["1"] = '൧',
["2"] = '൨',
["3"] = '൩',
["4"] = '൪',
["5"] = '൫',
["6"] = '൬',
["7"] = '൭',
["8"] = '൮',
["9"] = '൯'
}
local digitmn = {
["0"] = '᠐',
["1"] = '᠑',
["2"] = '᠒',
["3"] = '᠓',
["4"] = '᠔',
["5"] = '᠕',
["6"] = '᠖',
["7"] = '᠗',
["8"] = '᠘',
["9"] = ''
}
local digitte = {
["0"] = '౦',
["1"] = '౧',
["2"] = '౨',
["3"] = '౩',
["4"] = '౪',
["5"] = '౫',
["6"] = '౬',
["7"] = '౭',
["8"] = '౮',
["9"] = '౯'
}
local digitth = {
["0"] = '๐',
["1"] = '๑',
["2"] = '๒',
["3"] = '๓',
["4"] = '๔',
["5"] = '๕',
["6"] = '๖',
["7"] = '๗',
["8"] = '๘',
["9"] = '๙'
}
}


if args[2] == "arabic-indic" then
function p.formatNum(number, lang, prec, compact)
language = "ks"
 
elseif args[2] == "ml-old" then
    -- Do not alter the specified value when it is not a valid number, return it as is
language = "ml"
    local value = tonumber(number)
else
    if value == nil then
language = args[2]
        return number
end
    end
    -- Basic ASCII-only formatting (without paddings)
-- Formatnum
    number = tostring(value)
if tonumber(number) ~= nil and mw.language.isKnownLanguageTag(language or "") == true then
 
formatnum = mw.getLanguage( language ):formatNum( tonumber(number) )
    -- Check the presence of an exponent (incorrectly managed in mw.language:FormatNum() and even forgotten due to an internal bug, e.g. in Hindi)
elseif tonumber(number) ~= nil then
    local exponent
formatnum = mw.getLanguage(frame:preprocess( "{{int:lang}}" )):formatNum(tonumber(number))
    local pos = string.find(number, '[Ee]')
else
    if pos ~= nil then
formatnum = number
        exponent = string.sub(number, pos + 1, string.len(number))
end
        number = string.sub(number, 1, pos - 1)
    else
-- Formatnum, special cases
        exponent = ''
local numsc = formatnum
    end
if args[2] == "ml-old" then
 
for en, ml in pairs(digitml) do
    -- Check the minimum precision requested
numsc = mw.ustring.gsub(numsc, en, ml)
    prec = tonumber(prec) -- nil if not specified as a true number
end
    if prec ~= nil then
elseif args[2] == "mn" then
        prec = math.floor(prec)
for en, mn in pairs(digitmn) do
        if prec < 0 then
numsc = mw.ustring.gsub(numsc, en, mn)
            prec = nil -- discard an incorrect precision (not a positive integer)
end
        elseif prec > 14 then
elseif args[2] == "te" then
            prec = 14 -- maximum precision supported by tostring(number)
for en, te in pairs(digitte) do
        end
numsc = mw.ustring.gsub(numsc, en, te)
    end
end
 
elseif args[2] == "th" then
    -- Preprocess the minimum precision in the ASCII string
for en, th in pairs(digitth) do
    local dot
numsc = mw.ustring.gsub(numsc, en, th)
    if (prec or 0) > 0 then
end
        pos = string.find(number, '.', 1, true) -- plain search, no regexp
end
        if pos ~= nil then
            prec = pos + prec - string.len(number) -- effective number of trailing decimals to add or remove
--Postprocessing prec
            dot = '' -- already present
if precA == "true" then
        else
postprec = mw.ustring.sub(numsc, 1, (mw.ustring.len(numsc) - 1))
            dot = mw.ustring.sub (mw.language.new(lang):formatNum(0.1), 2, 2) -- must be added
else
        end
postprec = numsc
    else
end
        dot = '' -- don't add dot
        prec = 0 -- don't alter the precision
-- Seperator
    end
if args.sep ~= nil and args.sep ~= "" then
 
local replace = mw.ustring.gsub( "", "%%", "%%%%" )
    if lang ~= nil and mw.language.isKnownLanguageTag(lang) == true then
if mw.language.isKnownLanguageTag(language or "") == true then
        -- Convert number to localized digits, decimal separator, and group separators
local seperator = mw.ustring.sub(mw.getLanguage(language):formatNum(tonumber("1000")), 2, 2)
        local language = mw.getLanguage(lang)
if tostring(mw.ustring.find(seperator, "%s")) == "1" then
        if compact then
pattern = mw.ustring.format(" ", "%s")
            number = language:formatNum(tonumber(number), { noCommafy = 'y' }) -- caveat: can load localized resources for up to 20 languages
elseif tostring(mw.ustring.find(seperator, "%p")) == "1" then
        else
pattern = mw.ustring.gsub(seperator, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1")
            number = language:formatNum(tonumber(number)) -- caveat: can load localized resources for up to 20 languages
else
        end
pattern = ""
        -- Postprocessing the precision
end
        if prec > 0 then
return tostring(mw.ustring.gsub( postprec, pattern, replace ))
            local zero = language:formatNum(0)
else
            number = number .. dot .. mw.ustring.rep(zero, prec)
local seperator = mw.ustring.sub(mw.getLanguage(frame:preprocess("{{int:lang}}")):formatNum(tonumber("1000")), 2, 2)
        elseif prec < 0 then
if tostring(mw.ustring.find(seperator, "%s")) == "1" then
            -- TODO: rounding of last decimal; here only truncate decimals in excess
pattern = mw.ustring.format(" ", "%s")
            number = mw.ustring.sub(number, 1, mw.ustring.len(number) + prec)
elseif tostring(mw.ustring.find(seperator, "%p")) == "1" then
        end
pattern = mw.ustring.gsub(seperator, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1")
 
else
        -- Append the localized base-10 exponent without grouping separators (there's no reliable way to detect a localized leading symbol 'E')
pattern = ""
        if exponent ~= '' then
end
            number = number .. 'E' .. language:formatNum(tonumber(exponent),{noCommafy=true})
return tostring(mw.ustring.gsub( postprec, pattern, replace ))
        end
end
    else -- not localized, ASCII only
else
        -- Postprocessing the precision
return postprec
        if prec > 0 then
end
            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.