Module:Documentation

local p = {} local h = {}

local list = require("Module:List").unorderedList local utilsString = require("Module:UtilsString") local utilsTable = require("Module:UtilsTable") local utilsMarkup = require("Module:UtilsMarkup")

local frame = mw.getCurrentFrame function p.Main(frame) local args = frame:getParent.args return p.template(args) end

function p.Module(frame) local docPage = mw.title.new(frame:getParent:getTitle) local modulePage = "Module:" .. docPage.baseText local module = require(modulePage) if not module.Documentation then error("No `Documentation` property exists on module " .. modulePage) end return p.module(module, frame.args) end

function p.template(templateExamples) if not templateExamples.vertical then local tableData = { hideEmptyColumns = true, rows = { { "Input", "Output", "Categories added", header = true } }		}		for _, example in ipairs(templateExamples) do			local input, output, categoryList = h.templateExample(example) input = utilsMarkup.format(input, { code = true }) table.insert(tableData.rows, {input, output, categoryList}) end return utilsMarkup.wikitable(tableData) end local result = "" for _, example in ipairs(templateExamples) do		local input, output, categoryList = h.templateExample(example) input = utilsMarkup.format(input, {pre = true}) local headerStyles = { ["width"] = "5rem" -- for alignment. See Template:Letters/Documentation for an example of why this is needed }		result = result .. utilsMarkup.wikitable({			hideEmptyRows = true,			rows = {				{					{ header = true, content= "Input", styles = headerStyles}, 					input,				},				{					{ header = true, content = "Output", styles = headerStyles}, 					output				},				{					{ header = true, content = "Categories\nAdded", styles = headerStyles },					categoryList				},			}		}) .. "\n" end return result end

function h.templateExample(example) local input = mw.text.unstripNoWiki(example) local output = frame:preprocess(input) input = mw.text.trim(input) input = mw.text.nowiki(input) local output, categories = utilsMarkup.stripCategories(output) local output = utilsMarkup.killBacklinks(output) local categoryList = list(categories) return input, output, categoryList end

function p.module(module, options) local output = '' for functionName, functionDoc in pairs(module.Documentation) do output = output .. ("==%s=="):format(functionName) .. "\n" output = output .. h.printFunctionSyntax(functionName, functionDoc.params) output = output .. h.printParamsDescription(functionDoc.params) output = output .. h.printReturnsDescription(functionDoc.returns) output = output .. h.printFunctionCases(module[functionName], functionName, functionDoc.cases, functionDoc.resultOnly) end return output end

function h.printFunctionSyntax(functionName, params) local paramSyntax = "" if params then local paramNames = utilsTable.map(h.printParamSyntax, params) paramSyntax = table.concat(paramNames, ", ") end local output = (" "):format(functionName, paramSyntax) return output .. "\n" end

function h.printParamSyntax(param) local name = param.name if param.optional then name = "[" .. name .. "]"	end return name end

function h.printParamsDescription(params) if not params or #params == 0 then return "" end local output = ";Parameters\n" for _, param in ipairs(params) do output = output .. mw.getCurrentFrame:expandTemplate({ title = "Parameter", args = { 			param.name,			param.description or "",			param.optional and "Optional" or "Required" 		}}) .. "\n" end return output .. "\n" end

function h.printReturnsDescription(returns) if not returns then return "" end local output = ";Returns\n" output = output .. "* " .. mw.getCurrentFrame:preprocess(returns) return output .. "\n" end

function h.printFunctionCases(fn, fnName, fnExamples, resultOnly) local output = ";Examples\n" local headerCells = resultOnly and {"Input", "Result"} or {"Input", "Output", "Result"} local tableData = { rows = { {				header = true, cells = headerCells, }		},	}	for _, example in ipairs(fnExamples) do		local argsText = utilsTable.map(utilsTable.print, example.args) argsText = table.concat(argsText, ", ") argsText = ("%s(%s)"):format(fnName, argsText) local input = utilsMarkup.format(argsText, {syntaxHighlight = "lua"}) local output = fn and fn(unpack(example.args)) or "" if example.description then table.insert(tableData.rows, {				{					header = true,					colspan = -1,					styles = {						["text-align"] = "left"					},					content = example.description,				}			}) end local result, categories if type(output == "string") then result = utilsMarkup.killBacklinks(output) result, categories = utilsMarkup.stripCategories(output) output = utilsMarkup.format(output, {pre = true}) else output = utilsMarkup.format(Output, {syntaxHighlight = "lua"}) end if resultOnly then table.insert(tableData.rows, {input, result}) else table.insert(tableData.rows, {input, output, result}) end end output = output .. utilsMarkup.wikitable(tableData) .. "\n" return output end

return p