added --ignore flag (can be in config) to prevent LD from complaining about files with no docs. @submodule implemented
This commit is contained in:
parent
ac29c8e9c6
commit
f4b164f24f
19
ldoc.lua
19
ldoc.lua
|
@ -51,6 +51,7 @@ ldoc, a documentation generator for Lua, vs 1.2.0
|
|||
-b,--package (default .) top-level package basename (needed for module(...))
|
||||
-x,--ext (default html) output file extension
|
||||
-c,--config (default config.ld) configuration name
|
||||
-i,--ignore ignore any 'no doc comment or no module' warnings
|
||||
--dump debug output dump
|
||||
--filter (default none) filter output as Lua data (e.g pl.pretty.dump)
|
||||
--tags (default none) show all references to given tags, comma-separated
|
||||
|
@ -176,7 +177,7 @@ end
|
|||
local ldoc_contents = {
|
||||
'alias','add_language_extension','new_type','add_section', 'tparam_alias',
|
||||
'file','project','title','package','format','output','dir','ext', 'topics',
|
||||
'one','style','template','description','examples','readme','all','manual_url',
|
||||
'one','style','template','description','examples','readme','all','manual_url', 'ignore',
|
||||
'no_return_or_parms','no_summary','full_description','backtick_references', 'custom_see_handler',
|
||||
}
|
||||
ldoc_contents = tablex.makeset(ldoc_contents)
|
||||
|
@ -220,15 +221,14 @@ local quote = tools.quote
|
|||
--- processing command line and preparing for output ---
|
||||
|
||||
local F
|
||||
local file_list,module_list = List(),List()
|
||||
module_list.by_name = {}
|
||||
local file_list = List()
|
||||
File.list = file_list
|
||||
local config_dir
|
||||
|
||||
|
||||
local ldoc_dir = arg[0]:gsub('[^/\\]+$','')
|
||||
local doc_path = ldoc_dir..'/ldoc/builtin/?.lua'
|
||||
|
||||
|
||||
-- ldoc -m is expecting a Lua package; this converts this to a file path
|
||||
if args.module then
|
||||
-- first check if we've been given a global Lua lib function
|
||||
|
@ -314,6 +314,8 @@ end
|
|||
-- where it is a list of files or directories. If specified on the command-line, we have
|
||||
-- to find an optional associated config.ld, if not already loaded.
|
||||
|
||||
if ldoc.ignore then args.ignore = true end
|
||||
|
||||
local function process_file (f, flist)
|
||||
local ext = path.extension(f)
|
||||
local ftype = file_types[ext]
|
||||
|
@ -379,9 +381,6 @@ end
|
|||
override 'format'
|
||||
ldoc.markup = markup.create(ldoc, args.format)
|
||||
|
||||
local multiple_files = #file_list > 1
|
||||
local first_module
|
||||
|
||||
------ 'Special' Project-level entities ---------------------------------------
|
||||
-- Examples and Topics do not contain code to be processed for doc comments.
|
||||
-- Instead, they are intended to be rendered nicely as-is, whether as pretty-lua
|
||||
|
@ -439,7 +438,10 @@ end
|
|||
|
||||
-- extract modules from the file objects, resolve references and sort appropriately ---
|
||||
|
||||
local first_module
|
||||
local project = ProjectMap()
|
||||
local module_list = List()
|
||||
module_list.by_name = {}
|
||||
|
||||
for F in file_list:iter() do
|
||||
for mod in F.modules:iter() do
|
||||
|
@ -569,8 +571,7 @@ if args.style == '!' or args.template == '!' then
|
|||
end
|
||||
end
|
||||
|
||||
|
||||
ldoc.single = not multiple_files and first_module or nil
|
||||
ldoc.single = #module_list == 1 and first_module or nil
|
||||
ldoc.log = print
|
||||
ldoc.kinds = project
|
||||
ldoc.modules = module_list
|
||||
|
|
94
ldoc/doc.lua
94
ldoc/doc.lua
|
@ -11,32 +11,39 @@ local global = require 'ldoc.builtin.globals'
|
|||
local tools = require 'ldoc.tools'
|
||||
local split_dotted_name = tools.split_dotted_name
|
||||
|
||||
local TAG_MULTI,TAG_ID,TAG_SINGLE,TAG_TYPE,TAG_FLAG = 'M','id','S','T','N'
|
||||
|
||||
-- these are the basic tags known to ldoc. They come in several varieties:
|
||||
-- - tags with multiple values like 'param' (TAG_MULTI)
|
||||
-- - tags which are identifiers, like 'name' (TAG_ID)
|
||||
-- - tags with a single value, like 'release' (TAG_SINGLE)
|
||||
-- - tags which represent a type, like 'function' (TAG_TYPE)
|
||||
-- - 'M' tags with multiple values like 'param' (TAG_MULTI)
|
||||
-- - 'id' tags which are identifiers, like 'name' (TAG_ID)
|
||||
-- - 'S' tags with a single value, like 'release' (TAG_SINGLE)
|
||||
-- - 'N' tags which have no associated value, like 'local` (TAG_FLAG)
|
||||
-- - 'T' tags which represent a type, like 'function' (TAG_TYPE)
|
||||
local known_tags = {
|
||||
param = 'M', see = 'M', usage = 'M', ['return'] = 'M', field = 'M', author='M';
|
||||
class = 'id', name = 'id', pragma = 'id', alias = 'id';
|
||||
class = 'id', name = 'id', pragma = 'id', alias = 'id', within = 'id',
|
||||
copyright = 'S', summary = 'S', description = 'S', release = 'S', license = 'S',
|
||||
fixme = 'S', todo = 'S', warning = 'S', raise = 'S';
|
||||
module = 'T', script = 'T', example = 'T', topic = 'T', -- project-level
|
||||
['function'] = 'T', lfunction = 'T', table = 'T', section = 'T', type = 'T',
|
||||
annotation = 'T', factory = 'T'; -- module-level
|
||||
fixme = 'S', todo = 'S', warning = 'S', raise = 'S',
|
||||
['local'] = 'N', export = 'N', private = 'N', constructor = 'N';
|
||||
-- project-level
|
||||
module = 'T', script = 'T', example = 'T', topic = 'T', submodule='T',
|
||||
-- module-level
|
||||
['function'] = 'T', lfunction = 'T', table = 'T', section = 'T', type = 'T',
|
||||
annotation = 'T', factory = 'T';
|
||||
|
||||
}
|
||||
known_tags._alias = {}
|
||||
known_tags._project_level = {
|
||||
module = true,
|
||||
script = true,
|
||||
example = true,
|
||||
topic = true
|
||||
topic = true,
|
||||
submodule = true;
|
||||
}
|
||||
|
||||
local see_reference_handlers = {}
|
||||
|
||||
local TAG_MULTI,TAG_ID,TAG_SINGLE,TAG_TYPE,TAG_FLAG = 'M','id','S','T','N'
|
||||
|
||||
doc.TAG_MULTI,doc.TAG_ID,doc.TAG_SINGLE,doc.TAG_TYPE,doc.TAG_FLAG =
|
||||
TAG_MULTI,TAG_ID,TAG_SINGLE,TAG_TYPE,TAG_FLAG
|
||||
|
||||
|
@ -148,9 +155,27 @@ local function mod_section_type (this_mod)
|
|||
return this_mod and this_mod.section and this_mod.section.type
|
||||
end
|
||||
|
||||
local function find_module_in_files (name)
|
||||
for f in File.list:iter() do
|
||||
for m in f.modules:iter() do
|
||||
if m.name == name then
|
||||
return m,f.filename
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function File:finish()
|
||||
local this_mod
|
||||
local items = self.items
|
||||
local tagged_inside
|
||||
local function add_section (item, display_name)
|
||||
display_name = display_name or item.display_name
|
||||
this_mod.section = item
|
||||
this_mod.kinds:add_kind(display_name,display_name)
|
||||
this_mod.sections:append(item)
|
||||
this_mod.sections.by_name[display_name:gsub('%A','_')] = item
|
||||
end
|
||||
for item in items:iter() do
|
||||
if mod_section_type(this_mod) == 'factory' and item.tags then
|
||||
local klass = '@{'..this_mod.section.name..'}'
|
||||
|
@ -164,19 +189,30 @@ function File:finish()
|
|||
item:finish()
|
||||
if doc.project_level(item.type) then
|
||||
this_mod = item
|
||||
local package,mname
|
||||
local package,mname,submodule
|
||||
if item.type == 'module' then
|
||||
-- if name is 'package.mod', then mod_name is 'mod'
|
||||
package,mname = split_dotted_name(this_mod.name)
|
||||
elseif item.type == 'submodule' then
|
||||
local mf
|
||||
submodule = true
|
||||
this_mod,mf = find_module_in_files(item.name)
|
||||
if this_mod == nil then
|
||||
self:error("'"..item.name.."' not found for submodule")
|
||||
end
|
||||
tagged_inside = tools.this_module_name(self.base,self.filename)..' Functions'
|
||||
this_mod.kinds:add_kind(tagged_inside, tagged_inside)
|
||||
end
|
||||
if not package then
|
||||
mname = this_mod.name
|
||||
package = ''
|
||||
end
|
||||
self.modules:append(this_mod)
|
||||
this_mod.package = package
|
||||
this_mod.mod_name = mname
|
||||
this_mod.kinds = ModuleMap() -- the iterator over the module contents
|
||||
if not submodule then
|
||||
this_mod.package = package
|
||||
this_mod.mod_name = mname
|
||||
this_mod.kinds = ModuleMap() -- the iterator over the module contents
|
||||
self.modules:append(this_mod)
|
||||
end
|
||||
elseif doc.section_tag(item.type) then
|
||||
local display_name = item.name
|
||||
if display_name == 'end' then
|
||||
|
@ -191,10 +227,7 @@ function File:finish()
|
|||
display_name = summary
|
||||
end
|
||||
item.display_name = display_name
|
||||
this_mod.section = item
|
||||
this_mod.kinds:add_kind(display_name,display_name)
|
||||
this_mod.sections:append(item)
|
||||
this_mod.sections.by_name[display_name:gsub('%A','_')] = item
|
||||
add_section(item)
|
||||
end
|
||||
else
|
||||
local to_be_removed
|
||||
|
@ -217,14 +250,22 @@ function File:finish()
|
|||
item.name = fname
|
||||
end
|
||||
|
||||
if tagged_inside then
|
||||
item.tags.inside = tagged_inside
|
||||
end
|
||||
if item.tags.inside then
|
||||
this_mod.section = nil
|
||||
end
|
||||
|
||||
-- right, this item was within a section or a 'class'
|
||||
local section_description
|
||||
if this_mod.section then
|
||||
item.section = this_mod.section.display_name
|
||||
local this_section = this_mod.section
|
||||
item.section = this_section.display_name
|
||||
-- if it was a class, then the name should be 'Class:foo'
|
||||
local stype = this_mod.section.type
|
||||
local stype = this_section.type
|
||||
if doc.class_tag(stype) then
|
||||
local prefix = this_mod.section.name .. (not item.tags.constructor and ':' or '.')
|
||||
local prefix = section.name .. (not item.tags.constructor and ':' or '.')
|
||||
if not has_prefix(item.name,prefix) then
|
||||
item.name = prefix .. item.name
|
||||
end
|
||||
|
@ -238,7 +279,10 @@ function File:finish()
|
|||
end
|
||||
end
|
||||
end
|
||||
section_description = this_mod.section.description
|
||||
section_description = this_section.description
|
||||
elseif item.tags.inside then
|
||||
section_description = item.tags.inside
|
||||
item.section = item.tags.inside
|
||||
else -- otherwise, just goes into the default sections (Functions,Tables,etc)
|
||||
item.section = item.type
|
||||
end
|
||||
|
@ -423,7 +467,7 @@ function Item:finish()
|
|||
if params then
|
||||
for line in params:iter() do
|
||||
local name, comment = line :match('%s*([%w_%.:]+)(.*)')
|
||||
assert(name, "bad param name format")
|
||||
assert(name, "bad param name format '"..line.."'")
|
||||
names:append(name)
|
||||
comments:append(comment)
|
||||
end
|
||||
|
|
|
@ -407,7 +407,7 @@ function lexer.get_separated_list(tok,endtoken,delim)
|
|||
token,value=tok()
|
||||
if not token then return nil,'EOS' end -- end of stream is an error!
|
||||
if is_end(token,value) and level == 1 then
|
||||
if next(t1) then
|
||||
if next(tl) then
|
||||
append(parm_values,tl)
|
||||
end
|
||||
break
|
||||
|
|
|
@ -119,12 +119,14 @@ end
|
|||
-- encountered, then ldoc looks for a call to module() to find the name of the
|
||||
-- module if there isn't an explicit module name specified.
|
||||
|
||||
local function parse_file(fname,lang, package)
|
||||
local function parse_file(fname, lang, package, args)
|
||||
local line,f = 1
|
||||
local F = File(fname)
|
||||
local module_found, first_comment = false,true
|
||||
local current_item, module_item
|
||||
|
||||
F.base = package
|
||||
|
||||
local tok,f = lang.lexer(fname)
|
||||
if not tok then return nil end
|
||||
|
||||
|
@ -168,7 +170,10 @@ local function parse_file(fname,lang, package)
|
|||
t,v = tnext(tok)
|
||||
end
|
||||
if not t then
|
||||
F:warning("no module() call found; no initial doc comment")
|
||||
if not args.ignore then
|
||||
F:warning("no module() call found; no initial doc comment")
|
||||
end
|
||||
--return nil
|
||||
else
|
||||
mod,t,v = lang:parse_module_call(tok,t,v)
|
||||
if mod ~= '...' then
|
||||
|
@ -208,8 +213,10 @@ local function parse_file(fname,lang, package)
|
|||
comment = table.concat(comment)
|
||||
|
||||
if not ldoc_comment and first_comment then
|
||||
F:warning("first comment must be a doc comment!")
|
||||
break
|
||||
if not args.ignore then
|
||||
F:warning("first comment must be a doc comment!")
|
||||
break
|
||||
end
|
||||
end
|
||||
if first_comment then
|
||||
first_comment = false
|
||||
|
@ -304,7 +311,7 @@ local function parse_file(fname,lang, package)
|
|||
end
|
||||
|
||||
function parse.file(name,lang, args)
|
||||
local F,err = parse_file(name,lang, args.package)
|
||||
local F,err = parse_file(name,lang,args.package,args)
|
||||
if err or not F then return F,err end
|
||||
local ok,err = xpcall(function() F:finish() end,debug.traceback)
|
||||
if not ok then return F,err end
|
||||
|
|
|
@ -221,7 +221,7 @@ function M.this_module_name (basename,fname)
|
|||
--print('deduce',lpath,cnt,basename)
|
||||
if cnt ~= 1 then quit("module(...) name deduction failed: base "..basename.." "..fname) end
|
||||
lpath = lpath:gsub(path.sep,'.')
|
||||
return M.name_of(lpath):gsub('%.init$','')
|
||||
return (M.name_of(lpath):gsub('%.init$',''))
|
||||
end
|
||||
|
||||
function M.find_existing_module (name, dname, searchfn)
|
||||
|
|
Loading…
Reference in New Issue