Zum Inhalt springen

Modul:Vorlage:projekt-gutenberg.org

aus AufEinWort, der freien Forschung
Dies ist die aktuelle Version dieser Seite, zuletzt bearbeitet am 21. Juli 2026 um 14:52 Uhr durch Nikolaos (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „local PGorg = { suite = "projekt-gutenberg.org", serial = "2026-06-22", item = 140008106, globals = { WLink = 19363224 }, config = { } } --[=[ Create external link for projekt-gutenberg.org loadJsonData: ./config.json ./a.json require: getArticleBase@WLink ]=] local Failsafe = PGorg local GlobalMod = PGorg local foreignModule = function ( access, ad…“).
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Vorlagenprogrammierung Diskussionen Lua Unterseiten
Modul Deutsch

Modul: Dokumentation

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

Weiterleitung der Diskussionsseite fehlt

local PGorg = { suite   = "projekt-gutenberg.org",
                serial  = "2026-06-22",
                item    = 140008106,
                globals = { WLink = 19363224 },
                config  = { }
              }
--[=[
Create external link for projekt-gutenberg.org
loadJsonData: ./config.json
              ./a.json
require:      getArticleBase@WLink
]=]
local Failsafe  = PGorg
local GlobalMod = PGorg



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 facility = function ( access )
    -- Retrieve JSON page name
    -- Precondition:
    --     access  -- string, page identifier
    -- Postcondition:
    --     Returns page name
    return string.format( "%s/%s.json", PGorg.sources, access )
end -- facility()



local factory = function ( assign, assigned )
    -- Retrieve transclusion suggestion
    -- Precondition:
    --     assign    -- string, with template name
    --     assigned  -- table, with [1]= key and [2]= name
    -- Postcondition:
    --     Returns wikitext
    local r = assigned[ 2 ] .. "\n"
    local s = string.format( "{{%s |a=%s}}",
                             assign,
                             assigned[ 1 ] )
    r = r .. PGorg.frame:extensionTag( "syntaxhighlight",
                                       s,
                                       { lang = "wikitext",
                                         copy = "1" } )
    return r .. "\n"
end -- factory()



local fault = function ( alert, about, access )
    -- Create error message
    -- Precondition:
    --     alert   -- string, message identifier
    --     about   -- ID code
    --     access  -- JSON id
    -- Postcondition:
    --     Build PGorg.scream
    --     Returns PGorg.scream
    local e   = mw.html.create( "span" )
                       :addClass( "error" )
    local err = PGorg.config.err
    if type( err ) ~= "table" then
        err = { }
    end
    e:wikitext( string.format( "[[%s]] – ",  PGorg.sources ) )
    if type( err[ alert ] ) == "string" then
        e:wikitext( err[ alert ] )
    else
        e:wikitext( alert )
    end
    if type( about ) == "string" then
        local e2 = mw.html.create( "code" )
                          :css( "white-space", "nowrap" )
                          :wikitext( " – ",
                                     mw.text.nowiki( about ) )
        e:wikitext( tostring( e2 ) )
    end
    if type( access ) == "string" then
        e:wikitext( string.format( " – [[%s]]",
                                   facility( access ) ) )
    end
    PGorg.scream = tostring( e )
    if type( err.cat ) == "string"   then
        PGorg.scream = string.format( "%s[[category:%s]]",
                                      PGorg.scream, err.cat )
    end
    return PGorg.scream
end -- fault()




local fetch = function ( access, allow )
    -- Retrieve JSON object
    -- Precondition:
    --     access  -- page identifier
    --     allow   -- lazy mode
    -- Postcondition:
    --     Returns JSON object, or not
    local s = facility( access )
    local lucky, json, r
    lucky, json = pcall( mw.loadJsonData, s )
    if type( json ) == "table" then
        r = json
    elseif not allow then
        fault( "0json", false, access )
    end
    return r
end -- fetch()



local fiat = function ( apply )
    -- Create external link
    -- Precondition:
    --     apply  -- table, with URL segments
    --               .site
    --               .a
    --               .w
    --               .n
    --               .live
    --               .locked
    --               .show
    -- Postcondition:
    --     Returns string, with external link
    local r    = apply.site
    local last, show
    if apply.show then
        show = apply.show
        if not show:match( "[.!?]$" )  and
           not show:match( "[.!?]''$" ) then
            last = true
        end
    else
        show = string.format( "?????%s?????", apply.a )
        if not PGorg.scream then
            fault( "unknown", show )
        end
    end
    if type( PGorg.config.a ) == "table"  and
       type( PGorg.config.a.slice ) == "string" then
        r = r .. PGorg.config.a.slice
    end
    r = r .. apply.a
    if apply.w then
       r = r .. "/"
       if type( PGorg.config.w ) == "table"  and
          type( PGorg.config.w.slice ) == "string" then
           r = r .. PGorg.config.w.slice
       end
       r = r .. apply.w
       if type( apply.n ) == "number" then
           local configN = PGorg.config.n
           r = r .. "/"
           if type( configN ) == "table" then
               if type( configN.slice ) == "string" then
                   r = r .. configN.slice
               end
               if not apply.locked then
                   local scheme = " #%d"
                   if type( configN.dPattern ) == "string" then
                       if configN.dPattern:find( "%d", 1, true ) then
                           scheme = configN.dPattern
                       elseif configN.dPattern == "-" then
                           scheme = false
                       end
                   end
                   if scheme then
                       show = show .. string.format( scheme, apply.n )
                   end
               end
           end
           r = r .. tostring( apply.n )
       end
    end
    r = r .. "/"
    if not apply.locked then
        show = mw.text.nowiki( mw.text.decode( show ) )
        if apply.live then
            show = string.format( "''%s''", show )
        end
    end
    if last then
        show = show .. "."
    end
    r = string.format( "[%s %s]", r, show )
    if PGorg.scream then
        r = string.format( "%s %s", r, PGorg.scream )
    end
    return r
end -- fiat()



local fill = function ( adapt )
    -- Initialize config
    -- Precondition:
    --     adapt  -- string, JSON environment, or not
    -- Postcondition:
    --     Returns string, with transclusion
    if adapt then
        PGorg.sources = adapt
    else
        PGorg.sources = string.format( "%s:%s",
                                       mw.site.namespaces.Template.name,
                                       PGorg.suite )
    end
    PGorg.config = fetch( "config" )
    return PGorg.config
end -- fill()



local find = function ( args )
    -- Find author code for author name query
    -- Precondition:
    --     args  -- table, with parameters
    --              .seek     -- string, with author query
    --              .supply   -- string, with template name, or not
    --              .sources  -- string, with JSON environment, or not
    --              .luxury   -- .seek is a pattern
    -- Postcondition:
    --     Returns string, with (temporary) transclusion
    local r
    if fill( args.sources ) then
        if args.seek then
            local json = fetch( "a" )
            if json then
                if type( json.hash ) == "table" then
                    local seek = args.seek
                    local s    = mw.ustring.char( 0x2019 )
                    local got, log
                    local n
                    seek, n = mw.ustring.gsub( seek, "'", s )
                    if args.luxury then
                        if seek:find( "%", 1, true ) then
                            seek, n = mw.ustring.gsub( seek,
                                                       "([^%%])%-",
                                                       "%1%%-" )
                        end
                    else
                        seek  = mw.ustring.lower( args.seek )
                    end
                    for k, v in pairs( json.hash ) do
                        s   = mw.ustring.lower( v )
                        log = false
                        if args.luxury then
                            if mw.ustring.find( s, seek ) then
                                log = true
                            end
                        else
                            if mw.ustring.find( s, seek, 1, true ) then
                                log = true
                            end
                        end
                        if log then
                            local e = { }
                            got = got  or  { }
                            table.insert( e, k )
                            table.insert( e, v )
                            table.insert( got, e )
                        end
                    end -- for k, v
                    if got then
                        local supply = args.supply or PGorg.suite
                        r = "----\n"
                        for i = 1, #got do
                            r = r .. factory( supply, got[ i ] )
                        end -- for i
                    end
                else
                    fault( "0hash", false, "a" )
                end
            end
        else
            fault( "0query" )
        end
    end
    if not r then
        if PGorg.scream then
            r = PGorg.scream
        else
            r = "???????"
        end
    end
    return r
end -- find()



local fix = function ( a, authors )
    -- Fix author code by legacy redirect
    -- Precondition:
    --     a        -- string, with author code
    --     authors  -- table, with current name hash map
    -- Postcondition:
    --     Returns table, with author code and link text, or not
    local last, r, shift, sign
    if a:match( "^[1-9]%d?%d?%d?$" ) then
        shift = "Num"
        sign  = tonumber( a )
        last  = true
    elseif a:match( "^%l+%-?%l*%d?$" )  and  a:len() <= 9 then
        shift = "Str"
        sign  = a
    end
    if shift then
        local json
        shift = "Aex" .. shift
        json  = fetch( shift, true )
        if json then
            if type( json.hash ) == "table" then
                local swap = json.hash[ sign ]
                if swap then
                    shift = authors[ swap ]
                    if shift then
                        r      = { }
                        r.a    = swap
                        r.show = shift
                        r.live = true
                    else
                        fault( "redir", swap )
                    end
                elseif last then
                    fault( "invalid", a )
                end
            else
                fault( "0hash", false, shift )
            end
        elseif last then
            fault( "invalid", a )
        end
    end
    return r
end -- fix()



local fulfil = function ( args )
    -- Execute main task
    -- Precondition:
    --     args  -- table, with parameters
    --              .sources  -- string, with JSON environment, or not
    --              .lazy
    --              .sA
    --              .sW
    --              .n
    --              .show
    -- Postcondition:
    --     Returns string, with transclusion
    local r
    if fill( args.sources ) then
        if type( PGorg.config.site ) ~= "string" then
            r = fault( "0site", false, "config" )
        elseif not args.sA then
            r = fault( "0a" )
        elseif not args.sA:match( "^[%l%-%d]+$" ) then
            r = fault( "invalid", args.sA )
        end
        if not r then
            local url = { }
            url.site = PGorg.config.site
            if args.sW then
                if args.sA:match( "^%l%l[%l%-]*%d?$" ) then
                    url.a = args.sA
                    url.w = args.sW
                    if type( PGorg.config.w ) == "table"  and
                       type( PGorg.config.w.show ) == "string" then
                        url.show = PGorg.config.w.show
                    else
                        url.show = args.sW
                    end
                    if args.n then
                        if args.n:match( "^[1-9]%d?%d?$" ) then
                            url.n = tonumber( args.n )
                        else
                            r = fault( "invalid", args.n )
                        end
                    end
                else
                    r = fault( "invalid", args.sW )
                end
            else
                local json = fetch( "a" )
                if json then
                    if type( json.hash ) == "table" then
                        local show = json.hash[ args.sA ]
                        if show then
                            url.a    = args.sA
                            url.show = show
                            url.live = true
                        else
                            local polyfill = fix( args.sA, json.hash )
                            if polyfill then
                                url.a    = polyfill.a
                                url.show = polyfill.show
                                url.live = polyfill.live
                            elseif PGorg.scream then
                                r = PGorg.scream
                            elseif args.lazy then
                                url.a = args.sA
                            else
                                fault( "invalid", args.sA )
                            end
                        end
                    else
                        r = fault( "0hash", false, "a" )
                    end
                else
                    r = PGorg.scream
                end
            end
            if not r then
                if args.show then
                    url.show   = args.show
                    url.locked = true
                elseif not url.show  and  args.lazy then
                    local WLink = foreignModule( "WLink",
                                                 true,
                                                 false,
                                                 PGorg.globals.WLink )
                    if type( WLink ) == "table" then
                        local lucky
                        lucky, WLink = pcall( WLink )
                        if type( WLink ) == "table" then
                            local fallback = WLink.getArticleBase
                            if type( fallback ) == "function" then
                                url.show = fallback()
                            end
                        end
                    end
                end
                r = fiat( url )
            end
        end
    else
        r = PGorg.scream
    end
    return r
end -- fulfil()



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 )
    -- Major template call
    local params = { }
    local parent = frame:getParent().args
    params.sources = frame.args.root
    params.sA      = parent.a
    params.sW      = parent.w
    params.n       = parent.n
    params.show    = parent.linktext
    for k, v in pairs( params ) do
        if v == "" then
            params[ k ] = false
        end
    end -- for k, v
    if frame.args.lazy == "1" then
        params.lazy = true
    end
    return fulfil( params )
end -- p.f

p.find = function ( frame )
    -- Template to find an author name
    local params = { }
    local parent = frame:getParent().args
    PGorg.frame = frame
    params.sources = frame.args.root
    params.supply  = frame.args.template
    if parent[ 1 ] then
        params.seek = mw.text.trim( parent[ 1 ] )
    end
    for k, v in pairs( params ) do
        if v == "" then
            params[ k ] = false
        end
    end -- for k, v
    if parent.pattern == "1" then
        params.luxury = true
    end
    return find( params )
end -- p.find

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

return p