Modul:Vorlage:Handle

Aus FreeWiki
Version vom 24. November 2016, 14:47 Uhr von te>PerfektesChaos (2016-11-24)
Wechseln zu: Navigation, Suche

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

local Serial = "2016-11-24"
--[=[
Template:Handle   {{DOI}} {{HDL}}
require: URIutil
]=]



local Config = {
   parProblem  = "problem",
   scheme      = false,
   doi         = { showArticle = "Digital Object Identifier",
                   showName    = "DOI",
                   stemURL     = "https://dx.doi.org/" },
   hdl         = { showArticle = false,
                   showName    = "Handle",
                   stemURL     = "https://hdl.handle.net/" },
   errCat      = false,
   errClass    = "error_Handle",
   errClasses  = false,
   errHide     = false,
   errNS       = false,
   errInvalid  = { en = "Invalid:",
                   de = "Ungültig:" },
   errScheme   = { en = "Bad #invoke|scheme=" },
   errUnkown   = { en = "Unkown parameter:",
                   de = "Parameter unbekannt:" },
   problemNote = { en = "(currently unavailable)",
                   de = "(zurzeit nicht erreichbar)" }
}



local function factory( apply )
    -- Localization of messages
    --     apply  -- string, with message key
    -- Returns message text; at least english
    local r
    entry = Config[ apply ]
    if entry then
        r = entry[ mw.language.getContentLanguage():getCode() ]
        if not r then
            r = entry.en
        end
    else
        r = string.format( "<span class=\"error\">????.%s.????</span>",
                           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, add )
    -- Format message with class="error" or similar
    --     alert  -- string, with message key
    --     add    -- string, with additional information, or nil
    -- Returns message with markup
    local story = factory( alert )
    local r, scope, style
    if add then
        story = string.format( "%s %s", story, add )
    end
    if not Config.frame then
        Config.frame = mw.getCurrentFrame()
    end
    if Config.frame:preprocess( "{{REVISIONID}}" ) == "" then
        Config.errCat  = false
        Config.errHide = false
        scope          = string.format( "%s error", Config.errClass )
    else
        scope = Config.errClass
    end
    if Config.errHide then
        style = "style='display:none'"
    else
        style = ""
    end
    if Config.errClasses then
        scope = string.format( "%s %s",
                               scope, Config.errClasses )
    end
    r = string.format( "<span class=\"%s\" %s>%s</span>",
                       scope, style, story )
    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 fiat( access, args )
    -- Format template request
    --     access  -- string, with trimmed ID
    --     args    -- table, with template parameters
    -- Returns appropriate string
    local r, unknown
    for k, v in pairs( args ) do
        if k ~= 1  and
           k ~= "demo"  and
           k ~= "NoCat"  and
           k ~= Config.parProblem then
            if not unknown then
                unknown = { }
            end
            table.insert( unknown, k )
        end
    end -- for k, v
    if args.demo  or  faculty( args.NoCat ) then
        Config.errCat  = false
        Config.errHide = false
    end
    if unknown then
        r = string.format( "'<code>%s</code>' in Template:%s",
                           table.concat( unknown, " " ),
                           Config.scheme )
        r = fault( "errUnkown", r )
    else
        local lucky, util = pcall( require, "Module:URIutil" );
        if lucky then
            if type( util ) == "table" then
                util = util.URIutil();
            else
                util = "library URIutil invalid";
            end
        end
        if type( util ) ~= "table" then
            error( util, 0 );
        end
        if util[ "is" .. Config.showName ]( access )  then
            r = util[ "link" .. Config.showName ]( access )
            if Config.showArticle then
                r = string.format( "[[%s|%s]]:%s",
                                   Config.showArticle, Config.scheme, r )
            else
                r = string.format( "%s:%s", Config.scheme, r )
            end
            if args[ Config.parProblem ] then
                r = string.format( "%s <small>%s</small>",
                                   r,  factory( "problemNote" ) )
            end
        else
            r = fault( "errInvalid",
                        string.format( "%s=%s",
                                       Config.showName,
                                       mw.text.nowiki( access ) ) )
        end
    end
    return r
end -- fiat()



-- Export
local p = { }

p.main = function ( argsF, argsT )
    -- Invocation; decide between first and secondary processing
    --     argsF  -- table, with #invoke parameters
    --     argsT  -- table, with template parameters
    -- Returns appropriate string
    local r = argsT[ 1 ]
    if r then
        local cnf = Config[ argsF.scheme ]
        if cnf then
            r = mw.text.trim( r )
            if r == ""  or
               r:find( cnf.stemURL, 1, true )  or
               r:find( Config.errClass, 1, true ) then
                argsF = false
            elseif r:find( "[[", 1, true ) then
                local seek = "%[%[%s*" .. argsF.scheme .. ":"
                if r:lower():find( seek ) then
                    argsF = false
                end
            end
            if argsF then
                Config.errCat     = argsF.errCat
                Config.errClasses = argsF.errClasses
                Config.errHide    = faculty( argsF.errHide )
                Config.errNS      = argsF.errNS
                if argsF.parProblem then
                    Config.parProblem = argsF.parProblem
                end
                Config.scheme = argsF.scheme
                if argsF.showArticle then
                    if argsF.showArticle == "" then
                        Config.showArticle = false
                    else
                        Config.showArticle = argsF.showArticle
                    end
                else
                    Config.showArticle = cnf.showArticle
                end
                Config.showName = cnf.showName
                r               = fiat( r, argsT )
            end
        else
            Config.errHide  = false
            Config.errClass = "error"
            r = fault( "errScheme", argsF.scheme )
        end
    else
        r = ""
    end
    return r
end -- p.main()



p.f = function ( frame )
    local lucky, r
    Config.frame = frame
    lucky, r = pcall( p.main, frame.args, frame:getParent().args )
    if not lucky then
        r = string.format( "<span class=\"error\">%s * %s</span>",
                           frame:getTitle(),
                           r )
    end
    return r
end -- p.f()



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

return p