276 lines
8.6 KiB
Lua
276 lines
8.6 KiB
Lua
-------------------------------------------------------------------------------
|
|
-- Doclet that generates HTML output. This doclet generates a set of html files
|
|
-- based on a group of templates. The main templates are:
|
|
-- <ul>
|
|
-- <li>index.lp: index of modules and files;</li>
|
|
-- <li>file.lp: documentation for a lua file;</li>
|
|
-- <li>module.lp: documentation for a lua module;</li>
|
|
-- <li>function.lp: documentation for a lua function. This is a
|
|
-- sub-template used by the others.</li>
|
|
-- </ul>
|
|
--
|
|
-- @release $Id: html.lua 3941 2008-12-23 21:39:38Z jow $
|
|
-------------------------------------------------------------------------------
|
|
|
|
local assert, getfenv, ipairs, loadstring, pairs, setfenv, tostring, tonumber, type = assert, getfenv, ipairs, loadstring, pairs, setfenv, tostring, tonumber, type
|
|
local io = require"io"
|
|
local posix = require "posix"
|
|
local lp = require "luadoc.lp"
|
|
local luadoc = require"luadoc"
|
|
local package = package
|
|
local string = require"string"
|
|
local table = require"table"
|
|
|
|
module "luadoc.doclet.html"
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Looks for a file `name' in given path. Removed from compat-5.1
|
|
-- @param path String with the path.
|
|
-- @param name String with the name to look for.
|
|
-- @return String with the complete path of the file found
|
|
-- or nil in case the file is not found.
|
|
|
|
local function search (path, name)
|
|
for c in string.gfind(path, "[^;]+") do
|
|
c = string.gsub(c, "%?", name)
|
|
local f = io.open(c)
|
|
if f then -- file exist?
|
|
f:close()
|
|
return c
|
|
end
|
|
end
|
|
return nil -- file not found
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Include the result of a lp template into the current stream.
|
|
|
|
function include (template, env)
|
|
-- template_dir is relative to package.path
|
|
local templatepath = options.template_dir .. template
|
|
|
|
-- search using package.path (modified to search .lp instead of .lua
|
|
local search_path = string.gsub(package.path, "%.lua", "")
|
|
local templatepath = search(search_path, templatepath)
|
|
assert(templatepath, string.format("template `%s' not found", template))
|
|
|
|
env = env or {}
|
|
env.table = table
|
|
env.io = io
|
|
env.lp = lp
|
|
env.ipairs = ipairs
|
|
env.tonumber = tonumber
|
|
env.tostring = tostring
|
|
env.type = type
|
|
env.luadoc = luadoc
|
|
env.options = options
|
|
|
|
return lp.include(templatepath, env)
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Returns a link to a html file, appending "../" to the link to make it right.
|
|
-- @param html Name of the html file to link to
|
|
-- @return link to the html file
|
|
|
|
function link (html, from)
|
|
local h = html
|
|
from = from or ""
|
|
string.gsub(from, "/", function () h = "../" .. h end)
|
|
return h
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Returns the name of the html file to be generated from a module.
|
|
-- Files with "lua" or "luadoc" extensions are replaced by "html" extension.
|
|
-- @param modulename Name of the module to be processed, may be a .lua file or
|
|
-- a .luadoc file.
|
|
-- @return name of the generated html file for the module
|
|
|
|
function module_link (modulename, doc, from)
|
|
-- TODO: replace "." by "/" to create directories?
|
|
-- TODO: how to deal with module names with "/"?
|
|
assert(modulename)
|
|
assert(doc)
|
|
from = from or ""
|
|
|
|
if doc.modules[modulename] == nil then
|
|
-- logger:error(string.format("unresolved reference to module `%s'", modulename))
|
|
return
|
|
end
|
|
|
|
local href = "modules/" .. modulename .. ".html"
|
|
string.gsub(from, "/", function () href = "../" .. href end)
|
|
return href
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Returns the name of the html file to be generated from a lua(doc) file.
|
|
-- Files with "lua" or "luadoc" extensions are replaced by "html" extension.
|
|
-- @param to Name of the file to be processed, may be a .lua file or
|
|
-- a .luadoc file.
|
|
-- @param from path of where am I, based on this we append ..'s to the
|
|
-- beginning of path
|
|
-- @return name of the generated html file
|
|
|
|
function file_link (to, from)
|
|
assert(to)
|
|
from = from or ""
|
|
|
|
local href = to
|
|
href = string.gsub(href, "lua$", "html")
|
|
href = string.gsub(href, "luadoc$", "html")
|
|
href = "files/" .. href
|
|
string.gsub(from, "/", function () href = "../" .. href end)
|
|
return href
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Returns a link to a function or to a table
|
|
-- @param fname name of the function or table to link to.
|
|
-- @param doc documentation table
|
|
-- @param kind String specying the kinf of element to link ("functions" or "tables").
|
|
|
|
function link_to (fname, doc, module_doc, file_doc, from, kind)
|
|
assert(fname)
|
|
assert(doc)
|
|
from = from or ""
|
|
kind = kind or "functions"
|
|
|
|
if file_doc then
|
|
for _, func_name in pairs(file_doc[kind]) do
|
|
if func_name == fname then
|
|
return file_link(file_doc.name, from) .. "#" .. fname
|
|
end
|
|
end
|
|
end
|
|
|
|
if module_doc and module_doc[kind] then
|
|
for func_name, tbl in pairs(module_doc[kind]) do
|
|
if func_name == fname then
|
|
return "#" .. fname
|
|
end
|
|
end
|
|
end
|
|
|
|
local _, _, modulename, fname = string.find(fname, "^(.-)[%.%:]?([^%.%:]*)$")
|
|
assert(fname)
|
|
|
|
-- if fname does not specify a module, use the module_doc
|
|
if string.len(modulename) == 0 and module_doc then
|
|
modulename = module_doc.name
|
|
end
|
|
|
|
local module_doc = doc.modules[modulename]
|
|
if not module_doc then
|
|
-- logger:error(string.format("unresolved reference to function `%s': module `%s' not found", fname, modulename))
|
|
return
|
|
end
|
|
|
|
for _, func_name in pairs(module_doc[kind]) do
|
|
if func_name == fname then
|
|
return module_link(modulename, doc, from) .. "#" .. fname
|
|
end
|
|
end
|
|
|
|
-- logger:error(string.format("unresolved reference to function `%s' of module `%s'", fname, modulename))
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Make a link to a file, module or function
|
|
|
|
function symbol_link (symbol, doc, module_doc, file_doc, from)
|
|
assert(symbol)
|
|
assert(doc)
|
|
|
|
local href =
|
|
-- file_link(symbol, from) or
|
|
module_link(symbol, doc, from) or
|
|
link_to(symbol, doc, module_doc, file_doc, from, "functions") or
|
|
link_to(symbol, doc, module_doc, file_doc, from, "tables")
|
|
|
|
if not href then
|
|
logger:error(string.format("unresolved reference to symbol `%s'", symbol))
|
|
end
|
|
|
|
return href or ""
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Assembly the output filename for an input file.
|
|
-- TODO: change the name of this function
|
|
function out_file (filename)
|
|
local h = filename
|
|
h = string.gsub(h, "lua$", "html")
|
|
h = string.gsub(h, "luadoc$", "html")
|
|
h = "files/" .. h
|
|
-- h = options.output_dir .. string.gsub (h, "^.-([%w_]+%.html)$", "%1")
|
|
h = options.output_dir .. h
|
|
return h
|
|
end
|
|
|
|
-------------------------------------------------------------------------------
|
|
-- Assembly the output filename for a module.
|
|
-- TODO: change the name of this function
|
|
function out_module (modulename)
|
|
local h = modulename .. ".html"
|
|
h = "modules/" .. h
|
|
h = options.output_dir .. h
|
|
return h
|
|
end
|
|
|
|
-----------------------------------------------------------------
|
|
-- Generate the output.
|
|
-- @param doc Table with the structured documentation.
|
|
|
|
function start (doc)
|
|
-- Generate index file
|
|
if (#doc.files > 0 or #doc.modules > 0) and (not options.noindexpage) then
|
|
local filename = options.output_dir.."index.html"
|
|
logger:info(string.format("generating file `%s'", filename))
|
|
local f = posix.open(filename, "w")
|
|
assert(f, string.format("could not open `%s' for writing", filename))
|
|
io.output(f)
|
|
include("index.lp", { doc = doc })
|
|
f:close()
|
|
end
|
|
|
|
-- Process modules
|
|
if not options.nomodules then
|
|
for _, modulename in ipairs(doc.modules) do
|
|
local module_doc = doc.modules[modulename]
|
|
-- assembly the filename
|
|
local filename = out_module(modulename)
|
|
logger:info(string.format("generating file `%s'", filename))
|
|
|
|
local f = posix.open(filename, "w")
|
|
assert(f, string.format("could not open `%s' for writing", filename))
|
|
io.output(f)
|
|
include("module.lp", { doc = doc, module_doc = module_doc })
|
|
f:close()
|
|
end
|
|
end
|
|
|
|
-- Process files
|
|
if not options.nofiles then
|
|
for _, filepath in ipairs(doc.files) do
|
|
local file_doc = doc.files[filepath]
|
|
-- assembly the filename
|
|
local filename = out_file(file_doc.name)
|
|
logger:info(string.format("generating file `%s'", filename))
|
|
|
|
local f = posix.open(filename, "w")
|
|
assert(f, string.format("could not open `%s' for writing", filename))
|
|
io.output(f)
|
|
include("file.lp", { doc = doc, file_doc = file_doc} )
|
|
f:close()
|
|
end
|
|
end
|
|
|
|
-- copy extra files
|
|
local f = posix.open(options.output_dir.."luadoc.css", "w")
|
|
io.output(f)
|
|
include("luadoc.css")
|
|
f:close()
|
|
end
|