Module:Module introspection: Difference between revisions
Jump to navigation
Jump to search
todo |
ArrowHead294 (talk | contribs) mNo edit summary |
||
| (97 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
-- This module follows [[User:Ganaram inukshuk/Provisional style guide for Lua]] | -- This module follows [[User:Ganaram inukshuk/Provisional style guide for Lua]] | ||
local getArgs = require("Module:Arguments").getArgs | local getArgs = require("Module:Arguments").getArgs | ||
local iutils = require("Module:Introspection utils") | |||
local yesno = require("Module:Yesno") | |||
local p = {} | local p = {} | ||
-- Helper function | -- Helper function | ||
-- | -- Given the output of the above function, create a mediawiki table | ||
function p. | function p.make_dependency_table(module_deps) | ||
-- Table headers | |||
local lines = {} | local lines = {} | ||
table.insert(lines, '{| class="wikitable sortable"') | |||
table.insert(lines, "|+ style=\"font-size: 105%;\" | " .. string.format("Lua modules required (%d)", #module_deps)) | |||
table.insert(lines, "|-") | |||
table.insert(lines, "! Variable") | |||
table.insert(lines, "! Module") | |||
table.insert(lines, "! Functions used") | |||
for | -- Table rows (assuming they're all alphabetized) | ||
local | for _, info in ipairs(module_deps) do | ||
local funcs_text | |||
if | if #info.funcs == 0 then | ||
funcs_text = "''dependency not used''" | |||
else | else | ||
local | local func_lines = {} | ||
for _, func in ipairs(info.funcs) do | |||
table.insert(func_lines, string.format("<code>%s</code>", func)) | |||
end | end | ||
funcs_text = table.concat(func_lines, "<br />") | |||
end | end | ||
table.insert(lines, "|-") | |||
table.insert(lines, "| " .. info.var) | |||
table.insert(lines, "| [[" .. info.dep .. "]]") | |||
table.insert(lines, "| " .. funcs_text) | |||
table.insert( | |||
end | end | ||
-- | -- Table footer | ||
table.insert(lines, "|}") | |||
-- Join all lines into a single string | |||
return table.concat(lines, "\n") | |||
end | end | ||
-- Helper function | -- Helper function | ||
-- | -- Lists module's own functions; requires module name to produce links to each | ||
-- function. | |||
function p.make_function_table(module_name, module_funcs, descriptions, main_function) | |||
-- Check whether descriptions was passed in | |||
-- | local has_descriptions = false | ||
if type(descriptions) == "table" then | |||
for _, _ in pairs(descriptions) do | |||
has_descriptions = true | |||
break | |||
end | end | ||
end | end | ||
-- Table headers | |||
local lines = {} | |||
--table.insert(lines, string.format("'''Module:%s''' provides %d function(s):", module_name, #module_funcs)) | |||
-- | table.insert(lines, '{| class="wikitable sortable"') | ||
- | table.insert(lines, "|+ style=\"font-size: 105%;\" | " .. string.format("Functions provided (%d)", #module_funcs)) | ||
- | table.insert(lines, "|-") | ||
table.insert(lines, "! Line") | |||
table.insert(lines, "! Function") | |||
table.insert(lines, "! Params") | |||
-- | -- If there are descriptions, add a column for that | ||
if has_descriptions then | |||
if | table.insert(lines, "! Description") | ||
end | end | ||
for _, | -- Table rows | ||
local link = string.format("[[Module:%s#L-%d|% | for _, info in ipairs(module_funcs) do | ||
-- Find params for that function, or say "none" if none | |||
local params = {} | |||
for _, param in ipairs(info.params) do | |||
table.insert(params, param) | |||
end | |||
local params_string = "" | |||
if #params == 0 then | |||
params_string = "''none''" | |||
else | |||
params_string = string.format("<code>(%s)</code>", table.concat(params, ", ")) | |||
end | |||
-- Create link to line for that function | |||
local line_num = string.format("[[Module:%s#L-%d|%d]]", module_name, info.line, info.line) | |||
-- Create text for function | |||
local func = "" | |||
if info.name then | |||
func = string.format("<code>%s</code>", info.name) | |||
else | |||
func = "''none''" | |||
end | |||
-- If the function is the main function, add "main" to that cell | -- If the function is the main function, add "main" to that cell | ||
if | if info.name == main_function then | ||
func = func .. " '''(main)'''" | |||
end | end | ||
table.insert( | -- If the function is invokable (it has one param called "frame"), add | ||
table.insert( | -- "invokable" to that cell | ||
table.insert( | if #params == 1 and params[1] == "frame" then | ||
func = func .. " '''(invokable)'''" | |||
end | |||
table.insert(lines, "|-") | |||
table.insert(lines, "| " .. line_num) | |||
table.insert(lines, "| " .. func) | |||
table.insert(lines, "| " .. params_string) | |||
if has_descriptions then | |||
table.insert(lines, "| " .. (descriptions[info.name] or "")) | |||
end | |||
end | end | ||
table.insert( | table.insert(lines, "|}") | ||
return | return table.concat(lines, "\n") | ||
end | end | ||
-- Main function; to be called by wrapper | -- Main function; to be called by wrapper | ||
function p._module_introspection(args) | function p._module_introspection(args) | ||
local args = args or {} | local args = args or {} | ||
local module_name = args["module_name" ] | local module_name = args["module_name" ] | ||
local main_function = args["main_function"] | local main_function = args["main_function"] | ||
local descriptions = args["descriptions" ] | |||
local is_doc = args["is_doc"] | |||
-- Check whether this page is a docpage | |||
-- If so, don't bother | |||
if is_doc then | |||
return "''To see introspection summary, see this module's main page.''" | |||
end | |||
-- Preprocess module and blank-out comments | -- Preprocess module and blank-out comments | ||
local title = mw.title.new('Module:' .. module_name) | --local title = mw.title.new('Module:' .. module_name) | ||
local | --local code = title:getContent() | ||
--code = iutils.preprocess_code(code) -- Blank-out comments | |||
local code = iutils.get_and_preprocess_content("Module", module_name) | |||
-- Get dependencies | -- Get dependencies and their functions used, then build a table | ||
local | local module_deps = iutils.find_dependencies(code) | ||
local | local dep_table = p.make_dependency_table(module_deps) | ||
-- Get module's functions, then build a table using that information | -- Get module's functions, then build a table using that information | ||
local | local module_funcs = iutils.find_functions(code) | ||
local | local func_table = p.make_function_table(module_name, module_funcs, descriptions, main_function) | ||
-- Return the tables | |||
-- Styling may be improved at a later time | |||
local lines = { | |||
'{| class="wikitable mw-collapsible"', | |||
'|-', | |||
'! colspan="2" style="font-size: 105%;" | ' .. string.format("Introspection summary for Module:%s ", module_name), | |||
"|-", | |||
'| style="vertical-align: top; border-right: none;" | ', | |||
func_table, | |||
'| style="vertical-align: top; border-left: none;" | ', | |||
dep_table, | |||
"|}" | |||
} | |||
-- Check whether descriptions was passed in | |||
local has_descriptions = false | |||
if type(descriptions) == "table" then | |||
for _, _ in pairs(descriptions) do | |||
has_descriptions = true | |||
break | |||
end | |||
end | |||
-- If no descriptions were provided, add text below that points to the code. | |||
if not has_descriptions then | |||
table.insert(lines, "''No function descriptions were provided. The Lua code may have further information.''") | |||
end | |||
return table.concat(lines, "\n") | |||
return | |||
end | end | ||
-- Wrapper function for modules | -- Wrapper function for modules | ||
| Line 276: | Line 193: | ||
-- Strip trailing "/doc" if the template is used on a documentation subpage | -- Strip trailing "/doc" if the template is used on a documentation subpage | ||
module_name = module_name:gsub("/doc$", "") | --module_name = module_name:gsub("/doc$", "") | ||
-- Check whether page is the doc page | |||
-- To ensure proper referencing, do not display introspection on a docpage. | |||
local is_doc = string.find(module_name, "/doc$") | |||
-- Normalize module name so it can be used to find the main function, which | -- Normalize module name so it can be used to find the main function, which | ||
| Line 283: | Line 204: | ||
local normalized_name = module_name:gsub("[^%w]", "_"):lower() | local normalized_name = module_name:gsub("[^%w]", "_"):lower() | ||
local main_function = args["main_function"] or "_" .. normalized_name | local main_function = args["main_function"] or "_" .. normalized_name | ||
-- Process all function descriptions, if provided as desc_function_name | |||
local func_descriptions = {} | |||
for key, val in pairs(args) do | |||
local func_name = key:match("^desc_([%w_]+)$") | |||
if func_name and val and val ~= "" then | |||
func_descriptions[func_name] = val | |||
end | |||
end | |||
-- Return | -- Return | ||
local result = p._module_introspection({ | |||
["module_name"] | ["module_name" ] = module_name, | ||
["main_function"] = main_function, | ["main_function"] = main_function, | ||
["descriptions" ] = func_descriptions, | |||
["is_doc"] = is_doc | |||
}) | }) | ||
-- 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 frame:preprocess(result) | |||
end | end | ||
return p | return p | ||
Latest revision as of 20:23, 3 December 2025
- This module should not be invoked directly; use its corresponding template instead: Template:Module introspection.
| Introspection summary for Module:Module introspection | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
| |||||||||||||||||||||||||||
No function descriptions were provided. The Lua code may have further information.
-- This module follows [[User:Ganaram inukshuk/Provisional style guide for Lua]]
local getArgs = require("Module:Arguments").getArgs
local iutils = require("Module:Introspection utils")
local yesno = require("Module:Yesno")
local p = {}
-- Helper function
-- Given the output of the above function, create a mediawiki table
function p.make_dependency_table(module_deps)
-- Table headers
local lines = {}
table.insert(lines, '{| class="wikitable sortable"')
table.insert(lines, "|+ style=\"font-size: 105%;\" | " .. string.format("Lua modules required (%d)", #module_deps))
table.insert(lines, "|-")
table.insert(lines, "! Variable")
table.insert(lines, "! Module")
table.insert(lines, "! Functions used")
-- Table rows (assuming they're all alphabetized)
for _, info in ipairs(module_deps) do
local funcs_text
if #info.funcs == 0 then
funcs_text = "''dependency not used''"
else
local func_lines = {}
for _, func in ipairs(info.funcs) do
table.insert(func_lines, string.format("<code>%s</code>", func))
end
funcs_text = table.concat(func_lines, "<br />")
end
table.insert(lines, "|-")
table.insert(lines, "| " .. info.var)
table.insert(lines, "| [[" .. info.dep .. "]]")
table.insert(lines, "| " .. funcs_text)
end
-- Table footer
table.insert(lines, "|}")
-- Join all lines into a single string
return table.concat(lines, "\n")
end
-- Helper function
-- Lists module's own functions; requires module name to produce links to each
-- function.
function p.make_function_table(module_name, module_funcs, descriptions, main_function)
-- Check whether descriptions was passed in
local has_descriptions = false
if type(descriptions) == "table" then
for _, _ in pairs(descriptions) do
has_descriptions = true
break
end
end
-- Table headers
local lines = {}
--table.insert(lines, string.format("'''Module:%s''' provides %d function(s):", module_name, #module_funcs))
table.insert(lines, '{| class="wikitable sortable"')
table.insert(lines, "|+ style=\"font-size: 105%;\" | " .. string.format("Functions provided (%d)", #module_funcs))
table.insert(lines, "|-")
table.insert(lines, "! Line")
table.insert(lines, "! Function")
table.insert(lines, "! Params")
-- If there are descriptions, add a column for that
if has_descriptions then
table.insert(lines, "! Description")
end
-- Table rows
for _, info in ipairs(module_funcs) do
-- Find params for that function, or say "none" if none
local params = {}
for _, param in ipairs(info.params) do
table.insert(params, param)
end
local params_string = ""
if #params == 0 then
params_string = "''none''"
else
params_string = string.format("<code>(%s)</code>", table.concat(params, ", "))
end
-- Create link to line for that function
local line_num = string.format("[[Module:%s#L-%d|%d]]", module_name, info.line, info.line)
-- Create text for function
local func = ""
if info.name then
func = string.format("<code>%s</code>", info.name)
else
func = "''none''"
end
-- If the function is the main function, add "main" to that cell
if info.name == main_function then
func = func .. " '''(main)'''"
end
-- If the function is invokable (it has one param called "frame"), add
-- "invokable" to that cell
if #params == 1 and params[1] == "frame" then
func = func .. " '''(invokable)'''"
end
table.insert(lines, "|-")
table.insert(lines, "| " .. line_num)
table.insert(lines, "| " .. func)
table.insert(lines, "| " .. params_string)
if has_descriptions then
table.insert(lines, "| " .. (descriptions[info.name] or ""))
end
end
table.insert(lines, "|}")
return table.concat(lines, "\n")
end
-- Main function; to be called by wrapper
function p._module_introspection(args)
local args = args or {}
local module_name = args["module_name" ]
local main_function = args["main_function"]
local descriptions = args["descriptions" ]
local is_doc = args["is_doc"]
-- Check whether this page is a docpage
-- If so, don't bother
if is_doc then
return "''To see introspection summary, see this module's main page.''"
end
-- Preprocess module and blank-out comments
--local title = mw.title.new('Module:' .. module_name)
--local code = title:getContent()
--code = iutils.preprocess_code(code) -- Blank-out comments
local code = iutils.get_and_preprocess_content("Module", module_name)
-- Get dependencies and their functions used, then build a table
local module_deps = iutils.find_dependencies(code)
local dep_table = p.make_dependency_table(module_deps)
-- Get module's functions, then build a table using that information
local module_funcs = iutils.find_functions(code)
local func_table = p.make_function_table(module_name, module_funcs, descriptions, main_function)
-- Return the tables
-- Styling may be improved at a later time
local lines = {
'{| class="wikitable mw-collapsible"',
'|-',
'! colspan="2" style="font-size: 105%;" | ' .. string.format("Introspection summary for Module:%s ", module_name),
"|-",
'| style="vertical-align: top; border-right: none;" | ',
func_table,
'| style="vertical-align: top; border-left: none;" | ',
dep_table,
"|}"
}
-- Check whether descriptions was passed in
local has_descriptions = false
if type(descriptions) == "table" then
for _, _ in pairs(descriptions) do
has_descriptions = true
break
end
end
-- If no descriptions were provided, add text below that points to the code.
if not has_descriptions then
table.insert(lines, "''No function descriptions were provided. The Lua code may have further information.''")
end
return table.concat(lines, "\n")
end
-- Wrapper function for modules
function p.module_introspection(frame)
-- Extract arguments using getArgs
local args = getArgs(frame) or {}
-- Get module name from arguments, or default to current page
local module_name = args["module_name"] or mw.title.getCurrentTitle().text
-- Strip trailing "/doc" if the template is used on a documentation subpage
--module_name = module_name:gsub("/doc$", "")
-- Check whether page is the doc page
-- To ensure proper referencing, do not display introspection on a docpage.
local is_doc = string.find(module_name, "/doc$")
-- Normalize module name so it can be used to find the main function, which
-- is assumed to be the same name as the module. Module assumes snake_case
-- is used for function names. (If this fails, it can be entered manually.)
local normalized_name = module_name:gsub("[^%w]", "_"):lower()
local main_function = args["main_function"] or "_" .. normalized_name
-- Process all function descriptions, if provided as desc_function_name
local func_descriptions = {}
for key, val in pairs(args) do
local func_name = key:match("^desc_([%w_]+)$")
if func_name and val and val ~= "" then
func_descriptions[func_name] = val
end
end
-- Return
local result = p._module_introspection({
["module_name" ] = module_name,
["main_function"] = main_function,
["descriptions" ] = func_descriptions,
["is_doc"] = is_doc
})
-- 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 frame:preprocess(result)
end
return p