Modul:Vorlage:LuaModuleDoc

Aus Wikipedia
Vorlagenprogrammierung Diskussionen Lua Unterseiten
Modul Deutsch English

Modul: Dokumentation

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

Weiterleitung der Diskussionsseite fehlt
Diese Seite ist eine lokale Kopie aus de.wikipedia.org und von dort zu aktualisieren.

Versionsbezeichnung auf WikiData: 2024-03-01 Updating notwendig (lokal: 2022-04-22)


local LuaModuleDoc = { suite  = "LuaModuleDoc",
                       serial = "2022-04-22",
                       item   = 12981914,
                       frame  = false,
                       ns     = -9999,
                                -- current namespace number
                       nsDocs = -99999,
                                -- central documentation namespace number
                       title  = false,
                                -- current page Title object
                       transl = false }
--[=[
Support {{LuaModuleDoc}}
* nav()
* failsafe()
]=]
local Failsafe = LuaModuleDoc



local function fetch( arg, assign )
    -- Retrieve template argument
    -- Precondition:
    --     arg     -- string or number; argument identifier
    --     assign  -- any, optional; default value
    -- Uses:
    --     >  LuaModuleDoc.frame
    local r = LuaModuleDoc.frame.args[ arg ]
    if type( r ) ~= "string" then
        if assign == nil then
            r = "{{{<" .. arg .. ">}}}"
        else
            r = assign
        end
    end
    return r
end -- fetch()



local function catIfDefined( slot )
    -- Categorize if category defined
    --     slot  -- string; Config entry
    -- Return:
    --     string or false:  categorization, if any
    -- Uses:
    --     mw.title.makeTitle()
    local s = fetch( slot, "" )
    local r
    if #s > 0 then
        local t = mw.title.makeTitle( "Category", s )
        if t.exists then
            r = string.format( "[[%s]]", t.prefixedText )
        end
    end
    return r
end -- catIfDefined()



local function createPage( swift, sub, start, ns, script )
    -- Create button for page creation
    --     swift   -- string;
    --                "NoPageCentral", "NoTalkCentral", "NoTalkRedir"
    --     sub     -- string; page name to be created
    --     start   -- string; defined pageDocRoot argument
    --     ns      -- number; namespace
    --     script  -- string; module name (main)
    -- Return:
    --     string
    -- Uses:
    --     >  LuaModuleDoc.frame
    --     fetch()
    -- MediaWiki:Move-leave-redirect   Weiterleitung erstellen
    -- MediaWiki:autosumm-new          Seite wurde neu angelegt: „$1“
    local setup = "preload" .. swift:sub( 7 )
    local r
    setup = fetch( setup )
    if setup then
        local create = { action  = "edit",
                         preload = setup,
                         redlink = "1" }
        local button, path, show, story, summary
        if swift == "NoTalkRedir" then
            show    = "move-leave-redirect"
            story   = string.format( "%s/%s", start, script )
            story   = mw.title.makeTitle( ns, story ).prefixedText
            story   = string.format( "[[%s]]", story )
            summary = "#redirect " .. story
        else
            local s = fetch( "langsRequest", false )
            show    = "recreate"
            if s then
                s = mw.text.trim( s )
                if s ~= "" then
                    s = "|" .. s
                end
            end
            story = ( s or "" )
            summary = "{{LuaModuleDoc}}"
        end
    --  summary = mw.message.new( "autosumm-new" ):params( summary )
        create.summary      = summary
        create.preloadtitle = summary
        if story then
            create[ "preloadparams[]" ] = story
        end
        path   = { sub,  mw.uri.buildQueryString( create ) }
        r      = LuaModuleDoc.frame:callParserFunction( "fullurl", path )
        show   = mw.message.new( show ):plain()
        button = mw.title.makeTitle( mw.site.namespaces.Template.id,
                                     "MediaWiki-Button" )
        if button.exists then
            button = { template = button.text,
                       Typ      = "progressive",
                       ["Groß"] = "1",
                       Link     = r,
                       Text     = show }
            r      = LuaModuleDoc.frame:expandTemplate{
                                                 title = button.template,
                                                 args  = button }
        else
            r = string.format( "<br>[%s '''%s''']", r, show )
        end
    end
    return r or ""
end -- createPage()



local function globalRepos( script )
    -- Check for global dissemination
    --     script  -- string; module name (main)
    -- Uses:
    --     >  LuaModuleDoc.title
    --     >  LuaModuleDoc.frame
    --     fetch()
    --     mw.wikibase.getEntity()
    --     mw.title.makeTitle()
    -- Return:
    --     string
    local entity = mw.wikibase.getEntity()
    local r
    if type( entity ) == "table" then
        local mode = 0
        local repo = entity:formatPropertyValues( "P1324" )
        local params, s
        if type( repo ) == "table"  and
           type( repo.value ) == "string"  and
           repo.value:find( "//" ) then
            local t = mw.text.split( repo.value, ",%s+" )
            if #t > 1 then
                for i = 1, #t do
                    if t[ i ]:find( mw.site.server, 1, true ) then
                        s = t[ i ]
                        break -- for i
                    end
                end -- for i
                if not s then
                    s = t[ 1 ]
                end
            else
                s = repo.value
            end
            repo = mw.uri.new( s )
            if type( repo.path ) == "string"  and
               repo.path:match( "^/wiki/" ) then
                local space
                space, s = repo.path:sub( 7 ):match( "^([^:]+):(.+)$" )
                if space and
                   mw.site.namespaces[ space ] then
                    t = mw.title.makeTitle( space, s )
                    s = "//" .. repo.host
                    if mw.title.equals( LuaModuleDoc.title, t )  and
                       mw.site.server:find( s, 1, true ) then
                        mode = 2
                    else
                        mode = 1
                    end
                end
            end
            s = fetch( "templateGlobal", "" )
            if #s > 0 then
                local l, bib = pcall( require,
                                      LuaModuleDoc.title.prefixedText )
                local vsn = entity:formatPropertyValues( "P348" )
                params = { }
                if mode < 2 then
                    params[ 1 ] = string.format( "[%s %s]",
                                                 tostring( repo ),
                                                 repo.host )
                end
                if type( vsn ) == "table"  and
                   type( vsn.value) == "string" and
                   vsn.value ~= "" then
                    params.version = vsn.value
                end
                if type( bib ) == "table" then
                    local serial
                    if bib.failsafe then
                        if type( bib.failsafe ) == "function" then
                            serial = bib.failsafe( { args = { } } )
                        else
                            serial = bib.failsafe
                        end
                    elseif bib[ "#serial"] then
                        serial = bib[ "#serial"]
                    end
                    if type( serial ) == "number" then
                        serial = string.format( "%d", serial )
                    end
                    if type( serial ) == "string" then
                        params.here = serial
                    end
                end
                if fetch( "forkedGlobal", "0" ) ~= "1"  and
                   params.version  and  params.here  and
                   params.version ~= params.here then
                    params.update = "1"
                end
                r = LuaModuleDoc.frame:expandTemplate{ title=s,
                                                       args=params }
            end
        end
        s = fetch( "categoryWikiData", "" )
        if #s > 0 then
            local slot
            if mode > 0 then
                if mode == 2 then
                    slot = catIfDefined( "categoryWikiDataParent" )
                else
                    slot = catIfDefined( "categoryWikiDataChild" )
                end
            end
            if not slot then
                slot = catIfDefined( s )
            end
            if slot then
                if r then
                    r = r .. slot
                else
                    r = slot
                end
                if params and params.update then
                    slot = catIfDefined( "categoryWikiDataReplication" )
                    if slot then
                        r = r .. slot
                    end
                end
            end
        end
    end
    return r or ""
end -- globalRepos()



local function navDevelop( start, script )
    -- Most interesting test and development page
    -- Precondition:
    --     start   -- string; central documentation root
    --     script  -- string; basic module name
    -- Return:
    --     string or false:  full page name, if any
    -- Uses:
    --     >  LuaModuleDoc.nsDocs
    --     mw.title.makeTitle()
    local n   = LuaModuleDoc.nsDocs
    local r   = false
    local sub = "/" .. fetch( "subTest", "Test" )
    local s   = string.format( "%s/%s%s", start, script, sub )
    local t   = mw.title.makeTitle( n, s )
    if not t.exists then
        local low    = false
        local subLow = mw.ustring.lower( sub )
        if subLow ~= sub then
            s   = string.format( "%s/%s%s", start, script, subLow )
            t   = mw.title.makeTitle( n, s )
            low = t.exists
        end
        if not low then
            n = mw.site.namespaces.Module.id
            s = string.format( "%s/%s", script, sub )
            t = mw.title.makeTitle( n, s )
            if not t.exists  and  subLow ~= sub then
                s = script .. subLow
                t = mw.title.makeTitle( n, s )
                t = t.exists
            end
        end
    end
    if t then
        r = string.format( "%s:%s",
                           mw.site.namespaces[ n ].name, s )
    end
    return r
end -- navDevelop()



local function navError( say, specific )
    -- Return error message, evaluate page .pageErr
    -- Precondition:
    --     say       -- string; message key
    --     specific  -- string, optional; additional information
    -- Uses:
    --     >  LuaModuleDoc.frame
    --     fetch()
    local show = fetch( "pageErr" )
    local r
    if type( show ) == "string" then
        local pars = { say }
        if type( specific ) == "string" then
            table.insert( pars, specific )
        end
        r = LuaModuleDoc.frame:expandTemplate{ title = show,
                                               args = pars }
    else
        local e = mw.html.create( "span" )
                         :attr( "class", "error" )
                         :wikitext( error( "arg 'pageErr' missing", 3 ) )
        r = tostring( e )
    end
    return r
end -- navError()



local function navLang( suite, collect, lazy )
    -- Append languages from string to collection
    -- Precondition:
    --     suite    -- string; space separated source
    --     collect  -- table; to be extended
    --                 every element: { langCode, lazy }
    --     lazy     -- true if only existing page is to be linked
    if type( suite ) == "string" then
        local raw = mw.text.split( suite, "%s+" )
        local e, i, j, s
        for i = 1, #raw do
            s = raw[ i ]
            if #s > 1 then
                for j = 1, #collect do
                    if s then
                        e = collect[ j ]
                        if e[ 1 ] == s then
                            s = false
                            if not lazy then
                                e[ 2 ] = false
                            end
                        end
                    end
                end -- for j
                if s then
                    table.insert( collect,  { s, lazy } )
                end
            end
        end -- for i
    end
end -- navLang()



local function navLangs( start, script )
    -- Analyze languages
    -- Precondition:
    --     current page is supposed to transclude LuaModuleDoc
    --     start   -- string; central documentation root
    --     script  -- string; basic module name
    -- Postcondition:
    --     LuaModuleDoc.transl is set up as table:
    --                         args for navigation template
    --                         [1] basic module name
    --                         [2] number of language codes  +  1
    --                         [3] first language code
    --                         [4] second language code
    --                         ... list of further language codes
    -- Uses:
    --     >  LuaModuleDoc.nsDocs
    --      < LuaModuleDoc.transl
    --     fetch()
    --     navLang()
    --     mw.title.makeTitle()
    local e, i, s, t
    local specified = fetch( "langsRequest", false )
    local super     = start .. "/" .. script .. "/"
    LuaModuleDoc.transl = { }
    if type( specified ) == "string" then
        if specified:match( "^%s*$" ) then
            specified = false
        end
    end
    navLang( fetch( "langsDefault" ),  LuaModuleDoc.transl,  specified )
    navLang( fetch( "langsMore" ),  LuaModuleDoc.transl,  true  )
    navLang( specified, LuaModuleDoc.transl, false )
    if #LuaModuleDoc.transl < 1 then
        LuaModuleDoc.transl = { { "en", false } }
    end
    for i = #LuaModuleDoc.transl, 1, -1 do
        e = LuaModuleDoc.transl[ i ]
        s = e[ 1 ]
        if e[ 2 ] then
            t = mw.title.makeTitle( LuaModuleDoc.nsDocs,  super .. s )
            if not t.exists then
                s = false
            end
        end
        if s then
            LuaModuleDoc.transl[ i ] = s
        else
            table.remove( LuaModuleDoc.transl, i )
        end
    end -- for i -1
    table.insert( LuaModuleDoc.transl,
                  1,
                  script )
    table.insert( LuaModuleDoc.transl,
                  2,
                  tostring( #LuaModuleDoc.transl ) )
end -- navLangs()



local function navMerge( start, swift, script, sub, lead )
    -- Include various external content into page
    -- Precondition:
    --     start   -- string; defined pageDocRoot argument
    --     swift   -- string; defined pageNav argument
    --     script  -- string; module name (main)
    --     sub     -- string or false; possible sub-module name
    --     lead    -- true: Module: namespace;   false: text namespace
    -- Uses:
    --     >  LuaModuleDoc.transl
    --     >  LuaModuleDoc.ns
    --     >  LuaModuleDoc.nsDocs
    --     >  LuaModuleDoc.title
    --     >  LuaModuleDoc.frame
    --     navError()
    --     mw.title.makeTitle()
    --     createPage()
    --     fetch()
    local server = mw.site.server
    local super  = false
    local t      = navDevelop( start, script )
    local collect, low, r, s
    collect = LuaModuleDoc.transl
    if t then
        collect.Test = t
    end
    if LuaModuleDoc.ns == LuaModuleDoc.nsDocs then
        s = string.format( "%s/%s", start, script )
        if LuaModuleDoc.title.text == s then
            super = LuaModuleDoc.title.text .. "/"
        elseif sub then
            collect.subDoc = sub
            collect.subModule = sub
            s = string.format( "%s/%s/%s", start, script, sub )
            if LuaModuleDoc.title.text == s then
                s = string.format( "%s/%s", s, collect[ 3 ] )
                t = mw.title.makeTitle( LuaModuleDoc.nsDocs, s )
                if t.exists then
                    super = LuaModuleDoc.title.text .. "/"
                end
            end
        end
    elseif lead and sub then
        s = string.format( "%s/%s/%s", start, script, sub )
        t = mw.title.makeTitle( LuaModuleDoc.nsDocs, s )
        if t.exists then
            collect.subDoc = sub
        end
    end
    if server:match( "%.beta%.wmflabs%.org$" ) then
        local slang, series = server:match( "//(%l+)%.(%l+)%." )
        low = true
        if series == "wikipedia" then
            if slang == "de" then
                collect.BETA = "w:de:"   --Talk
            end
        end
    end
    r = LuaModuleDoc.frame:expandTemplate{ title = swift,
                                           args = collect }
    if not low then
        t = LuaModuleDoc.title.talkPageTitle
        if LuaModuleDoc.ns == mw.site.namespaces.Module.id then
            local doc
            s   = string.format( "%s/%s", start, script )
            doc = mw.title.makeTitle( LuaModuleDoc.nsDocs, s )
            if not doc.exists then
                r = r .. createPage( "NoPageCentral",
                                     doc.prefixedText,
                                     start,
                                     LuaModuleDoc.nsDocs,
                                     script )
                t = false
            end
        end
        if t  and  not t.exists then
            if super then
                s = "NoTalkCentral"
            elseif LuaModuleDoc.ns == LuaModuleDoc.nsDocs + 1 then
                s = false
            else
                s = "NoTalkRedir"
            end
            if s then
                r = string.format( "%s%s%s",
                                   r,
                                   navError( s ),
                                   createPage( s,
                                               t.prefixedText,
                                               start,
                                               LuaModuleDoc.nsDocs + 1,
                                               script ) )
            end
        end
    end
    if super then
        local d  = "{{%s*[lL]uaModuleDoc[^}]*}}%s*"
        local p1 = "^%s*" .. d .. "<onlyinclude>"
        local p2 = "%s*<noinclude>" .. d .. "</noinclude>"
        local space, sub, support
        for i = 3, #collect do
            t = mw.title.makeTitle( LuaModuleDoc.nsDocs,
                                    super .. collect[ i ] )
            s = t:getContent()
            if s then
                s = s:gsub( p1, "" ):gsub( p2, "" )
                if s:match( d ) then
                    r = string.format( "%s<br />%s<br />",
                                       r,
                                       navError( "BadInclude",
                                                 t.prefixedText ) )
                else
                    r = r ..
                        LuaModuleDoc.frame:expandTemplate{
                                                 title = t.prefixedText }
                    break    -- for i
                end
            end
        end -- for i
        s = fetch( "pageTemplateInsert", "" )
        space, support = s:match( "^([^:]+):(.+)$" )
        if space  and  mw.title.makeTitle( space, support ).exists then
            local suppress = fetch( "noHint", "" )
            if #suppress == 0 then
                local swift = collect[ 1 ]
                if sub then
                    swift = string.format( "%s/%s", swift, sub )
                end
                r = r ..
                    LuaModuleDoc.frame:expandTemplate{ title = s,
                                                       args = { swift } }
            end
        end
        s = fetch( "categoryDocs", "" )
        if #s > 0 then
            i = mw.title.makeTitle( "Category", s )
            if i.exists then
                r = string.format( "%s[[%s|%s]]",
                                   r, i.prefixedText, collect[ 1 ] )
            end
        end
        r = r .. "__NOEDITSECTION__"
    end
    if lead then
        r = r .. globalRepos( script )
    end
    return r
end -- navMerge()



local function navPage( lead )
    -- Return navigation text; analyze page location
    -- Precondition:
    --     current namespace will support LuaModuleDoc
    --     lead    -- true: Module: namespace;   false: text namespace
    -- Uses:
    --     >  LuaModuleDoc.title
    --     >  LuaModuleDoc.transl
    --     fetch()
    --     navLangs()
    --     navMerge()
    --     navError()
    local r
    local start = fetch( "pageDocRoot" )
    if type( start ) == "string" then
        local s      = "^"
        local script
        if not lead then
            s = "^" .. start .. "/"
        end
        s = s .. "([^/]+)/(.*/?)$"
        script, s = string.match( LuaModuleDoc.title.text .. "/",  s )
        if type( script ) == "string" then
            local sub   = false
            local swift = fetch( "pageNav" )
            navLangs( start, script )
            if type( s ) == "string" then
                if #s > 1 then
                    local q
                    s = s:match( "^([^/]+)/.*/?$" )
                    q = mw.title.makeTitle( "Module",
                                            script .. "/" .. s )
                    if q.exists and q.contentModel == "Scribunto" then
                        sub = s
                        for i = 1, #LuaModuleDoc.transl do
                            if LuaModuleDoc.transl[ i ] == s then
                                sub = false
                                break    -- for i
                            end
                        end -- for i
                    end
                end
            end
            if type( swift ) == "string" then
                r = navMerge( start,
                              swift,
                              script,
                              sub,
                              lead )
            else
                r = navError( "configMissing", "pageNav" )
            end
        else
            r = navError( "BadPage" ) .. LuaModuleDoc.title.text
        end
    else
        r = navError( "configMissing", "pageDocRoot" )
    end
    return r
end -- navPage()



local function navigation()
    -- Start execution; return navigation text; analyze namespace
    -- Uses:
    --      < LuaModuleDoc.title
    --      < LuaModuleDoc.ns
    --      < LuaModuleDoc.nsDocs
    --     fetch()
    --     mw.title.getCurrentTitle()
    --     navPage()
    --     navError()
    local r
    local nsDocs = fetch( "nsDocs" )
    if nsDocs then
        local lead
        LuaModuleDoc.title  = mw.title.getCurrentTitle()
        LuaModuleDoc.ns     = LuaModuleDoc.title.namespace
        lead                = ( LuaModuleDoc.ns ==
                                mw.site.namespaces.Module.id )
        LuaModuleDoc.nsDocs = tonumber( nsDocs )
        if lead  or
           LuaModuleDoc.ns == LuaModuleDoc.nsDocs  or
           LuaModuleDoc.ns == LuaModuleDoc.nsDocs + 1 then
            r = navPage( lead )
        else
            r = navError( "BadNamespace" )
        end
    else
        r = navError( "configMissing", "nsDocs" )
    end
    return  r
end -- navigation()



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
    -- 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()



-- Provide template access
local p = {}

function p.nav( frame )
    -- Uses:
    --      < LuaModuleDoc.frame
    --     navigation()
    local lucky, r
    LuaModuleDoc.frame = frame
    lucky, r = pcall( navigation )
    if not lucky then
        local e = mw.html.create( "span" )
                         :attr( "class", "error" )
                         :wikitext( r )
        r = tostring( e )
    end
    return r or ""
end



p.failsafe = function ( frame )
    -- Check or retrieve version information
    -- Precondition:
    --     frame  -- object; #invoke environment
    -- Postcondition:
    --     Return string with error message or ""
    -- Uses:
    --     LuaModuleDoc.failsafe()
    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()

return p