in implicit function style (a la Geoff) the first comment refers to the return value. In colon style, an exclamation mark allows a typename to be directly used as a 'tag'. The word 'optional' is only issued if we have either nil or a type

This commit is contained in:
steve donovan 2012-12-31 14:52:00 +02:00
parent c49fa67644
commit 1bb83924bb
7 changed files with 145 additions and 28 deletions

View File

@ -47,6 +47,10 @@ known_tags._code_types = {
script = true
}
known_tags._module_info = {
'copyright','release','license','author'
}
local see_reference_handlers = {}
@ -80,6 +84,7 @@ function doc.project_level(tag)
return known_tags._project_level[tag]
end
-- is it a project level tag containing code?
function doc.code_tag (tag)
return known_tags._code_types[tag]
end
@ -94,6 +99,10 @@ function doc.class_tag (tag)
return tag == 'type' or tag == 'factory'
end
function doc.module_info_tags ()
return List.iter(known_tags._module_info)
end
-- annotation tags can appear anywhere in the code and may contain of these tags:
known_tags._annotation_tags = {
@ -523,10 +532,21 @@ function Item:finish()
comments:append(comment)
end
end
self.modifiers['return'] = self.modifiers['return'] or List()
self.modifiers[field] = self.modifiers[field] or List()
-- not all arguments may be commented: we use the formal arguments
-- if available as the authoritative list, and warn if there's an inconsistency.
if self.formal_args then
local fargs = self.formal_args
if not self.ret and fargs.return_comment then
local retc = fargs.return_comment
local type,rest = retc:match '([^:]+):(.*)'
if type then
self.modifiers['return']:append{type=type}
retc = rest
end
self.ret = List{retc}
end
if #fargs ~= 0 then
local pnames, pcomments = names, comments
names, comments = List(),List()
@ -554,7 +574,6 @@ function Item:finish()
comment = comment:gsub('^%-+%s*','')
local type,rest = comment:match '([^:]+):(.*)'
if type then
if not self.modifiers[field] then self.modifiers[field] = List() end
self.modifiers[field]:append {type = type}
comment = rest
end
@ -624,7 +643,6 @@ function Item:type_of_ret(idx)
end
function Item:warning(msg)
local file = self.file and self.file.filename
if type(file) == 'table' then pretty.dump(file); file = '?' end

View File

@ -20,6 +20,7 @@ local stringx = require 'pl.stringx'
local template = require 'pl.template'
local tools = require 'ldoc.tools'
local markup = require 'ldoc.markup'
local doc = require 'ldoc.doc'
local html = {}
@ -34,6 +35,21 @@ local function cleanup_whitespaces(text)
return table.concat(lines, "\n")
end
local function get_module_info(m)
local info = {}
for tag in doc.module_info_tags() do
local val = m.tags[tag]
if type(val)=='table' then
val = table.concat(val,',')
end
tag = stringx.title(tag)
info[tag] = val
end
if next(info) then
return info
end
end
local escape_table = { ["'"] = "&apos;", ["\""] = "&quot;", ["<"] = "&lt;", [">"] = "&gt;", ["&"] = "&amp;" }
function html.generate_output(ldoc, args, project)
@ -105,6 +121,10 @@ function html.generate_output(ldoc, args, project)
function ldoc.typename (tp)
if not tp or tp == '' then return '' end
local optional
-- ?<type> is short for ?nil|<type>
if tp:match("^%?") and not tp:match '|' then
tp = '?|'..tp:sub(2)
end
local tp2 = tp:match("%?|?(.*)")
if tp2 then
optional = true
@ -123,7 +143,7 @@ function html.generate_output(ldoc, args, project)
if #types > 1 then names = names.." or "..types[#types] end
if optional then
if names ~= '' then
names = "optional "..names
if #types == 1 then names = "optional "..names end
else
names = "optional"
end
@ -139,6 +159,7 @@ function html.generate_output(ldoc, args, project)
local css = ldoc.css
ldoc.output = args.output
ldoc.ipairs = ipairs
ldoc.pairs = pairs
-- in single mode there is one module and the 'index' is the
-- documentation for that module.
@ -147,9 +168,10 @@ function html.generate_output(ldoc, args, project)
ldoc.kinds_allowed = {module = true, topic = true}
end
ldoc.root = true
ldoc.module.info = get_module_info(ldoc.module)
local out,err = template.substitute(module_template,{
ldoc = ldoc,
module = ldoc.module
module = ldoc.module,
})
ldoc.root = false
if not out then quit("template failed: "..err) end
@ -185,6 +207,7 @@ function html.generate_output(ldoc, args, project)
for m in modules() do
ldoc.module = m
ldoc.body = m.body
m.info = get_module_info(m)
if ldoc.body and m.postprocess then
ldoc.body = m.postprocess(ldoc.body)
end

View File

@ -100,6 +100,15 @@ return [==[
# end -- for
</ul>
# end -- if usage
# if module.info then
<h3>Info:</h3>
<ul>
# for tag, value in ldoc.pairs(module.info) do
<li><strong>$(tag)</strong>: $(value)</li>
# end
</ul>
# end -- if module.info
# if not ldoc.no_summary then
# -- bang out the tables of item types for this module (e.g Functions, Tables, etc)

View File

@ -48,7 +48,8 @@ function parse_at_tags(text)
return preamble,tag_items
end
local colon_tag = '%s*(%a+):%s'
--local colon_tag = '%s*(%a+):%s'
local colon_tag = '%s*(%S-):%s'
local colon_tag_value = colon_tag..'(.*)'
function parse_colon_tags (text)
@ -58,7 +59,13 @@ function parse_colon_tags (text)
while line do
local tag, rest = line:match(colon_tag_value)
follows, line = tools.grab_while_not(lines,colon_tag)
append(tag_items,{tag, rest .. '\n' .. follows})
local value = rest .. '\n' .. follows
if tag:match '^[%?!]' then
tag = tag:gsub('^!','')
value = tag .. ' ' .. value
tag = 'tparam'
end
append(tag_items,{tag, value})
end
return preamble,tag_items
end
@ -235,7 +242,7 @@ local function parse_file(fname, lang, package, args)
else
item_follows, is_local, case = lang:item_follows(t,v,tok)
end
if item_follows or comment:find '@'then
if item_follows or comment:find '@' or comment:find ': ' then
tags = extract_tags(comment)
if doc.project_level(tags.class) then
module_found = tags.name

View File

@ -282,19 +282,19 @@ function M.get_parameters (tok,endtoken,delim)
if not ltl or not ltl[1] or #ltl[1] == 0 then return args end -- no arguments
local function set_comment (idx,tok)
local text = stringx.rstrip(value_of(tok)) --
local current_comment = args.comments[args[idx]]
if current_comment then
text = text:match("%s*%-%-+%s*(.*)")
args.comments[args[idx]] = current_comment .. " " .. text
else
args.comments[args[idx]] = text
end
local function strip_comment (text)
return text:match("%s*%-%-+%s*(.*)")
end
local function fetch_comment (tl)
return
local function set_comment (idx,tok)
local text = stringx.rstrip(value_of(tok))
text = strip_comment(text)
local arg = args[idx]
local current_comment = args.comments[arg]
if current_comment then
text = current_comment .. " " .. text
end
args.comments[arg] = text
end
for i = 1,#ltl do
@ -308,6 +308,9 @@ function M.get_parameters (tok,endtoken,delim)
set_comment(i-1,tl[j])
j = j + 1
end
else -- first comment however is for the function return comment!
args.return_comment = strip_comment(value_of(tl[i]))
j = j + 1
end
if #tl > 1 then
args:append(value_of(tl[j]))

View File

@ -1 +0,0 @@
print(arg,DOOFUS)

58
tests/styles/four.lua Normal file
View File

@ -0,0 +1,58 @@
------------
-- Yet another module.
-- @module four
-- Description can continue after simple tags, if you
-- like
-- @author bob, james
-- @license MIT
-- @copyright InfoReich 2013
--- a function with typed args.
-- Note the the standard tparam aliases
-- @string name person's name
-- @int age
-- @treturn string
function one (name,age)
end
--- second useless function.
-- If you hate @ tags, you can use colons.
-- Optional type specifiers are allowed in this format.
-- As an extension, '?' is short for '?|'.
-- Note how these types are rendered!
-- string: name
-- int: age
-- ?person2: options
-- treturn: ?table|string
function two (name,age,options)
end
--- third useless function.
-- Can always put comments inline, may
-- be multiple.
-- note that first comment is refers to return
function three ( -- person:
name, -- string: person's name
age -- int:
-- not less than zero!
)
--- an implicit table.
-- Again, we can use the comments
person = {
name = '', -- string: name of person
age = 0, -- int:
}
--- an explicit table.
-- Can now use tparam aliases in table defns
-- @string name
-- @int age
-- @table person2
--- explicit table in colon format.
-- Note how '!' lets you use a type name directly.
-- string: surname
-- string: birthdate
-- !person2: options
-- table: person3