Jump to content
Toggle menu
  • 8 articles
  • 75 files
  • 7 users
  • 37.8K edits
Neodyland Wiki
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Module:TemplatePar

From Neodyland Wiki
Revision as of 08:40, 20 December 2013 by commons>Deavalma
Module documentation[ view · edit · history · purge ]
This documentation is transcluded from Module:TemplatePar/doc.

Script error: Lua error at line 68: '<eof>' expected near 'end'.

--[=[ TemplatePar 2013-07-09Template parameter utility* assert* check* count
* countNotEmpty* downcase* match* valid* verify* TemplatePar()]=]
-- Module globalslocal TemplatePar = { }
local messagePrefix = "lua-module-TemplatePar-"local l10nDef = {}
l10nDef[ "en" ] = {
    badPattern  = "&#35;invoke:TemplatePar pattern syntax error",
    dupOpt      = "&#35;invoke:TemplatePar repeated optional parameter",
    dupRule     = "&#35;invoke:TemplatePar conflict key/pattern",
    empty       = "Error in template * undefined value for mandatory",
    invalid     = "Error in template * invalid parameter",
    invalidPar  = "&#35;invoke:TemplatePar invalid parameter",
    minmax      = "&#35;invoke:TemplatePar min > max",
    multiSpell  = "Error in template * multiple spelling of parameter",
    noErrorCat  = "&#35;invoke:TemplatePar noError and missing category",
    noname      = "&#35;invoke:TemplatePar missing parameter name",
    tooLong     = "Error in template * parameter too long",
    tooShort    = "Error in template * parameter too short",
    undefined   = "Error in template * mandatory parameter missing",
    unknown     = "Error in template * unknown parameter name",
    unknownRule = "&#35;invoke:TemplatePar unknown rule"}l10nDef[ "de" ]  = {
    badPattern  = "&#35;invoke:TemplatePar Syntaxfehler des pattern",
    dupOpt      = "&#35;invoke:TemplatePar Optionsparameter wiederholt",
    dupRule     = "&#35;invoke:TemplatePar Konflikt key/pattern",
    empty       = "Fehler bei Vorlage * Pflichtparameter ohne Wert",
    invalid     = "Fehler bei Vorlage * Parameter ungültig",
    invalidPar  = "&#35;invoke:TemplatePar Ungültiger Parameter",
    minmax      = "&#35;invoke:TemplatePar min > max",
    multiSpell  = "Fehler bei Vorlage * Mehrere Parameter-Schreibweisen",
    noErrorCat  = "&#35;invoke:TemplatePar noError und keine Kategorie",
    noname      = "&#35;invoke:TemplatePar Parameter nicht angegeben",
    tooLong     = "Fehler bei Vorlage * Parameter zu lang",
    tooShort    = "Fehler bei Vorlage * Parameter zu kurz",
    undefined   = "Fehler bei Vorlage * Pflichtparameter fehlt",
    unknown     = "Fehler bei Vorlage * Parametername unbekannt",
    unknownRule = "&#35;invoke:TemplatePar Unbekannte Regel"}local Patterns = {
    [ "ASCII" ]   = "^[ -~]*$",    [ "ASCII+" ]   = "^[ -~]+$",
    [ "ASCII+1" ]  = "^[!-~]+$",    [ "n" ]        = "^%-?[0-9]*$",
    [ "n>0" ]      = "^[0-9]*[1-9][0-9]*$",
    [ "N+" ]       = "^%-?[1-9][0-9]*$",    [ "N>0" ]      = "^[1-9][0-9]*$",
    [ "x" ]        = "^[0-9A-Fa-f]*$",    [ "x+" ]       = "^[0-9A-Fa-f]+$",
    [ "X" ]        = "^[0-9A-F]*$",    [ "X+" ]       = "^[0-9A-F]+$",
    [ "0,0" ]      = "^%-?[0-9]*,?[0-9]*$",
    [ "0,0+" ]     = "^%-?[0-9]+,[0-9]+$",
    [ "0,0+?" ]    = "^%-?[0-9]+,?[0-9]*$",
    [ "0.0" ]      = "^%-?[0-9]*%.?[0-9]*$",
    [ "0.0+" ]     = "^%-?[0-9]+%.[0-9]+$",
    [ "0.0+?" ]    = "^%-?[0-9]+%.?[0-9]*$",
    [ ".0+" ]      = "^%-?[0-9]*%.?[0-9]+$",
    [ "ID" ]       = "^[A-Za-z]?[A-Za-z_0-9]*$",
    [ "ID+" ]      = "^[A-Za-z][A-Za-z_0-9]*$",    [ "ABC" ]      = "^[A-Z]*$",
    [ "ABC+" ]     = "^[A-Z]+$",    [ "Abc" ]      = "^[A-Z]*[a-z]*$",
    [ "Abc+" ]     = "^[A-Z][a-z]+$",    [ "abc" ]      = "^[a-z]*$",
    [ "abc+" ]     = "^[a-z]+$",    [ "aBc+" ]     = "^[a-z]+[A-Z][A-Za-z]*$",
    [ "base64" ]   = "^[A-Za-z0-9%+/]*$",
    [ "base64+" ]  = "^[A-Za-z0-9%+/]+$",    [ "aa" ]       = "[%a%a].*[%a%a]",
    [ "pagename" ] = string.format( "^[^#<>%%[%%]|{}%s%-s%s]+$",
                                    1, 31, 127 ),    [ "+" ]        = "%S"}
local patternCJK = falselocal function containsCJK( s )
    -- Is any CJK character present?    -- Precondition:    --     s  -- string
    -- Postcondition:    --     Return false iff no CJK present    -- Uses:
    --     >< patternCJK    --     mw.ustring.char()
    --     mw.ustring.match()    local r = false    if not patternCJK then
        patternCJK = mw.ustring.char( 91,
                                       13312, 45,  40959,
                                      131072, 45, 178207,
                                      93 )    end
    if mw.ustring.match( s, patternCJK ) then        r = true    end    return r
end -- containsCJK()local function factory( say )
    -- Retrieve localized message string in content language    -- Precondition:
    --     say  -- string; message ID    -- Postcondition:
    --     Return some message string    -- Uses:    --     >  messagePrefix
    --     >  l10nDef    --     mw.language.getContentLanguage()
    --     mw.message.new()
    local c = mw.language.getContentLanguage():getCode()
    local m = mw.message.new( messagePrefix .. say )    local r = false
    if m:isBlank() then        local l10n = l10nDef[ c ]        if not l10n then
            l10n = l10nDef[ "en" ]        end        r = l10n[ say ]    else
        m:inLanguage( c )        r = m:plain()    end    if not r then
        r = "(((".. say .. ")))"    end    return rend -- factory()
local function failsafe( story, scan )
    -- Test for match (possibly user-defined with syntax error)
    -- Precondition:    --     story  -- string; parameter value
    --     scan   -- string; pattern    -- Postcondition:
    --     Return nil, if not matching, else non-nil    -- Uses:
    --     mw.ustring.match()    return  mw.ustring.match( story, scan )
end -- failsafe()local function failure( spec, suspect, options )
    -- Submit localized error message    -- Precondition:
    --     spec     -- string; message ID
    --     suspect  -- string or nil; additional information
    --     options  -- table or nil; optional details
    --                 options.template    -- Postcondition:
    --     Return string    -- Uses:    --     factory()
    local r = factory( spec )    if type( options ) == "table" then
        if type( options.template ) == "string" then
            if #options.template > 0 then
                r = r .. " (" .. options.template .. ")"            end
        end    end    if suspect then        r = r .. ": " .. suspect    end
    return rend -- failure()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 rend -- fault()
local function feasible( analyze, options, abbr )    -- Check content of a value
    -- Precondition:    --     analyze  -- string to be analyzed
    --     options  -- table or nil; optional details
    --                 options.pattern    --                 options.key
    --                 options.say
    --     abbr     -- true: abbreviated error message    -- Postcondition:
    --     Return string with error message as configured;
    --            false if valid or no answer permitted    -- Uses:
    --     >  Patterns    --     failure()    --     mw.text.trim()
    --     failsafe()    --     containsCJK()    local r    = false
    local s    = false    local show = nil    local scan = false
    if type( options.pattern ) == "string" then        if options.key then
            r = failure( "dupRule", false, options )        else
            scan = options.pattern        end    else
        if type( options.key ) == "string" then
            s = mw.text.trim( options.key )        else            s = "+"
        end        if s ~= "*" then            scan = Patterns[ s ]        end
        if type( scan ) == "string" then
            if s == "n" or s == "0,0" or s == "0.0" then
                if not analyze:match( "[0-9]" ) then
                    scan = false                    if options.say then
                        show = "'" .. options.say .. "'"                    end
                    if abbr then                        r = show
                    else
                        r = failure( "invalid", show, options )
                    end                end            end
        elseif s ~= "*" then
            local op, n, plus = s:match( "([<!>]=?)([-0-9][%S]*)(+?)" )
            if op then                n = tonumber( n )                if n then
                    local i = tonumber( analyze )                    if i then
                        if op == "<" then
                            i = ( i < n )
                        elseif op == "<=" then
                            i = ( i <= n )
                        elseif op == ">" then
                            i = ( i > n )
                        elseif op == ">=" then
                            i = ( i >= n )
                        elseif op == "!=" then
                            i = ( i ~= n )                        else
                            n = false                        end
                    end                    if not i then
                        r = "invalid"                    end
                elseif plus then                    r = "undefined"
                end            end            if not n and not r then
                r = "unknownRule"            end            if r then
                if options.say then
                    show = "'" .. options.say .. "' " .. s                else
                    show = s                end                if abbr then
                    r = show                else
                    r = failure( r, show, options )                end
            end        end    end    if scan then
        local legal, got = pcall( failsafe, analyze, scan )        if legal then
            if not got then                if s == "aa" then
                    got = containsCJK( analyze )                end
                if not got then                    if options.say then
                        show = "'" .. options.say .. "'"                    end
                    if abbr then                        r = show
                    else
                        r = failure( "invalid", show, options )
                    end                end            end        else
            r = failure( "badPattern",
                         scan .. " *** " .. got,
                         options )        end    end    return r
end -- feasible()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( light, options )
    -- Return regular table with all parameters    -- Precondition:
    --     light    -- true: template transclusion;  false: #invoke
    --     options  -- table; optional details    --                 options.low
    -- Postcondition:    --     Return table; whitespace-only values as false
    -- Uses:    --     TemplatePar.downcase()    --     mw.getCurrentFrame()
    --     frame:getParent()    local g, k, v    local r = { }
    if options.low then        g = TemplatePar.downcase( options )    else
        g = mw.getCurrentFrame()        if light then
            g = g:getParent()        end        g = g.args    end
    if type( g ) == "table"  then        r = { }
        for k, v in pairs( g ) 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    else
        r = g    end    return rend -- fetch()
local function figure( append, options )
    -- Extend options by rule from #invoke strings    -- Precondition:
    --     append   -- string or nil; requested rule
    --     options  --  table; details    --                  ++ .key
    --                  ++ .pattern    -- Postcondition:
    --     Return sequence table    local r = options
    if type( append ) == "string" then
        local story = mw.text.trim( append )
        local sub   = story:match( "^/(.*%S)/$" )
        if type( sub ) == "string" then
            sub             = sub:gsub( "%%!", "|" )
            sub             = sub:gsub( "%%%(%(", "{{" )
            sub             = sub:gsub( "%%%)%)", "}}" )
            options.pattern = sub            options.key     = nil        else
            options.key     = story            options.pattern = nil        end
    end    return rend -- figure()local function fill( specified )
    -- Split requirement string separated by '='    -- Precondition:
    --     specified  -- string or nil; requested parameter set
    -- Postcondition:    --     Return sequence table    -- Uses:
    --     mw.text.split()    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 rend -- fill()
local function finalize( submit, options )    -- Finalize message
    -- Precondition:
    --     submit   -- string or false or nil; non-empty error message
    --     options  -- table or nil; optional details
    --                 options.noError    --                 options.cat
    --                 options.template    -- Postcondition:
    --     Return string or false    -- Uses:    --     factory()
    local r = false    if submit then        local opt, s
        if type( options ) == "table" then            opt = options        else
            opt = { }        end        if opt.noError then
            if not opt.cat then
                r = submit .. " " .. factory( "noErrorCat" )            end
        else            r = submit        end        if r then
            r = "<span class='error'>" .. r .. "</span>"        end
        s = opt.cat        if type( s ) == "string" then
            if not r then               r = ""            end
            if s:find( "@@@" ) then
                if type( opt.template ) == "string" then
                    s = s:gsub( "@@@", opt.template )                end
            end            r = r .. "[[Category:" .. s .. "]]"        end    end
    return rend -- finalize()local function finder( haystack, needle )
    -- Find needle in haystack sequence    -- Precondition:
    --     haystack  -- table; sequence of key names, downcased if low
    --     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 falseend -- finder()
local function fix( valid, duty, got, options )    -- Perform parameter analysis
    -- Precondition:
    --     valid    -- table; unique sequence of known parameters
    --     duty     -- table; sequence of mandatory parameters
    --     got      -- table; sequence of current parameters
    --     options  -- table or nil; optional details    -- Postcondition:
    --     Return string as configured; empty if valid    -- Uses:
    --     finder()    --     fault()    --     failure()    --     fed()
    local k, v    local r = false    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 = failure( "unknown",  "'" .. r .. "'",  options )
    else -- all names valid        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 = failure( "undefined", r, options )
        else -- all mandatory present            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 = failure( "empty", r, options )
            end        end    end    return rend -- fix()
local function flat( collection, options )
    -- Return all table elements with downcased string    -- Precondition:
    --     collection  -- table; k=v pairs
    --     options     -- table or nil; optional messaging details
    -- Postcondition:
    --     Return table, may be empty; or string with error message.    -- Uses:
    --     mw.ustring.lower()    --     fault()    --     failure()
    local k, v    local r = { }    local e = false
    for k, v in pairs( collection ) do        if type ( k ) == "string" then
            k = mw.ustring.lower( k )            if r[ k ] then
                e = fault( e, k )            end        end        r[ k ] = v
    end -- for k, v    if e then        r = failure( "multiSpell", e, options )
    end    return rend -- flat()local function fold( options )
    -- Merge two tables, create new sequence if both not empty
    -- Precondition:    --     options  -- table; details
    --                 options.mandatory   sequence to keep unchanged
    --                 options.optional    sequence to be appended
    --                 options.low         downcased expected
    -- Postcondition:    --     Return merged table, or message string if error
    -- Uses:    --     finder()    --     fault()    --     failure()
    --     flat()    local i, e, r, s    local base   = options.mandatory
    local extend = options.optional    if #base == 0 then
        if #extend == 0 then            r = { }        else
            r = extend        end    else        if #extend == 0 then
            r = base        else            e = false
            for i = 1, #extend do                s = extend[ i ]
                if finder( base, s ) then                    e = fault( e, s )
                end            end -- for i            if e then
                r = failure( "dupOpt", e, options )            else
                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
    if options.low  and  type( r ) == "table" then        r = flat( r, options )
    end    return rend -- fold()local function form( light, options )
    -- Run parameter analysis on current environment    -- Precondition:
    --     light    -- true: template transclusion;  false: #invoke
    --     options  -- table or nil; optional details
    --                 options.mandatory    --                 options.optional
    -- Postcondition:    --     Return string with error message as configured;
    --            false if valid    -- Uses:    --     fold()    --     fetch()
    --     fix()    --     finalize()    local duty, r
    if type( options ) == "table" then
        if type( options.mandatory ) ~= "table" then
            options.mandatory = { }        end        duty = options.mandatory
        if type( options.optional ) ~= "table" then
            options.optional = { }        end        r = fold( options )    else
        options = { }        duty    = { }        r       = { }    end
    if type( r ) == "table" then        local got = fetch( light, options )
        if type( got ) == "table" then
            r = fix( r, duty, got, options )        else            r = got
        end    end    return finalize( r, options )end -- form()
local function format( analyze, options )    -- Check validity of a value
    -- Precondition:    --     analyze  -- string to be analyzed
    --     options  -- table or nil; optional details
    --                 options.say    --                 options.min
    --                 options.max    -- Postcondition:
    --     Return string with error message as configured;
    --            false if valid or no answer permitted    -- Uses:
    --     feasible()    --     failure()
    local r    = feasible( analyze, options, false )    local show
    if options.min  and  not r then
        if type( options.min ) == "number" then
            if type( options.max ) == "number" then
                if options.max < options.min then
                    r = failure( "minmax",
                                 tostring( options.min )
                                 .. " > " ..
                                 tostring( options.max ),
                                 options )                end            end
            if #analyze < options.min  and  not r then
                show = " <" .. options.min                if options.say then
                    show = show .. " '" .. options.say .. "'"                end
                r = failure( "tooShort", show, options )            end
        else            r = failure( "invalidPar", "min", options )        end
    end    if options.max  and  not r then
        if type( options.max ) == "number" then
            if #analyze > options.max then
                show = " >" .. options.max                if options.say then
                    show = show .. " '" .. options.say .. "'"                end
                r = failure( "tooLong", show, options )            end
        else            r = failure( "invalidPar", "max", options )        end
    end    return rend -- format()
local function formatted( assignment, access, options )
    -- Check validity of one particular parameter in a collection
    -- Precondition:    --     assignment  -- collection
    --     access      -- id of parameter in collection
    --     options     -- table or nil; optional details    -- Postcondition:
    --     Return string with error message as configured;
    --            false if valid or no answer permitted    -- Uses:
    --     format()    --     failure()    local r = false
    if type( assignment ) == "table" then
        local story = assignment.args[ access ]
        if type( story ) == "string" then
            if type( options ) ~= "table" then                options = { }
            end            options.say = access
            r = format( story, options )        else
            r = failure( "invalid", access, options )        end    end
    return rend -- formatted()local function furnish( frame, action )
    -- Prepare #invoke evaluation of .assert() or .valid()    -- Precondition:
    --     frame    -- object; #invoke environment
    --     action   -- "assert" or "valid"    -- Postcondition:
    --     Return string with error message or ""    -- Uses:    --     form()
    --     mw.text.trim()    --     failure()    --     TemplatePar.assert()
    --     TemplatePar.valid()    local options = { mandatory = { "1" },
                      optional  = { "2",
                                    "cat",
                                    "low",
                                    "max",
                                    "min",
                                    "noError",
                                    "template" },
                      template  = "&#35;invoke:TemplatePar|".. action .. "|"
                    }    local r       = form( false, options )    if not r then
        local s        options = { cat      = frame.args.cat,
                    low      = frame.args.low,
                    noError  = frame.args.noError,
                    template = frame.args.template                  }
        options = figure( frame.args[ 2 ], options )
        if type( frame.args.min ) == "string" then
            s = frame.args.min:match( "^%s*([0-9]+)%s*$" )            if s then
                options.min = tonumber( s )            else
                r = failure( "invalidPar",
                             "min=" .. frame.args.min,
                             options )            end        end
        if type( frame.args.max ) == "string" then
            s = frame.args.max:match( "^%s*([1-9][0-9]*)%s*$" )
            if s then                options.max = tonumber( s )            else
                r = failure( "invalidPar",
                             "max=" .. frame.args.max,
                             options )            end        end
        if r then            r = finalize( r, options )        else
            s = frame.args[ 1 ] or ""            r = tonumber( s )
            if ( r ) then                s = r            end
            r = TemplatePar[ action ]( s, options )        end    end
    return r or ""end -- furnish()
TemplatePar.assert = function ( analyze, append, options )
    -- Perform parameter analysis on a single string    -- Precondition:
    --     analyze  -- string to be analyzed
    --     append   -- string: append error message, prepending <br />
    --                 false or nil: throw error with message
    --     options  -- table; optional details    -- Postcondition:
    --     Return string with error message as configured;
    --            false if valid    -- Uses:    --     format()
    local r = format( analyze, options )    if ( r ) then
        if ( type( append ) == "string" ) then
            if ( append ~= "" ) then                r = append .. "<br />" .. r
            end        else            error( r, 0 )        end    end
    return rend -- TemplatePar.assert()TemplatePar.check = function ( options )
    -- Run parameter analysis on current template environment
    -- Precondition:    --     options  -- table or nil; optional details
    --                 options.mandatory    --                 options.optional
    -- Postcondition:    --     Return string with error message as configured;
    --            false if valid    -- Uses:    --     form()
    return form( true, options )end -- TemplatePar.check()
TemplatePar.count = function ()    -- Return number of template parameters
    -- Postcondition:    --     Return number, starting at 0    -- Uses:
    --     mw.getCurrentFrame()    --     frame:getParent()    local k, v
    local r = 0    local t = mw.getCurrentFrame():getParent()
    local o = t.args    for k, v in pairs( o ) do        r = r + 1
    end -- for k, v    return rend -- TemplatePar.count()
TemplatePar.countNotEmpty = function ()
    -- Return number of template parameters with more than whitespace
    -- Postcondition:    --     Return number, starting at 0    -- Uses:
    --     mw.getCurrentFrame()    --     frame:getParent()    local k, v
    local r = 0    local t = mw.getCurrentFrame():getParent()
    local o = t.args    for k, v in pairs( o ) do
        if not v:match( "^%s*$" ) then            r = r + 1        end
    end -- for k, v    return rend -- TemplatePar.countNotEmpty()
TemplatePar.downcase = function ( options )
    -- Return all template parameters with downcased name    -- Precondition:
    --     options  -- table or nil; optional messaging details
    -- Postcondition:
    --     Return table, may be empty; or string with error message.    -- Uses:
    --     mw.getCurrentFrame()    --     frame:getParent()    --     flat()
    local t = mw.getCurrentFrame():getParent()    return flat( t.args, options )
end -- TemplatePar.downcase()TemplatePar.valid = function ( access, options )
    -- Check validity of one particular template parameter    -- Precondition:
    --     access   -- id of parameter in template transclusion
    --     options  -- table or nil; optional details    -- Postcondition:
    --     Return string with error message as configured;
    --            false if valid or no answer permitted    -- Uses:
    --     mw.text.trim()    --     TemplatePar.downcase()
    --     mw.getCurrentFrame()    --     frame:getParent()
    --     formatted()    --     failure()    --     finalize()    local r
    if type( access ) == "string" then        r = mw.text.trim( access )
        if #r == 0 then            r = false        end    end    if r then
        local params        if type( options ) ~= "table" then
            options = { }        end        if options.low then
            params = TemplatePar.downcase( options )        else
            params = mw.getCurrentFrame():getParent()        end
        r = formatted( params, access, options )    else
        r = failure( "noname", false, options )    end
    return finalize( r, options )end -- TemplatePar.valid()
TemplatePar.verify = function ( options )
    -- Perform #invoke parameter analysis    -- Precondition:
    --     options  -- table or nil; optional details    -- Postcondition:
    --     Return string with error message as configured;
    --            false if valid    -- Uses:    --     form()
    return form( false, options )end -- TemplatePar.verify()
-- Provide external accesslocal p = {}function p.assert( frame )
    -- Perform parameter analysis on some single string    -- Precondition:
    --     frame  -- object; #invoke environment    -- Postcondition:
    --     Return string with error message or ""    -- Uses:
    --     furnish()    return furnish( frame, "assert" )end -- .assert()
function p.check( frame )    -- Check validity of template parameters
    -- Precondition:    --     frame  -- object; #invoke environment
    -- Postcondition:    --     Return string with error message or ""
    -- Uses:    --     form()    --     fill()
    local options = { optional  = { "all",
                                    "opt",
                                    "cat",
                                    "low",
                                    "noError",
                                    "template" },
                      template  = "&#35;invoke:TemplatePar|check|"
                    }    local r = form( false, options )    if not r then
        options = { mandatory = fill( frame.args.all ),
                    optional  = fill( frame.args.opt ),
                    cat       = frame.args.cat,
                    low       = frame.args.low,
                    noError   = frame.args.noError,
                    template  = frame.args.template                  }
        r       = form( true, options )    end    return r or ""end -- .check()
function p.count( frame )    -- Count number of template parameters
    -- Postcondition:    --     Return string with digits including "0"
    -- Uses:    --     TemplatePar.count()
    return tostring( TemplatePar.count() )end -- .count()
function p.countNotEmpty( frame )
    -- Count number of template parameters which are not empty
    -- Postcondition:    --     Return string with digits including "0"
    -- Uses:    --     TemplatePar.countNotEmpty()
    return tostring( TemplatePar.countNotEmpty() )end -- .countNotEmpty()
function p.match( frame )    -- Combined analysis of parameters and their values
    -- Postcondition:    --     Return string with error message or ""
    -- Uses:    --     mw.text.trim()    --     mw.ustring.lower()
    --     failure()    --     form()    --     TemplatePar.downcase()
    --     figure()    --     feasible()    --     fault()    --     finalize()
    local r = false    local options = { cat       = frame.args.cat,
                      low       = frame.args.low,
                      noError   = frame.args.noError,
                      template  = frame.args.template                    }
    local k, v, s    local params = { }    for k, v in pairs( frame.args ) do
        if type( k ) == "number" then
            s, v = v:match( "^ *([^=]+) *= *(%S.*%S*) *$" )            if s then
                s = mw.text.trim( s )                if s == "" then
                    s = false                end            end
            if s then                if options.low then
                    s = mw.ustring.lower( s )                end
                if params[ s ] then                    s = params[ s ]
                    s[ #s + 1 ] = v                else
                    params[ s ] = { v }                end            else
                r = failure( "invalidPar",  tostring( k ),  options )
                break -- for k, v            end        end    end -- for k, v
    if not r then        s = { }        for k, v in pairs( params ) do
            s[ #s + 1 ] = k        end -- for k, v        options.optional = s
        r = form( true, options )    end    if not r then
        local errMiss, errValues, lack, rule
        local targs = frame:getParent().args        options.optional = nil
        if options.low then            targs = TemplatePar.downcase()
        else            targs = frame:getParent().args        end
        errMiss   = false        errValues = false
        for k, v in pairs( params ) do            options.say = k
            errValue    = false            s = targs[ k ]            if s then
                if s == "" then                    lack = true
                else                    lack = false                end
            else                s    = ""                lack = true
            end            for r, rule in pairs( v ) do
                options = figure( rule, options )
                r       = feasible( s, options, true )                if r then
                    if lack then                        if errMiss then
                            errMiss = errMiss .. ", '" .. k .. "'"
                        else
                            errMiss = "'" .. k .. "'"                        end
                    elseif not errMiss then
                        errValues = fault( errValues, r )                    end
                    break -- for r, rule                end
            end -- for s, rule        end -- for k, v
        r = ( errMiss or errValues )        if r then            if errMiss then
                r = failure( "undefined", errMiss, options )            else
                r = failure( "invalid", errValues, options )            end
            r = finalize( r, options )        end    end    return r or ""
end -- .match()function p.valid( frame )
    -- Check validity of one particular template parameter    -- Precondition:
    --     frame  -- object; #invoke environment    -- Postcondition:
    --     Return string with error message or ""    -- Uses:
    --     furnish()    return furnish( frame, "valid" )end -- .valid()
function p.TemplatePar()    -- Retrieve function access for modules
    -- Postcondition:    --     Return table with functions
    return TemplateParend -- .TemplatePar()return p
Cookies help us deliver our services. By using our services, you agree to our use of cookies.