Module:Doc

local utils = require( 'Module:Utils' )

--- PRIVATE FUNCTIONS --

function parse( content ) local info = parseLines( content ) local info = groupFuncs( info ) local text = generateDocumentation( info ) return text end

function parseLines( content ) content = mw.ustring.gsub( content, '[^%-%[]%[=-%[.-%]=-%]', '' ) local lines = mw.text.split( content, '[\n\f\r\v]' ) local info = { [ 'functions' ] = {}, }	local currDoc = { [ 'params' ] = {}, [ 'desc' ] = '' }	local inDocComment = false for i, line in ipairs( lines ) do		line = mw.ustring.gsub( line, "'[^']-'", '') line = mw.ustring.gsub( line, '"[^"]-"', )		if not utils.empty( line ) then			if inDocComment then				if mw.ustring.find( line, '%]%]' ) then					inDocComment = false				end				line = mw.ustring.gsub( line, '%]%].-', )				local tag = mw.ustring.match( line, '^%s-@%s-([^%s]+)')				if tag then					local content = mw.ustring.match( line, '^@%s-[^%s]+%s+([^%s].+)')					handleTag(currDoc, tag, content)				else					currDoc.desc = currDoc.desc .. ' ' .. line				end			else				local func = mw.ustring.match( line, '^%s-function%s+([^%(%s]+)' )				if func then					local fullname = mw.text.split( func, '%.')					currDoc.name = fullname[#fullname]					fullname[#fullname] = nil					currDoc.owner = table.concat( fullname, '.' )					table.insert( info.functions, currDoc )					currDoc = {						[ 'params' ] = {},						[ 'desc' ] = ''					}				end				local returns = mw.ustring.match( line, '^return%s+([^%s]+)') if returns then info.returns = returns end if mw.ustring.find( line, '--%[%[%[' ) then inDocComment = true end end end end return info end

function handleTag( currDoc, tag, content ) tag = mw.ustring.lower( tag ) if tag == 'param' or tag == 'parameter' or tag == 'arg' or tag == 'argument' then local words = mw.text.split( content, "-" ) local name = words[1] or '???' local type = '' if words[3] then type = words[2] end local desc = words[3] or words[2] table.insert( currDoc.params, {			[ 'name' ] = utils.strip( tostring( name ) ),			[ 'type' ] = utils.strip( tostring( type ) ),			[ 'desc' ] = utils.strip( tostring( desc ) )		} ) elseif tag == "return" or tag == "returns" then local words = mw.text.split( content, "-" ) local type = '' if words[2] then type = words[1] end local desc = words[2] or words[1] currDoc.returns = { [ 'type' ] = utils.strip( tostring( type ) ), [ 'desc' ] = utils.strip( tostring( desc ) ) }	end end

function groupFuncs( info ) local private = {} local public = {} if info.returns then for i, func in ipairs( info.functions ) do			if func.owner == info.returns then table.insert( public, func ) else table.insert( private, func ) end end else private = info.functions end info.functions = { [ 'private' ] = private, [ 'public' ] = public }	return info end

function generateDocumentation( info ) local text = '' if next( info.functions.public ) then text = text .. '\n==Public Functions==\n' for i, func in ipairs( info.functions.public ) do text = text .. generateFuncDocumentation( func ) end end if next( info.functions.private ) then text = text .. '\n==Private Functions==\n' for i, func in ipairs( info.functions.private ) do text = text .. generateFuncDocumentation( func ) end end text = text .. '\n==Code==\n\nA copy of the code for this module follows:' return text end

function generateFuncDocumentation( func ) local text = '===' if not utils.empty( func.owner ) then text = text .. func.owner .. '.' .. func.name else text = text .. func.name end text = text .. '===\n' if not utils.empty( func.desc ) then text = text .. utils.strip( func.desc ) .. '\n\n' end if ( not utils.empty( func.params ) ) and next( func.params ) then text = text .. "Parameters:\n\n" for i, param in ipairs( func.params ) do text = text .. "*" .. param.name if not utils.empty( param.type ) then text = text .. " (" .. param.type .. ")" end if not utils.empty( param.desc ) then text = text .. ' - ' .. utils.strip( param.desc ) end text = text .. '\n' end text = text .. '\n' end if not utils.empty( func.returns ) then text = text .. "Returns:\n\n" text = text .. "''" .. func.returns.type .. "'' - " .. func.returns.desc .. '\n' end text = text .. '\n' return text end

--- PUBLIC FUNCTIONS ---

local doc = {}

function doc.module( frame ) local name = frame.args[1] or frame.args['Name'] if utils.empty( name ) then return utils.error(			'No module specified! Please provide a valid module name!',			'documentation',			'Invalid module documentation pages' ) end name = tostring( name ) local title = mw.title.new( name, 'Module' ) if not title then return utils.error(			'There is no module page entitled "' .. name .. '"!',			'documentation',			'Invalid module documentation pages' ) end local content = title:getContent if utils.empty( content ) then return utils.error(			'There is no module page entitled "' .. name .. '"!',			'documentation',			'Invalid module documentation pages' ) end return parse( content ) end

return doc