Modul:TemplateData: Unterschied zwischen den Versionen
2021-05-03
K (Datum) |
(2021-05-03) |
||
Zeile 1: | Zeile 1: | ||
local TemplateData = { suite = "TemplateData", | local TemplateData = { suite = "TemplateData", | ||
serial = " | serial = "2021-05-03", | ||
item = 46997995 } | item = 46997995 } | ||
--[=[ | --[==[ | ||
improve template:TemplateData | improve template:TemplateData | ||
]=] | ]==] | ||
local Failsafe = TemplateData | local Failsafe = TemplateData | ||
Zeile 13: | Zeile 12: | ||
basicCnf = { catProblem = "strange", | basicCnf = { catProblem = "strange", | ||
classNoNumTOC = "suppressTOCnum", | classNoNumTOC = "suppressTOCnum", | ||
classTable = "classTable", | |||
cssParWrap = "cssTabWrap", | cssParWrap = "cssTabWrap", | ||
cssParams = "cssTable", | cssParams = "cssTable", | ||
Zeile 31: | Zeile 31: | ||
msgDescMiss = "solo", | msgDescMiss = "solo", | ||
tStylesTOCnum = "stylesTOCnum" }, | tStylesTOCnum = "stylesTOCnum" }, | ||
classTable = { "wikitable" }, -- classes for params table | |||
debugmultilang = "C0C0C0", | debugmultilang = "C0C0C0", | ||
loudly = false, -- show exported element, etc. | loudly = false, -- show exported element, etc. | ||
Zeile 49: | Zeile 48: | ||
got = false, -- table, initial templatedata object | got = false, -- table, initial templatedata object | ||
heirs = false, -- table, params that are inherited | heirs = false, -- table, params that are inherited | ||
jump = false, -- source position at end of "params" | |||
less = false, -- main description missing | less = false, -- main description missing | ||
lasting = false, -- old syntax encountered | lasting = false, -- old syntax encountered | ||
Zeile 67: | Zeile 67: | ||
} | } | ||
local Permit = { | local Permit = { | ||
builder = { after | builder = { after = "block", | ||
align | align = "block", | ||
block | block = "block", | ||
compressed = "block", | compressed = "block", | ||
dense | dense = "block", | ||
grouped | grouped = "inline", | ||
half | half = "inline", | ||
indent | indent = "block", | ||
inline | inline = "inline", | ||
last | last = "block", | ||
lead | lead = "block", | ||
newlines | newlines = "*", | ||
spaced | spaced = "inline" }, | ||
colors = { tableheadbg = "B3B7FF", | colors = { tableheadbg = "B3B7FF", | ||
required = "EAF3FF", | required = "EAF3FF", | ||
Zeile 85: | Zeile 85: | ||
optional = "EAECF0", | optional = "EAECF0", | ||
deprecated = "FFCBCB" }, | deprecated = "FFCBCB" }, | ||
params = { aliases | params = { aliases = "table", | ||
autovalue | autovalue = "string", | ||
default | default = "string table I18N nowiki", | ||
deprecated | deprecated = "boolean string I18N", | ||
description = "string table I18N", | description = "string table I18N", | ||
example | example = "string table I18N nowiki", | ||
label | label = "string table I18N", | ||
inherits | inherits = "string", | ||
required | required = "boolean", | ||
style | style = "string table", | ||
suggested | suggested = "boolean", | ||
type | suggestedvalues = "string table number", | ||
type = "string" }, | |||
root = { description = "string table I18N", | root = { description = "string table I18N", | ||
format = "string", | format = "string", | ||
Zeile 212: | Zeile 213: | ||
:gsub( "([%-.()+*?^$%[%]])", | :gsub( "([%-.()+*?^$%[%]])", | ||
"%%%1" ) ) | "%%%1" ) ) | ||
local i, k = Data.source:find( | local i, k, r, slice, source | ||
if not Data.jump then | |||
Data.jump = Data.source:find( "params", 2 ) | |||
if Data.jump then | |||
Data.jump = Data.jump + 7 | |||
else | |||
Data.jump = 1 | |||
end | |||
end | |||
i, k = Data.source:find( seek, at + Data.jump ) | |||
while i and not r do | while i and not r do | ||
source = Data.source:sub( k + 1 ) | source = Data.source:sub( k + 1 ) | ||
Zeile 224: | Zeile 233: | ||
r = k | r = k | ||
else | else | ||
i, k = Data.source:find( seek, k ) | i, k = Data.source:find( seek, k ) | ||
end | end | ||
end -- while i | end -- while i | ||
Zeile 292: | Zeile 301: | ||
-- adjust -- string | -- adjust -- string | ||
-- Returns string, with adjusted text | -- Returns string, with adjusted text | ||
local f = function ( a ) | local f = function ( a ) | ||
return a:gsub( "%s*\n%s*", " " ) | |||
:gsub( "%s%s+", " " ) | |||
end | |||
local | local tags = { { start = "<noexport>", | ||
stop = "</noexport>" }, | |||
{ start = "<exportonly>", | |||
stop = "</exportonly>", | |||
l = false } | |||
} | |||
local r = adjust | |||
local i, j, k, s, tag | |||
for m = 1, 2 do | |||
i = | tag = tags[ m ] | ||
j, k = | if r:find( tag.start, 1, true ) then | ||
if j then | s = r | ||
r = "" | |||
i = 1 | |||
tag.l = true | |||
j, k = s:find( tag.start, i, true ) | |||
while j do | |||
if j > 1 then | |||
r = r .. f( s:sub( i, j - 1 ) ) | |||
end | |||
i = k + 1 | i = k + 1 | ||
j, k = | j, k = s:find( tag.stop, i, true ) | ||
if j then | |||
if m == 1 then | |||
r = r .. s:sub( i, j - 1 ) | |||
end | |||
i = k + 1 | |||
j, k = s:find( tag.start, i, true ) | |||
r = | else | ||
Fault( "missing " .. tag.stop ) | |||
end | |||
end -- while j | |||
r = r .. s:sub( i ) | |||
else | |||
r = f( r ) | |||
end | |||
end -- for m | |||
if tags[ 2 ].l then | |||
r = r:gsub( "<exportonly>.*</exportonly>", "" ) | |||
end | end | ||
return r | return r | ||
Zeile 382: | Zeile 408: | ||
if type( v ) == "string" then | if type( v ) == "string" then | ||
v = mw.text.trim( v ) | v = mw.text.trim( v ) | ||
if v ~= "" then | if v ~= "" and type( k ) == "string" then | ||
k = k:lower() | k = k:lower() | ||
variants[ k ] = v | variants[ k ] = v | ||
Zeile 650: | Zeile 676: | ||
local function | local function feasible( about, at ) | ||
-- | -- Deal with suggestedvalues within parameter | ||
-- Parameter: | |||
-- about -- parameter details | |||
-- .suggestedvalues -- table|string|number, | |||
-- value and possibly description | |||
-- .code -- mandatory | |||
-- .label -- table|string | |||
-- .icon -- string | |||
-- .class -- table|string | |||
-- .css -- table | |||
-- .style -- string | |||
-- .less -- true: suppress code | |||
-- .type | |||
-- at -- string, with parameter name | |||
-- Returns | |||
-- 1: mw.html object | |||
-- 2: sequence table with values, or nil | |||
local p = about.suggestedvalues | |||
for | local s = type( p ) | ||
i = | local e, r1, r2, v | ||
if | if s == "table" then | ||
if type( | if #p > 0 then | ||
s = mw.text.trim( | for i = 1, #p do | ||
if s == "" then | e = p[ i ] | ||
s = | s = type( e ) | ||
end | if s == "table" then | ||
if type( e.code ) == "string" then | |||
s = mw.text.trim( e.code ) | |||
if s == "" then | |||
e = nil | |||
else | |||
e.code = s | |||
end | |||
else | |||
e = nil | |||
s = string.format( "params.%s.%s[%d] %s", | |||
at, | |||
"suggestedvalues", | |||
i, | |||
"MISSING 'code:'" ) | |||
end | |||
elseif s == "string" then | |||
s = mw.text.trim( e ) | |||
if s == "" then | |||
e = nil | |||
s = string.format( "params.%s.%s[%d] EMPTY", | |||
at, "suggestedvalues", i ) | |||
Fault( s ) | |||
else | else | ||
s | e = { code = s } | ||
end | end | ||
elseif s == "number" then | |||
e = { code = tostring( e ) } | |||
else | |||
s = string.format( "params.%s.%s[%d] INVALID", | |||
at, "suggestedvalues", i ) | |||
Fault( s ) | |||
end | |||
if e then | |||
v = v or { } | |||
table.insert( v, e ) | |||
end | |||
end -- for i | |||
else | |||
Fault( string.format( "params.%s.suggestedvalues %s", | |||
at, "NOT AN ARRAY" ) ) | |||
end | |||
elseif s == "string" then | |||
s = mw.text.trim( p ) | |||
if s ~= "" then | |||
v = { } | |||
table.insert( v, | |||
{ code = s } ) | |||
end | |||
elseif s == "number" then | |||
v = { } | |||
table.insert( v, | |||
{ code = tostring( p ) } ) | |||
end | |||
if v then | |||
local d, less, story, swift, t, u | |||
r1 = mw.html.create( "ul" ) | |||
r2 = { } | |||
for i = 1, #v do | |||
e = v[ i ] | |||
table.insert( r2, e.code ) | |||
u = mw.html.create( "li" ) | |||
less = ( e.less == true ) | |||
if not less then | |||
swift = e.code | |||
if about.type:sub( 1, 5 ) == "wiki-" then | |||
local rooms = { file = 6, | |||
temp = 10, | |||
user = 2 } | |||
local ns = rooms[ about.type:sub( 6, 9 ) ] or 0 | |||
t = mw.title.makeTitle( ns, swift ) | |||
if t and t.exists then | |||
swift = string.format( "[[:%s|%s]]", | |||
t.prefixedText, swift ) | |||
end | end | ||
end | end | ||
u:node( mw.html.create( "code" ) | |||
:css( "white-space", "nowrap" ) | |||
:wikitext( swift ) ) | |||
end | |||
if e.class then | |||
s = type( e.class ) | |||
if s == "string" then | |||
end | u:addClass( e.class ) | ||
elseif s == "table" then | |||
for k, s in pairs( e.class ) do | |||
u:addClass( s ) | |||
end -- for k, s | |||
else | else | ||
s = " | s = string.format( "params.%s.%s[%d].class INVALID", | ||
Fault | at, "suggestedvalues", i ) | ||
Fault( s ) | |||
end | end | ||
end | end | ||
if e.css then | |||
if type( e.css ) == "table" then | |||
u:css( e.css ) | |||
end | else | ||
s = string.format( "params.%s.%s[%d].css INVALID", | |||
at, "suggestedvalues", i ) | |||
Fault( s ) | |||
end | |||
end | |||
if e.style then | |||
if type( e.style ) == "string" then | |||
u:cssText( e.style ) | |||
else | |||
s = string.format( "params.%s.%s[%d].style INVALID", | |||
at, "suggestedvalues", i ) | |||
Fault( s ) | |||
end | |||
end | |||
if about.type == "wiki-file-name" and not e.icon then | |||
e.icon = e.code | |||
end | |||
if e.label then | |||
s = type( e.label ) | |||
if s == "string" then | |||
s = mw.text.trim( e.label ) | |||
if s == "" then | |||
s = string.format( "params.%s.%s[%d].label %s", | |||
at, | |||
"suggestedvalues", | |||
i, | |||
"EMPTY" ) | |||
else | |||
story = s | |||
end | |||
elseif s == "table" then | |||
story = faraway( e.label ) | |||
else | |||
s = string.format( "params.%s.%s[%d].label INVALID", | |||
at, "suggestedvalues", i ) | |||
Fault( s ) | |||
end | |||
end | |||
s = false | |||
if type( e.icon ) == "string" then | |||
t = mw.title.makeTitle( 6, e.icon ) | |||
if t and t.file.exists then | |||
s = string.format( "[[%s|16px]]", t.prefixedText ) | |||
end | |||
end | |||
if not s and not less and e.label then | |||
s = mw.ustring.char( 0x2013 ) | |||
end | |||
if s then | |||
d = mw.html.create( "span" ) | |||
:wikitext( s ) | |||
if TemplateData.ltr then | |||
if not less then | |||
d:css( "margin-left", "0.5em" ) | |||
end | |||
if story then | |||
d:css( "margin-right", "0.5em" ) | |||
end | |||
else | |||
if not less then | |||
d:css( "margin-right", "0.5em" ) | |||
end | |||
if story then | |||
d:css( "margin-left", "0.5em" ) | |||
end | end | ||
end | |||
u:node( d ) | |||
end | |||
if story then | |||
u:wikitext( story ) | |||
end | |||
r1:newline() | |||
:node( u ) | |||
end -- for i | |||
end | |||
if not r1 then | |||
Fault( string.format( "params.%s.suggestedvalues INVALID", at ) ) | |||
r1 = mw.html.create( "code" ) | |||
:addClass( "error" ) | |||
:wikitext( "INVALID" ) | |||
end | |||
return r1, r2 | |||
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 | |||
local | |||
for k, v in pairs( | |||
if | |||
else | else | ||
i = 2 | |||
break -- for k, v | |||
end | end | ||
end -- for k, v | end -- for k, v | ||
if | if i > 1 then | ||
local pointers = { } | |||
local points = { } | |||
local given = { } | |||
for k, v in pairs( Data.tree.params ) do | |||
i = facet( k, 1 ) | |||
if type( v ) == "table" then | |||
if type( v.label ) == "string" then | |||
s = mw.text.trim( v.label ) | |||
if s == "" then | |||
s = k | |||
end | |||
else | |||
s = k | |||
end | end | ||
if | if given[ s ] then | ||
if given[ s ] == 1 then | |||
local scream = "Parameter label '%s' detected multiple times" | |||
Fault( string.format( scream, s ) ) | |||
given[ s ] = 2 | |||
end | end | ||
else | |||
given[ s ] = 1 | |||
end | end | ||
end | |||
if i then | |||
table.insert( points, i ) | |||
if | pointers[ i ] = k | ||
i = facet( k, i ) | |||
if i then | |||
s = "Parameter '%s' detected twice" | |||
Fault( string.format( s, k ) ) | |||
end | end | ||
else | else | ||
s = "Parameter '%s' not detected" | |||
Fault( string.format( s, k ) ) | |||
end | 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 | ||
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 styles = "mw-templatedata-doc-param-" | |||
local sort, typed | |||
for k, v in pairs( param ) do | |||
if v == "" then | |||
param[ k ] = false | |||
end | 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 | 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 | end | ||
code = mw.html.create( "td" ) | |||
:addClass( styles .. "name" ) | |||
:node( code ) | |||
if access:match( "^%d+$" ) then | |||
code:attr( "data-sort-value", | |||
string.format( "%05d", tonumber( access ) ) ) | |||
end | end | ||
if type( param.aliases ) == "table" then | |||
local lapsus, syn | |||
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" ) ) | |||
:wikitext( s ) | |||
else | |||
syn = mw.html.create( "span" ) | |||
:addClass( styles .. "alias" ) | |||
:css( "white-space", "nowrap" ) | |||
:wikitext( s ) | |||
code:node( syn ) | |||
end | |||
else | |||
lapsus = true | |||
code:node( mw.html.create( "code" ) | |||
:addClass( "error" ) | |||
:wikitext( type( v ) ) ) | |||
end | end | ||
end -- for k, v | |||
if lapsus then | |||
s = string.format( "params.<code>%s</code>.aliases", access ) | |||
Fault( factory( "invalid-value" ):gsub( "$1", s ) ) | |||
legal = false | |||
end | end | ||
end | |||
-- description etc. | |||
s = fashioned( param ) | |||
if s then | |||
desc:node( s ) | |||
end | |||
if param.style then | |||
s = type( param.style ) | |||
if s == "table" then | |||
desc:css( param.style ) | |||
elseif s == "string" then | |||
desc:cssText( param.style ) | |||
end | |||
end | |||
if param.suggestedvalues or | |||
- | param.default or | ||
param.example or | |||
param.autovalue then | |||
local details = { "suggestedvalues", | |||
"default", | |||
"example", | |||
"autovalue" } | |||
local dl = mw.html.create( "dl" ) | |||
local dd, section, show | |||
for i = 1, #details do | |||
elseif s | s = details[ i ] | ||
show = param[ s ] | |||
if show then | |||
else | dd = mw.html.create( "dd" ) | ||
section = factory( "doc-param-" .. s ) | |||
if param.type == "boolean" and | |||
( show == "0" or show == "1" ) then | |||
local boole = Permit.boole[ ( show == "1" ) ] | |||
if boole.lead == true then | |||
dd:node( mw.html.create( "code" ) | |||
:wikitext( show ) ) | |||
:wikitext( " " ) | |||
end | |||
if type( boole.show ) == "string" then | |||
local v = mw.html.create( "span" ) | |||
:attr( "aria-hidden", "true" ) | |||
:wikitext( boole.show ) | |||
if boole.css then | |||
v:css( boole.css ) | |||
end | |||
dd:node( v ) | |||
end | |||
if type( boole.suffix ) == "string" then | |||
dd:wikitext( boole.suffix ) | |||
end | |||
if boole.lead == false then | |||
dd:wikitext( " " ) | |||
:node( mw.html.create( "code" ) | |||
:wikitext( show ) ) | |||
end | |||
elseif s == "suggestedvalues" then | |||
local html, values = feasible( param, access ) | |||
dd:newline() | |||
:node( html ) | |||
Data.params[ access ].suggestedvalues = values | |||
else | |||
dd:wikitext( show ) | |||
end | end | ||
dl:node( mw.html.create( "dt" ) | |||
:wikitext( section ) ) | |||
:node( dd ) | |||
end | end | ||
end -- i = 1, #details | |||
end | desc:node( dl ) | ||
end | end | ||
-- type | |||
if type( param.type ) == "string" then | |||
local function finalize( advance ) | param.type = mw.text.trim( param.type ) | ||
-- Wrap presentation into frame | if param.type == "" then | ||
-- Parameter: | param.type = false | ||
-- advance -- true, for nice | end | ||
-- Returns string | end | ||
local r, lapsus | if param.type then | ||
if Data.div then | s = Permit.types[ param.type ] | ||
r = tostring( Data.div ) | typed = mw.html.create( "td" ) | ||
elseif Data.strip then | if s then | ||
r = Data.strip | if s == "string" then | ||
else | Data.params[ access ].type = s | ||
lapsus = true | typed:wikitext( factory( "doc-param-type-" .. s ) ) | ||
r = "" | :tag( "br" ) | ||
end | typed:node( mw.html.create( "span" ) | ||
r = r .. failures() | :addClass( "error" ) | ||
if Data.source then | :wikitext( param.type ) ) | ||
local live = ( advance or lapsus ) | Data.lasting = true | ||
if not live then | else | ||
live = TemplateData.frame:preprocess( "{{REVISIONID}}" ) | local support = Config[ "support4" .. param.type ] | ||
live = ( live == "" ) | s = factory( "doc-param-type-" .. param.type ) | ||
end | if support then | ||
if live then | s = string.format( "[[%s|%s]]", support, s ) | ||
r = r .. fancy( advance, lapsus ) | end | ||
end | typed:wikitext( s ) | ||
end | end | ||
return r | else | ||
end -- finalize() | Data.params[ access ].type = "unknown" | ||
typed:addClass( "error" ) | |||
:wikitext( "INVALID" ) | |||
s = string.format( "params.<code>%s</code>.type", access ) | |||
local function find() | Fault( factory( "invalid-value" ):gsub( "$1", s ) ) | ||
-- Find JSON data within page source (title) | legal = false | ||
-- Returns string, or nil | end | ||
local s = Data.title:getContent() | else | ||
local i, j = s:find( "<templatedata>", 1, true ) | typed = mw.html.create( "td" ) | ||
local r | :wikitext( factory( "doc-param-type-unknown" ) ) | ||
if i then | Data.params[ access ].type = "unknown" | ||
if param.default then | |||
Data.params[ access ].default = nil | |||
Fault( "Default value requires <code>type</code>" ) | |||
legal = false | |||
end | |||
end | |||
-- status | |||
if param.required then | |||
mode = 1 | |||
if param.autovalue then | |||
Fault( string.format( "autovalued <code>%s</code> required", | |||
access ) ) | |||
legal = false | |||
end | |||
if param.default then | |||
Fault( string.format( "Defaulted <code>%s</code> required", | |||
access ) ) | |||
legal = false | |||
end | |||
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 = factory( "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 | |||
if param.suggested and mode == 4 then | |||
s = string.format( "Suggesting deprecated <code>%s</code>", | |||
access ) | |||
Fault( s ) | |||
legal = false | |||
end | |||
end | |||
-- <tr> | |||
r:attr( "id", "templatedata:" .. mw.uri.anchorEncode( access ) ) | |||
:css( Permit.css[ 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( "border", "#FF0000 3px 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 tbl = mw.html.create( "table" ) | |||
local tr = mw.html.create( "tr" ) | |||
feat() | |||
if Data.order and #Data.order > 1 then | |||
tbl:addClass( "sortable" ) | |||
end | |||
if type( Config.classTable ) == "table" then | |||
for k, v in pairs( Config.classTable ) do | |||
tbl:addClass( v ) | |||
end -- for k, v | |||
end | |||
if type( Config.cssTable ) == "table" then | |||
tbl:css( Config.cssTable ) | |||
end | |||
tr:node( mw.html.create( "th" ) | |||
:attr( "colspan", "2" ) | |||
:css( Permit.css.tablehead ) | |||
:wikitext( factory( "doc-param-name" ) ) ) | |||
:node( mw.html.create( "th" ) | |||
:css( Permit.css.tablehead ) | |||
:wikitext( factory( "doc-param-desc" ) ) ) | |||
:node( mw.html.create( "th" ) | |||
:css( Permit.css.tablehead ) | |||
:wikitext( factory( "doc-param-type" ) ) ) | |||
:node( mw.html.create( "th" ) | |||
:css( Permit.css.tablehead ) | |||
:wikitext( factory( "doc-param-status" ) ) ) | |||
tbl:newline() | |||
-- :node( mw.html.create( "thead" ) | |||
:node( tr ) | |||
-- ) | |||
:newline() | |||
if Data.order then | |||
local leave, s | |||
for i = 1, #Data.order do | |||
s = Data.order[ i ] | |||
if s:sub( 1, 1 ) == "=" then | |||
leave = true | |||
tbl:node( fatten( s ) ) | |||
Data.order[ i ] = false | |||
elseif s:match( "[=|]" ) then | |||
Fault( string.format( "Bad param <code>%s</code>", | |||
s ) ) | |||
else | |||
tbl:node( feature( s ) ) | |||
end | |||
end -- for i = 1, #Data.order | |||
if leave then | |||
for i = #Data.order, 1, -1 do | |||
if not Data.order[ i ] then | |||
table.remove( Data.order, i ) | |||
end | |||
end -- for i = #Data.order, 1, -1 | |||
end | |||
Data.tag.paramOrder = Data.order | |||
end | |||
if Config.cssTabWrap or Data.scroll then | |||
r = mw.html.create( "div" ) | |||
if type( Config.cssTabWrap ) == "table" then | |||
r:css( Config.cssTabWrap ) | |||
elseif type( Config.cssTabWrap ) == "string" then | |||
-- deprecated | |||
r:cssText( Config.cssTabWrap ) | |||
end | |||
if Data.scroll then | |||
r:css( "height", Data.scroll ) | |||
:css( "overflow", "auto" ) | |||
end | |||
r:node( tbl ) | |||
else | |||
r = tbl | |||
end | |||
end | |||
return r | |||
end -- features() | |||
local function fellow( any, assigned, at ) | |||
-- Check sets[] parameter and issue error message, if necessary | |||
-- Parameter: | |||
-- any -- should be number | |||
-- assigned -- parameter name | |||
-- at -- number, of set | |||
local s | |||
if type( any ) ~= "number" then | |||
s = "<code>sets[%d].params[%s]</code>??" | |||
Fault( string.format( s, | |||
at, | |||
mw.text.nowiki( tostring( any ) ) ) ) | |||
elseif type( assigned ) == "string" then | |||
if not Data.got.params[ assigned ] then | |||
s = "<code>sets[%d].params %s</code> is undefined" | |||
Fault( string.format( s, at, assigned ) ) | |||
end | |||
else | |||
s = "<code>sets[%d].params[%d] = %s</code>??" | |||
Fault( string.format( s, k, type( assigned ) ) ) | |||
end | |||
end -- fellow() | |||
local function fellows() | |||
-- Check sets[] and issue error message, if necessary | |||
local s | |||
if type( Data.got.sets ) == "table" then | |||
if type( Data.got.params ) == "table" then | |||
for k, v in pairs( Data.got.sets ) do | |||
if type( k ) == "number" then | |||
if type( v ) == "table" then | |||
for ek, ev in pairs( v ) do | |||
if ek == "label" then | |||
s = type( ev ) | |||
if s ~= "string" and | |||
s ~= "table" then | |||
s = "<code>sets[%d].label</code>??" | |||
Fault( string.format( s, k ) ) | |||
end | |||
elseif ek == "params" and | |||
type( ev ) == "table" then | |||
for pk, pv in pairs( ev ) do | |||
fellow( pk, pv, k ) | |||
end -- for pk, pv | |||
else | |||
ek = mw.text.nowiki( tostring( ek ) ) | |||
s = "<code>sets[%d][%s]</code>??" | |||
Fault( string.format( s, k, ek ) ) | |||
end | |||
end -- for ek, ev | |||
else | |||
k = mw.text.nowiki( tostring( k ) ) | |||
v = mw.text.nowiki( tostring( v ) ) | |||
s = string.format( "<code>sets[%s][%s]</code>??", | |||
k, v ) | |||
Fault( s ) | |||
end | |||
else | |||
k = mw.text.nowiki( tostring( k ) ) | |||
s = string.format( "<code>sets[%s]</code> ?????", k ) | |||
Fault( s ) | |||
end | |||
end -- for k, v | |||
else | |||
s = "<code>params</code> required for <code>sets</code>" | |||
Fault( s ) | |||
end | |||
else | |||
s = "<code>sets</code> needs to be of <code>object</code> type" | |||
Fault( s ) | |||
end | |||
end -- fellows() | |||
local function finalize( advance ) | |||
-- Wrap presentation into frame | |||
-- Parameter: | |||
-- advance -- true, for nice | |||
-- Returns string | |||
local r, lapsus | |||
if Data.div then | |||
r = tostring( Data.div ) | |||
elseif Data.strip then | |||
r = Data.strip | |||
else | |||
lapsus = true | |||
r = "" | |||
end | |||
r = r .. failures() | |||
if Data.source then | |||
local live = ( advance or lapsus ) | |||
if not live then | |||
live = TemplateData.frame:preprocess( "{{REVISIONID}}" ) | |||
live = ( live == "" ) | |||
end | |||
if live then | |||
r = r .. fancy( advance, lapsus ) | |||
end | |||
end | |||
return r | |||
end -- finalize() | |||
local function find() | |||
-- Find JSON data within page source (title) | |||
-- Returns string, or nil | |||
local s = Data.title:getContent() | |||
local i, j = s:find( "<templatedata>", 1, true ) | |||
local r | |||
if i then | |||
local k = s:find( "</templatedata>", j, true ) | local k = s:find( "</templatedata>", j, true ) | ||
if k then | if k then | ||
Zeile 1.088: | Zeile 1.425: | ||
local function flat( adjust ) | local function flat( adjust ) | ||
-- Remove formatting from text string | -- Remove formatting from text string for VE | ||
-- Parameter: | -- Parameter: | ||
-- arglist -- string, to be stripped, or nil | -- arglist -- string, to be stripped, or nil | ||
Zeile 1.096: | Zeile 1.433: | ||
r = adjust:gsub( "\n", " " ) | r = adjust:gsub( "\n", " " ) | ||
if r:find( "<noexport>", 1, true ) then | if r:find( "<noexport>", 1, true ) then | ||
r = r:gsub( "<noexport> | r = r:gsub( "<noexport>.*</noexport>", "" ) | ||
end | |||
if r:find( "<exportonly>", 1, true ) then | |||
r = r:gsub( "</?exportonly>", "" ) | |||
end | end | ||
if r:find( "''", 1, true ) then | if r:find( "''", 1, true ) then | ||
Zeile 1.260: | Zeile 1.600: | ||
if type( elem ) ~= "nil" then | if type( elem ) ~= "nil" then | ||
if not target then | if not target then | ||
if access then | |||
if not Data.tree.params then | |||
Data.tree.params = { } | |||
end | |||
Data.tree.params[ slot ] = { } | |||
target = Data.tree.params[ slot ] | |||
else | |||
Data.tree = { } | |||
target = Data.tree | |||
end | |||
end | end | ||
target[ k ] = elem | target[ k ] = elem | ||
Zeile 1.292: | Zeile 1.632: | ||
end | end | ||
end | end | ||
if type( v ) ~= "nil" then | if type( v ) ~= "nil" and | ||
k ~= "suggestedvalues" then | |||
tag[ k ] = v | tag[ k ] = v | ||
end | end | ||
Zeile 1.305: | Zeile 1.646: | ||
end | end | ||
end -- for k, v | end -- for k, v | ||
if not access and Data.got.sets then | |||
fellows() | |||
end | |||
else | else | ||
Fault( f() .. " needs to be of <code>object</code> type" ) | Fault( f() .. " needs to be of <code>object</code> type" ) | ||
Zeile 1.434: | Zeile 1.778: | ||
end | end | ||
if n > 1 then | if n > 1 then | ||
spaced = string.rep( "_", n ) .. " " | spaced = string.rep( "_", n - 1 ) .. " " | ||
end | end | ||
show = show .. s | show = show .. s | ||
Zeile 1.481: | Zeile 1.825: | ||
end | end | ||
end | end | ||
if source then | if source and Data.tag then | ||
Data.tag.format = source | Data.tag.format = source | ||
end | end | ||
Zeile 1.713: | Zeile 2.057: | ||
-- Retrieve versioning and check for compliance | -- Retrieve versioning and check for compliance | ||
-- Precondition: | -- Precondition: | ||
-- atleast -- string, with required version | -- atleast -- string, with required version | ||
-- | -- or wikidata|item|~|@ or false | ||
-- Postcondition: | -- Postcondition: | ||
-- Returns string -- with queried version, also if problem | -- Returns string -- with queried version/item, also if problem | ||
-- false -- if appropriate | -- false -- if appropriate | ||
-- 2020-08-17 | |||
local since = atleast | local since = atleast | ||
local last = ( since == "~" ) | |||
local linked = ( since == "@" ) | |||
local link = ( since == "item" ) | |||
local r | local r | ||
if last or since == "wikidata" then | if last or link or linked or since == "wikidata" then | ||
local item = Failsafe.item | local item = Failsafe.item | ||
since = false | since = false | ||
if type( item ) == "number" and item > 0 then | if type( item ) == "number" and item > 0 then | ||
local | local suited = string.format( "Q%d", item ) | ||
if link then | |||
r = suited | |||
else | |||
local entity = mw.wikibase.getEntity( suited ) | |||
if type( entity ) == "table" then | |||
local seek = Failsafe.serialProperty or "P348" | |||
local vsn = entity:formatPropertyValues( seek ) | |||
r = false | if type( vsn ) == "table" and | ||
type( vsn.value ) == "string" and | |||
r = vsn.value | vsn.value ~= "" then | ||
if last and vsn.value == Failsafe.serial then | |||
r = false | |||
elseif linked then | |||
if mw.title.getCurrentTitle().prefixedText | |||
== mw.wikibase.getSitelink( suited ) then | |||
r = false | |||
else | |||
r = suited | |||
end | |||
else | |||
r = vsn.value | |||
end | |||
end | end | ||
end | end |