Modul:Vorlage:PersonZelle

aus Wikipedia, der freien Enzyklopädie
local Sort = { suite   = "Sort",
               sub     = "cellPerson",
               serial  = "2021-03-20",
               cat     = "Wikipedia:Vorlagenfehler/Vorlage:PersonZelle",
               item    = 62090703,
               globals = { Cell     = 90144855,
                           Sorter   = 24205172,
                           TemplUtl = 52364930 } }
--[=[
Vorlage:PersonZelle
]=]
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, alert )
    -- Fetch global library
    -- Precondition:
    --     access    -- string|false, with name of base module
    --     append    -- string, with subpage part, if any; or false
    --     alert     -- true, for throwing error on data problem
    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 ],
                                   alert )
        if bib  and  type( bib[ suite ] ) == "function" then
            Sort[ store ] = bib[ suite ]()
        else
            error( tostring( bib ) )
        end
    end
    return Sort[ store ]
end -- fetch()



local function fault( alert, frame )
    -- Format error message
    -- Parameter:
    --     alert  -- string, with complaint
    --     frame  -- object, or nil
    -- Returns string
    local TemplUtl = fetch( "TemplUtl" )
    local staff    = "editoronly"
    local r
    if TemplUtl then
        local live
        if mw.title.getCurrentTitle().namespace ~= 0 then
            live  = true
            staff = false
        end
        r = TemplUtl.failure( alert, live, staff, frame )
    else
        local e = mw.html.create( "span" )
                         :addClass( "error" )
                         :wikitext( alert )
        r = tostring( e )
    end
    r = string.format( " %s [[Category:%s]]", r, Sort.cat )
    return r
end -- fault()



Sort.f = function ( arglist, frame )
    -- Do it.
    -- Parameter:
    --     arglist  -- table, with parameters
    --     frame    -- object, or nil
    -- Returns:
    --     string
    local params = { [ 1 ]   = false,
                     [ 2 ]   = false,
                     [ 3 ]   = false,
                     fett    = false,
                     k       = false,
                     kursiv  = false,
                     nl      = false,
                     pre     = false,
                     postfix = false,
                     revers  = false,
                     zeige1  = true,
                     zeige2  = true,
                     rowspan = false,
                     colspan = false,
                     class   = false,
                     style   = false,
                     id      = false,
                     lang    = false,
                     dir     = false
                      }
    local r, unknown
    fetch( false, "Cell", true )
    for k, v in pairs( arglist ) do
        if type( params[ k ] ) == "boolean" then
            v = mw.text.trim( v )
            if v ~= "" then
                params[ k ] = v
            end
        else
            if unknown then
                unknown = string.format( "%s, %s", unknown, k )
            else
                unknown = k
            end
        end
    end -- for k, v in arglist
    params.vor = params[ 1 ]
    params.fam = params[ 2 ]
    if params.fam then
        local got, present
        present        = Sort.Cell.first( params, true )
        params.artikel = params[ 3 ]
        if params.nl == "0" then
            params.nl = false
        end
        if params.fett == "0" then
            params.fett = false
        end
        if params.kursiv == "0" then
            params.kursiv = false
        end
        if params.revers == "0" then
            params.revers = false
        end
        if params.zeige1 == "0" then
            params.zeige1 = false
        end
        if params.zeige2 == "0"  and
           params.zeige1  and
           params.vor then
            params.zeige2 = false
        end
        got = Sort.fiat( params )
        if got.sort then
            Sort.Cell.faced( present, got.sort )
        end
        r = Sort.Cell.finalize( present, got.show )
        if got.strange then
            r = r .. fault( got.strange, frame )
        end
    else
        local s = "Pflichtparameter (Familienname) fehlt"
        r = "|"
        if params.vor then
            r = r .. params.vor
            s = string.format( "%s – %s", s, params.vor )
        end
        r = r .. fault( s, frame )
    end
    if unknown then
        r = r  ..  fault( "Unbekannter Parametername(n) " .. unknown,
                          frame )
    end
    return r
end -- Sort.f()



Sort.fiat = function ( arglist )
    -- Create sortkey and presented name
    -- Parameter:
    --     arglist  -- table, with parameters
    -- Postcondition:
    --     Returns  table, or nil
    --              .show     -- string, with HTML cell contents
    --              .sort     -- string, with sort-value, if required
    --              .strange  -- string, with error message, if any
    local params = { fam     = false,
                     vor     = false,
                     artikel = false,
                     fett    = false,
                     k       = false,
                     kursiv  = false,
                     nl      = false,
                     pre     = false,
                     postfix = false,
                     revers  = false,
                     zeige1  = true,
                     zeige2  = true,
                   }
    local r, s
    for k, v in pairs( arglist ) do
        if type( params[ k ] ) == "boolean" then
            s = type( v )
            if s == "string" then
                v = mw.text.trim( v )
                if v ~= "" then
                    params[ k ] = v
                end
            elseif s == "boolean" then
                params[ k ] = v
            end
        end
    end -- for k, v in arglist
    if params.fam then
        local slot = params.artikel
        local sort
        r    = { show = params.fam }
        sort = r.show
        s    = r.show
        if params.vor  and  params.zeige1 then
            s = params.vor
            if params.zeige2 then
                if not Sort.swing then
                    Sort.swing = mw.ustring.char( 91,   39,
                                                      0x2019,
                                                        37, 45,
                                                  93 )
                end
                if mw.ustring.find( mw.ustring.sub( s, -1 ),
                                    Sort.swing ) then
                    r.show = string.format( "%s%s", s, r.show )
                else
                    r.show = string.format( "%s %s", s, r.show )
                end
            else
                r.show = s
            end
            if params.revers then
                sort = string.format( "%s, %s", s, sort )
            else
                sort = string.format( "%s, %s", sort, s )
            end
        end
        if params.k then
            if params.nl then
                r.strange = "Widerspruch k=... und nl=1"
            elseif slot then
                r.strange = "Widerspruch k=... und 3=..."
            else
                slot = string.format( "%s (%s)", r.show, params.k )
            end
            sort = string.format( "%s @%s", sort, params.k )
        end
        if params.postfix then
            sort = string.format( "%s %s", sort, params.postfix )
        end
        if not params.nl then
            if slot then
                r.show = string.format( "%s|%s", slot, r.show )
            end
            r.show = string.format( "[[%s]]", r.show )
        end
        if params.fett or params.kursiv then
            local e = mw.html.create( "span" )
            if params.fett then
                e:css( "font-weight", "bold" )
            end
            if params.kursiv then
                e:css( "font-style", "italic" )
            end
            r.show = tostring( e:wikitext( r.show ) )
        end
        if params.pre then
            r.show = string.format( "%s %s", params.pre, r.show )
        end
        if sort:find( "[^ %w,#]" ) then
            local Sorter = fetch( "Sort", false, true )
            sort = Sorter.lex( sort, "latin" )
        end
        if sort:find( "[^, %w]" ) then
            local quotes = mw.ustring.char( 91,   34,
                                                  39,
                                                 171,
                                                 187,
                                                8216,
                                                8217,
                                                8218,
                                                8220,
                                                8221,
                                                8222,
                                                8249,
                                                8250,
                                                0x300C,
                                                0x300D,
                                                0x300E,
                                                0x300F, 93 )
            sort = mw.ustring.gsub( sort, quotes, "" )
        end
        if params.pre  or  params.vor  or  sort ~= params.fam then
            r.sort = sort
        end
    end
    return r
end -- Sort.fiat()



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-17
    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
        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 = { }

function p.test( arglist )
    return Sort.f( arglist )
end

p.f = function ( frame )
    local lucky, r = pcall( Sort.f, frame:getParent().args, frame )
    if not lucky then
        r = fault( r )
    end
    return r
end

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

function p.Sort()
    -- Module interface
    return Sort
end -- p.Sort()

return p