Mòideal:Teamplaid:Handle
Documentation for this module may be created at Mòideal:Teamplaid:Handle/doc
local Handle = { suite = "Handle",
serial = "2019-07-14",
item = 19644424 }
--[=[
Template:Handle {{DOI}} {{HDL}}
require: URIutil
]=]
local Failsafe = Handle
local Config = {
parProblem = "problem",
scheme = false,
doi = { showArticle = "Digital Object Identifier",
showName = "DOI",
stemURL = "//doi.org/" },
hdl = { showArticle = false,
showName = "Handle",
stemURL = "//hdl.handle.net/" },
errCat = false,
errClass = "error_Handle",
errClasses = false,
errHide = false,
errNS = false,
errDate = { en = "Bad ISO year (month)",
de = "ISO-Jahr (ggf. Monat) fehlerhaft" },
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)" }
}
Config.fault = function ( alert )
-- Format error message by class=error
-- Parameter:
-- alert -- string, error message
-- Returns:
-- string, HTML span
return tostring( mw.html.create( "span" )
:addClass( "error" )
:wikitext( alert ) )
end -- Config.fault()
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 = Config.fault( 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 failed( 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 lucky, TemplUtl = pcall( require, "Module:TemplUtl" )
local scope = Config.errClass
local story = factory( alert )
local r
if add then
story = string.format( "%s %s", story, add )
end
if Config.errClasses then
scope = string.format( "%s %s", scope, Config.errClasses )
end
if type( TemplUtl ) == "table" then
TemplUtl = TemplUtl.TemplUtl()
end
if type( TemplUtl ) == "table" and
type( TemplUtl.failure ) == "function" then
r = TemplUtl.failure( story,
not Config.errHide,
scope,
Config.frame )
else
-- LEGACY and global wiki mode
local element = mw.html.create( "span" )
:addClass( scope )
if not Config.frame then
Config.frame = mw.getCurrentFrame()
end
if Config.frame:preprocess( "{{REVISIONID}}" ) == "" then
Config.errCat = false
Config.errHide = false
element:addClass( "error" )
end
if Config.errHide then
element:css( "display", "none" )
end
r = tostring( element:wikitext( story ) )
end
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 -- failed()
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
local e = mw.html.create( "code" )
e:wikitext( table.concat( unknown, " " ) )
r = string.format( "'%s' in Template:%s",
tostring( e ), Config.scheme )
r = failed( "errUnkown", r )
else
local lucky, URIutil = pcall( require, "Module:URIutil" )
if lucky then
if type( URIutil ) == "table" then
URIutil = URIutil.URIutil()
else
URIutil = "library URIutil invalid"
end
end
if type( URIutil ) ~= "table" then
error( URIutil, 0 )
end
if URIutil[ "is" .. Config.showName ]( access ) then
local suffer = args[ Config.parProblem ]
r = URIutil[ "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 suffer and suffer ~= "" then
local scan = "^(2[01]%d%d)(%-?[01]?%d?)$"
local s, sm = suffer:match( scan )
local e
if sm and sm ~= "" then
s = sm:match( "^%-([01]%d)$" )
if s then
local m = tonumber( s )
if m < 1 or m > 12 then
s = false
end
end
end
if s then
e = mw.html.create( "small" )
:wikitext( factory( "problemNote" ) )
r = string.format( "%s %s", r, tostring( e ) )
else
e = mw.html.create( "code" )
:wikitext( Config.parProblem .. "=" )
r = failed( "errDate", tostring( e ) )
end
end
else
r = failed( "errInvalid",
string.format( "%s=%s",
Config.showName,
mw.text.nowiki( access ) ) )
end
end
return r
end -- fiat()
Handle.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 = failed( "errScheme", argsF.scheme )
end
else
r = ""
end
return r
end -- Handle.main()
Failsafe.failsafe = function ( atleast )
-- Retrieve versioning and check for compliance
-- Precondition:
-- atleast -- string, with required version or "wikidata" or "~"
-- or false
-- Postcondition:
-- Returns string -- with queried version, also if problem
-- false -- if appropriate
local last = ( atleast == "~" )
local since = atleast
local r
if last or since == "wikidata" then
local item = Failsafe.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
if last and vsn.value == Failsafe.serial then
r = false
else
r = vsn.value
end
end
end
end
end
if type( r ) == "nil" then
if not since or since <= Failsafe.serial then
r = Failsafe.serial
else
r = false
end
end
return r
end -- Failsafe.failsafe()
-- Export
local p = { }
p.f = function ( frame )
local lucky, r
Config.frame = frame
lucky, r = pcall( Handle.main, frame.args, frame:getParent().args )
if not lucky then
r = Config.fault( 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 Failsafe.failsafe( since ) or ""
end -- p.failsafe()
p.Handle = function ()
-- Module interface
return Handle
end -- p.Handle()
return p