Modul:Vorlage:URN

Aus AnthroWiki

Die Dokumentation für dieses Modul kann unter Modul:Vorlage:URN/Doku erstellt werden

local Serial = "2018-02-15"
--[=[
Template:URN
]=]



local Config = {
    self        = "URN",
    errCat      = false,
    errClass    = "error_URN",
    errClasses  = false,
    errHide     = false,
    errNS       = false,
    errConflict = { en = "Conflict in multiple parameters",
                    de = "Konflikt durch überbestimmte Parameter" },
    errInvalid  = { en = "Invalid:",
                    de = "Ungültig:" },
    errMissing  = { en = "Missing ID",
                    de = "ID fehlt" },
    errModule   = { en = "Library module missing:",
                    de = "Bibliotheksmodul fehlt:" },
    errUnkown   = { en = "Unkown parameter:",
                    de = "Parameter unbekannt:" }
}



local function factory( apply )
    -- Localization of messages
    --     apply  -- string, with message key
    -- Returns message text; at least English
    local entry = Config[ apply ]
    local r
    if entry then
        -- TODO: page language
        r = entry[ mw.language.getContentLanguage():getCode() ]
        if not r then
            r = entry.en
        end
    else
        r = tostring( mw.html.create( "span" )
                             :addClass( "error" )
                             :wikitext( string.format( "????.%s.????",
                                                       apply ) ) )
    end
    return r
end -- factory()



local function faculty( adjust )
    -- Test template arg for boolean
    --     adjust  -- string or nil
    -- Returns boolean
    local r = false
    if adjust then
        r = mw.text.trim( adjust )
        if r ~= ""  and  r ~= "0" then
            r = true
        end
    end
    return r
end -- faculty()



local function fault( alert, about )
    -- Format message with class="error" or similar
    --     alert  -- string, with message key
    --     about  -- string, with explanation
    -- Returns message with markup
    local scope = Config.errClass
    local story = factory( alert )
    local lucky, TemplUtl = pcall( require, "Module:TemplUtl" )
    local r
    if type( TemplUtl ) == "table" then
        TemplUtl = TemplUtl.TemplUtl()
    end
    if Config.self then
        story = string.format( "%s * %s", Config.self, story )
    end
    if about then
        story = string.format( "%s %s", story, about )
    end
    if Config.errClasses then
        if scope then
            scope = string.format( "%s %s",
                                   scope, Config.errClasses )
        else
            scope = Config.errClasses
        end
    end
    if type( TemplUtl ) == "table" then
        r = TemplUtl.failure( story,
                              not Config.errHide,
                              scope,
                              Config.frame )
    else
        r = tostring(  mw.html.create( "span" )
                              :addClass( scope )
                              :addClass( "error" )
                              :wikitext( story ) )
    end
    if Config.errCat then
        if Config.errNS then
            local ns = mw.title.getCurrentTitle().namespace
            local st = type( Config.errNS )
            if st == "string" then
                local space  = string.format( ".*%%s%d%%s.*", ns )
                local spaces = string.format( " %s ", Config.errNS )
                if spaces:match( space ) then
                    Config.errNS = false
                end
            elseif st == "table" then
                for i = 1, #Config.errNS do
                    if Config.errNS[ i ] == ns then
                        Config.errNS = false
                        break    -- for i
                    end
                end -- for i
            end
        end
        if not Config.errNS then
            r = string.format( "%s[[Category:%s]]", r, Config.errCat )
        end
    end
    return r
end -- fault()



local function format( access )
    -- Analyze code, create URL
    --     access  -- table
    --                .id        -- string, with URN ID component
    --                .resolver  -- string, or false
    --                .fragment  -- string, or false
    -- Returns string, perhaps with error message
    local lucky, r = pcall( require, "Module:URIutil" )
    if type( r ) == "table" then
        local URIutil = r.URIutil()
        r = URIutil.uriURN( "urn:" .. access.id,
                            false,
                            access.resolver,
                            false,
                            access.fragment )
        if not r:find( "//", 1, true ) then
            r = fault( "errInvalid", access.id )
        end
    else
        r = fault( "errModule", "URIutil" )
    end
    return r
end -- format()



local function main( argsF, argsT )
    -- Invocation
    --     argsF  -- table, with #invoke parameters, or false
    --     argsT  -- table, with template parameters
    -- Returns appropriate string
    local r
    if argsF then
        Config.errCat     = argsF.errCat
        Config.errClasses = argsF.errClasses
        Config.errHide    = faculty( argsF.errHide )
        Config.errNS      = argsF.errNS
    end
    if type( argsT ) == "table" then
        local unknown
        r = { }
        for k, v in pairs( argsT ) do
            s = type( k )
            if s == "number" then
                if ( k <= 3 ) then
                    r[ k ] = mw.text.trim( v )
                    if r[ k ] == "" then
                        r[ k ] = false
                    end
                    k = false
                else
                    k = tostring( k )
                end
            elseif s == "string" then
                if k == "resolver"  or  k == "fragment" then
                    r[ k ] = v
                    k = false
                elseif argsF.demo  or  faculty( argsF.NoCat ) then
                    Config.errCat  = false
                    Config.errHide = false
                    k = false
                end
            end
            if k then
                if not unknown then
                    unknown = { }
                end
                table.insert( unknown, k )
            end
        end -- for k, v
        if unknown then
            r = string.format( "'<code>%s</code>' in Template:URN",
                               table.concat( unknown, " " ) )
            r = fault( "errUnkown", r )
        elseif r[ 3 ] and r.resolver then
            r = fault( "errConflict", "3= ./. resolver=" )
        else
            if r[ 1 ] then
                r.id = r[ 1 ]
                if r[ 2 ] then
                    r.id = string.format( "%s:%s", r.id, r[ 2 ] )
                end
                if r[ 3 ] then
                    r.resolver = r[ 3 ]
                end
                if r.resolver == "" then
                    r.resolver = false
                end
                r = format( r, r.fragment )
            else
                r = fault( "errMissing" )
            end
        end
    end
    return r
end -- main()



-- Export
local p = { }

p.f = function ( frame )
    local lucky, r
    Config.frame = frame
    lucky, r = pcall( main, frame.args, frame:getParent().args )
    if not lucky then
        r = tostring( mw.html.create( "span" )
                             :addClass( "error" )
                             :wikitext( string.format( "%s * %s",
                                                       frame:getTitle(),
                                                       r ) ) )
    end
    return r
end -- p.f()

p.failsafe = function ()
    return Serial
end -- p.failsafe()

p.test = function ( argsF, argsT )
    lucky, r = pcall( main, argsF, argsT )
    return r
end -- p.test()

return p