Modul:Vorlage:arXiv: Unterschied zwischen den Versionen
te>PerfektesChaos (2018-02-01) |
te>PerfektesChaos (2019-05-12) |
||
Zeile 1: | Zeile 1: | ||
local Export = { suite = "arXiv", | local Export = { suite = "arXiv", | ||
− | serial = " | + | serial = "2019-05-12", |
+ | item = 0 } | ||
--[=[ | --[=[ | ||
Template:arXiv | Template:arXiv | ||
Zeile 142: | Zeile 143: | ||
Export.failsafe = function ( attempt ) | Export.failsafe = function ( attempt ) | ||
− | local since = | + | -- Retrieve versioning and check for compliance |
+ | -- Precondition: | ||
+ | -- assert -- string, with required version or "wikidata", | ||
+ | -- or false | ||
+ | -- Postcondition: | ||
+ | -- Returns string with appropriate version, or false | ||
+ | local since = assert | ||
local r | local r | ||
− | if since then | + | if since == "wikidata" then |
− | since = mw. | + | local item = Export.item |
− | + | since = false | |
− | + | if type( item ) == "number" and item > 0 then | |
+ | local entity = mw.wikibase.getEntity( string.format( "Q%d", | ||
+ | item ) ) | ||
+ | if type( entity ) == "table" then | ||
+ | local vsn = entity:formatPropertyValues( "P348" ) | ||
+ | if type( vsn ) == "table" and | ||
+ | type( vsn.value ) == "string" and | ||
+ | vsn.value ~= "" then | ||
+ | r = vsn.value | ||
+ | end | ||
+ | end | ||
end | end | ||
end | end | ||
− | if | + | if not r then |
− | if since | + | if not since or since <= Export.serial then |
− | r = | + | r = Export.serial |
else | else | ||
− | r = | + | r = false |
end | end | ||
− | |||
− | |||
end | end | ||
return r | return r | ||
Zeile 372: | Zeile 387: | ||
r[ k ] = v | r[ k ] = v | ||
k = false | k = false | ||
− | elseif | + | elseif argsT.demo or faculty( argsT.NoCat ) then |
Config.errCat = false | Config.errCat = false | ||
Config.errHide = false | Config.errHide = false | ||
Zeile 444: | Zeile 459: | ||
p.failsafe = function ( frame ) | 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 Export.failsafe( since ) or "" | ||
end -- p.failsafe() | end -- p.failsafe() | ||
Version vom 12. Mai 2019, 19:08 Uhr
Die Dokumentation für dieses Modul kann unter Modul:Vorlage:arXiv/Doku erstellt werden
local Export = { suite = "arXiv",
serial = "2019-05-12",
item = 0 }
--[=[
Template:arXiv
and other issues dealing with arXiv ID.
]=]
local Config = {
self = Export.suite,
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" },
errModule = { en = "Library module missing:",
de = "Bibliotheksmodul 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 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, frame )
-- Format message with class="error" or similar
-- alert -- string, with message key
-- about -- string, with explanation
-- frame -- object
-- Returns message with markup
local scope = Config.errClass
local story = factory( alert )
local lucky, TemplUtl = pcall( require, "Module:TemplUtl" )
local r, scope, style
if type( TemplUtl ) == "table" then
TemplUtl = TemplUtl.TemplUtl()
end
if Config.self then
story = string.format( "%s * %s", Config.self, story )
end
if Config.errClasses then
if scope then
scope = string.format( "%s %s",
scope, Config.errClasses )
else
scope = Config.errClasses
end
end
if about then
story = string.format( "%s %s", story, about )
end
if type( TemplUtl ) == "table" then
r = TemplUtl.failure( story,
not Config.errHide,
scope,
frame )
else
r = tostring( mw.html.create( "span" )
:addClass( scope )
:addClass( "error" )
:wikitext( story ) )
end
if Config.errCat then
if Config.errNS then
local st = type( Config.errNS )
local ns
if not Config.title then
Config.title = mw.title.getCurrentTitle()
end
ns = Config.title.namespace
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()
Export.failsafe = function ( attempt )
-- Retrieve versioning and check for compliance
-- Precondition:
-- assert -- string, with required version or "wikidata",
-- or false
-- Postcondition:
-- Returns string with appropriate version, or false
local since = assert
local r
if since == "wikidata" then
local item = Export.item
since = false
if type( item ) == "number" and item > 0 then
local entity = mw.wikibase.getEntity( string.format( "Q%d",
item ) )
if type( entity ) == "table" then
local vsn = entity:formatPropertyValues( "P348" )
if type( vsn ) == "table" and
type( vsn.value ) == "string" and
vsn.value ~= "" then
r = vsn.value
end
end
end
end
if not r then
if not since or since <= Export.serial then
r = Export.serial
else
r = false
end
end
return r
end -- Export.failsafe()
Export.fair = function ( arXiv )
-- Analyze code, create URL
-- arXiv -- string, with arXiv ID
-- Returns table
-- .url
-- .site URL of repository
-- .scope thematic archive until 2007
-- .since yymm
-- .serial n
-- .sequence version number
-- .signature identifier within scope
-- .legacy true: before 2007-04-01
-- .legal true: fine
local r = { arXiv = arXiv,
site = "https://arxiv.org/abs/",
url = "https://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
parts = mw.text.split( r.serial, "v", true )
if #parts > 1 then
r.serial = parts[ 1 ]
r.sequence = parts[ 2 ]
r.legal = ( #parts == 2 and
r.sequence:match( "^[1-9]%d*$" ) )
end
if r.legal then
local split = "^([0129]%d)([01]%d)[.]?(%d+)$"
local j, m, n = r.serial:match( split )
r.legal = n
if r.legal then
r.since = j .. m
r.serial = n
m = tonumber( m )
r.legal = ( m <= 12 )
if r.legal then
j = tonumber( j )
if j < 90 then
r.legal = ( j <= tonumber( os.date( "%y" ) ) )
end
if r.legal then
local k = 5
local scheme
r.legacy = ( j > 90 or
j < 7 or
( j == 7 and m < 4 ) )
if r.legacy then
k = 3
elseif j < 15 then
k = 4
end
n = tonumber( n )
scheme = string.format( "%%0%dd", k )
r.serial = string.format( scheme, n )
r.legal = ( r.serial:len() == k )
if r.legacy and not r.scope then
r.legal = false
end
end
end
end
end
end
if r.legal then
r.signature = r.since
if not r.legacy then
r.signature = r.signature .. "."
end
r.signature = r.signature .. r.serial
if r.sequence then
r.signature = string.format( "%sv%s",
r.signature, r.sequence )
end
if r.legacy then
r.signature = string.format( "%s/%s", r.scope, r.signature )
end
r.url = r.signature
else
r.signature = arXiv
r.url = r.signature
end
r.url = r.site .. r.url
return r
end -- Export.fair()
Export.features = function ( assign )
-- Configure appearance
-- assign -- table, with components
if type( assign ) == "table" then
for k, v in pairs( assign ) do
Config[ k ] = v
end -- for k, v
end
end -- Export.features()
Export.format = function ( 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
if arXiv.scope and not arXiv.legacy then
show = string.format( "%s [%s]",
arXiv.signature, arXiv.scope )
else
show = arXiv.signature
end
r = string.format( "[%s %s]", arXiv.url, show )
show = "arxiv"
if Config.showArticle then
local title = mw.title.new( Config.showArticle )
if not Config.title then
Config.title = mw.title.getCurrentTitle()
end
if not mw.title.equals( title, Config.title ) then
show = string.format( "[[%s|arxiv]]",
Config.showArticle )
end
end
r = string.format( "%s:%s", show, r )
end
if not arXiv.legal then
r = string.format( "%s %s ''%s''",
r,
fault( "errInvalid", false, frame ),
arXiv.arXiv )
end
else
r = "Module:Template:arXiv::format() no table arg"
end
return r
end -- Export.format()
-- Export
local p = { }
p.main = function ( argsF, argsT, frame )
-- Invocation
-- argsF -- table, with #invoke parameters, or false
-- argsT -- table, with template parameters
-- frame -- object, or nil
-- 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 argsT.demo or faculty( argsT.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, frame )
elseif ( r[ 1 ] and r.archive ) or
( r[ 2 ] and r.id ) then
r = fault( "errConflict",
"1= ./. archive= | 2= ./. id=",
frame )
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", false, frame )
end
end
end
else
r = false
end
if type( r ) == "table" then
r = Export.fair( r[ 1 ] )
if Config.mode then
r = Export.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, frame )
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 ( 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 Export.failsafe( since ) or ""
end -- p.failsafe()
p.arXiv = function ()
return Export
end -- p.arXiv()
return p