Module:Dochead: Difference between revisions
No edit summary |
autocategorize metatemplates |
||
| (10 intermediate revisions by 2 users not shown) | |||
| Line 6: | Line 6: | ||
local p = {} | local p = {} | ||
-- TODO: | -- TODO: (Low-ish priority): rewrite to eliminate redundant code | ||
-- Produces a hatnote that is placed on the top of a documentation page (either | -- Produces a hatnote that is placed on the top of a documentation page (either | ||
| Line 18: | Line 16: | ||
-- - whether a template has an accompanying module (overridable/toggleable) | -- - whether a template has an accompanying module (overridable/toggleable) | ||
-- - what functions from which modules are invoked | -- - what functions from which modules are invoked | ||
-- Helper function: categorize modules | -- Helper function: categorize modules | ||
| Line 65: | Line 32: | ||
-- Check whether corresponding template exists | -- Check whether corresponding template exists | ||
-- Then check whether that template invokes the module | -- Then check whether that template invokes the module | ||
local has_template = iutils.page_exists("Template:" .. corr_template) | local has_template = iutils.page_exists("Template:" .. corr_template:gsub("/doc$", "")) | ||
-- Check whether to use detect_corr_page option | -- Check whether to use detect_corr_page option | ||
| Line 76: | Line 43: | ||
-- If the module has a template, check for whether it invokes it. | -- If the module has a template, check for whether it invokes it. | ||
if has_template then | if has_template then | ||
local wikitext = iutils.get_and_preprocess_content("Template", corr_template) | local wikitext = iutils.get_and_preprocess_content("Template", corr_template:gsub("/doc$", "")) | ||
local invokes = iutils.find_invokes(wikitext) | local invokes = iutils.find_invokes(wikitext) | ||
has_template = has_template and iutils.invocation_exists(invokes, pagename) | has_template = has_template and iutils.invocation_exists(invokes, pagename:gsub("/doc$", "")) | ||
end | end | ||
| Line 92: | Line 59: | ||
-- other modules. Such modules generally don't have a corresponding | -- other modules. Such modules generally don't have a corresponding | ||
-- template. | -- template. | ||
-- - data/datamodule indicates a module whose purpose is to provide data | |||
-- values to other modules. Like library modules, these don't have a | |||
-- corresponding template. | |||
-- Does the module have a template? | -- Does the module have a template? | ||
-- - dualuse, metatemplate, and noinvoke: YES (REQUIRED!!) | -- - dualuse, metatemplate, and noinvoke: YES (REQUIRED!!) | ||
-- - metamodule/library: GENERALLY NO | -- - metamodule/library and data: GENERALLY NO | ||
local result = "" | local result = "" | ||
if header == "dualuse" then | if header == "dualuse" then | ||
| Line 100: | Line 70: | ||
result = string.format( | result = string.format( | ||
"This module may be invoked by templates using its corresponding template [[Template:%s]], or used directly from other modules.", | "This module may be invoked by templates using its corresponding template [[Template:%s]], or used directly from other modules.", | ||
corr_template | corr_template:gsub("/doc$", "") | ||
) | ) | ||
else | else | ||
result = string.format( | result = string.format( | ||
"This module has a | "This module has a corresponding template that is currently missing or does not use this module. ([[Special:EditPage/Template:%s|edit template]])", | ||
corr_template | corr_template:gsub("/doc$", "") | ||
) | ) | ||
end | end | ||
| Line 113: | Line 83: | ||
result = string.format( | result = string.format( | ||
"This module implements a metatemplate, and may be invoked by templates using its corresponding template [[Template:%s]], or used directly from other modules.", | "This module implements a metatemplate, and may be invoked by templates using its corresponding template [[Template:%s]], or used directly from other modules.", | ||
corr_template | corr_template:gsub("/doc$", "") | ||
) | ) | ||
else | else | ||
| Line 122: | Line 92: | ||
if has_template then | if has_template then | ||
result = string.format( | result = string.format( | ||
"This module should not be invoked directly; use its corresponding instead: [[Template:%s]].", | "This module should not be invoked directly; use its corresponding template instead: [[Template:%s]].", | ||
corr_template | corr_template:gsub("/doc$", "") | ||
) | ) | ||
else | else | ||
result = string.format( | result = string.format( | ||
"This module implements a template that is currently missing or does not use this module. ([[Special:EditPage/Template:%s|edit template]])", | "This module implements a template that is currently missing or does not use this module. ([[Special:EditPage/Template:%s|edit template]])", | ||
corr_template | corr_template:gsub("/doc$", "") | ||
) | ) | ||
end | end | ||
| Line 134: | Line 104: | ||
elseif header == "library" or header == "metamodule" then | elseif header == "library" or header == "metamodule" then | ||
result = "This module primarily serves as a library for other modules and has no corresponding template." | result = "This module primarily serves as a library for other modules and has no corresponding template." | ||
elseif header == "data" or pagename:gsub("/doc$", ""):match("/data$") then | |||
result = "This module primarily serves to provide data values for other modules and has no corresponding template." | |||
elseif header == "none" then | |||
result = "" | |||
else | else | ||
if has_template and header ~= "" then | if has_template and header ~= "" then | ||
result = string.format("%s This module implements [[Template:%s]].", header, corr_template) | result = string.format("%s This module implements [[Template:%s]].", header, corr_template:gsub("/doc$", "")) | ||
elseif has_template and header == "" then | elseif has_template and header == "" then | ||
result = string.format("This module implements [[Template:%s]].", corr_template) | result = string.format("This module implements [[Template:%s]].", corr_template:gsub("/doc$", "")) | ||
else | else | ||
result = header | result = header | ||
| Line 152: | Line 128: | ||
return "" .. cats | return "" .. cats | ||
else | else | ||
return string.format(":''%s''", result) | return string.format(": ''%s''%s\n", result, cats) | ||
end | end | ||
end | end | ||
-- Helper function: categorize template | -- Helper function: categorize template | ||
local function categorize_template(pagename, has_invoke) | local function categorize_template(pagename, has_invoke, is_metatemplate) | ||
local cats = "" | local cats = "" | ||
if pagename:match("/doc$") then | if pagename:match("/doc$") then | ||
| Line 165: | Line 141: | ||
if has_invoke then | if has_invoke then | ||
cats = cats .. " [[Category:Lua-based templates]]" | cats = cats .. " [[Category:Lua-based templates]]" | ||
end | |||
if is_metatemplate then | |||
cats = cats .. " [[Category:Metatemplates]]" | |||
end | end | ||
end | end | ||
| Line 192: | Line 171: | ||
-- Check whether corresponding module exists | -- Check whether corresponding module exists | ||
-- Then check whether this template invokes the module | -- Then check whether this template invokes the module | ||
local has_module = iutils.page_exists("Module:" .. corr_module) | local has_module = iutils.page_exists("Module:" .. corr_module:gsub("/doc$", "")) | ||
-- Check whether to use detect_corr_page option | -- Check whether to use detect_corr_page option | ||
| Line 204: | Line 183: | ||
-- Check for whether the template invokes that module, regardless of whether | -- Check for whether the template invokes that module, regardless of whether | ||
-- it uses the corresponding module. | -- it uses the corresponding module. | ||
local wikitext = iutils.get_and_preprocess_content("Template", pagename) | local wikitext = iutils.get_and_preprocess_content("Template", pagename:gsub("/doc$", "")) | ||
local invokes = iutils.find_invokes(wikitext) | local invokes = iutils.find_invokes(wikitext) | ||
local is_module_invoked = iutils.invocation_exists(invokes, corr_module) | local is_module_invoked = iutils.invocation_exists(invokes, corr_module:gsub("/doc$", "")) | ||
-- Heading meanings and usage on templates | -- Heading meanings and usage on templates | ||
| Line 216: | Line 195: | ||
-- Does the template have a module? | -- Does the template have a module? | ||
-- - dualuse and metatemplate: YES (REQUIRED!!) | -- - dualuse and metatemplate: YES (REQUIRED!!) | ||
-- - noinvoke | -- - noinvoke, metamodule/library, and data/datamodule: option's don't apply | ||
-- to templates. | |||
-- RATIONALE FOR NOINVOKE NOT APPLYING: a template may invoke functions from | -- RATIONALE FOR NOINVOKE NOT APPLYING: a template may invoke functions from | ||
-- more than one module, but one of them must be the "main" module. Since | -- more than one module, but one of them must be the "main" module. Since | ||
| Line 226: | Line 206: | ||
result = string.format( | result = string.format( | ||
"This template is implemented by the Lua module [[Module:%s]]. See its module page for Lua-based template implementation.", | "This template is implemented by the Lua module [[Module:%s]]. See its module page for Lua-based template implementation.", | ||
corr_module | corr_module:gsub("/doc$", "") | ||
) | ) | ||
elseif has_module and not is_module_invoked then | elseif has_module and not is_module_invoked then | ||
result = string.format( | result = string.format( | ||
"This template has a corresponding Lua module [[Module:%s]], but does not invoke its functions.", | "This template has a corresponding Lua module [[Module:%s]], but does not invoke its functions.", | ||
corr_module | corr_module:gsub("/doc$", "") | ||
) | ) | ||
else | else | ||
result = string.format( | result = string.format( | ||
"This template is implemented by a module that is currently missing. [[Special:EditPage/Module:%s]]", | "This template is implemented by a module that is currently missing. [[Special:EditPage/Module:%s]]", | ||
corr_module | corr_module:gsub("/doc$", "") | ||
) | ) | ||
end | end | ||
| Line 244: | Line 224: | ||
result = string.format( | result = string.format( | ||
"This template is a metatemplate. It is used to build other templates and should not be used standalone, except for testing or simple usage. This template is implemented by the Lua module [[Module:%s]].", | "This template is a metatemplate. It is used to build other templates and should not be used standalone, except for testing or simple usage. This template is implemented by the Lua module [[Module:%s]].", | ||
corr_module | corr_module:gsub("/doc$", "") | ||
) | ) | ||
elseif has_module and not is_module_invoked then | elseif has_module and not is_module_invoked then | ||
result = string.format( | result = string.format( | ||
"This metatemplate has a corresponding Lua module [[Module:%s]], but does not invoke its functions.", | "This metatemplate has a corresponding Lua module [[Module:%s]], but does not invoke its functions.", | ||
corr_module | corr_module:gsub("/doc$", "") | ||
) | ) | ||
else | else | ||
| Line 255: | Line 235: | ||
end | end | ||
elseif header == "noinvoke" or header == "library" or header == "metamodule" then | elseif header == "noinvoke" or header == "library" or header == "metamodule" or header == "data" or header == "datamodule" then | ||
result = "This template has a header option in the wrong namespace. It should be used within the Module namespace." | result = "This template has a header option in the wrong namespace. It should be used within the Module namespace." | ||
| Line 263: | Line 243: | ||
"%s. This template is implemented by the Lua module [[Module:%s]].", | "%s. This template is implemented by the Lua module [[Module:%s]].", | ||
header, | header, | ||
corr_module | corr_module:gsub("/doc$", "") | ||
) | ) | ||
elseif has_module and header ~= "" and not is_module_invoked then | elseif has_module and header ~= "" and not is_module_invoked then | ||
| Line 269: | Line 249: | ||
"%s. This template has a corresponding Lua module [[Module:%s]], but does not invoke its functions.", | "%s. This template has a corresponding Lua module [[Module:%s]], but does not invoke its functions.", | ||
header, | header, | ||
corr_module | corr_module:gsub("/doc$", "") | ||
) | ) | ||
elseif has_module and header == "" and is_module_invoked then | elseif has_module and header == "" and is_module_invoked then | ||
result = string.format( | result = string.format( | ||
"This template is implemented by the Lua module [[Module:%s]].", | "This template is implemented by the Lua module [[Module:%s]].", | ||
corr_module | corr_module:gsub("/doc$", "") | ||
) | ) | ||
elseif has_module and header == "" and not is_module_invoked then | elseif has_module and header == "" and not is_module_invoked then | ||
result = string.format( | result = string.format( | ||
"This template has a corresponding Lua module [[Module:%s]], but does not invoke its functions.", | "This template has a corresponding Lua module [[Module:%s]], but does not invoke its functions.", | ||
corr_module | corr_module:gsub("/doc$", "") | ||
) | ) | ||
else | else | ||
| Line 290: | Line 270: | ||
-- Categorize | -- Categorize | ||
local cats = categorize_template(pagename, #invokes > 0) | local cats = categorize_template(pagename, #invokes > 0, header == "metatemplate") | ||
if result == "" and invocation_hatnote == "" then | if header == "none" then | ||
return cats | |||
elseif result == "" and invocation_hatnote == "" then | |||
return "" | return "" | ||
elseif result == "" and invocation_hatnote ~= "" then | elseif result == "" and invocation_hatnote ~= "" then | ||
return string.format(":''%s''", invocation_hatnote) | return string.format(": ''%s''%s\n", invocation_hatnote, cats) | ||
elseif result ~= "" and invocation_hatnote == "" then | elseif result ~= "" and invocation_hatnote == "" then | ||
return string.format(":''%s''", result) | return string.format(": ''%s''%s\n", result, cats) | ||
else | else | ||
return string.format(":''%s''\n:''%s''", result, invocation_hatnote) | return string.format(": ''%s''\n: ''%s'' %s\n", result, invocation_hatnote, cats) | ||
end | end | ||
end | end | ||
| Line 315: | Line 297: | ||
-- If header is none, skip everything | -- If header is none, skip everything | ||
if header == "none" then | if header == "none" then | ||
return categorize(namespace, pagename) | --return categorize(namespace, pagename) | ||
end | end | ||
| Line 327: | Line 309: | ||
result = p.make_template_hatnote(header, pagename, corr_module, detect_corr_page) | result = p.make_template_hatnote(header, pagename, corr_module, detect_corr_page) | ||
else | else | ||
result = ":''This documentation template is in the wrong namespace. It should be within the Template or Module namespaces.''\n" | result = ": ''This documentation template is in the wrong namespace. It should be within the Template or Module namespaces.''\n" | ||
end | end | ||
| Line 357: | Line 339: | ||
-- Option to detect corresponding page (default true) | -- Option to detect corresponding page (default true) | ||
args["detect_corr_page"] = args["detect_corr_page"] == nil and true or yesno(args["detect_corr_page"]) | args["detect_corr_page"] = args["detect_corr_page"] == nil and true or yesno(args["detect_corr_page"]) | ||
local result = p._dochead(args) | |||
-- Debugger option to show generated WikiText | |||
local wtext = yesno(frame.args["wtext"] or args["wtext"]) | |||
if wtext == true then | |||
result = "<syntaxhighlight lang=\"wikitext\">" .. result .. "</syntaxhighlight>" | |||
end | |||
return | return frame:preprocess(result) | ||
end | end | ||