Modul:Vorlage:arXiv: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
te>PerfektesChaos (2016-05-14) |
K (13 Versionen importiert) |
||
(6 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
local Export = { suite = "arXiv", | local Export = { suite = "arXiv", | ||
− | serial = " | + | serial = "2019-05-16", |
+ | item = 0 } | ||
--[=[ | --[=[ | ||
Template:arXiv | Template:arXiv | ||
Zeile 9: | Zeile 10: | ||
local Config = { | 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 | ||
} | } | ||
Zeile 32: | Zeile 35: | ||
-- Localization of messages | -- Localization of messages | ||
-- apply -- string, with message key | -- apply -- string, with message key | ||
− | -- Returns message text; at least | + | -- Returns message text; at least English |
+ | local entry = Config[ apply ] | ||
local r | local r | ||
− | |||
if entry then | if entry then | ||
+ | -- TODO: page language | ||
r = entry[ mw.language.getContentLanguage():getCode() ] | r = entry[ mw.language.getContentLanguage():getCode() ] | ||
if not r then | if not r then | ||
Zeile 41: | Zeile 45: | ||
end | end | ||
else | else | ||
− | r = | + | r = tostring( mw.html.create( "span" ) |
− | + | :addClass( "error" ) | |
+ | :wikitext( string.format( "????.%s.????", | ||
+ | apply ) ) ) | ||
end | end | ||
return r | return r | ||
Zeile 65: | Zeile 71: | ||
− | local function fault( alert, about ) | + | |
+ | local function fault( alert, about, frame ) | ||
-- Format message with class="error" or similar | -- Format message with class="error" or similar | ||
-- alert -- string, with message key | -- alert -- string, with message key | ||
-- about -- string, with explanation | -- about -- string, with explanation | ||
+ | -- frame -- object | ||
-- Returns message with markup | -- Returns message with markup | ||
+ | local scope = Config.errClass | ||
local story = factory( alert ) | local story = factory( alert ) | ||
+ | local lucky, TemplUtl = pcall( require, "Module:TemplUtl" ) | ||
local r, scope, style | local r, scope, style | ||
+ | if type( TemplUtl ) == "table" then | ||
+ | TemplUtl = TemplUtl.TemplUtl() | ||
+ | end | ||
if Config.self then | if Config.self then | ||
story = string.format( "%s * %s", Config.self, story ) | story = string.format( "%s * %s", Config.self, story ) | ||
end | end | ||
− | if | + | if Config.errClasses then |
− | Config. | + | if scope then |
+ | scope = string.format( "%s %s", | ||
+ | scope, Config.errClasses ) | ||
+ | else | ||
+ | scope = Config.errClasses | ||
+ | end | ||
end | end | ||
− | if | + | if about then |
− | + | story = string.format( "%s %s", story, about ) | |
− | |||
− | |||
− | |||
− | |||
end | end | ||
− | if Config.errHide | + | if type( TemplUtl ) == "table" then |
− | + | r = TemplUtl.failure( story, | |
+ | not Config.errHide, | ||
+ | scope, | ||
+ | frame ) | ||
else | else | ||
− | + | r = tostring( mw.html.create( "span" ) | |
− | + | :addClass( scope ) | |
− | + | :addClass( "error" ) | |
− | + | :wikitext( story ) ) | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
if Config.errCat then | if Config.errCat then | ||
if Config.errNS then | if Config.errNS then | ||
− | |||
local st = type( Config.errNS ) | 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 | if st == "string" then | ||
local space = string.format( ".*%%s%d%%s.*", ns ) | local space = string.format( ".*%%s%d%%s.*", ns ) | ||
Zeile 127: | Zeile 142: | ||
− | Export.failsafe = function ( | + | Export.failsafe = function ( ask ) |
− | local since = | + | -- Retrieve versioning and check for compliance |
+ | -- Precondition: | ||
+ | -- ask -- string, with required version or "wikidata", or false | ||
+ | -- Postcondition: | ||
+ | -- Returns string with appropriate version, or false | ||
+ | local since = ask | ||
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 164: | Zeile 192: | ||
-- .legal true: fine | -- .legal true: fine | ||
local r = { arXiv = arXiv, | local r = { arXiv = arXiv, | ||
− | site = " | + | site = "https://arxiv.org/abs/", |
− | url = " | + | url = "https://arxiv.org/abs/" .. arXiv } |
local parts | local parts | ||
r.legal = arXiv:match( "^[-.0-9v]+$" ) | r.legal = arXiv:match( "^[-.0-9v]+$" ) | ||
Zeile 287: | Zeile 315: | ||
show = arXiv.signature | show = arXiv.signature | ||
end | end | ||
− | r = string.format( "[%s %s]", arXiv.url, show ) | + | r = string.format( "[%s %s]", arXiv.url, show ) |
+ | show = "arxiv" | ||
if Config.showArticle then | 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 | end | ||
+ | r = string.format( "%s:%s", show, r ) | ||
end | end | ||
if not arXiv.legal then | if not arXiv.legal then | ||
r = string.format( "%s %s ''%s''", | r = string.format( "%s %s ''%s''", | ||
− | r, | + | r, |
+ | fault( "errInvalid", false, frame ), | ||
+ | arXiv.arXiv ) | ||
end | end | ||
else | else | ||
Zeile 310: | Zeile 346: | ||
local p = { } | local p = { } | ||
− | p.main = function ( argsF, argsT ) | + | p.main = function ( argsF, argsT, frame ) |
-- Invocation | -- Invocation | ||
-- argsF -- table, with #invoke parameters, or false | -- argsF -- table, with #invoke parameters, or false | ||
-- argsT -- table, with template parameters | -- argsT -- table, with template parameters | ||
+ | -- frame -- object, or nil | ||
-- Returns appropriate string, or table if argsF.mode = false | -- Returns appropriate string, or table if argsF.mode = false | ||
local r | local r | ||
Zeile 349: | Zeile 386: | ||
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 365: | Zeile 402: | ||
r = string.format( "'<code>%s</code>' in Template:arXiv", | r = string.format( "'<code>%s</code>' in Template:arXiv", | ||
table.concat( unknown, " " ) ) | table.concat( unknown, " " ) ) | ||
− | r = fault( "errUnkown", r ) | + | r = fault( "errUnkown", r, frame ) |
elseif ( r[ 1 ] and r.archive ) or | elseif ( r[ 1 ] and r.archive ) or | ||
( r[ 2 ] and r.id ) then | ( r[ 2 ] and r.id ) then | ||
r = fault( "errConflict", | r = fault( "errConflict", | ||
− | "1= ./. archive= | 2= ./. id=" ) | + | "1= ./. archive= | 2= ./. id=", |
+ | frame ) | ||
else | else | ||
r[ 1 ] = ( r[ 1 ] or r.archive ) | r[ 1 ] = ( r[ 1 ] or r.archive ) | ||
Zeile 385: | Zeile 423: | ||
r[ 1 ] = r[ 2 ] | r[ 1 ] = r[ 2 ] | ||
else | else | ||
− | r = fault( "errMissing" ) | + | r = fault( "errMissing", false, frame ) |
end | end | ||
end | end | ||
Zeile 406: | Zeile 444: | ||
local lucky, r | local lucky, r | ||
Config.frame = frame | Config.frame = frame | ||
− | lucky, r = pcall( p.main, frame.args, frame:getParent().args ) | + | lucky, r = pcall( p.main, frame.args, frame:getParent().args, frame ) |
if not lucky then | if not lucky then | ||
− | r = | + | r = tostring( mw.html.create( "span" ) |
− | + | :addClass( "error" ) | |
+ | :wikitext( string.format( "%s * %s", | ||
+ | frame:getTitle(), | ||
+ | r ) ) ) | ||
end | end | ||
return r | return r | ||
Zeile 417: | Zeile 458: | ||
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() | ||
Aktuelle Version vom 6. September 2019, 12:28 Uhr
local Export = { suite = "arXiv",
serial = "2019-05-16", 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", r, Config.errCat ) end end return r
end -- fault()
Export.failsafe = function ( ask )
-- Retrieve versioning and check for compliance -- Precondition: -- ask -- string, with required version or "wikidata", or false -- Postcondition: -- Returns string with appropriate version, or false local since = ask 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( "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( "'%s
' 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