Modul:Vorlage:arXiv
Version vom 3. Januar 2016, 18:14 Uhr von te>PerfektesChaos (Setup)
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