gemeinsam neue Wege der Erkenntnis gehen
Eine freie Initiative von Menschen bei anthrowiki.at anthrowiki.at, anthro.world anthro.world, biodyn.wiki biodyn.wiki und steiner.wiki steiner.wiki
mit online Lesekreisen, Übungsgruppen, Vorträgen ...
Wie Sie die Entwicklung von AnthroWiki durch Ihre Spende unterstützen können, erfahren Sie hier.

Use Google Translate for a raw translation of our pages into more than 100 languages.
Please note that some mistranslations can occur due to machine translation.
Alle Banner auf einen Klick
Bild: Robert Wróblewski
Der neue Glomer Katalog 2025/26 ist da!

Aktuelle Neuerscheinungen und alle lieferbaren Bücher anthroposophischer Verlage
Anthroposophie, Waldorf, Jugend & Kinderbücher, Gesundheit, Lebensphasen, Wissenschaften mit mehr als 7.500 Titeln aus über 80 Verlagen.


Modul:Vorlage:projekt-gutenberg.org

Aus AnthroWiki

Die Dokumentation für dieses Modul kann unter Modul:Vorlage:projekt-gutenberg.org/Doku erstellt werden

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