Vorlagenprogrammierung Diskussionen Lua Test Unterseiten
Modul Deutsch English

Modul: Dokumentation

Diese Seite enthält Code in der Programmiersprache Lua. Einbindungszahl Cirrus

Dies ist die (produktive) Mutterversion eines global benutzten Lua-Moduls.
Wenn die serial-Information nicht übereinstimmt, müsste eine Kopie hiervon in das lokale Wiki geschrieben werden.
Versionsbezeichnung auf WikiData: 2020-08-06

local FormatCash = { suite    = "FormatCash",
                     serial   = "2020-08-06",
                     item     = 98112089,
                     globals  = { FormatNum = 15709679,
                                  TemplUtl  = 52364930 } }
--[=[
Format amount of money
]=]
local Failsafe  = FormatCash
local GlobalMod = FormatCash



local foreignModule = function ( access, advanced, append, alt, alert )
    -- Fetch global module
    -- Precondition:
    --     access    -- string, with name of base module
    --     advanced  -- true, for require(); else mw.loadData()
    --     append    -- string, with subpage part, if any; or false
    --     alt       -- number, of wikidata item of root; or false
    --     alert     -- true, for throwing error on data problem
    -- Postcondition:
    --     Returns whatever, probably table
    -- 2020-01-01
    local storage = access
    local finer = function ()
                      if append then
                          storage = string.format( "%s/%s",
                                                   storage,
                                                   append )
                      end
                  end
    local fun, lucky, r, suited
    if advanced then
        fun = require
    else
        fun = mw.loadData
    end
    GlobalMod.globalModules = GlobalMod.globalModules or { }
    suited = GlobalMod.globalModules[ access ]
    if not suited then
        finer()
        lucky, r = pcall( fun,  "Module:" .. storage )
    end
    if not lucky then
        if not suited  and
           type( alt ) == "number"  and
           alt > 0 then
            suited = string.format( "Q%d", alt )
            suited = mw.wikibase.getSitelink( suited )
            GlobalMod.globalModules[ access ] = suited or true
        end
        if type( suited ) == "string" then
            storage = suited
            finer()
            lucky, r = pcall( fun, storage )
        end
        if not lucky and alert then
            error( "Missing or invalid page: " .. storage )
        end
    end
    return r
end -- foreignModule()



local function faculty( analyze, another )
    -- Test template arg for boolean
    --     analyze  -- string, boolean, or nil
    --     another  -- fallback: string, boolean, or nil
    -- Returns boolean
    local s = type( analyze )
    local r
    if s == "string" then
        r = mw.text.trim( analyze )
        if r == "" then
            r = another
        elseif r == "0"  or  r == "-" then
            r = false
        elseif r == "1" then
            r = true
        else
            local TemplUtl = fetch( "TemplUtl" )
            r = TemplUtl.faculty( analyze, another )
        end
    elseif s == "boolean" then
        r = analyze
    end
    if type( r ) ~= "boolean" then
        r = another
    end
    return r
end -- faculty()



local fault = function ()
    -- Create HTML error message
    local show = "error"
    local err
    if FormatCash.frame then
        local t = FormatCash.frame:getParent():getTitle()
        if t then
            show = string.format( "[[%s]] %s", t, show )
        end
    end
    err = mw.html.create( "span" )
                 :addClass( "error" )
                 :wikitext( show )
    return tostring( err )
end -- fault()



local fetch = function ( access )
    -- Fetch global library
    -- Precondition:
    --     access    -- string, with name of base module
    if type( FormatCash[ access ] ) == "nil" then
        local bib = foreignModule( access,
                                   true,
                                   false,
                                   FormatCash.globals[ access ],
                                   true )
        if bib  and  type( bib[ access ] ) == "function" then
            FormatCash[ access ] = bib[ access ]()
        else
            error( tostring( bib ) )
        end
    end
    return FormatCash[ access ]
end -- fetch()



local fashion = function ()
    -- Retrieve typographic minus sign U+2212
    if not FormatCash.minus then
        FormatCash.minus = mw.ustring.char( 0x2212 )
    end
    return FormatCash.minus
end -- fashion()



FormatCash.f = function ( arglist )
    -- Perform main task
    -- Precondition:
    --     arglist  -- table, with parameters
    --                 money   -- number/string, with amount, mandatory
    --                 n       -- number/string, with rounding precision
    --                 error   -- string, with HTML error message
    --                 schema  -- string, formatting pattern
    --                 pre     -- string, with currency prepended
    --                 post    -- string, with currency appended
    --                 style   -- string, with style
    --                 styleM  -- string, with style on negative amount
    --                 classM  -- string, with class on negative amount
    local m, r, s
    if type( arglist ) == "table"  and  arglist.money then
        s = type( arglist.money )
        if s == "string" then
            m = mw.text.trim( arglist.money )
            if m == "" then
                m = false
            else
                if mw.ustring.sub( 1, 1 ) == fashion() then
                    m = "-" .. mw.ustring.sub( m, 2 )
                end
                m = tonumber( m )
            end
        elseif s == "number" then
            m = arglist.money
        end
    end
    if m then
        local n, schema
        s = type( arglist.n )
        if s == "string" then
            n = tonumber( arglist.n )
        elseif s == "number" then
            n = arglist.n
        end
        if type( n ) ~= "number" then
            n = 0
        end
        if n > 0 then
            n = math.floor( n )
            if n > 20 then
                n = 20
            end
            s = string.format( "%%.%df", n )
            r = string.format( s, m )
        else
            if n < 0 then
                n = math.floor( n )
                if n < -20 then
                    n = -20
                end
            end
            r = tostring( m )
        end
        if arglist.schema then
            local FormatNum = fetch( "FormatNum" )
            r = FormatNum.format( FormatNum.round( r, n ),
                                  arglist.schema )
            if m < 0 then
                r = fashion() .. mw.ustring.sub( r, 2 )
            end
        end
        if arglist.pre or
           arglist.post or
           arglist.style or
           arglist.styleM or
           arglist.classM then
            local class, leap, style
            if arglist.post  and  arglist.post ~= "" then
                r    = string.format( "%s %s", r, arglist.post )
                leap = true
            end
            if not leap  and  arglist.pre  and  arglist.pre ~= "" then
                r    = string.format( "%s %s", arglist.pre, r )
                leap = true
            end
            if leap then
                style = ";white-space:nowrap"
            else
                style = ""
            end
            if arglist.style  and  arglist.style ~= "" then
                style = string.format( "%s;%s", style, arglist.style )
            end
            if m < 0 then
                if arglist.styleM  and  arglist.styleM ~= "" then
                    style = string.format( "%s;%s",
                                           style, arglist.styleM )
                end
                if arglist.classM  and  arglist.classM ~= "" then
                    class = arglist.classM
                end
            end
            if style == "" then
                style = false
            end
            if class or style then
                local e = mw.html.create( "span" )
                                 :wikitext( r )
                if style then
                    e:cssText( style:sub( 2 ) )
                end
                if class then
                    e:addClass( class )
                end
                r = tostring( e )
            end
        end
    else
        r = arglist.error or fault()
    end
    return r
end -- FormatCash.f()



Failsafe.failsafe = function ( atleast )
    -- Retrieve versioning and check for compliance
    -- Precondition:
    --     atleast  -- string, with required version
    --                         or "wikidata" or "~" or "@" or false
    -- Postcondition:
    --     Returns  string  -- with queried version/item, also if problem
    --              false   -- if appropriate
    -- 2020-08-01
    local last  = ( atleast == "~" )
    local link  = ( atleast == "@" )
    local since = atleast
    local r
    if last  or  link  or  since == "wikidata" then
        local item = Failsafe.item
        since = false
        if type( item ) == "number"  and  item > 0 then
            local suited = string.format( "Q%d", item )
            local entity = mw.wikibase.getEntity( suited )
            if type( entity ) == "table" then
                local seek = Failsafe.serialProperty or "P348"
                local vsn  = entity:formatPropertyValues( seek )
                if type( vsn ) == "table"  and
                   type( vsn.value ) == "string"  and
                   vsn.value ~= "" then
                    if last  and  vsn.value == Failsafe.serial then
                        r = false
                    elseif link then
                        if mw.title.getCurrentTitle().prefixedText  ==
                           mw.wikibase.getSitelink( suited ) then
                            r = false
                        else
                            r = suited
                        end
                    else
                        r = vsn.value
                    end
                end
            end
        end
    end
    if type( r ) == "nil" then
        if not since  or  since <= Failsafe.serial then
            r = Failsafe.serial
        else
            r = false
        end
    end
    return r
end -- Failsafe.failsafe()



-- Export
local p = { }

p.f = function ( frame )
    -- Template call in German projects
    local tArgs = frame:getParent().args
    local params = { money  = tArgs[ 1 ],
                     n      = tArgs.n,
                     error  = tArgs.error,
                     pre    = tArgs[ "$u" ],
                     post   = tArgs[ "u$" ],
                     style  = tArgs.style,
                     styleM = tArgs[ "style-" ],
                     classM = tArgs[ "class-" ] }
    local dewiki = true
    local ch
    if tArgs.dewiki then
        dewiki = faculty( tArgs.dewiki, true )
    end
    if tArgs.CH then
        ch = faculty( tArgs.CH, false )
    end
    if ch then
        params.schema = "ch_currency"
    elseif dewiki then
        params.schema = "de_currency"
    end
    FormatCash.frame = frame
    return FormatCash.f( params )  or  ""
end -- p.f

p.failsafe = function ( frame )
    -- Versioning interface
    local s = type( frame )
    local since
    if s == "table" then
        since = frame.args[ 1 ]
    elseif s == "string" then
        since = frame
    end
    if since then
        since = mw.text.trim( since )
        if since == "" then
            since = false
        end
    end
    return Failsafe.failsafe( since )  or  ""
end -- p.failsafe

p.FormatCash = function ()
    -- Module interface
    return FormatCash
end

return p