Modul:Vorlage:arXiv

Aus FreeWiki
Version vom 3. Januar 2016, 18:14 Uhr von te>PerfektesChaos (Setup)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

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

local Serial = "2016-01-03"
--[=[
Template:arXiv
and other issues dealing with arXiv ID.
]=]



local Config = {
   errCat      = false,
   errClass    = "error_arXiv",
   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" },
   errUnkown   = { en = "Unkown parameter:",
                   de = "Parameter unbekannt:" },
   mode        = 0,
   showArticle = false
}



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 fair( arXiv )
    -- Analyze code
    --     arXiv  -- string, with message key
    -- Returns table
    --     .url
    --     .scope    thematic archive until 2007
    --     .serial   digits
    --     .legal    true: fine
    local r = { arXiv = arXiv,
                url   = "http://arxiv.org/abs/" .. arXiv }
    local parts
    r.legal = arXiv:match( "^[-.0-9v]+$" )
    if r.legal then
        r.serial = arXiv
    else
        parts = mw.text.split( arXiv, "/", true )
        if #parts == 2  and  parts[ 2 ] ~= "" then
            r.scope  = parts[ 1 ]
            r.serial = parts[ 2 ]
            parts = mw.text.split( r.scope, ".", true )
            if #parts <= 2 then
                local p = mw.text.split( parts[ 1 ], "-", true )
                if #p <= 2 then
                    r.legal = p[ 1 ]:match( "^%l+$" )
                    if r.legal  and  #p == 2 then
                        r.legal = p[ 2 ]:match( "^%l+$" )
                    end
                    if r.legal  and  #parts == 2 then
                        r.legal = parts[ 2 ]:match( "^%l+$" )   or
                                  parts[ 2 ]:match( "^%u%u$" )
                    end
                end
            end
        end
    end
    if r.legal and r.serial then
        local sub = r.serial
        parts = mw.text.split( r.serial, "v", true )
        if #parts > 1 then
            r.legal = ( #parts == 2   and
                        parts[ 2 ]:match( "^[1-9]%d*$" ) )
            sub     = parts[ 1 ]
        end
        if r.legal then
            if r.scope then
                r.legal = sub:match( "^%d+$" )
            else
                local y, m = sub:match( "^([0-2]%d)([01]%d)%.%d+$" )
                r.legal = ( y and
                            tonumber( y ) >= 7   and
                            tonumber( m ) <= 12 )
            end
        end
    end
    return r
end -- fair()



local function fault( alert )
    -- Format message with class="error" or similar
    --     alert  -- string, with message key
    -- Returns message with markup
    local story = factory( alert )
    local r, scope, style
    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 format( arXiv )
    -- Format template request
    --     arXiv  -- table, with result of analysis
    -- May be influenced by Config.mode (0: standard appearance).
    -- Returns appropriate string
    local r
    if type( arXiv ) == "table" then
        local show
        if Config.mode == 0  or  true then
            show = arXiv.serial
            if arXiv.scope then
                show = string.format( "%s/%s", arXiv.scope, show )
            end
            r = string.format( "[%s %s]", arXiv.url, show )
            if Config.showArticle then
                r = string.format( "[[%s|arxiv]]:%s",
                                   Config.showArticle, r )
            else
                r = string.format( "arxiv:%s", r )
            end
        end
        if not arXiv.legal then
            r = string.format( "%s %s ''%s''",
                               r,  fault( "errInvalid" ),  arXiv.arXiv )
        end
    else
        r = "Module:Template:arXiv::format() no table arg"
    end
    return r
end -- format()



-- Export
local p = { }

p.main = function ( argsF, argsT )
    -- Invocation
    --     argsF  -- table, with #invoke parameters, or false
    --     argsT  -- table, with template parameters
    -- Returns appropriate string, or table if argsF.mode = false
    local r
    if argsF then
        Config.errCat     = argsF.errCat
        Config.errClasses = argsF.errClasses
        Config.errHide    = faculty( argsF.errHide )
        Config.errNS      = argsF.errNS
        if argsF.mode ~= nil then
            Config.mode = argsF.mode
        end
        if argsF.showArticle ~= nil then
            if argsF.showArticle == "" then
                Config.showArticle = false
            else
                Config.showArticle = argsF.showArticle
            end
        end
    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 <= 2 ) then
                    r[ k ] = mw.text.trim( v )
                    k = false
                else
                    k = tostring( k )
                end
            elseif s == "string" then
                if k == "id"  or
                   k == "archive" then
                    r[ k ] = v
                    k = false
                elseif args.demo  or  faculty( args.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:arXiv",
                               table.concat( unknown, " " ) )
            r = fault( "errUnkown", r )
        elseif ( r[ 1 ] and r.archive )  or
               ( r[ 2 ] and r.id )   then
            r = fault( "errConflict", r )
        else
            r[ 1 ] = ( r[ 1 ] or r.archive )
            r[ 2 ] = ( r[ 2 ] or r.id )
            if r[ 1 ] == "" then
                r[ 1 ] = false
            end
            if r[ 2 ] == "" then
                r[ 2 ] = false
            end
            if r[ 1 ] and r[ 2 ] then
                r[ 1 ] = string.format( "%s/%s", r[ 1 ], r[ 2 ] )
            elseif not r[ 1 ] then
                if r[ 2 ] then
                    r[ 1 ] = r[ 2 ]
                else
                    r = fault( "errMissing", r )
                end
            end
        end
    else
        r = false
    end
    if type( r ) == "table" then
        r = fair( r[ 1 ] )
        if Config.mode then
            r = format( r )
        end
    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()



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



p.format = function ( arXiv )
    return format( arXiv )
end -- p.format()

return p