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
call to tolower() on lang argument was failing on any use of Formatnum that did not specify the lang argument
revert my previous edit but keep the code formatting
 
(17 intermediate revisions by 4 users not shown)
Line 2: Line 2:
local p = {}
local p = {}


local digit = { -- languages not supported by the Lua of wikimedia software
function p.main(frame)
["ml-old"] = { '൦', '൧', '൨', '൩', '൪', '൫', '൬', '൭', '൮', '൯' },
    local args = frame:getParent().args
["mn"]    = { '᠐', '᠑', '᠒', '᠓', '᠔', '᠕', '᠖', '᠗', '᠘', '᠙'},
    local prec    = args.prec or ''
["te"]    = { '౦', '౧', '౨', '౩', '౪', '౫', '౬', '౭', '౮', '౯'},
    local sep    = args.sep or ''
["th"]    = { '๐', '๑', '๒', '๓', '๔', '๕', '๖', '๗', '๘', '๙'}
    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.main(frame)
function p.formatNum(number, lang, prec, compact)
local pframe = frame:getParent()
 
local config = frame.args
    -- Do not alter the specified value when it is not a valid number, return it as is
local prec  = pframe.args.prec
    local value = tonumber(number)
local number = pframe.args[1]
    if value == nil then
local lang  = pframe.args[2]
        return number
local sep    = pframe.args.sep or ""
    end
if not lang or not mw.language.isSupportedLanguage(lang) then
    -- Basic ASCII-only formatting (without paddings)
lang = frame:preprocess( "{{int:lang}}" )
    number = tostring(value)
end
 
return p._main(number, lang, sep, prec, config)
    -- Check the presence of an exponent (incorrectly managed in mw.language:FormatNum() and even forgotten due to an internal bug, e.g. in Hindi)
end
    local exponent
    local pos = string.find(number, '[Ee]')
function p._main(number, lang, sep, prec, config)
    if pos ~= nil then
-- Preprocessing prec
        exponent = string.sub(number, pos + 1, string.len(number))
local precNum = tonumber(prec)
        number = string.sub(number, 1, pos - 1)
if precNum ~= nil and precNum > 0 and tonumber(number) ~= nil then
    else
if string.find(tostring(number), "%.") ~= nil then
        exponent = ''
if (string.len(number) - string.find(tostring(number), "%.")) < precNum then
    end
precnumber = "" .. number .. string.rep("0", precNum - (string.len(number) - string.find(tostring(number), "%.")))
 
elseif (string.len(number) - string.find(tostring(number), "%.")) > precNum then
    -- Check the minimum precision requested
local proc = string.gsub(number, "0+$", "")
    prec = tonumber(prec) -- nil if not specified as a true number
if (string.len(proc) - string.find(tostring(proc), "%.")) < precNum then
    if prec ~= nil then
precnumber = proc .. string.rep("0", precNum - (string.len(proc) - string.find(tostring(proc), "%.")))
        prec = math.floor(prec)
else
        if prec < 0 then
precnumber = proc
            prec = nil -- discard an incorrect precision (not a positive integer)
end
        elseif prec > 14 then
elseif (string.len(number) - string.find(tostring(number), "%.")) == precNum then
            prec = 14 -- maximum precision supported by tostring(number)
precnumber = number
        end
end
    end
else
 
precnumber = "" .. number .. "." .. string.rep("0", prec)
    -- Preprocess the minimum precision in the ASCII string
end
    local dot
number = precnumber .. "1"
    if (prec or 0) > 0 then
precA = "true"
        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
if lang == "arabic-indic" then
            dot = '' -- already present
lang = "ks"
        else
end
            dot = mw.ustring.sub (mw.language.new(lang):formatNum(0.1), 2, 2) -- must be added
        end
-- Formatnum
    else
if tonumber(number) ~= nil and mw.language.isKnownLanguageTag(lang) == true then
        dot = '' -- don't add dot
formatnum = mw.getLanguage( lang ):formatNum( tonumber(number) )
        prec = 0 -- don't alter the precision
else
    end
formatnum = number
 
formatA = "true"
    if lang ~= nil and mw.language.isKnownLanguageTag(lang) == true then
end
        -- Convert number to localized digits, decimal separator, and group separators
        local language = mw.getLanguage(lang)
-- Formatnum, special cases
        if compact then
local numsc = formatnum
            number = language:formatNum(tonumber(number), { noCommafy = 'y' }) -- caveat: can load localized resources for up to 20 languages
if lang == "ml-old" or lang == "mn" or lang == "te" or lang == "th" then
        else
for i, v in ipairs( digit[lang] ) do
            number = language:formatNum(tonumber(number)) -- caveat: can load localized resources for up to 20 languages
numsc = mw.ustring.gsub(numsc, tostring(i-1), v)
        end
end
        -- Postprocessing the precision
end
        if prec > 0 then
            local zero = language:formatNum(0)
--Postprocessing prec
            number = number .. dot .. mw.ustring.rep(zero, prec)
if precA == "true" then
        elseif prec < 0 then
postprec = mw.ustring.sub(numsc, 1, (mw.ustring.len(numsc) - 1))
            -- TODO: rounding of last decimal; here only truncate decimals in excess
else
            number = mw.ustring.sub(number, 1, mw.ustring.len(number) + prec)
postprec = numsc
        end
end
 
        -- Append the localized base-10 exponent without grouping separators (there's no reliable way to detect a localized leading symbol 'E')
-- separator
        if exponent ~= '' then
if sep ~= "" and formatA ~= "true" then
            number = number .. 'E' .. language:formatNum(tonumber(exponent),{noCommafy=true})
local replace = mw.ustring.gsub( "", "%%", "%%%%" )
        end
local separator = mw.ustring.sub(mw.getLanguage(lang):formatNum(tonumber("10000")), 3, 3)
    else -- not localized, ASCII only
if tostring(mw.ustring.find(separator, "%s")) == "1" then
        -- Postprocessing the precision
pattern = mw.ustring.format(separator, "%s")
        if prec > 0 then
elseif tostring(mw.ustring.find(separator, "%p")) == "1" then
            number = number .. dot .. mw.string.rep('0', prec)
pattern = mw.ustring.gsub(separator, "([%(%)%.%%%+%-%*%?%[%^%$%]])", "%%%1")
        elseif prec < 0 then
else
            -- TODO: rounding of last decimal; here only truncate decimals in excess
pattern = ""
            number = mw.string.sub(number, 1, mw.string.len(number) + prec)
end
        end
return tostring(mw.ustring.gsub( postprec, pattern, replace ))
 
else
        -- Append the base-10 exponent
return postprec
        if exponent ~= '' then
end
            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.