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: 2024-07-02

local Sort = { suite   = "Sort",
               sub     = "cellText",
               serial  = "2024-07-02",
               item    = 90147626,
               globals = { Sorter = 24205172,
                           Cell   = 90144855,
                           WLink  = 19363224 } }
--[=[
Sort/cellText -- support table cells with lexically sortable wikitext
]=]
local Failsafe  = Sort
local GlobalMod = Sort



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 fetch = function ( access, append )
    -- Fetch global library
    -- Precondition:
    --     access    -- string|false, with name of base module
    --     append    -- string, with subpage part, if any; or false
    -- Postcondition:
    --     library added to Sort object, if available
    local store, sub, suite
    if access then
        suite = access
        store = access
    else
        suite = Sort.suite
        if append then
            sub   = append:lower()
            store = append
        else
            store = "Sorter"
        end
    end
    if type( Sort[ store ] ) == "nil" then
        local bib = foreignModule( suite,
                                   true,
                                   sub,
                                   Sort.globals[ store ],
                                   true )
        if type( bib ) == "table"   and
           type( bib[ suite ] ) == "function" then
            Sort[ store ] = bib[ suite ]()         -- MIGRATE    = bib()
        else
            error( tostring( bib ) )
        end
    end
end -- fetch()



local fiat = function ( args )
    -- Execute task
    -- Parameter:
    --     args    -- table, parameters
    -- Postcondition:
    --     Returns string, or expands .cell
    --     Throws error on failure
    local r
    fetch( false, "Cell" )
    if type( args ) == "table" then
        local present = Sort.Cell.first( args, true )
        Sort.Cell.fair( args, "source", present )
        if present.source then
            local s = mw.text.unstrip( present.source )
            if s:find( "<", 1, true ) then
                s = s:gsub( "(</?%l[^>]*>)", "" )
            end
            if s:find( "'", 1, true ) then
                s = s:gsub( "'''(.+)'''", "%1" )
                     :gsub( "''(.+)''", "%1" )
            end
            if s:find( "[", 1, true ) then
                fetch( "WLink" )
                s = Sort.WLink.getPlain( s )
            end
            s = mw.text.decode( s )
            s = mw.ustring.gsub( s,  mw.ustring.char( 160 ),  " " )
            s = mw.text.trim( s )
            s = mw.ustring.gsub( s, "%s+", " " )
            if s ~= "" then
                r = present.source
                fetch()
                s = Sort.Sorter.lex( s, "latin" )
                if s ~= r  or  present.pre then
                    Sort.Cell.faced( present, s )
                end
                if present.pre then
                    r = Sort.Cell.fore( present.pre, "-", r )
                end
                r = Sort.Cell.finalize( present, r )
            end
        end
        if not r then
            r = Sort.Cell.fault( "?????", present )
        end
    else
        error( "'args' is not a table" )
    end
    return r
end -- fiat()



Sort.f = function ( args )
    -- Create table cell start or equip table cell object
    -- Parameter:
    -- Parameter:
    --     args    -- table, parameters
    --                .source     -- string, with sortable wikitext
    --                .pre        -- string, with preceding wikitext
    --                .cell       -- table|nil, sort environment
    --                .rowspan    -- number|string, for cell attribute
    --                .colspan    -- number|string, for cell attribute
    --                .class      -- string, for cell attribute
    --                .style      -- string|table, for cell attribute
    --                .id         -- string, for cell attribute
    --                .lang       -- string, for cell attribute
    --                .dir        -- string, for cell attribute
    --                .cat        -- string|nil, for error category
    -- Postcondition:
    --     Returns string, or expands .cell
    local lucky, r = pcall( fiat, args )
    if not lucky then
        local e = mw.html.create( "span" )
                         :addClass( "error" )
                         :wikitext( "Module:Sort/cell * " .. r )
        if type( args.cell ) == "table"  and
           type( args.cell.wikitext ) == "function" then
            args.cell:node( e )
        else
            r = tostring( e )
        end
    end
    return r
end -- Sort.f()



Failsafe.failsafe = function ( atleast )
    -- Retrieve versioning and check for compliance
    -- Precondition:
    --     atleast  -- string, with required version
    --                         or wikidata|item|~|@ or false
    -- Postcondition:
    --     Returns  string  -- with queried version/item, also if problem
    --              false   -- if appropriate
    -- 2024-03-01
    local since  = atleast
    local last   = ( since == "~" )
    local linked = ( since == "@" )
    local link   = ( since == "item" )
    local r
    if last  or  link  or  linked  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 )
            if link then
                r = suited
            else
                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 linked 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
        elseif link then
            r = false
        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
    Sort.frame = frame
    return Sort.f( frame.args )  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.Sort = function ()
    -- Module interface
    return Sort
end

setmetatable( p,  { __call = function ( func, ... )
                                 setmetatable( p, nil )
                                 return Failsafe
                             end } )

return p