require ('strict');
--[[--------------------------< A R T I C L E _ C O N T E N T _ G E T >----------------------------------------
get template content
]]
local function template_content_get (template)
if not template:match ('^[Tt]emplate:') then -- when template name does not include template namespace
template = 'Template:' .. template; -- add it
end
local content = mw.title.new (template):getContent(); -- get the content of the template
if not content then -- nil when template does not exist
return nil, '<span style="color:#bf3c2c">cannot find [[' .. template .. ']]</span>'; -- return nil with error message
end
content = content:gsub ('<!%-%-[^>]*%-%->', ''); -- remove html comments that might be placed near our parameters of interest
return content;
end
--[[--------------------------< A L I A S _ M A P >------------------------------------------------------------
special case
read the contents of |_alias-map= and add unordered list and parameter formatting
|alias-map= holds a comma-separated list of colon-separated parameter pairs where the left parameter name is the
wrapper template's parameter name (from) and the right parameter name is the working template's parameter name (to).
render as:
* from → to
]]
local function alias_map (alias_map_t)
for k, v in ipairs (alias_map_t) do
alias_map_t[k] = v:gsub ('([^:]+)%s*:%s*(.+)', '%*{{para|%1}} → {{para|%2}}'); -- make an unordered list item
end
return alias_map_t;
end
--[[--------------------------< S P E C I A L _ S O R T >------------------------------------------------------
special sort function for the alias map list (sort only by the from portion of 'from:to') and for the default
settings list (sort by parameter name only)
]]
local function special_sort (seq_t, pattern)
local function comp (a, b) -- local function to do the sort comparison
pattern = pattern or '^[^:]+'; -- default to pattern for alias map sorting; pattern for default settings is '|[^|]+'
a = a:match (pattern); -- compare the 'from' portions only
b = b:match (pattern);
a = mw.text.trim (a); -- make sure no extraneous white space
b = mw.text.trim (b);
return a < b; -- and do the comparison
end
return table.sort (seq_t, comp); -- do the sort and done
end
--[[--------------------------< S I M P L E >------------------------------------------------------------------
read the contents of <simple_t> (|_reuse= or |_exclude= parameter lists) and add unordered list and parameter
formatting
|_reuse= and |_exclude= each hold a simple list of comma-separated parameter names
]]
local function simple (simple_t)
for k, v in ipairs (simple_t) do
simple_t[k] = v:gsub ('(.+)', '%*{{para|%1}}'); -- make an unordered list item
end
return simple_t;
end
--[[--------------------------< D E F A U L T _ S E T T I N G S >----------------------------------------------
extracts {{#invoke:Template wrapper...}} from the template wikitext, converts from 'wrap' to 'list' and then
preprocesses to get a rendering of only the default parameters. Converts that rendering to an unsorted list
sorted by parameter name.
]]
local function default_settings (template_content, frame, settings_t)
local start, _ = template_content:find ('{{#invoke:Template wrapper');
local listed = template_content:match ('%b{}', start); -- extract the #invoke
listed = listed:gsub ('| *wrap *|', '|list|'); -- switch to list mode
listed = mw.text.unstripNoWiki (frame:preprocess (listed)); -- get the 'listed' template and unstrip the nowikis
listed = listed:gsub ('}}</code>', '<wbr>'); -- replace with html wbr tag for use as a delimiter
listed = listed:gsub ('<code[^>]*>', ''); -- delete opening code tag
local wrapper_t = {} -- individual parameters will go here
for v in listed:gmatch ('<wbr>([^<]+)') do -- extract wach parameter and its value
v = mw.text.decode (v); -- convert html entities
v = v:gsub ('^|', '*{{para|'):gsub ('=', '|', 1) .. '}}'; -- format into an unordered list item
table.insert (wrapper_t, v); -- and save it
end
special_sort (wrapper_t, '|[^|]+'); -- sort by parameter name
table.insert (wrapper_t, 1, settings_t.intro); -- add the introductory sentence
table.insert (wrapper_t, 1, settings_t.hdr_lvl .. settings_t.hdr .. settings_t.hdr_lvl); -- and the section heading
return table.concat (wrapper_t, '\n'); -- and make a big damn string and done
end
--[[--------------------------< G E T _ P A R A M _ V A L _ A S _ S E Q >--------------------------------------
extract the comma-separated list of parameter names from a parameter and split on the commas into a sequence of
parameters. return the sequence when parameter is found in <template_content>; nil else
]]
local function get_param_val_as_seq (template_content, parameter)
local param_value = template_content:match ('| *' .. parameter .. ' *= *([^|]*)'); -- extract parameter value
if not param_value then -- match failed
return nil;
end
param_value = mw.text.trim (param_value); -- no leading or trailing whitespace
return mw.text.split (param_value, '%s*,%s'); -- return a sequence of comma-separated values
end
--[[--------------------------< M A I N >----------------------------------------------------------------------
{{#invoke:Sandbox/trappist the monk/wrapper doc|main|template=Infobox Australian place}}
]]
local function main (frame)
local args_t = require ('Module:Arguments').getArgs (frame); -- get arguments from the invoke
local template_content, msg = template_content_get (args_t.template); -- get the template contents
if not template_content then
return msg; -- when <template_content> nil, msg has an error message
end
local hdr_lvl = string.rep ('=', tonumber (args_t.hdr_lvl) or 3); -- default to '==='
local params_t = {
{
pattern = '_alias%-map', -- for use in string.match()
func = alias_map, -- function to reformat comma-separated list into an unordered list
sort_func = special_sort,
hdr = 'Alias map', -- section header name
intro = 'Introductory sentence ... [[Module:Template_wrapper#alias-map|documentation]]',
},
{
pattern = '_reuse',
func = simple,
sort_func = table.sort,
hdr = 'Reused parameters',
intro = 'Introductory sentence ... [[Module:Template_wrapper#reuse|documentation]]',
},
{
pattern = '_exclude',
func = simple,
sort_func = table.sort,
hdr = 'Excluded parameters',
intro = 'Introductory sentence ... [[Module:Template_wrapper#exclude|documentation]]',
},
defaults_t = {
hdr = 'Default settings',
hdr_lvl = hdr_lvl,
intro = 'Introductory sentence ... ',
}
};
local out_t = {}; -- final output goes here
for _, v_t in ipairs (params_t) do -- for each of the known parameters
local param_seq_t = get_param_val_as_seq (template_content, v_t.pattern); -- a sequence of parameter values nil else
if param_seq_t then -- if we got a sequence
v_t.sort_func (param_seq_t);
param_seq_t = v_t.func (param_seq_t); -- reformat into an unordered list
if 20 < #param_seq_t then -- when the unordered list has more than 20 items
table.insert (param_seq_t, 1, '{{div col}}'); -- add basic column formatting
table.insert (param_seq_t, '{{div col end}}');
end
table.insert (param_seq_t, 1, v_t.intro); -- insert introductory sentence
table.insert (param_seq_t, 1, hdr_lvl .. v_t.hdr .. hdr_lvl); -- insert a header
table.insert (out_t, table.concat (param_seq_t, '\n')); -- and make a big damn string
end
end
table.insert (out_t, default_settings (template_content, frame, params_t.defaults_t));
table.insert (out_t, 1, '<syntaxhighlight lang="wikitext">'); -- add styling for final rendering
table.insert (out_t, '</syntaxhighlight>');
return frame:preprocess (table.concat (out_t, '\n\n')); -- and make a big damn string and done
end
--[[--------------------------< E X P O R T S >----------------------------------------------------------------
]]
return {
main = main,
}