------ generating HTML output --------- -- Although this can be generalized for outputting any format, since the template -- is language-agnostic, this implementation concentrates on HTML. -- This does the actual generation of HTML, and provides support functions in the ldoc -- table for the template -- -- A fair amount of the complexity comes from operating in two basic modes; first, where -- there is a number of modules (classic LuaDoc) or otherwise, where there is only one -- module and the index contains the documentation for that module. -- -- Like LuaDoc, LDoc puts similar kinds of documentation files in their own directories. -- So module docs go into 'modules/', scripts go into 'scripts/', and so forth. LDoc -- generalizes the idea of these project-level categories and in fact custom categories -- can be created (refered to as 'kinds' in the code) local template = require 'pl.template' local tools = require 'ldoc.tools' local html = {} local quit = utils.quit function html.generate_output(ldoc, args, project) local check_directory, check_file, writefile = tools.check_directory, tools.check_file, tools.writefile -- this generates the internal module/function references function ldoc.href(see) if see.href then -- explict reference, e.g. to Lua manual return see.href else return ldoc.ref_to_module(see.mod)..'#'..see.name end end -- this is either called from the 'root' (index or single module) or -- from the 'modules' etc directories. If we are in one of those directories, -- then linking to another kind is `../kind/name`; to the same kind is just `name`. -- If we are in the root, then it is `kind/name`. function ldoc.ref_to_module (mod) local base = "" -- default: same directory local kind, module = mod.kind, ldoc.module local name = mod.name -- default: name of module if not ldoc.single then if module then -- we are in kind/ if module.type ~= type then -- cross ref to ../kind/ base = "../"..kind.."/" end else -- we are in root: index base = kind..'/' end else -- single module if mod == ldoc.single then name = ldoc.output if not ldoc.root then base = '../' end elseif ldoc.root then -- ref to other kinds (like examples) base = kind..'/' else if module.type ~= type then -- cross ref to ../kind/ base = "../"..kind.."/" end end end return base..name..'.html' end function ldoc.use_li(ls) if #ls > 1 then return '
  • ','
  • ' else return '','' end end function ldoc.display_name(item) if item.type == 'function' then return item.name..' '..item.args else return item.name end end function ldoc.no_spaces(s) return (s:gsub('%s','_')) end function ldoc.titlecase(s) return (s:gsub('(%a)(%a*)',function(f,r) return f:upper()..r end)) end local module_template,err = utils.readfile (path.join(args.template,ldoc.templ)) if not module_template then quit("template not found. Use -l to specify directory containing ldoc.ltp") end local css = ldoc.css ldoc.output = args.output -- in single mode there is one module and the 'index' is the -- documentation for that module. ldoc.module = ldoc.single if ldoc.single and args.one then ldoc.kinds_allowed = {module = true, topic = true} end ldoc.root = true local out,err = template.substitute(module_template,{ ldoc = ldoc, module = ldoc.module }) ldoc.root = false if not out then quit("template failed: "..err) end check_directory(args.dir) -- make sure output directory is ok args.dir = args.dir .. path.sep check_file(args.dir..css, path.join(args.style,css)) -- has CSS been copied? -- write out the module index writefile(args.dir..args.output..args.ext,out) -- write out the per-module documentation -- in single mode, we exclude any modules since the module has been done; -- this step is then only for putting out any examples or topics ldoc.css = '../'..css for kind, modules in project() do kind = kind:lower() if not ldoc.single or ldoc.single and kind ~= 'modules' then check_directory(args.dir..kind) for m in modules() do ldoc.module = m ldoc.body = m.body if ldoc.body then ldoc.body = m.postprocess(ldoc.body) end out,err = template.substitute(module_template,{ module=m, ldoc = ldoc }) if not out then quit('template failed for '..m.name..': '..err) else writefile(args.dir..kind..'/'..m.name..args.ext,out) end end end end if not args.quiet then print('output written to '..args.dir) end end return html