build: add modified luadoc for use with LuCI sources
Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
This commit is contained in:
parent
e6e74b712f
commit
c669c01cea
20 changed files with 2511 additions and 2 deletions
126
build/luadoc/doc.lua
Executable file
126
build/luadoc/doc.lua
Executable file
|
@ -0,0 +1,126 @@
|
|||
#!/usr/bin/env lua
|
||||
-------------------------------------------------------------------------------
|
||||
-- LuaDoc launcher.
|
||||
-- @release $Id: luadoc.lua.in,v 1.1 2008/02/17 06:42:51 jasonsantos Exp $
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
--local source = debug.getinfo(1).source or ""
|
||||
--local mypath = source:match("@(.+)/[^/]+")
|
||||
|
||||
--package.path = package.path .. ";" .. mypath .. "/?.lua;" .. mypath .. "/?/init.lua"
|
||||
|
||||
require "luadoc.init"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Print version number.
|
||||
|
||||
local function print_version ()
|
||||
print (string.format("%s\n%s\n%s",
|
||||
luadoc._VERSION,
|
||||
luadoc._DESCRIPTION,
|
||||
luadoc._COPYRIGHT))
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Print usage message.
|
||||
|
||||
local function print_help ()
|
||||
print ("Usage: "..arg[0]..[[ [options|files]
|
||||
Generate documentation from files. Available options are:
|
||||
-d path output directory path
|
||||
-t path template directory path
|
||||
-h, --help print this help and exit
|
||||
--noindexpage do not generate global index page
|
||||
--nofiles do not generate documentation for files
|
||||
--nomodules do not generate documentation for modules
|
||||
--doclet doclet_module doclet module to generate output
|
||||
--taglet taglet_module taglet module to parse input code
|
||||
-q, --quiet suppress all normal output
|
||||
-v, --version print version information]])
|
||||
end
|
||||
|
||||
local function off_messages (arg, i, options)
|
||||
options.verbose = nil
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Process options. TODO: use getopts.
|
||||
-- @class table
|
||||
-- @name OPTIONS
|
||||
|
||||
local OPTIONS = {
|
||||
d = function (arg, i, options)
|
||||
local dir = arg[i+1]
|
||||
if string.sub (dir, -2) ~= "/" then
|
||||
dir = dir..'/'
|
||||
end
|
||||
options.output_dir = dir
|
||||
return 1
|
||||
end,
|
||||
t = function (arg, i, options)
|
||||
local dir = arg[i+1]
|
||||
if string.sub (dir, -2) ~= "/" then
|
||||
dir = dir..'/'
|
||||
end
|
||||
options.template_dir = dir
|
||||
return 1
|
||||
end,
|
||||
h = print_help,
|
||||
help = print_help,
|
||||
q = off_messages,
|
||||
quiet = off_messages,
|
||||
v = print_version,
|
||||
version = print_version,
|
||||
doclet = function (arg, i, options)
|
||||
options.doclet = arg[i+1]
|
||||
return 1
|
||||
end,
|
||||
taglet = function (arg, i, options)
|
||||
options.taglet = arg[i+1]
|
||||
return 1
|
||||
end,
|
||||
}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local function process_options (arg)
|
||||
local files = {}
|
||||
local options = require "luadoc.config"
|
||||
local i = 1
|
||||
while i <= #arg do
|
||||
local argi = arg[i]
|
||||
if string.sub (argi, 1, 1) ~= '-' then
|
||||
table.insert (files, argi)
|
||||
else
|
||||
local opt = string.sub (argi, 2)
|
||||
if string.sub (opt, 1, 1) == '-' then
|
||||
opt = string.gsub (opt, "%-", "")
|
||||
end
|
||||
if OPTIONS[opt] then
|
||||
if OPTIONS[opt] (arg, i, options) then
|
||||
i = i + 1
|
||||
end
|
||||
else
|
||||
options[opt] = 1
|
||||
end
|
||||
end
|
||||
i = i+1
|
||||
end
|
||||
return files, options
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Main function. Process command-line parameters and call luadoc processor.
|
||||
|
||||
function main (arg)
|
||||
-- Process options
|
||||
local argc = #arg
|
||||
if argc < 1 then
|
||||
print_help ()
|
||||
return
|
||||
end
|
||||
local files, options = process_options (arg)
|
||||
return luadoc.main(files, options)
|
||||
end
|
||||
|
||||
main(arg)
|
34
build/luadoc/luadoc/config.lua
Normal file
34
build/luadoc/luadoc/config.lua
Normal file
|
@ -0,0 +1,34 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- LuaDoc configuration file. This file contains the default options for
|
||||
-- luadoc operation. These options can be overriden by the command line tool
|
||||
-- @see luadoc.print_help
|
||||
-- @release $Id: config.lua,v 1.6 2007/04/18 14:28:39 tomas Exp $
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
module "luadoc.config"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Default options
|
||||
-- @class table
|
||||
-- @name default_options
|
||||
-- @field output_dir default output directory for generated documentation, used
|
||||
-- by several doclets
|
||||
-- @field taglet parser used to analyze source code input
|
||||
-- @field doclet documentation generator
|
||||
-- @field template_dir directory with documentation templates, used by the html
|
||||
-- doclet
|
||||
-- @field verbose command line tool configuration to output processing
|
||||
-- information
|
||||
|
||||
local default_options = {
|
||||
output_dir = "",
|
||||
taglet = "luadoc.taglet.standard",
|
||||
doclet = "luadoc.doclet.html",
|
||||
-- TODO: find a way to define doclet specific options
|
||||
template_dir = "luadoc/doclet/html/",
|
||||
nomodules = false,
|
||||
nofiles = false,
|
||||
verbose = true,
|
||||
}
|
||||
|
||||
return default_options
|
46
build/luadoc/luadoc/doclet/debug.lua
Normal file
46
build/luadoc/luadoc/doclet/debug.lua
Normal file
|
@ -0,0 +1,46 @@
|
|||
-----------------------------------------------------------------
|
||||
-- LuaDoc debugging facilities.
|
||||
-- @release $Id: debug.lua,v 1.3 2007/04/18 14:28:39 tomas Exp $
|
||||
-----------------------------------------------------------------
|
||||
|
||||
module "luadoc.doclet.debug"
|
||||
|
||||
function printline()
|
||||
print(string.rep('-', 79))
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------
|
||||
-- Print debug information about document
|
||||
-- @param doc Table with the structured documentation.
|
||||
|
||||
function start (doc)
|
||||
print("Files:")
|
||||
for _, filepath in ipairs(doc.files) do
|
||||
print('\t', filepath)
|
||||
end
|
||||
printline()
|
||||
|
||||
print("Modules:")
|
||||
for _, modulename in ipairs(doc.modules) do
|
||||
print('\t', modulename)
|
||||
end
|
||||
printline()
|
||||
|
||||
for i, v in pairs(doc.files) do
|
||||
print('\t', i, v)
|
||||
end
|
||||
printline()
|
||||
for i, v in pairs(doc.files[doc.files[1]]) do
|
||||
print(i, v)
|
||||
end
|
||||
|
||||
printline()
|
||||
for i, v in pairs(doc.files[doc.files[1]].doc[1]) do
|
||||
print(i, v)
|
||||
end
|
||||
printline()
|
||||
print("Params")
|
||||
for i, v in pairs(doc.files[doc.files[1]].doc[1].param) do
|
||||
print(i, v)
|
||||
end
|
||||
end
|
84
build/luadoc/luadoc/doclet/formatter.lua
Normal file
84
build/luadoc/luadoc/doclet/formatter.lua
Normal file
|
@ -0,0 +1,84 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- Doclet to format source code according to LuaDoc standard tags. This doclet
|
||||
-- (re)write .lua files adding missing standard tags. Texts are formatted to
|
||||
-- 80 columns and function parameters are added based on code analysis.
|
||||
--
|
||||
-- @release $Id: formatter.lua,v 1.5 2007/04/18 14:28:39 tomas Exp $
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local util = require "luadoc.util"
|
||||
local assert, ipairs, pairs, type = assert, ipairs, pairs, type
|
||||
local string = require"string"
|
||||
local table = require"table"
|
||||
|
||||
module "luadoc.doclet.formatter"
|
||||
|
||||
options = {
|
||||
output_dir = "./",
|
||||
}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Assembly the output filename for an input file.
|
||||
-- TODO: change the name of this function
|
||||
function out_file (filename)
|
||||
local h = filename
|
||||
h = options.output_dir..h
|
||||
return h
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Generate a new lua file for each input lua file. If the user does not
|
||||
-- specify a different output directory input files will be rewritten.
|
||||
-- @param doc documentation table
|
||||
|
||||
function start (doc)
|
||||
local todo = "<TODO>"
|
||||
|
||||
-- Process files
|
||||
for i, file_doc in ipairs(doc.files) do
|
||||
-- assembly the filename
|
||||
local filename = out_file(file_doc.name)
|
||||
luadoc.logger:info(string.format("generating file `%s'", filename))
|
||||
|
||||
-- TODO: confirm file overwrite
|
||||
local f = posix.open(filename, "w")
|
||||
assert(f, string.format("could not open `%s' for writing", filename))
|
||||
|
||||
for _, block in ipairs(file_doc.doc) do
|
||||
|
||||
-- write reorganized comments
|
||||
f:write(string.rep("-", 80).."\n")
|
||||
|
||||
-- description
|
||||
f:write(util.comment(util.wrap(block.description, 77)))
|
||||
f:write("\n")
|
||||
|
||||
if block.class == "function" then
|
||||
-- parameters
|
||||
table.foreachi(block.param, function (_, param_name)
|
||||
f:write(util.comment(util.wrap(string.format("@param %s %s", param_name, block.param[param_name] or todo), 77)))
|
||||
f:write("\n")
|
||||
end)
|
||||
|
||||
-- return
|
||||
if type(block.ret) == "table" then
|
||||
table.foreachi(block.ret, function (_, ret)
|
||||
f:write(util.comment(util.wrap(string.format("@return %s", ret), 77)).."\n")
|
||||
end)
|
||||
else
|
||||
f:write(util.comment(util.wrap(string.format("@return %s", block.ret or todo), 77)).."\n")
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO: usage
|
||||
-- TODO: see
|
||||
|
||||
-- write code
|
||||
for _, line in ipairs(block.code) do
|
||||
f:write(line.."\n")
|
||||
end
|
||||
end
|
||||
|
||||
f:close()
|
||||
end
|
||||
end
|
275
build/luadoc/luadoc/doclet/html.lua
Normal file
275
build/luadoc/luadoc/doclet/html.lua
Normal file
|
@ -0,0 +1,275 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- 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,v 1.29 2007/12/21 17:50:48 tomas Exp $
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
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 "nixio.fs"
|
||||
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
|
28
build/luadoc/luadoc/doclet/html/constant.lp
Normal file
28
build/luadoc/luadoc/doclet/html/constant.lp
Normal file
|
@ -0,0 +1,28 @@
|
|||
<%
|
||||
if module_doc then
|
||||
from = "modules/"..module_doc.name
|
||||
elseif file_doc then
|
||||
from = "files/.."..file_doc.name
|
||||
else
|
||||
from = ""
|
||||
end
|
||||
%>
|
||||
|
||||
<dt><%=const.private and "local " or ""%><a name="<%=const.name%>"></a><strong><%=const.name:gsub(".+%.","")%></strong></dt>
|
||||
<dd>
|
||||
<%=const.description or ""%>
|
||||
|
||||
<%if type(const.see) == "string" then %>
|
||||
<h3>See also:</h3>
|
||||
<a href="<%=const.see%>"><%=const.see%></a>
|
||||
<%elseif type(const.see) == "table" and #const.see > 0 then %>
|
||||
<h3>See also:</h3>
|
||||
<ul>
|
||||
<%for i = 1, #const.see do%>
|
||||
<li><a href="<%=luadoc.doclet.html.symbol_link(const.see[i], doc, module_doc, file_doc, from)%>">
|
||||
<%=const.see[i]:gsub(".+%.","")%>
|
||||
</a>
|
||||
<%end%>
|
||||
</ul
|
||||
<%end%>
|
||||
</dd>
|
112
build/luadoc/luadoc/doclet/html/file.lp
Normal file
112
build/luadoc/luadoc/doclet/html/file.lp
Normal file
|
@ -0,0 +1,112 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Reference</title>
|
||||
<link rel="stylesheet" href="<%=luadoc.doclet.html.link('luadoc.css', 'files/'..file_doc.name)%>" type="text/css" />
|
||||
<!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/-->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<%=luadoc.doclet.html.include("menu.lp", { doc=doc, file_doc=file_doc })%>
|
||||
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h1>File <code><%=file_doc.name%></code></h1>
|
||||
|
||||
<%if file_doc.description then%>
|
||||
<p><%=file_doc.description%></p>
|
||||
<%end%>
|
||||
<%if file_doc.author then%>
|
||||
<p><b><%= #file_doc.author>1 and "Authors" or "Author" %>:</b>
|
||||
<table class="authors_list">
|
||||
<%for _, author in ipairs(file_doc.author) do%>
|
||||
<tr><td class="name"><%= author %></td></tr>
|
||||
<%end%>
|
||||
</table>
|
||||
</p>
|
||||
<%end%>
|
||||
<%if file_doc.copyright then%>
|
||||
<p>Copyright ©<%=file_doc.copyright%></p>
|
||||
<%end%>
|
||||
<%if file_doc.release then%>
|
||||
<p><small><b>Release:</b> <%=file_doc.release%></small></p>
|
||||
<%end%>
|
||||
|
||||
<%if #file_doc.functions > 0 then%>
|
||||
<h2>Functions</h2>
|
||||
<table class="function_list">
|
||||
<%for _, func_name in ipairs(file_doc.functions) do
|
||||
local func_data = file_doc.functions[func_name]%>
|
||||
<tr>
|
||||
<td class="name" nowrap><%=func_data.private and "local " or ""%><a href="#<%=func_name%>"><%=func_name%></a> (<%=table.concat(func_data.param or {}, ", ")%>)</td>
|
||||
<td class="summary"><%=func_data.summary%></td>
|
||||
</tr>
|
||||
<%end%>
|
||||
</table>
|
||||
<%end%>
|
||||
|
||||
|
||||
<%if #file_doc.tables > 0 then%>
|
||||
<h2>Tables</h2>
|
||||
<table class="table_list">
|
||||
<%for _, tab_name in ipairs(file_doc.tables) do%>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#<%=tab_name%>"><%=tab_name%></a></td>
|
||||
<td class="summary"><%=file_doc.tables[tab_name].summary%></td>
|
||||
</tr>
|
||||
<%end%>
|
||||
</table>
|
||||
<%end%>
|
||||
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
|
||||
|
||||
<%if #file_doc.functions > 0 then%>
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<dl class="function">
|
||||
<%for _, func_name in ipairs(file_doc.functions) do%>
|
||||
<%=luadoc.doclet.html.include("function.lp", { doc=doc, file_doc=file_doc, func=file_doc.functions[func_name] })%>
|
||||
<%end%>
|
||||
</dl>
|
||||
<%end%>
|
||||
|
||||
|
||||
<%if #file_doc.tables > 0 then%>
|
||||
<h2><a name="tables"></a>Tables</h2>
|
||||
<dl class="table">
|
||||
<%for _, tab_name in ipairs(file_doc.tables) do%>
|
||||
<%=luadoc.doclet.html.include("table.lp", { doc=doc, file_doc=file_doc, tab=file_doc.tables[tab_name] })%>
|
||||
<%end%>
|
||||
</dl>
|
||||
<%end%>
|
||||
|
||||
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
</html>
|
64
build/luadoc/luadoc/doclet/html/function.lp
Normal file
64
build/luadoc/luadoc/doclet/html/function.lp
Normal file
|
@ -0,0 +1,64 @@
|
|||
<%
|
||||
if module_doc then
|
||||
from = "modules/"..module_doc.name
|
||||
elseif file_doc then
|
||||
from = "files/.."..file_doc.name
|
||||
else
|
||||
from = ""
|
||||
end
|
||||
%>
|
||||
|
||||
<dt><%=func.private and "local " or ""%><a name="<%=func.name%>"></a><strong><%=func.printname%></strong> (<%=table.concat(func.param or {}, ", ")%>)</dt>
|
||||
<dd>
|
||||
<%=func.description or ""%>
|
||||
|
||||
<%if type(func.param) == "table" and #func.param > 0 then%>
|
||||
<h3>Parameters</h3>
|
||||
<ul>
|
||||
<%for p = 1, #func.param do%>
|
||||
<li>
|
||||
<%=func.param[p]%>: <%=func.param[func.param[p]] or ""%>
|
||||
</li>
|
||||
<%end%>
|
||||
</ul>
|
||||
<%end%>
|
||||
|
||||
|
||||
<%if type(func.usage) == "string" then%>
|
||||
<h3>Usage:</h3>
|
||||
<%=func.usage%>
|
||||
<%elseif type(func.usage) == "table" then%>
|
||||
<h3>Usage</h3>
|
||||
<ul>
|
||||
<%for _, usage in ipairs(func.usage) do%>
|
||||
<li><%= usage %>
|
||||
<%end%>
|
||||
</ul>
|
||||
<%end%>
|
||||
|
||||
<%if type(func.ret) == "string" then%>
|
||||
<h3>Return value:</h3>
|
||||
<%=func.ret%>
|
||||
<%elseif type(func.ret) == "table" then%>
|
||||
<h3>Return values:</h3>
|
||||
<ol>
|
||||
<%for _, ret in ipairs(func.ret) do%>
|
||||
<li><%= ret %>
|
||||
<%end%>
|
||||
</ol>
|
||||
<%end%>
|
||||
|
||||
<%if type(func.see) == "string" then %>
|
||||
<h3>See also:</h3>
|
||||
<a href="<%=func.see%>"><%=func.see%></a>
|
||||
<%elseif type(func.see) == "table" and #func.see > 0 then %>
|
||||
<h3>See also:</h3>
|
||||
<ul>
|
||||
<%for i = 1, #func.see do%>
|
||||
<li><a href="<%=luadoc.doclet.html.symbol_link(func.see[i], doc, module_doc, file_doc, from)%>">
|
||||
<%=(oop and func.see[i]:gsub("%.",":") or func.see[i]:gsub(".+%.",""))%>
|
||||
</a>
|
||||
<%end%>
|
||||
</ul>
|
||||
<%end%>
|
||||
</dd>
|
67
build/luadoc/luadoc/doclet/html/index.lp
Normal file
67
build/luadoc/luadoc/doclet/html/index.lp
Normal file
|
@ -0,0 +1,67 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Reference</title>
|
||||
<link rel="stylesheet" href="<%=luadoc.doclet.html.link("luadoc.css")%>" type="text/css" />
|
||||
<!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/-->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<%=luadoc.doclet.html.include("menu.lp", { doc=doc })%>
|
||||
|
||||
</div> <!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
|
||||
<%if not options.nomodules and #doc.modules > 0 then%>
|
||||
<h2>Modules</h2>
|
||||
<table class="module_list">
|
||||
<!--<tr><td colspan="2">Modules</td></tr>-->
|
||||
<%for _, modulename in ipairs(doc.modules) do%>
|
||||
<tr>
|
||||
<td class="name"><a href="<%=luadoc.doclet.html.module_link(modulename, doc)%>"><%=modulename%></a></td>
|
||||
<td class="summary"><%=doc.modules[modulename].summary%></td>
|
||||
</tr>
|
||||
<%end%>
|
||||
</table>
|
||||
<%end%>
|
||||
|
||||
|
||||
|
||||
<%if not options.nofiles and #doc.files > 0 then%>
|
||||
<h2>Files</h2>
|
||||
<table class="file_list">
|
||||
<!--<tr><td colspan="2">Files</td></tr>-->
|
||||
<%for _, filepath in ipairs(doc.files) do%>
|
||||
<tr>
|
||||
<td class="name"><a href="<%=luadoc.doclet.html.file_link(filepath)%>"><%=filepath%></a></td>
|
||||
<td class="summary"></td>
|
||||
</tr>
|
||||
<%end%>
|
||||
</table>
|
||||
<%end%>
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
</html>
|
285
build/luadoc/luadoc/doclet/html/luadoc.css
Normal file
285
build/luadoc/luadoc/doclet/html/luadoc.css
Normal file
|
@ -0,0 +1,285 @@
|
|||
body {
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
font-family: arial, helvetica, geneva, sans-serif;
|
||||
background-color:#ffffff; margin:0px;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: "Andale Mono", monospace;
|
||||
}
|
||||
|
||||
tt {
|
||||
font-family: "Andale Mono", monospace;
|
||||
}
|
||||
|
||||
body, td, th { font-size: 11pt; }
|
||||
|
||||
h1, h2, h3, h4 { margin-left: 0em; }
|
||||
|
||||
textarea, pre, tt { font-size:10pt; }
|
||||
body, td, th { color:#000000; }
|
||||
small { font-size:0.85em; }
|
||||
h1 { font-size:1.5em; }
|
||||
h2 { font-size:1.25em; }
|
||||
h3 { font-size:1.15em; }
|
||||
h4 { font-size:1.06em; }
|
||||
|
||||
a:link { font-weight:bold; color: #004080; text-decoration: none; }
|
||||
a:visited { font-weight:bold; color: #006699; text-decoration: none; }
|
||||
a:link:hover { text-decoration:underline; }
|
||||
hr { color:#cccccc }
|
||||
img { border-width: 0px; }
|
||||
|
||||
|
||||
h3 { padding: 1em 0 0.5em; }
|
||||
|
||||
p { margin-left: 1em; }
|
||||
|
||||
p.name {
|
||||
font-family: "Andale Mono", monospace;
|
||||
padding-top: 1em;
|
||||
margin-left: 0em;
|
||||
}
|
||||
|
||||
blockquote { margin-left: 3em; }
|
||||
|
||||
pre.example {
|
||||
background-color: rgb(245, 245, 245);
|
||||
border-top-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-width: 1px;
|
||||
border-top-style: solid;
|
||||
border-right-style: solid;
|
||||
border-bottom-style: solid;
|
||||
border-left-style: solid;
|
||||
border-top-color: silver;
|
||||
border-right-color: silver;
|
||||
border-bottom-color: silver;
|
||||
border-left-color: silver;
|
||||
padding: 1em;
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
font-family: "Andale Mono", monospace;
|
||||
font-size: smaller;
|
||||
}
|
||||
|
||||
|
||||
hr {
|
||||
margin-left: 0em;
|
||||
background: #00007f;
|
||||
border: 0px;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
ul { list-style-type: disc; }
|
||||
|
||||
table.index { border: 1px #00007f; }
|
||||
table.index td { text-align: left; vertical-align: top; }
|
||||
table.index ul { padding-top: 0em; margin-top: 0em; }
|
||||
|
||||
table {
|
||||
border: 1px solid black;
|
||||
border-collapse: collapse;
|
||||
margin: 1em auto;
|
||||
}
|
||||
th {
|
||||
border: 1px solid black;
|
||||
padding: 0.5em;
|
||||
}
|
||||
td {
|
||||
border: 1px solid black;
|
||||
padding: 0.5em;
|
||||
}
|
||||
div.header, div.footer { margin-left: 0em; }
|
||||
|
||||
#container
|
||||
{
|
||||
margin-left: 1em;
|
||||
margin-right: 1em;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
#product
|
||||
{
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #cccccc;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
#product big {
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
#product_logo
|
||||
{
|
||||
}
|
||||
|
||||
#product_name
|
||||
{
|
||||
}
|
||||
|
||||
#product_description
|
||||
{
|
||||
}
|
||||
|
||||
#main
|
||||
{
|
||||
background-color: #f0f0f0;
|
||||
border-left: 2px solid #cccccc;
|
||||
}
|
||||
|
||||
#navigation
|
||||
{
|
||||
float: left;
|
||||
width: 18em;
|
||||
margin: 0;
|
||||
vertical-align: top;
|
||||
background-color: #f0f0f0;
|
||||
overflow:visible;
|
||||
}
|
||||
|
||||
#navigation h1 {
|
||||
background-color:#e7e7e7;
|
||||
font-size:1.1em;
|
||||
color:#000000;
|
||||
text-align:left;
|
||||
margin:0px;
|
||||
padding:0.2em;
|
||||
border-top:1px solid #dddddd;
|
||||
border-bottom:1px solid #dddddd;
|
||||
}
|
||||
|
||||
#navigation ul
|
||||
{
|
||||
font-size:1em;
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
#navigation li
|
||||
{
|
||||
text-indent: -1em;
|
||||
margin: 0em 0em 0em 0.5em;
|
||||
display: block;
|
||||
padding: 3px 0px 0px 12px;
|
||||
}
|
||||
|
||||
#navigation li li a
|
||||
{
|
||||
padding: 0px 3px 0px -1em;
|
||||
}
|
||||
|
||||
#content
|
||||
{
|
||||
margin-left: 18em;
|
||||
padding: 1em;
|
||||
border-left: 2px solid #cccccc;
|
||||
border-right: 2px solid #cccccc;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
#about
|
||||
{
|
||||
clear: both;
|
||||
margin: 0;
|
||||
padding: 5px;
|
||||
border-top: 2px solid #cccccc;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
@media print {
|
||||
body {
|
||||
font: 12pt "Times New Roman", "TimeNR", Times, serif;
|
||||
}
|
||||
a { font-weight:bold; color: #004080; text-decoration: underline; }
|
||||
|
||||
#main
{
background-color: #ffffff;
border-left: 0px;
}
|
||||
#container
{
margin-left: 2%;
margin-right: 2%;
background-color: #ffffff;
}
|
||||
|
||||
#content
{
margin-left: 0px;
padding: 1em;
border-left: 0px;
border-right: 0px;
background-color: #ffffff;
}
|
||||
|
||||
#navigation
{
display: none;
|
||||
}
|
||||
pre.example {
|
||||
font-family: "Andale Mono", monospace;
|
||||
font-size: 10pt;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
}
|
||||
|
||||
table.module_list td
|
||||
{
|
||||
border-width: 1px;
|
||||
padding: 3px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
}
|
||||
table.module_list td.name { background-color: #f0f0f0; }
|
||||
table.module_list td.summary { width: 100%; }
|
||||
|
||||
table.file_list
|
||||
{
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.file_list td
|
||||
{
|
||||
border-width: 1px;
|
||||
padding: 3px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
}
|
||||
table.file_list td.name { background-color: #f0f0f0; }
|
||||
table.file_list td.summary { width: 100%; }
|
||||
|
||||
|
||||
table.function_list
|
||||
{
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.function_list td
|
||||
{
|
||||
border-width: 1px;
|
||||
padding: 3px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
}
|
||||
table.function_list td.name { background-color: #f0f0f0; }
|
||||
table.function_list td.summary { width: 100%; }
|
||||
|
||||
|
||||
table.table_list
|
||||
{
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
table.table_list td
|
||||
{
|
||||
border-width: 1px;
|
||||
padding: 3px;
|
||||
border-style: solid;
|
||||
border-color: #cccccc;
|
||||
}
|
||||
table.table_list td.name { background-color: #f0f0f0; }
|
||||
table.table_list td.summary { width: 100%; }
|
||||
|
||||
dl.function dt {border-top: 1px solid #ccc; padding-top: 1em;}
|
||||
dl.function dd {padding: 0.5em 0;}
|
||||
dl.function h3 {margin: 0; font-size: medium;}
|
||||
|
||||
dl.table dt {border-top: 1px solid #ccc; padding-top: 1em;}
|
||||
dl.table dd {padding-bottom: 1em;}
|
||||
dl.table h3 {padding: 0; margin: 0; font-size: medium;}
|
||||
|
||||
#TODO: make module_list, file_list, function_list, table_list inherit from a list
|
||||
|
55
build/luadoc/luadoc/doclet/html/menu.lp
Normal file
55
build/luadoc/luadoc/doclet/html/menu.lp
Normal file
|
@ -0,0 +1,55 @@
|
|||
<%
|
||||
if module_doc then
|
||||
from = "modules/"..module_doc.name
|
||||
elseif file_doc then
|
||||
from = "files/.."..file_doc.name
|
||||
else
|
||||
from = ""
|
||||
end
|
||||
%>
|
||||
|
||||
<h1>LuaDoc</h1>
|
||||
<ul>
|
||||
<%if not module_doc and not file_doc then%>
|
||||
<li><strong>Index</strong></li>
|
||||
<%else%>
|
||||
<li><a href="<%=luadoc.doclet.html.link("index.html", from)%>">Index</a></li>
|
||||
<%end%>
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- Module list -->
|
||||
<%if not options.nomodules and #doc.modules > 0 then%>
|
||||
<h1>Modules</h1>
|
||||
<ul>
|
||||
<%for _, modulename in ipairs(doc.modules) do
|
||||
if module_doc and module_doc.name == modulename then%>
|
||||
<li><strong><%=modulename%></strong></li>
|
||||
<%else%>
|
||||
<li>
|
||||
<a href="<%=luadoc.doclet.html.module_link(modulename, doc, from)%>"><%=modulename%></a>
|
||||
</li>
|
||||
<% end
|
||||
end%>
|
||||
</ul>
|
||||
<%end%>
|
||||
|
||||
|
||||
<!-- File list -->
|
||||
<%if not options.nofiles and #doc.files > 0 then%>
|
||||
<h1>Files</h1>
|
||||
<ul>
|
||||
<%for _, filepath in ipairs(doc.files) do
|
||||
if file_doc and file_doc.name == filepath then%>
|
||||
<li><strong><%=filepath%></strong></li>
|
||||
<%else%>
|
||||
<li>
|
||||
<a href="<%=luadoc.doclet.html.file_link(filepath, from)%>"><%=filepath%></a>
|
||||
</li>
|
||||
<% end
|
||||
end%>
|
||||
</ul>
|
||||
<%end%>
|
||||
|
||||
|
||||
|
155
build/luadoc/luadoc/doclet/html/module.lp
Normal file
155
build/luadoc/luadoc/doclet/html/module.lp
Normal file
|
@ -0,0 +1,155 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||
<html>
|
||||
<head>
|
||||
<title>Reference</title>
|
||||
<link rel="stylesheet" href="<%=luadoc.doclet.html.link('luadoc.css', 'modules/'..module_doc.name)%>" type="text/css" />
|
||||
<!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/-->
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
|
||||
<div id="product">
|
||||
<div id="product_logo"></div>
|
||||
<div id="product_name"><big><b></b></big></div>
|
||||
<div id="product_description"></div>
|
||||
</div> <!-- id="product" -->
|
||||
|
||||
<div id="main">
|
||||
|
||||
<div id="navigation">
|
||||
<%=luadoc.doclet.html.include("menu.lp", { doc=doc, module_doc=module_doc })%>
|
||||
<% oop = not not ( module_doc.doc[1] and module_doc.doc[1].cstyle == "instance" ) %>
|
||||
|
||||
</div><!-- id="navigation" -->
|
||||
|
||||
<div id="content">
|
||||
|
||||
<h1><%=( oop and "Object Instance" or "Class" )%> <code><%=module_doc.name%></code></h1>
|
||||
|
||||
<p><%=module_doc.description%></p>
|
||||
<%if module_doc.author then%>
|
||||
<p><b><%= #module_doc.author>1 and "Authors" or "Author" %>:</b>
|
||||
<table class="authors_list">
|
||||
<%for _, author in ipairs(module_doc.author) do%>
|
||||
<tr><td class="name"><%= author %></td></tr>
|
||||
<%end%>
|
||||
</table>
|
||||
</p>
|
||||
<%end%>
|
||||
<%if module_doc.copyright then%>
|
||||
<p>Copyright© <%=module_doc.copyright%></p>
|
||||
<%end%>
|
||||
<%if module_doc.release then%>
|
||||
<p><small><b>Release:</b> <%=module_doc.release%></small></p>
|
||||
<%end%>
|
||||
|
||||
<%if #module_doc.constants > 0 then %>
|
||||
<h2>Constants</h2>
|
||||
<table class="function_list">
|
||||
<%for _, const_name in ipairs(module_doc.constants) do
|
||||
local const_data = module_doc.constants[const_name]%>
|
||||
<tr>
|
||||
<td class="name" nowrap><code><%=const_data.private and "local " or ""%><%=(const_name:gsub(".+%.",""))%></code></td>
|
||||
<td class="summary"><%=const_data.summary%></td>
|
||||
</tr>
|
||||
<%end%>
|
||||
</table>
|
||||
<%end%>
|
||||
|
||||
<% local funcs = { }; if #module_doc.functions > 0 then %>
|
||||
<h2>Functions</h2>
|
||||
<table class="function_list">
|
||||
<%
|
||||
for _, func_name in ipairs(module_doc.functions) do
|
||||
funcs[#funcs+1] = func_name
|
||||
end
|
||||
|
||||
table.sort(funcs, function(a, b)
|
||||
local func_data_a = module_doc.functions[a]
|
||||
local func_data_b = module_doc.functions[b]
|
||||
local x = func_data_a.sort or a
|
||||
local y = func_data_b.sort or b
|
||||
return x < y
|
||||
end)
|
||||
|
||||
for _, func_name in ipairs(funcs) do
|
||||
local func_data = module_doc.functions[func_name]
|
||||
|
||||
func_data.printname = func_name:gsub("^%d+#", "")
|
||||
if oop then
|
||||
func_data.printname = func_data.printname:gsub("%.", ":")
|
||||
else
|
||||
func_data.printname = func_data.printname:gsub("^.+%.", "")
|
||||
end
|
||||
%>
|
||||
<tr>
|
||||
<td class="name" nowrap><%=func_data.private and "local " or ""%><a href="#<%=func_name%>"><%=func_data.printname%></a> (<%=table.concat(module_doc.functions[func_name].param or {}, ", ")%>)</td>
|
||||
<td class="summary"><%=module_doc.functions[func_name].summary%></td>
|
||||
</tr>
|
||||
<%end%>
|
||||
</table>
|
||||
<%end%>
|
||||
|
||||
|
||||
<% local tabs = { }; if #module_doc.tables > 0 then%>
|
||||
<h2>Tables</h2>
|
||||
<table class="table_list">
|
||||
<%
|
||||
for _, tab_name in ipairs(module_doc.tables) do
|
||||
tabs[#tabs+1] = tab_name
|
||||
end
|
||||
|
||||
table.sort(tabs, function(a, b)
|
||||
local tab_data_a = module_doc.tables[a]
|
||||
local tab_data_b = module_doc.tables[b]
|
||||
local x = tab_data_a.sort or a
|
||||
local y = tab_data_b.sort or b
|
||||
return x < y
|
||||
end)
|
||||
|
||||
for _, tab_name in ipairs(tabs) do
|
||||
%>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#<%=tab_name%>"><%=tab_name%></a></td>
|
||||
<td class="summary"><%=module_doc.tables[tab_name].summary%></td>
|
||||
</tr>
|
||||
<%end%>
|
||||
</table>
|
||||
<%end%>
|
||||
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<%if #module_doc.functions > 0 then%>
|
||||
<h2><a name="functions"></a>Functions</h2>
|
||||
<dl class="function">
|
||||
<%for _, func_name in ipairs(funcs) do%>
|
||||
<%=luadoc.doclet.html.include("function.lp", { doc=doc, module_doc=module_doc, func=module_doc.functions[func_name], oop=oop })%>
|
||||
<%end%>
|
||||
</dl>
|
||||
<%end%>
|
||||
|
||||
<%if #module_doc.tables > 0 then%>
|
||||
<h2><a name="tables"></a>Tables</h2>
|
||||
<dl class="table">
|
||||
<%for _, tab_name in ipairs(tabs) do%>
|
||||
<%=luadoc.doclet.html.include("table.lp", { doc=doc, module_doc=module_doc, tab=module_doc.tables[tab_name] })%>
|
||||
<%end%>
|
||||
</dl>
|
||||
<%end%>
|
||||
|
||||
|
||||
</div> <!-- id="content" -->
|
||||
|
||||
</div> <!-- id="main" -->
|
||||
|
||||
<div id="about">
|
||||
<p><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
|
||||
</div> <!-- id="about" -->
|
||||
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
</html>
|
15
build/luadoc/luadoc/doclet/html/table.lp
Normal file
15
build/luadoc/luadoc/doclet/html/table.lp
Normal file
|
@ -0,0 +1,15 @@
|
|||
<dt><a name="<%=tab.name%>"></a><strong><%=tab.name%></strong></dt>
|
||||
<dd><%=tab.description%>
|
||||
|
||||
<%if type(tab.field) == "table" and #tab.field > 0 then%>
|
||||
<em>Fields</em>
|
||||
<ul>
|
||||
<%for p = 1, #tab.field do%>
|
||||
<li>
|
||||
<%=tab.field[p]%>: <%=tab.field[tab.field[p]] or ""%>
|
||||
</li>
|
||||
<%end%>
|
||||
</ul>
|
||||
<%end%>
|
||||
|
||||
</dd>
|
12
build/luadoc/luadoc/doclet/raw.lua
Normal file
12
build/luadoc/luadoc/doclet/raw.lua
Normal file
|
@ -0,0 +1,12 @@
|
|||
-----------------------------------------------------------------
|
||||
-- @release $Id: raw.lua,v 1.5 2007/04/18 14:28:39 tomas Exp $
|
||||
-----------------------------------------------------------------
|
||||
|
||||
module "luadoc.doclet.raw"
|
||||
|
||||
-----------------------------------------------------------------
|
||||
-- Generate the output.
|
||||
-- @param doc Table with the structured documentation.
|
||||
|
||||
function start (doc)
|
||||
end
|
50
build/luadoc/luadoc/init.lua
Normal file
50
build/luadoc/luadoc/init.lua
Normal file
|
@ -0,0 +1,50 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- LuaDoc main function.
|
||||
-- @release $Id: init.lua,v 1.4 2008/02/17 06:42:51 jasonsantos Exp $
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local require = require
|
||||
|
||||
local util = require "luadoc.util"
|
||||
|
||||
logger = {}
|
||||
|
||||
module ("luadoc")
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- LuaDoc version number.
|
||||
|
||||
_COPYRIGHT = "Copyright (c) 2003-2007 The Kepler Project"
|
||||
_DESCRIPTION = "Documentation Generator Tool for the Lua language"
|
||||
_VERSION = "LuaDoc 3.0.1"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Main function
|
||||
-- @see luadoc.doclet.html, luadoc.doclet.formatter, luadoc.doclet.raw
|
||||
-- @see luadoc.taglet.standard
|
||||
|
||||
function main (files, options)
|
||||
logger = util.loadlogengine(options)
|
||||
|
||||
-- load config file
|
||||
if options.config ~= nil then
|
||||
-- load specified config file
|
||||
dofile(options.config)
|
||||
else
|
||||
-- load default config file
|
||||
require("luadoc.config")
|
||||
end
|
||||
|
||||
local taglet = require(options.taglet)
|
||||
local doclet = require(options.doclet)
|
||||
|
||||
-- analyze input
|
||||
taglet.options = options
|
||||
taglet.logger = logger
|
||||
local doc = taglet.start(files)
|
||||
|
||||
-- generate output
|
||||
doclet.options = options
|
||||
doclet.logger = logger
|
||||
doclet.start(doc)
|
||||
end
|
130
build/luadoc/luadoc/lp.lua
Normal file
130
build/luadoc/luadoc/lp.lua
Normal file
|
@ -0,0 +1,130 @@
|
|||
----------------------------------------------------------------------------
|
||||
-- Lua Pages Template Preprocessor.
|
||||
--
|
||||
-- @release $Id: lp.lua,v 1.7 2007/04/18 14:28:39 tomas Exp $
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
local assert, error, getfenv, loadstring, setfenv = assert, error, getfenv, loadstring, setfenv
|
||||
local find, format, gsub, strsub = string.find, string.format, string.gsub, string.sub
|
||||
local concat, tinsert = table.concat, table.insert
|
||||
local open = io.open
|
||||
|
||||
module (...)
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- function to do output
|
||||
local outfunc = "io.write"
|
||||
-- accepts the old expression field: `$| <Lua expression> |$'
|
||||
local compatmode = true
|
||||
|
||||
--
|
||||
-- Builds a piece of Lua code which outputs the (part of the) given string.
|
||||
-- @param s String.
|
||||
-- @param i Number with the initial position in the string.
|
||||
-- @param f Number with the final position in the string (default == -1).
|
||||
-- @return String with the correspondent Lua code which outputs the part of the string.
|
||||
--
|
||||
local function out (s, i, f)
|
||||
s = strsub(s, i, f or -1)
|
||||
if s == "" then return s end
|
||||
-- we could use `%q' here, but this way we have better control
|
||||
s = gsub(s, "([\\\n\'])", "\\%1")
|
||||
-- substitute '\r' by '\'+'r' and let `loadstring' reconstruct it
|
||||
s = gsub(s, "\r", "\\r")
|
||||
return format(" %s('%s'); ", outfunc, s)
|
||||
end
|
||||
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- Translate the template to Lua code.
|
||||
-- @param s String to translate.
|
||||
-- @return String with translated code.
|
||||
----------------------------------------------------------------------------
|
||||
function translate (s)
|
||||
if compatmode then
|
||||
s = gsub(s, "$|(.-)|%$", "<?lua = %1 ?>")
|
||||
s = gsub(s, "<!%-%-$$(.-)$$%-%->", "<?lua %1 ?>")
|
||||
end
|
||||
s = gsub(s, "<%%(.-)%%>", "<?lua %1 ?>")
|
||||
local res = {}
|
||||
local start = 1 -- start of untranslated part in `s'
|
||||
while true do
|
||||
local ip, fp, target, exp, code = find(s, "<%?(%w*)[ \t]*(=?)(.-)%?>", start)
|
||||
if not ip then break end
|
||||
tinsert(res, out(s, start, ip-1))
|
||||
if target ~= "" and target ~= "lua" then
|
||||
-- not for Lua; pass whole instruction to the output
|
||||
tinsert(res, out(s, ip, fp))
|
||||
else
|
||||
if exp == "=" then -- expression?
|
||||
tinsert(res, format(" %s(%s);", outfunc, code))
|
||||
else -- command
|
||||
tinsert(res, format(" %s ", code))
|
||||
end
|
||||
end
|
||||
start = fp + 1
|
||||
end
|
||||
tinsert(res, out(s, start))
|
||||
return concat(res)
|
||||
end
|
||||
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- Defines the name of the output function.
|
||||
-- @param f String with the name of the function which produces output.
|
||||
|
||||
function setoutfunc (f)
|
||||
outfunc = f
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- Turns on or off the compatibility with old CGILua 3.X behavior.
|
||||
-- @param c Boolean indicating if the compatibility mode should be used.
|
||||
|
||||
function setcompatmode (c)
|
||||
compatmode = c
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- Internal compilation cache.
|
||||
|
||||
local cache = {}
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- Translates a template into a Lua function.
|
||||
-- Does NOT execute the resulting function.
|
||||
-- Uses a cache of templates.
|
||||
-- @param string String with the template to be translated.
|
||||
-- @param chunkname String with the name of the chunk, for debugging purposes.
|
||||
-- @return Function with the resulting translation.
|
||||
|
||||
function compile (string, chunkname)
|
||||
local f, err = cache[string]
|
||||
if f then return f end
|
||||
f, err = loadstring (translate (string), chunkname)
|
||||
if not f then error (err, 3) end
|
||||
cache[string] = f
|
||||
return f
|
||||
end
|
||||
|
||||
----------------------------------------------------------------------------
|
||||
-- Translates and executes a template in a given file.
|
||||
-- The translation creates a Lua function which will be executed in an
|
||||
-- optionally given environment.
|
||||
-- @param filename String with the name of the file containing the template.
|
||||
-- @param env Table with the environment to run the resulting function.
|
||||
|
||||
function include (filename, env)
|
||||
-- read the whole contents of the file
|
||||
local fh = assert (open (filename))
|
||||
local src = fh:read("*a")
|
||||
fh:close()
|
||||
-- translates the file into a function
|
||||
local prog = compile (src, '@'..filename)
|
||||
local _env
|
||||
if env then
|
||||
_env = getfenv (prog)
|
||||
setfenv (prog, env)
|
||||
end
|
||||
prog ()
|
||||
end
|
567
build/luadoc/luadoc/taglet/standard.lua
Normal file
567
build/luadoc/luadoc/taglet/standard.lua
Normal file
|
@ -0,0 +1,567 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- @release $Id: standard.lua,v 1.39 2007/12/21 17:50:48 tomas Exp $
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local assert, pairs, tostring, type = assert, pairs, tostring, type
|
||||
local io = require "io"
|
||||
local posix = require "nixio.fs"
|
||||
local luadoc = require "luadoc"
|
||||
local util = require "luadoc.util"
|
||||
local tags = require "luadoc.taglet.standard.tags"
|
||||
local string = require "string"
|
||||
local table = require "table"
|
||||
|
||||
module 'luadoc.taglet.standard'
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Creates an iterator for an array base on a class type.
|
||||
-- @param t array to iterate over
|
||||
-- @param class name of the class to iterate over
|
||||
|
||||
function class_iterator (t, class)
|
||||
return function ()
|
||||
local i = 1
|
||||
return function ()
|
||||
while t[i] and t[i].class ~= class do
|
||||
i = i + 1
|
||||
end
|
||||
local v = t[i]
|
||||
i = i + 1
|
||||
return v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Patterns for function recognition
|
||||
local identifiers_list_pattern = "%s*(.-)%s*"
|
||||
local identifier_pattern = "[^%(%s]+"
|
||||
local function_patterns = {
|
||||
"^()%s*function%s*("..identifier_pattern..")%s*%("..identifiers_list_pattern.."%)",
|
||||
"^%s*(local%s)%s*function%s*("..identifier_pattern..")%s*%("..identifiers_list_pattern.."%)",
|
||||
"^()%s*("..identifier_pattern..")%s*%=%s*function%s*%("..identifiers_list_pattern.."%)",
|
||||
}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Checks if the line contains a function definition
|
||||
-- @param line string with line text
|
||||
-- @return function information or nil if no function definition found
|
||||
|
||||
local function check_function (line)
|
||||
line = util.trim(line)
|
||||
|
||||
local info = table.foreachi(function_patterns, function (_, pattern)
|
||||
local r, _, l, id, param = string.find(line, pattern)
|
||||
if r ~= nil then
|
||||
return {
|
||||
name = id,
|
||||
private = (l == "local"),
|
||||
param = { } --util.split("%s*,%s*", param),
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
-- TODO: remove these assert's?
|
||||
if info ~= nil then
|
||||
assert(info.name, "function name undefined")
|
||||
assert(info.param, string.format("undefined parameter list for function `%s'", info.name))
|
||||
end
|
||||
|
||||
return info
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Checks if the line contains a module definition.
|
||||
-- @param line string with line text
|
||||
-- @param currentmodule module already found, if any
|
||||
-- @return the name of the defined module, or nil if there is no module
|
||||
-- definition
|
||||
|
||||
local function check_module (line, currentmodule)
|
||||
line = util.trim(line)
|
||||
|
||||
-- module"x.y"
|
||||
-- module'x.y'
|
||||
-- module[[x.y]]
|
||||
-- module("x.y")
|
||||
-- module('x.y')
|
||||
-- module([[x.y]])
|
||||
-- module(...)
|
||||
|
||||
local r, _, modulename = string.find(line, "^module%s*[%s\"'(%[]+([^,\"')%]]+)")
|
||||
if r then
|
||||
-- found module definition
|
||||
logger:debug(string.format("found module `%s'", modulename))
|
||||
return modulename
|
||||
end
|
||||
return currentmodule
|
||||
end
|
||||
|
||||
-- Patterns for constant recognition
|
||||
local constant_patterns = {
|
||||
"^()%s*([A-Z][A-Z0-9_]*)%s*=",
|
||||
"^%s*(local%s)%s*([A-Z][A-Z0-9_]*)%s*=",
|
||||
}
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Checks if the line contains a constant definition
|
||||
-- @param line string with line text
|
||||
-- @return constant information or nil if no constant definition found
|
||||
|
||||
local function check_constant (line)
|
||||
line = util.trim(line)
|
||||
|
||||
local info = table.foreachi(constant_patterns, function (_, pattern)
|
||||
local r, _, l, id = string.find(line, pattern)
|
||||
if r ~= nil then
|
||||
return {
|
||||
name = id,
|
||||
private = (l == "local"),
|
||||
}
|
||||
end
|
||||
end)
|
||||
|
||||
-- TODO: remove these assert's?
|
||||
if info ~= nil then
|
||||
assert(info.name, "constant name undefined")
|
||||
end
|
||||
|
||||
return info
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Extracts summary information from a description. The first sentence of each
|
||||
-- doc comment should be a summary sentence, containing a concise but complete
|
||||
-- description of the item. It is important to write crisp and informative
|
||||
-- initial sentences that can stand on their own
|
||||
-- @param description text with item description
|
||||
-- @return summary string or nil if description is nil
|
||||
|
||||
local function parse_summary (description)
|
||||
-- summary is never nil...
|
||||
description = description or ""
|
||||
|
||||
-- append an " " at the end to make the pattern work in all cases
|
||||
description = description.." "
|
||||
|
||||
-- read until the first period followed by a space or tab
|
||||
local summary = string.match(description, "(.-%.)[%s\t]")
|
||||
|
||||
-- if pattern did not find the first sentence, summary is the whole description
|
||||
summary = summary or description
|
||||
|
||||
return summary
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- @param f file handle
|
||||
-- @param line current line being parsed
|
||||
-- @param modulename module already found, if any
|
||||
-- @return current line
|
||||
-- @return code block
|
||||
-- @return modulename if found
|
||||
|
||||
local function parse_code (f, line, modulename)
|
||||
local code = {}
|
||||
while line ~= nil do
|
||||
if string.find(line, "^[\t ]*%-%-%-") then
|
||||
-- reached another luadoc block, end this parsing
|
||||
return line, code, modulename
|
||||
else
|
||||
-- look for a module definition
|
||||
modulename = check_module(line, modulename)
|
||||
|
||||
table.insert(code, line)
|
||||
line = f:read()
|
||||
end
|
||||
end
|
||||
-- reached end of file
|
||||
return line, code, modulename
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Parses the information inside a block comment
|
||||
-- @param block block with comment field
|
||||
-- @return block parameter
|
||||
|
||||
local function parse_comment (block, first_line, modulename)
|
||||
|
||||
-- get the first non-empty line of code
|
||||
local code = table.foreachi(block.code, function(_, line)
|
||||
if not util.line_empty(line) then
|
||||
-- `local' declarations are ignored in two cases:
|
||||
-- when the `nolocals' option is turned on; and
|
||||
-- when the first block of a file is parsed (this is
|
||||
-- necessary to avoid confusion between the top
|
||||
-- local declarations and the `module' definition.
|
||||
if (options.nolocals or first_line) and line:find"^%s*local" then
|
||||
return
|
||||
end
|
||||
return line
|
||||
end
|
||||
end)
|
||||
|
||||
-- parse first line of code
|
||||
if code ~= nil then
|
||||
local func_info = check_function(code)
|
||||
local module_name = check_module(code)
|
||||
local const_info = check_constant(code)
|
||||
if func_info then
|
||||
block.class = "function"
|
||||
block.name = func_info.name
|
||||
block.param = func_info.param
|
||||
block.private = func_info.private
|
||||
elseif const_info then
|
||||
block.class = "constant"
|
||||
block.name = const_info.name
|
||||
block.private = const_info.private
|
||||
elseif module_name then
|
||||
block.class = "module"
|
||||
block.name = module_name
|
||||
block.param = {}
|
||||
else
|
||||
block.param = {}
|
||||
end
|
||||
else
|
||||
-- TODO: comment without any code. Does this means we are dealing
|
||||
-- with a file comment?
|
||||
end
|
||||
|
||||
-- parse @ tags
|
||||
local currenttag = "description"
|
||||
local currenttext
|
||||
|
||||
table.foreachi(block.comment, function (_, line)
|
||||
line = util.trim_comment(line)
|
||||
|
||||
local r, _, tag, text = string.find(line, "@([_%w%.]+)%s+(.*)")
|
||||
if r ~= nil then
|
||||
-- found new tag, add previous one, and start a new one
|
||||
-- TODO: what to do with invalid tags? issue an error? or log a warning?
|
||||
tags.handle(currenttag, block, currenttext)
|
||||
|
||||
currenttag = tag
|
||||
currenttext = text
|
||||
else
|
||||
currenttext = util.concat(currenttext, "\n" .. line)
|
||||
assert(string.sub(currenttext, 1, 1) ~= " ", string.format("`%s', `%s'", currenttext, line))
|
||||
end
|
||||
end)
|
||||
tags.handle(currenttag, block, currenttext)
|
||||
|
||||
-- extracts summary information from the description
|
||||
block.summary = parse_summary(block.description)
|
||||
assert(string.sub(block.description, 1, 1) ~= " ", string.format("`%s'", block.description))
|
||||
|
||||
if block.name and block.class == "module" then
|
||||
modulename = block.name
|
||||
end
|
||||
|
||||
return block, modulename
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Parses a block of comment, started with ---. Read until the next block of
|
||||
-- comment.
|
||||
-- @param f file handle
|
||||
-- @param line being parsed
|
||||
-- @param modulename module already found, if any
|
||||
-- @return line
|
||||
-- @return block parsed
|
||||
-- @return modulename if found
|
||||
|
||||
local function parse_block (f, line, modulename, first)
|
||||
local multiline = not not (line and line:match("%[%["))
|
||||
local block = {
|
||||
comment = {},
|
||||
code = {},
|
||||
}
|
||||
|
||||
while line ~= nil do
|
||||
if (multiline == true and string.find(line, "%]%]") ~= nil) or
|
||||
(multiline == false and string.find(line, "^[\t ]*%-%-") == nil) then
|
||||
-- reached end of comment, read the code below it
|
||||
-- TODO: allow empty lines
|
||||
line, block.code, modulename = parse_code(f, line, modulename)
|
||||
|
||||
-- parse information in block comment
|
||||
block, modulename = parse_comment(block, first, modulename)
|
||||
|
||||
return line, block, modulename
|
||||
else
|
||||
table.insert(block.comment, line)
|
||||
line = f:read()
|
||||
end
|
||||
end
|
||||
-- reached end of file
|
||||
|
||||
-- parse information in block comment
|
||||
block, modulename = parse_comment(block, first, modulename)
|
||||
|
||||
return line, block, modulename
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Parses a file documented following luadoc format.
|
||||
-- @param filepath full path of file to parse
|
||||
-- @param doc table with documentation
|
||||
-- @return table with documentation
|
||||
|
||||
function parse_file (filepath, doc, handle, prev_line, prev_block, prev_modname)
|
||||
local blocks = { prev_block }
|
||||
local modulename = prev_modname
|
||||
|
||||
-- read each line
|
||||
local f = handle or io.open(filepath, "r")
|
||||
local i = 1
|
||||
local line = prev_line or f:read()
|
||||
local first = true
|
||||
while line ~= nil do
|
||||
|
||||
if string.find(line, "^[\t ]*%-%-%-") then
|
||||
-- reached a luadoc block
|
||||
local block, newmodname
|
||||
line, block, newmodname = parse_block(f, line, modulename, first)
|
||||
|
||||
if modulename and newmodname and newmodname ~= modulename then
|
||||
doc = parse_file( nil, doc, f, line, block, newmodname )
|
||||
else
|
||||
table.insert(blocks, block)
|
||||
modulename = newmodname
|
||||
end
|
||||
else
|
||||
-- look for a module definition
|
||||
local newmodname = check_module(line, modulename)
|
||||
|
||||
if modulename and newmodname and newmodname ~= modulename then
|
||||
parse_file( nil, doc, f )
|
||||
else
|
||||
modulename = newmodname
|
||||
end
|
||||
|
||||
-- TODO: keep beginning of file somewhere
|
||||
|
||||
line = f:read()
|
||||
end
|
||||
first = false
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
if not handle then
|
||||
f:close()
|
||||
end
|
||||
|
||||
if filepath then
|
||||
-- store blocks in file hierarchy
|
||||
assert(doc.files[filepath] == nil, string.format("doc for file `%s' already defined", filepath))
|
||||
table.insert(doc.files, filepath)
|
||||
doc.files[filepath] = {
|
||||
type = "file",
|
||||
name = filepath,
|
||||
doc = blocks,
|
||||
-- functions = class_iterator(blocks, "function"),
|
||||
-- tables = class_iterator(blocks, "table"),
|
||||
}
|
||||
--
|
||||
local first = doc.files[filepath].doc[1]
|
||||
if first and modulename then
|
||||
doc.files[filepath].author = first.author
|
||||
doc.files[filepath].copyright = first.copyright
|
||||
doc.files[filepath].description = first.description
|
||||
doc.files[filepath].release = first.release
|
||||
doc.files[filepath].summary = first.summary
|
||||
end
|
||||
end
|
||||
|
||||
-- if module definition is found, store in module hierarchy
|
||||
if modulename ~= nil then
|
||||
if modulename == "..." then
|
||||
assert( filepath, "Can't determine name for virtual module from filepatch" )
|
||||
modulename = string.gsub (filepath, "%.lua$", "")
|
||||
modulename = string.gsub (modulename, "/", ".")
|
||||
end
|
||||
if doc.modules[modulename] ~= nil then
|
||||
-- module is already defined, just add the blocks
|
||||
table.foreachi(blocks, function (_, v)
|
||||
table.insert(doc.modules[modulename].doc, v)
|
||||
end)
|
||||
else
|
||||
-- TODO: put this in a different module
|
||||
table.insert(doc.modules, modulename)
|
||||
doc.modules[modulename] = {
|
||||
type = "module",
|
||||
name = modulename,
|
||||
doc = blocks,
|
||||
-- functions = class_iterator(blocks, "function"),
|
||||
-- tables = class_iterator(blocks, "table"),
|
||||
author = first and first.author,
|
||||
copyright = first and first.copyright,
|
||||
description = "",
|
||||
release = first and first.release,
|
||||
summary = "",
|
||||
}
|
||||
|
||||
-- find module description
|
||||
for m in class_iterator(blocks, "module")() do
|
||||
doc.modules[modulename].description = util.concat(
|
||||
doc.modules[modulename].description,
|
||||
m.description)
|
||||
doc.modules[modulename].summary = util.concat(
|
||||
doc.modules[modulename].summary,
|
||||
m.summary)
|
||||
if m.author then
|
||||
doc.modules[modulename].author = m.author
|
||||
end
|
||||
if m.copyright then
|
||||
doc.modules[modulename].copyright = m.copyright
|
||||
end
|
||||
if m.release then
|
||||
doc.modules[modulename].release = m.release
|
||||
end
|
||||
if m.name then
|
||||
doc.modules[modulename].name = m.name
|
||||
end
|
||||
end
|
||||
doc.modules[modulename].description = doc.modules[modulename].description or (first and first.description) or ""
|
||||
doc.modules[modulename].summary = doc.modules[modulename].summary or (first and first.summary) or ""
|
||||
end
|
||||
|
||||
-- make functions table
|
||||
doc.modules[modulename].functions = {}
|
||||
for f in class_iterator(blocks, "function")() do
|
||||
if f and f.name then
|
||||
table.insert(doc.modules[modulename].functions, f.name)
|
||||
doc.modules[modulename].functions[f.name] = f
|
||||
end
|
||||
end
|
||||
|
||||
-- make tables table
|
||||
doc.modules[modulename].tables = {}
|
||||
for t in class_iterator(blocks, "table")() do
|
||||
if t and t.name then
|
||||
table.insert(doc.modules[modulename].tables, t.name)
|
||||
doc.modules[modulename].tables[t.name] = t
|
||||
end
|
||||
end
|
||||
|
||||
-- make constants table
|
||||
doc.modules[modulename].constants = {}
|
||||
for c in class_iterator(blocks, "constant")() do
|
||||
if c and c.name then
|
||||
table.insert(doc.modules[modulename].constants, c.name)
|
||||
doc.modules[modulename].constants[c.name] = c
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if filepath then
|
||||
-- make functions table
|
||||
doc.files[filepath].functions = {}
|
||||
for f in class_iterator(blocks, "function")() do
|
||||
if f and f.name then
|
||||
table.insert(doc.files[filepath].functions, f.name)
|
||||
doc.files[filepath].functions[f.name] = f
|
||||
end
|
||||
end
|
||||
|
||||
-- make tables table
|
||||
doc.files[filepath].tables = {}
|
||||
for t in class_iterator(blocks, "table")() do
|
||||
if t and t.name then
|
||||
table.insert(doc.files[filepath].tables, t.name)
|
||||
doc.files[filepath].tables[t.name] = t
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return doc
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Checks if the file is terminated by ".lua" or ".luadoc" and calls the
|
||||
-- function that does the actual parsing
|
||||
-- @param filepath full path of the file to parse
|
||||
-- @param doc table with documentation
|
||||
-- @return table with documentation
|
||||
-- @see parse_file
|
||||
|
||||
function file (filepath, doc)
|
||||
local patterns = { "%.lua$", "%.luadoc$" }
|
||||
local valid = table.foreachi(patterns, function (_, pattern)
|
||||
if string.find(filepath, pattern) ~= nil then
|
||||
return true
|
||||
end
|
||||
end)
|
||||
|
||||
if valid then
|
||||
logger:info(string.format("processing file `%s'", filepath))
|
||||
doc = parse_file(filepath, doc)
|
||||
end
|
||||
|
||||
return doc
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Recursively iterates through a directory, parsing each file
|
||||
-- @param path directory to search
|
||||
-- @param doc table with documentation
|
||||
-- @return table with documentation
|
||||
|
||||
function directory (path, doc)
|
||||
for f in posix.dir(path) do
|
||||
local fullpath = path .. "/" .. f
|
||||
local attr = posix.stat(fullpath)
|
||||
assert(attr, string.format("error stating file `%s'", fullpath))
|
||||
|
||||
if attr.type == "reg" then
|
||||
doc = file(fullpath, doc)
|
||||
elseif attr.type == "dir" and f ~= "." and f ~= ".." then
|
||||
doc = directory(fullpath, doc)
|
||||
end
|
||||
end
|
||||
return doc
|
||||
end
|
||||
|
||||
-- Recursively sorts the documentation table
|
||||
local function recsort (tab)
|
||||
table.sort (tab)
|
||||
-- sort list of functions by name alphabetically
|
||||
for f, doc in pairs(tab) do
|
||||
if doc.functions then
|
||||
table.sort(doc.functions)
|
||||
end
|
||||
if doc.tables then
|
||||
table.sort(doc.tables)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function start (files, doc)
|
||||
assert(files, "file list not specified")
|
||||
|
||||
-- Create an empty document, or use the given one
|
||||
doc = doc or {
|
||||
files = {},
|
||||
modules = {},
|
||||
}
|
||||
assert(doc.files, "undefined `files' field")
|
||||
assert(doc.modules, "undefined `modules' field")
|
||||
|
||||
table.foreachi(files, function (_, path)
|
||||
local attr = posix.stat(path)
|
||||
assert(attr, string.format("error stating path `%s'", path))
|
||||
|
||||
if attr.type == "reg" then
|
||||
doc = file(path, doc)
|
||||
elseif attr.type == "dir" then
|
||||
doc = directory(path, doc)
|
||||
end
|
||||
end)
|
||||
|
||||
-- order arrays alphabetically
|
||||
recsort(doc.files)
|
||||
recsort(doc.modules)
|
||||
|
||||
return doc
|
||||
end
|
191
build/luadoc/luadoc/taglet/standard/tags.lua
Normal file
191
build/luadoc/luadoc/taglet/standard/tags.lua
Normal file
|
@ -0,0 +1,191 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- Handlers for several tags
|
||||
-- @release $Id: tags.lua,v 1.8 2007/09/05 12:39:09 tomas Exp $
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local luadoc = require "luadoc"
|
||||
local util = require "luadoc.util"
|
||||
local string = require "string"
|
||||
local table = require "table"
|
||||
local assert, type, tostring, tonumber = assert, type, tostring, tonumber
|
||||
|
||||
module "luadoc.taglet.standard.tags"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local function author (tag, block, text)
|
||||
block[tag] = block[tag] or {}
|
||||
if not text then
|
||||
luadoc.logger:warn("author `name' not defined [["..text.."]]: skipping")
|
||||
return
|
||||
end
|
||||
table.insert (block[tag], text)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Set the class of a comment block. Classes can be "module", "function",
|
||||
-- "table". The first two classes are automatic, extracted from the source code
|
||||
|
||||
local function class (tag, block, text)
|
||||
block[tag] = text
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local function cstyle (tag, block, text)
|
||||
block[tag] = text
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local function sort (tag, block, text)
|
||||
block[tag] = tonumber(text) or 0
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local function copyright (tag, block, text)
|
||||
block[tag] = text
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local function description (tag, block, text)
|
||||
block[tag] = text
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local function field (tag, block, text)
|
||||
if block["class"] ~= "table" then
|
||||
luadoc.logger:warn("documenting `field' for block that is not a `table'")
|
||||
end
|
||||
block[tag] = block[tag] or {}
|
||||
|
||||
local _, _, name, desc = string.find(text, "^([_%w%.]+)%s+(.*)")
|
||||
assert(name, "field name not defined")
|
||||
|
||||
table.insert(block[tag], name)
|
||||
block[tag][name] = desc
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Set the name of the comment block. If the block already has a name, issue
|
||||
-- an error and do not change the previous value
|
||||
|
||||
local function name (tag, block, text)
|
||||
if block[tag] and block[tag] ~= text then
|
||||
luadoc.logger:error(string.format("block name conflict: `%s' -> `%s'", block[tag], text))
|
||||
end
|
||||
|
||||
block[tag] = text
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Processes a parameter documentation.
|
||||
-- @param tag String with the name of the tag (it must be "param" always).
|
||||
-- @param block Table with previous information about the block.
|
||||
-- @param text String with the current line beeing processed.
|
||||
|
||||
local function param (tag, block, text)
|
||||
block[tag] = block[tag] or {}
|
||||
-- TODO: make this pattern more flexible, accepting empty descriptions
|
||||
local _, _, name, desc = string.find(text, "^([_%w%.]+)%s+(.*)")
|
||||
if not name then
|
||||
luadoc.logger:warn("parameter `name' not defined [["..text.."]]: skipping")
|
||||
return
|
||||
end
|
||||
local i = table.foreachi(block[tag], function (i, v)
|
||||
if v == name then
|
||||
return i
|
||||
end
|
||||
end)
|
||||
if i == nil then
|
||||
luadoc.logger:warn(string.format("documenting undefined parameter `%s'", name))
|
||||
table.insert(block[tag], name)
|
||||
end
|
||||
block[tag][name] = desc
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local function release (tag, block, text)
|
||||
block[tag] = text
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local function ret (tag, block, text)
|
||||
tag = "ret"
|
||||
if type(block[tag]) == "string" then
|
||||
block[tag] = { block[tag], text }
|
||||
elseif type(block[tag]) == "table" then
|
||||
table.insert(block[tag], text)
|
||||
else
|
||||
block[tag] = text
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- @see ret
|
||||
|
||||
local function see (tag, block, text)
|
||||
-- see is always an array
|
||||
block[tag] = block[tag] or {}
|
||||
|
||||
-- remove trailing "."
|
||||
text = string.gsub(text, "(.*)%.$", "%1")
|
||||
|
||||
local s = util.split("%s*,%s*", text)
|
||||
|
||||
table.foreachi(s, function (_, v)
|
||||
table.insert(block[tag], v)
|
||||
end)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- @see ret
|
||||
|
||||
local function usage (tag, block, text)
|
||||
if type(block[tag]) == "string" then
|
||||
block[tag] = { block[tag], text }
|
||||
elseif type(block[tag]) == "table" then
|
||||
table.insert(block[tag], text)
|
||||
else
|
||||
block[tag] = text
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local handlers = {}
|
||||
handlers["author"] = author
|
||||
handlers["class"] = class
|
||||
handlers["cstyle"] = cstyle
|
||||
handlers["copyright"] = copyright
|
||||
handlers["description"] = description
|
||||
handlers["field"] = field
|
||||
handlers["name"] = name
|
||||
handlers["param"] = param
|
||||
handlers["release"] = release
|
||||
handlers["return"] = ret
|
||||
handlers["see"] = see
|
||||
handlers["sort"] = sort
|
||||
handlers["usage"] = usage
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
function handle (tag, block, text)
|
||||
if not handlers[tag] then
|
||||
luadoc.logger:error(string.format("undefined handler for tag `%s'", tag))
|
||||
return
|
||||
end
|
||||
|
||||
if text then
|
||||
text = text:gsub("`([^\n]-)`", "<code>%1</code>")
|
||||
text = text:gsub("`(.-)`", "<pre>%1</pre>")
|
||||
end
|
||||
|
||||
-- assert(handlers[tag], string.format("undefined handler for tag `%s'", tag))
|
||||
return handlers[tag](tag, block, text)
|
||||
end
|
201
build/luadoc/luadoc/util.lua
Normal file
201
build/luadoc/luadoc/util.lua
Normal file
|
@ -0,0 +1,201 @@
|
|||
-------------------------------------------------------------------------------
|
||||
-- General utilities.
|
||||
-- @release $Id: util.lua,v 1.16 2008/02/17 06:42:51 jasonsantos Exp $
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
local posix = require "nixio.fs"
|
||||
local type, table, string, io, assert, tostring, setmetatable, pcall = type, table, string, io, assert, tostring, setmetatable, pcall
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Module with several utilities that could not fit in a specific module
|
||||
|
||||
module "luadoc.util"
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Removes spaces from the begining and end of a given string
|
||||
-- @param s string to be trimmed
|
||||
-- @return trimmed string
|
||||
|
||||
function trim (s)
|
||||
return (string.gsub(s, "^%s*(.-)%s*$", "%1"))
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Removes spaces from the begining and end of a given string, considering the
|
||||
-- string is inside a lua comment.
|
||||
-- @param s string to be trimmed
|
||||
-- @return trimmed string
|
||||
-- @see trim
|
||||
-- @see string.gsub
|
||||
|
||||
function trim_comment (s)
|
||||
s = string.gsub(s, "^%s*%-%-+%[%[(.*)$", "%1")
|
||||
s = string.gsub(s, "^%s*%-%-+(.*)$", "%1")
|
||||
return s
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Checks if a given line is empty
|
||||
-- @param line string with a line
|
||||
-- @return true if line is empty, false otherwise
|
||||
|
||||
function line_empty (line)
|
||||
return (string.len(trim(line)) == 0)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Appends two string, but if the first one is nil, use to second one
|
||||
-- @param str1 first string, can be nil
|
||||
-- @param str2 second string
|
||||
-- @return str1 .. " " .. str2, or str2 if str1 is nil
|
||||
|
||||
function concat (str1, str2)
|
||||
if str1 == nil or string.len(str1) == 0 then
|
||||
return str2
|
||||
else
|
||||
return str1 .. " " .. str2
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Split text into a list consisting of the strings in text,
|
||||
-- separated by strings matching delim (which may be a pattern).
|
||||
-- @param delim if delim is "" then action is the same as %s+ except that
|
||||
-- field 1 may be preceeded by leading whitespace
|
||||
-- @usage split(",%s*", "Anna, Bob, Charlie,Dolores")
|
||||
-- @usage split(""," x y") gives {"x","y"}
|
||||
-- @usage split("%s+"," x y") gives {"", "x","y"}
|
||||
-- @return array with strings
|
||||
-- @see table.concat
|
||||
|
||||
function split(delim, text)
|
||||
local list = {}
|
||||
if string.len(text) > 0 then
|
||||
delim = delim or ""
|
||||
local pos = 1
|
||||
-- if delim matches empty string then it would give an endless loop
|
||||
if string.find("", delim, 1) and delim ~= "" then
|
||||
error("delim matches empty string!")
|
||||
end
|
||||
local first, last
|
||||
while 1 do
|
||||
if delim ~= "" then
|
||||
first, last = string.find(text, delim, pos)
|
||||
else
|
||||
first, last = string.find(text, "%s+", pos)
|
||||
if first == 1 then
|
||||
pos = last+1
|
||||
first, last = string.find(text, "%s+", pos)
|
||||
end
|
||||
end
|
||||
if first then -- found?
|
||||
table.insert(list, string.sub(text, pos, first-1))
|
||||
pos = last+1
|
||||
else
|
||||
table.insert(list, string.sub(text, pos))
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Comments a paragraph.
|
||||
-- @param text text to comment with "--", may contain several lines
|
||||
-- @return commented text
|
||||
|
||||
function comment (text)
|
||||
text = string.gsub(text, "\n", "\n-- ")
|
||||
return "-- " .. text
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Wrap a string into a paragraph.
|
||||
-- @param s string to wrap
|
||||
-- @param w width to wrap to [80]
|
||||
-- @param i1 indent of first line [0]
|
||||
-- @param i2 indent of subsequent lines [0]
|
||||
-- @return wrapped paragraph
|
||||
|
||||
function wrap(s, w, i1, i2)
|
||||
w = w or 80
|
||||
i1 = i1 or 0
|
||||
i2 = i2 or 0
|
||||
assert(i1 < w and i2 < w, "the indents must be less than the line width")
|
||||
s = string.rep(" ", i1) .. s
|
||||
local lstart, len = 1, string.len(s)
|
||||
while len - lstart > w do
|
||||
local i = lstart + w
|
||||
while i > lstart and string.sub(s, i, i) ~= " " do i = i - 1 end
|
||||
local j = i
|
||||
while j > lstart and string.sub(s, j, j) == " " do j = j - 1 end
|
||||
s = string.sub(s, 1, j) .. "\n" .. string.rep(" ", i2) ..
|
||||
string.sub(s, i + 1, -1)
|
||||
local change = i2 + 1 - (i - j)
|
||||
lstart = j + change
|
||||
len = len + change
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Opens a file, creating the directories if necessary
|
||||
-- @param filename full path of the file to open (or create)
|
||||
-- @param mode mode of opening
|
||||
-- @return file handle
|
||||
|
||||
function posix.open (filename, mode)
|
||||
local f = io.open(filename, mode)
|
||||
if f == nil then
|
||||
filename = string.gsub(filename, "\\", "/")
|
||||
local dir = ""
|
||||
for d in string.gfind(filename, ".-/") do
|
||||
dir = dir .. d
|
||||
posix.mkdir(dir)
|
||||
end
|
||||
f = io.open(filename, mode)
|
||||
end
|
||||
return f
|
||||
end
|
||||
|
||||
|
||||
----------------------------------------------------------------------------------
|
||||
-- Creates a Logger with LuaLogging, if present. Otherwise, creates a mock logger.
|
||||
-- @param options a table with options for the logging mechanism
|
||||
-- @return logger object that will implement log methods
|
||||
|
||||
function loadlogengine(options)
|
||||
local logenabled = pcall(function()
|
||||
require "logging"
|
||||
require "logging.console"
|
||||
end)
|
||||
|
||||
local logging = logenabled and logging
|
||||
|
||||
if logenabled then
|
||||
if options.filelog then
|
||||
logger = logging.file("luadoc.log") -- use this to get a file log
|
||||
else
|
||||
logger = logging.console("[%level] %message\n")
|
||||
end
|
||||
|
||||
if options.verbose then
|
||||
logger:setLevel(logging.INFO)
|
||||
else
|
||||
logger:setLevel(logging.WARN)
|
||||
end
|
||||
|
||||
else
|
||||
noop = {__index=function(...)
|
||||
return function(...)
|
||||
-- noop
|
||||
end
|
||||
end}
|
||||
|
||||
logger = {}
|
||||
setmetatable(logger, noop)
|
||||
end
|
||||
|
||||
return logger
|
||||
end
|
|
@ -1,2 +1,14 @@
|
|||
luadoc -d $2 --no-files $(for f in $(find $1 -name '*.lua' -type f); do if grep -q -- "@return" $f; then echo $f; fi; done)
|
||||
echo API-Documentation was created in $2.
|
||||
#!/bin/bash
|
||||
|
||||
topdir=$(pwd)
|
||||
|
||||
[ -f "$topdir/build/makedocs.sh" -a -n "$1" ] || {
|
||||
echo "Please execute as ./build/makedocs.sh [output directory]" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
(
|
||||
cd "$topdir/build/luadoc/"
|
||||
find "$topdir/libs/" "$topdir/modules/" -type f -name '*.lua' -or -name '*.luadoc' | \
|
||||
xargs grep -l '@return' | xargs ./doc.lua --no-files -d "$1"
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue