flm01/openwrt/packages/luci/host/usr/lib/lua/luadoc/doclet/html.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