if type( v2 ) ~= "nil" then
p2[ k2 ] = v2
end
end -- for k2, v2
end
p[ k ] = p2
for k2, v2 in pairs( t[ v ] ) do
t2[ k2 ] = v2
end -- for k2, v2
for k2, v2 in pairs( t[ k ] ) do
if type( v2 ) ~= "nil" then
t2[ k2 ] = v2
end
end -- for k2, v2
t[ k ] = t2
end
end -- for k, v
end -- i = 1, n
if n > 0 then
local s
for k, v in pairs( Data.heirs ) do
if v then
if s then
s = string.format( "%s &#124; %s", s, k )
else
s = "Circular inherits: " .. k
end
end
end -- for k, v
Fault( s )
end
end -- fathers  
local function feasible( about, asked )
-- Create description head
-- Parameter:
-- about -- table, supposed to contain description
-- asked -- true, if mandatory description
-- Returns <block>, with head, or nil
local para = mw.html.create( "div" )
local plus, r
if about and about.description then
if type( about.description ) == "string" then
para:wikitext( about.description )
else
para:wikitext( about.description[ 1 ] )
plus = mw.html.create( "ul" )
if not Config.loudly then
plus:addClass( "templatedata-maintain" )
:css( "display", "" )
end
for k, v in pairs( about.description[ 2 ] ) do
plus:node( mw.html.create( "li" )
:node( mw.html.create( "code" )
:wikitext( k ) )
:node( mw.html.create( "br" ) )
:wikitext( handleNoexportWhitespace( v ) ) )
end -- for k, v
end
elseif Config.solo and asked then
para:addClass( "error" )
:wikitext( Config.solo )
Data.less = true
else
para = false
end
if para then
if plus then
r = mw.html.create( "div" )
:node( para )
:node( plus )
else
r = para
end
end
return r
end -- feasible  
local function feat
-- Check and store parameter sequence
if Data.source then
local i = 0
local s
for k, v in pairs( Data.tree.params ) do
if i == 0 then
Data.order = { }
i = 1
s = k
else
i = 2
break -- for k, v
end
end -- for k, v
if i > 1 then
local pointers = { }
local points = { }
for k, v in pairs( Data.tree.params ) do
i = facet( k, 1 )
if i then
table.insert( points, i )
pointers[ i ] = k
i = facet( k, i )
if i then
s = "Parameter '%s' detected twice"
Fault( string.format( s, k ) )
end
else
s = "Parameter '%s' not detected"
Fault( string.format( s, k ) )
end
end -- for k, v
table.sort( points )
for i = 1, #points do
table.insert( Data.order, pointers[ points[ i ] ] )
end -- i = 1, #points
elseif s then
table.insert( Data.order, s )
end
end
end -- feat  
local function feature( access )
-- Create table row for parameter, check and display violations
-- Parameter:
-- access -- string, with name
-- Returns <tr>
local mode, s, status
local fine = function ( a )
s = mw.text.trim( a )
return a == s and
a ~= "" and
not a:find( "%|=\n" ) and
not a:find( "%s%s" )
end
local begin = mw.html.create( "td" )
local code = mw.html.create( "code" )
local desc = mw.html.create( "td" )
local legal = true
local param = Data.tree.params[ access ]
local ranking = { "required", "suggested", "optional", "deprecated" }
local r = mw.html.create( "tr" )
local sort, typed  
for k, v in pairs( param ) do
if v == "" then
param[ k ] = false
end
end -- for k, v  
-- label
sort = param.label or access
if sort:match( "^%d+$" ) then
begin:attr( "data-sort-value",
string.format( "%05d", tonumber( sort ) ) )
end
begin:css( "font-weight", "bold" )
:wikitext( sort )  
-- name and aliases
code:css( "font-size", "92%" )
:css( "white-space", "nowrap" )
:wikitext( access )
if not fine( access ) then
code:addClass( "error" )
Fault( string.format( "Bad ID params.<code>%s</code>", access ) )
legal = false
begin:attr( "data-sort-value", " " .. sort )
end
code = mw.html.create( "td" )
:node( code )
if access:match( "^%d+$" ) then
code:attr( "data-sort-value",
string.format( "%05d", tonumber( access ) ) )
end
if type( param.aliases ) == "table" then
local lapsus
for k, v in pairs( param.aliases ) do
code:tag( "br" )
if type( v ) == "string" then
if not fine( v ) then
lapsus = true
code:node( mw.html.create( "span" )
:addClass( "error" )
:css( "font-style", "italic" )
:wikitext( "string" ) )
end
code:wikitext( s )
else
lapsus = true
code:node( mw.html.create( "code" )
:addClass( "error" )
:wikitext( type( v ) ) )
end
end -- for k, v
if lapsus then
s = string.format( "params.<code>%s</code>.aliases", access )
Fault( getLocalizedText( "invalid-value" ):gsub( "$1", s ) )
legal = false
end
end  
-- description etc.
s = feasible( param )
if s then
desc:node( s )
end
if param.default or param.example or param.autovalue then
local details = { "default", "example", "autovalue" }
local dl = mw.html.create( "dl" )
local dd, section, show
for i = 1, #details do
s = details[ i ]
show = param[ s ]
if show then
section = getLocalizedText( "doc-param-" .. s )
dt = mw.html.create( "dt" ):wikitext( section )
dd = mw.html.create( "dd" )
if (string.len(show) < 80) then
dt:cssText("float: ;margin-: 1.6em;")
end
if param.type == "boolean" then
if show == "0" then
dd:wikitext("<span style=\"color: #610; font-weight: bold;\">False</span> (<code>0</code>)")
elseif show == "1" then
dd:wikitext("<span style=\"color: #050; font-weight: bold;\">True</span> (<code>1</code>)")
else
dd:wikitext( show )
end
else
dd:wikitext( show )
end
dl:node( dt )
:node( dd )
end
end -- i = 1, #details
desc:node( dl )
end  
-- type
if param.type then
s = Permit.types[ param.type ]
typed = mw.html.create( "td" )
if s then
if s == "string" then
Data.params[ access ].type = s
typed:wikitext( getLocalizedText( "doc-param-type-" .. s ) )
:tag( "br" )
typed:node( mw.html.create( "span" )
:addClass( "error" )
:wikitext( param.type ) )
Data.lasting = true
else
s = getLocalizedText( "doc-param-type-" .. param.type )
typed:wikitext( s )
end
else
Data.params[ access ].type = "unknown"
typed:addClass( "error" )
:wikitext( "INVALID" )
s = string.format( "params.<code>%s</code>.type", access )
Fault( getLocalizedText( "invalid-value" ):gsub( "$1", s ) )
legal = false
end
else
typed = mw.html.create( "td" )
:wikitext( getLocalizedText( "doc-param-type-unknown" ) )
end  
-- status
if param.required then
mode = 1
if param.deprecated then
Fault( string.format( "Required deprecated <code>%s</code>",
access ) )
legal = false
end
elseif param.deprecated then
mode = 4
elseif param.suggested then
mode = 2
else
mode = 3
end
status = ranking[ mode ]
ranking = getLocalizedText( "doc-param-status-" .. status )
if mode == 1 or mode == 4 then
ranking = mw.html.create( "span" )
:css( "font-weight", "bold" )
:wikitext( ranking )
if type( param.deprecated ) == "string" then
ranking:tag( "br" )
ranking:wikitext( param.deprecated )
end
end  
-- <tr>
r:attr( "id", "templatedata:" .. mw.uri.anchorEncode( access ) )
:cssText( Permit.styles[ status ] )
:node( begin )
:node( code )
:node( desc )
:node( typed )
:node( mw.html.create( "td" )
:attr( "data-sort-value", tostring( mode ) )
:node( ranking ) )
:newline
if not legal then
r:css( "", "#FF0000 solid" )
end
return r
end -- feature  
local function features
-- Create <table> for parameters
-- Returns <table>, or nil
local r
if Data.tree and Data.tree.params then
local style = Permit.styles.tableheadbg
local tbl = mw.html.create( "table" )
:addClass( "wikitable" )
local tr = mw.html.create( "tr" )
feat
if Data.order and #Data.order > 1 then
tbl:addClass( "sortable" )
end
-- if Config.classTable then
-- tbl:addClass( Config.classTable )
-- end
if Config.stylesTable then
tbl:cssText( Config.stylesTable )
end
tr:node( mw.html.create( "th" )
:attr( "colspan", "2" )
:cssText( style )
:wikitext( getLocalizedText( "doc-param-name" ) ) )
:node( mw.html.create( "th" )
:cssText( style )
:wikitext( getLocalizedText( "doc-param-desc" ) ) )
:node( mw.html.create( "th" )
:cssText( style )
:wikitext( getLocalizedText( "doc-param-type" ) ) )
:node( mw.html.create( "th" )
:cssText( style )
:wikitext( getLocalizedText( "doc-param-status" ) ) )
tbl:newline
-- :node( mw.html.create( "thead" )
:node( tr )
-- )
:newline
if Data.order then
for i = 1, #Data.order do
tbl:node( feature( Data.order[ i ] ) )
end -- for i = 1, #Data.order
end
if Config.stylesTabWrap then
r = mw.html.create( "div" )
:cssText( Config.stylesTabWrap )
:node( tbl )
else