Modul:TemplatePar: Unterschied zwischen den Versionen
te>PerfektesChaos (update) |
te>Leyo K (Schützte „Modul:TemplatePar“: Häufig eingebundenes Modul ([Bearbeiten=Nur angemeldete, nicht neue Benutzer] (unbeschränkt) [Verschieben=Nur Administratoren] (unbeschränkt))) |
(kein Unterschied)
|
Version vom 28. April 2013, 22:25 Uhr
Die Dokumentation für dieses Modul kann unter Modul:TemplatePar/Doku erstellt werden
--[=[ TemplatePar 2013-04-28
Template parameter utility
* check
* count
]=]
-- Module globals
local invokeFrame
local l10nDef = {}
l10nDef[ "en" ] = {
dupOpt = "TemplatePar#invoke: repeated optional parameter",
empty = "Error in template: undefined value for mandatory",
undefined = "Error in template: mandatory parameter missing",
unknown = "Error in template: unknown parameter name"
}
l10nDef[ "de" ] = {
dupOpt = "TemplatePar#invoke: Wiederholter Optionsparameter",
empty = "Fehler bei Vorlage: Pflichtparameter ohne Wert",
undefined = "Fehler bei Vorlage: fehlender Pflichtparameter",
unknown = "Fehler bei Vorlage: Unbekannter Parametername"
}
local function failed( spec, suspect )
-- Submit error message
-- Precondition:
-- spec -- string; message ID
-- suspect -- string or nil; additional information
-- Postcondition:
-- Return string
-- Uses:
-- > invokeFrame
-- > l10nDef
local r
local show = invokeFrame.args[ "template" ]
local l10n = mw.language.getContentLanguage()
l10n = l10nDef[ l10n:getCode() ]
if not l10n then
l10n = l10nDef[ "en" ]
end
r = l10n[ spec ]
if show then
r = r .. " (" .. show .. ")"
end
if suspect then
r = r .. " " .. suspect
end
return r
end -- failed()
local function fault( store, key )
-- Add key to collection string and insert separator
-- Precondition:
-- store -- string or nil or false; collection string
-- key -- string or number; to be appended
-- Postcondition:
-- Return string; extended
local r
local s
if type( key ) == "number" then
s = tostring( key )
else
s = key
end
if store then
r = store .. "; " .. s
else
r = s
end
return r
end -- fault()
local function fed( haystack, needle )
-- Find needle in haystack map
-- Precondition:
-- haystack -- table; map of key values
-- needle -- any; identifier
-- Postcondition:
-- Return true iff found
local k, v
for k, v in pairs( haystack ) do
if k == needle then
return true
end
end -- for k, v
return false
end -- fed()
local function fetch()
-- Return regular table with template parameters
-- Postcondition:
-- Return table; whitespace-only values as false
-- Uses:
-- > invokeFrame
-- frame:getParent()
local k, v
local r = { }
local t = invokeFrame:getParent()
local o = t.args
for k, v in pairs( o ) do
if type( v ) == "string" then
if v:match( "^%s*$" ) then
v = false
end
else
v = false
end
if type( k ) == "number" then
k = tostring( k )
end
r[ k ] = v
end -- for k, v
return r
end -- fetch()
local function figure()
-- Return number of template parameters
-- Postcondition:
-- Return number, starting at 0
-- Uses:
-- > invokeFrame
-- frame:getParent()
local k, v
local r = 0
local t = invokeFrame:getParent()
local o = t.args
for k, v in pairs( o ) do
r = r + 1
end -- for k, v
return r
end -- figure()
local function fill( specified )
-- Split requirement string separated by '='
-- Precondition:
-- specified -- string or nil; requested parameter set
-- Postcondition:
-- Return sequence table
local r
if specified then
local i, s
r = mw.text.split( specified, "%s*=%s*" )
for i = #r, 1, -1 do
s = r[ i ]
if #s == 0 then
table.remove( r, i )
end
end -- for i, -1
else
r = { }
end
return r
end -- fill()
local function finder( haystack, needle )
-- Find needle in haystack sequence
-- Precondition:
-- haystack -- table; sequence of key names
-- needle -- any; key name
-- Postcondition:
-- Return true iff found
local i
for i = 1, #haystack do
if haystack[ i ] == needle then
return true
end
end -- for i
return false
end -- finder()
local function fit( base, extend )
-- Merge two tables, create new sequence if both not empty
-- Precondition:
-- base -- table; sequence kept unchanged
-- extend -- table; sequence to be appended
-- Postcondition:
-- Return merged table, or message string if duplicated entries
-- Uses:
-- finder()
-- fault()
local r
if #base == 0 then
if #extend == 0 then
r = { }
else
r = extend
end
else
if #extend == 0 then
r = base
else
local i, s
r = false
for i = 1, #extend do
s = extend[ i ]
if finder( base, s ) then
r = fault( r, s )
end
end -- for i
if not r then
r = { }
for i = 1, #base do
table.insert( r, base[ i ] )
end -- for i
for i = 1, #extend do
table.insert( r, extend[ i ] )
end -- for i
end
end
end
return r
end -- fit()
local function fix( valid, duty )
-- Perform parameter analysis
-- Precondition:
-- valid -- table; unique sequence of known parameters
-- duty -- table; sequence of mandatory parameters
-- Postcondition:
-- Return string as configured; empty if valid
-- Uses:
-- > invokeFrame
-- fetch()
-- finder()
-- fault()
-- failed()
-- fed()
local k, v
local r = false
local got = fetch()
for k, v in pairs( got ) do
if not finder( valid, k ) then
r = fault( r, k )
end
end -- for k, v
if r then
r = failed( "unknown", r )
else -- all names valid
-- avoid confusing consecutive error messages
local i, s
for i = 1, #duty do
s = duty[ i ]
if not fed( got, s ) then
r = fault( r, s )
end
end -- for i
if r then
r = failed( "undefined", r )
else
for i = 1, #duty do
s = duty[ i ]
if not got[ s ] then
r = fault( r, s )
end
end -- for i
if r then
r = failed( "empty", r )
end
end
end
if r then
if invokeFrame.args[ "noError" ] then
r = ""
else
r = "<span class='error'>" .. r .. "</span>"
end
k = invokeFrame.args[ "cat" ]
if k then
if k:find( "@@@" ) then
v = invokeFrame.args[ "template" ]
if v then
k = k:gsub( "@@@", v )
end
end
r = r .. "[[Category:" .. k .. "]]"
end
else
r = ""
end
return r
end -- fix()
local function force()
-- Initialize parameter analysis
-- Postcondition:
-- Return string as configured; empty if valid
-- Uses:
-- > invokeFrame
-- fill()
-- fit()
-- failed()
-- fix()
local duty = fill( invokeFrame.args[ 1 ] )
local options = fill( invokeFrame.args[ 2 ] )
local r = fit( duty, options )
if type( r ) == "string" then
r = failed( "dupOpt", r )
else
r = fix( r, duty )
end
return r
end -- force()
-- Provide template access
local p = {}
function p.check( frame )
-- Check validity of template parameters
-- Precondition:
-- frame -- object; #invoke environment
-- Postcondition:
-- Return string with error message or ""
-- Uses:
-- force()
-- < invokeFrame
invokeFrame = frame
return force()
end -- .check()
function p.count( frame )
-- Count number of template parameters
-- Precondition:
-- frame -- object; #invoke environment
-- Postcondition:
-- Return string with digits including "0"
-- Uses:
-- figure()
-- < invokeFrame
invokeFrame = frame
return tostring( figure() )
end -- .count()
function p.valid( frame )
-- Check validity of one template parameter
-- Precondition:
-- frame -- object; #invoke environment
-- Postcondition:
-- Return string with error message or ""
-- Uses:
-- < invokeFrame
invokeFrame = frame
return "#invoke:TemplatePar|valid| Not yet available"
end -- .valid()
return p