Module:Database report/generate docs
--[[
Lua module for generating wikitext documentation from LuaDoc comments.
This module parses LuaDoc-style comments from Lua modules and generates
comprehensive wikitext documentation with function signatures, parameters,
return values, usage examples, and more.
Usage from Lua:
local generator = DocGenerator:new()
local wikitext = generator:generateDocumentation(moduleContent)
Usage from wikitext:
{{#invoke:DocGenerator|generate|module=ModuleName}}
]]
local DocGenerator = {}
DocGenerator.__index = DocGenerator
--- Initialize a new documentation generator.
-- Creates a new DocGenerator instance for parsing LuaDoc comments.
-- @return DocGenerator A new DocGenerator instance
-- @usage local generator = DocGenerator:new()
function DocGenerator:new()
local obj = {
functions = {},
module_info = {},
current_function = nil
}
setmetatable(obj, self)
return obj
end
--- Parse LuaDoc comments from module content.
-- Extracts function documentation, parameters, return values, and usage examples.
-- @param content string The Lua module content to parse
-- @return DocGenerator Returns self for method chaining
-- @usage generator:parseModule(content)
function DocGenerator:parseModule(content)
self.functions = {}
self.module_info = {}
self.current_function = nil
local lines = {}
for line in content:gmatch("[^\r\n]+") do
table.insert(lines, line)
end
local i = 1
while i <= #lines do
local line = lines[i]
-- Parse module-level documentation
if line:match("^%-%-%[%[") and not self.current_function then
i = self:parseModuleDoc(lines, i)
-- Parse function documentation
elseif line:match("^%-%-%-") then
i = self:parseFunctionDoc(lines, i)
-- Parse function definition
elseif line:match("^function") then
i = self:parseFunctionDef(lines, i)
else
i = i + 1
end
end
return self
end
--- Parse module-level documentation.
-- Extracts general module information and description.
-- @param lines table Array of lines from the module
-- @param start_index number Starting line index
-- @return number Next line index to process
function DocGenerator:parseModuleDoc(lines, start_index)
local i = start_index
local doc_lines = {}
-- Collect documentation until closing ]]
while i <= #lines do
local line = lines[i]
table.insert(doc_lines, line)
if line:match("%]%]") then
break
end
i = i + 1
end
-- Parse the documentation
local doc_text = table.concat(doc_lines, "\n")
self.module_info.description = self:extractDescription(doc_text)
self.module_info.usage = self:extractUsage(doc_text)
return i + 1
end
--- Parse function documentation block.
-- Extracts detailed function documentation including parameters and examples.
-- @param lines table Array of lines from the module
-- @param start_index number Starting line index
-- @return number Next line index to process
function DocGenerator:parseFunctionDoc(lines, start_index)
local i = start_index
local doc_lines = {}
-- Collect all documentation lines
while i <= #lines and lines[i]:match("^%-%-") do
table.insert(doc_lines, lines[i])
i = i + 1
end
-- Parse the documentation
local doc_text = table.concat(doc_lines, "\n")
local func_info = self:parseFunctionDocText(doc_text)
if func_info then
self.current_function = func_info
end
return i
end
--- Parse function definition.
-- Extracts function name and signature information.
-- @param lines table Array of lines from the module
-- @param start_index number Starting line index
-- @return number Next line index to process
function DocGenerator:parseFunctionDef(lines, start_index)
local line = lines[start_index]
local func_name = self:extractFunctionName(line)
if func_name and self.current_function then
self.current_function.name = func_name
self.current_function.signature = self:extractFunctionSignature(line)
table.insert(self.functions, self.current_function)
self.current_function = nil
end
return start_index + 1
end
--- Parse function documentation text.
-- Extracts all documentation elements from a function's doc block.
-- @param doc_text string The documentation text to parse
-- @return table|nil Function information table or nil if not a function doc
function DocGenerator:parseFunctionDocText(doc_text)
-- Check if this is a function documentation block
if not doc_text:match("^%-%-%-") then
return nil
end
local func_info = {
name = nil,
signature = nil,
description = "",
parameters = {},
return_value = nil,
usage_examples = {},
raises = {},
see_also = {}
}
-- Extract description (first line after ---)
func_info.description = self:extractDescription(doc_text)
-- Extract parameters with improved regex
for param_line in doc_text:gmatch("@param%s+([^\r\n]+)") do
local name, type, description = param_line:match("^([^%s]+)%s+([^%s]+)%s+(.+)")
if name and type and description then
table.insert(func_info.parameters, {
name = name,
type = type,
description = description
})
end
end
-- Extract return value with improved regex
local return_match = doc_text:match("@return%s+([^\r\n]+)")
if return_match then
local type, description = return_match:match("^([^%s]+)%s+(.+)")
if type and description then
func_info.return_value = {
type = type,
description = description
}
end
end
-- Extract usage examples
for example in doc_text:gmatch("@usage%s+([^\r\n]+)") do
table.insert(func_info.usage_examples, example)
end
-- Extract raises information
for raise in doc_text:gmatch("@raise%s+([^\r\n]+)") do
table.insert(func_info.raises, raise)
end
return func_info
end
--- Extract description from documentation text.
-- @param doc_text string Documentation text
-- @return string Extracted description
function DocGenerator:extractDescription(doc_text)
local lines = {}
for line in doc_text:gmatch("[^\r\n]+") do
table.insert(lines, line)
end
local description_lines = {}
local in_description = false
for _, line in ipairs(lines) do
if line:match("^%-%-%-") then
in_description = true
local desc = line:gsub("^%-%-%-%s*", "")
if desc ~= "" then
table.insert(description_lines, desc)
end
elseif in_description and line:match("^%-%-%s*@") then
break
elseif in_description and line:match("^%-%-%s*[^@]") then
local desc = line:gsub("^%-%-%s*", "")
table.insert(description_lines, desc)
end
end
return table.concat(description_lines, " ")
end
--- Extract usage information from module documentation.
-- @param doc_text string Module documentation text
-- @return string Extracted usage information
function DocGenerator:extractUsage(doc_text)
local usage_match = doc_text:match("@usage ([^}]+)")
if usage_match then
return usage_match:gsub("^%s*", ""):gsub("%s*$", "")
end
return ""
end
--- Extract function name from function definition line.
-- @param line string Function definition line
-- @return string|nil Function name or nil if not found
function DocGenerator:extractFunctionName(line)
local match = line:match("function%s+([^:]+):([^%(]+)")
if match then
return match .. ":" .. line:match("function%s+[^:]+:([^%(]+)")
end
match = line:match("function%s+([^%(]+)")
if match then
return match
end
return nil
end
--- Extract function signature from function definition line.
-- @param line string Function definition line
-- @return string Function signature
function DocGenerator:extractFunctionSignature(line)
return line:gsub("^%s*", "")
end
--- Generate wikitext documentation.
-- Creates comprehensive wikitext documentation from parsed information.
-- @return string Generated wikitext documentation
-- @usage local wikitext = generator:generateWikitext()
function DocGenerator:generateWikitext()
local wikitext = {}
-- -- Module header
-- table.insert(wikitext, "== Module Documentation ==")
-- table.insert(wikitext, "")
-- if self.module_info.description then
-- table.insert(wikitext, self.module_info.description)
-- table.insert(wikitext, "")
-- end
-- if self.module_info.usage and self.module_info.usage ~= "" then
-- table.insert(wikitext, "=== Usage ===")
-- table.insert(wikitext, "")
-- table.insert(wikitext, self:generateCodeBlock(self.module_info.usage))
-- table.insert(wikitext, "")
-- end
-- Method documentation
if #self.functions > 0 then
-- table.insert(wikitext, "== Usage ==")
-- table.insert(wikitext, "")
for _, func in ipairs(self.functions) do
table.insert(wikitext, self:generateFunctionWikitext(func))
table.insert(wikitext, "")
end
end
return table.concat(wikitext, "\n")
end
function DocGenerator:generateCodeBlock(content)
return mw.getCurrentFrame():preprocess("<syntaxhighlight lang=lua>" .. content .. "</syntaxhighlight>")
end
--- Generate wikitext for a single function.
-- @param func table Function information
-- @return string Function wikitext documentation
function DocGenerator:generateFunctionWikitext(func)
local wikitext = {}
-- Function header
table.insert(wikitext, "=== " .. (func.name or "Unknown function") .. " ===")
table.insert(wikitext, "")
-- Description
if func.description and func.description ~= "" then
table.insert(wikitext, func.description)
table.insert(wikitext, "")
end
-- Function signature
if func.signature then
table.insert(wikitext, "'''Signature:'''")
table.insert(wikitext, "")
table.insert(wikitext, self:generateCodeBlock(func.signature))
table.insert(wikitext, "")
end
-- Parameters
if #func.parameters > 0 then
table.insert(wikitext, "'''Parameters:'''")
table.insert(wikitext, "")
for _, param in ipairs(func.parameters) do
table.insert(wikitext, "* '''" .. param.name .. "''' (" .. param.type .. ") - " .. param.description)
end
table.insert(wikitext, "")
end
-- Return value
if func.return_value then
table.insert(wikitext, "'''Returns:'''")
table.insert(wikitext, "")
table.insert(wikitext, "* (" .. func.return_value.type .. ") " .. func.return_value.description)
table.insert(wikitext, "")
end
-- Usage examples
if #func.usage_examples > 0 then
table.insert(wikitext, "'''Usage examples:'''")
table.insert(wikitext, "")
for _, example in ipairs(func.usage_examples) do
table.insert(wikitext, self:generateCodeBlock(example))
end
end
-- Raises
if #func.raises > 0 then
table.insert(wikitext, "'''Raises:'''")
table.insert(wikitext, "")
for _, raise in ipairs(func.raises) do
table.insert(wikitext, "* " .. raise)
end
end
return table.concat(wikitext, "\n")
end
--- Generate documentation for a specific module.
-- Convenience method to parse and generate documentation in one call.
-- @param module_content string The module content to document
-- @return string Generated wikitext documentation
-- @usage local docs = generator:documentModule(content)
function DocGenerator:documentModule(module_content)
self:parseModule(module_content)
return self:generateWikitext()
end
-- MediaWiki interface functions
--- Main entry point for MediaWiki invocation.
-- @param frame table The frame object from MediaWiki
-- @return string Generated documentation
function DocGenerator.main(frame)
local generator = DocGenerator:new()
-- Get module name from parameters
local module_name = frame.args.module or frame.args[1]
if not module_name then
return "Error: No module specified. Use |module=ModuleName"
end
local module_code = mw.title.new('Module:' .. module_name).content
return generator:documentModule(module_code)
end
--- Generate documentation from file content.
-- Alternative entry point that takes file content directly.
-- @param frame table The frame object from MediaWiki
-- @return string Generated documentation
function DocGenerator.fromFile(frame)
local generator = DocGenerator:new()
local content = frame.args.content or frame.args[1]
if not content then
return "Error: No content provided. Use |content=... or provide content as first parameter."
end
return generator:documentModule(content)
end
return DocGenerator
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.