getting line numbers right for warnings in examples and topics; formatting function takes explicit item argument (no longer part of ldoc state)
This commit is contained in:
parent
74531d7106
commit
c370529976
|
@ -88,9 +88,8 @@ return [==[
|
|||
# if ldoc.body then -- verbatim HTML as contents; 'non-code' entries
|
||||
$(ldoc.body)
|
||||
# elseif module then -- module documentation
|
||||
# ldoc.item = module -- context for M()
|
||||
<p>$(M(module.summary))</p>
|
||||
<p>$(M(module.description))</p>
|
||||
<p>$(M(module.summary,module))</p>
|
||||
<p>$(M(module.description,module))</p>
|
||||
|
||||
# if not ldoc.no_summary then
|
||||
# -- bang out the tables of item types for this module (e.g Functions, Tables, etc)
|
||||
|
@ -100,7 +99,7 @@ return [==[
|
|||
# for item in items() do
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#$(item.name)">$(display_name(item))</a></td>
|
||||
<td class="summary">$(M(item.summary))</td>
|
||||
<td class="summary">$(M(item.summary,item))</td>
|
||||
</tr>
|
||||
# end -- for items
|
||||
</table>
|
||||
|
@ -117,21 +116,21 @@ return [==[
|
|||
# local show_parms = show_return
|
||||
# for kind, items in module.kinds() do
|
||||
<h2><a name="$(no_spaces(kind))"></a>$(kind)</h2>
|
||||
$(M(module.kinds:get_section_description(kind)))
|
||||
$(M(module.kinds:get_section_description(kind),nil))
|
||||
<dl class="function">
|
||||
# for item in items() do ldoc.item = item -- provides context for M()
|
||||
# for item in items() do
|
||||
<dt>
|
||||
<a name = "$(item.name)"></a>
|
||||
<strong>$(display_name(item))</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
$(M(item.summary..' '..(item.description or '')))
|
||||
$(M(item.summary..' '..(item.description or ''),item))
|
||||
|
||||
# if show_parms and item.params and #item.params > 0 then
|
||||
<h3>$(module.kinds:type_of(item).subnames):</h3>
|
||||
<ul>
|
||||
# for p in iter(item.params) do
|
||||
<li><code><em>$(p)</em></code>: $(M(item.params[p]))</li>
|
||||
<li><code><em>$(p)</em></code>: $(M(item.params[p],item))</li>
|
||||
# end -- for
|
||||
</ul>
|
||||
# end -- if params
|
||||
|
@ -151,7 +150,7 @@ return [==[
|
|||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
# for r in iter(item.ret) do
|
||||
$(li)$(M(r))$(il)
|
||||
$(li)$(M(r,item))$(il)
|
||||
# end -- for
|
||||
</ol>
|
||||
# end -- if returns
|
||||
|
@ -173,7 +172,7 @@ return [==[
|
|||
# else -- if module; project-level contents
|
||||
|
||||
# if ldoc.description then
|
||||
<p>$(M(ldoc.description))</p>
|
||||
<p>$(M(ldoc.description,nil))</p>
|
||||
# end
|
||||
|
||||
# for kind, mods in ldoc.kinds() do
|
||||
|
@ -183,7 +182,7 @@ return [==[
|
|||
# for m in mods() do
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="$(no_spaces(kind))/$(m.name).html">$(m.name)</a></td>
|
||||
<td class="summary">$(M(m.summary))</td>
|
||||
<td class="summary">$(M(m.summary,m))</td>
|
||||
</tr>
|
||||
# end -- for modules
|
||||
</table>
|
||||
|
@ -193,7 +192,7 @@ return [==[
|
|||
</div> <!-- id="content" -->
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 0.5</a></i>
|
||||
<i>generated by <a href="http://github.com/stevedonovan/LDoc">LDoc 0.7</a></i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
|
40
ldoc.lua
40
ldoc.lua
|
@ -91,6 +91,10 @@ local file_types = {
|
|||
local ldoc = {}
|
||||
local add_language_extension
|
||||
|
||||
local function override (field)
|
||||
if ldoc[field] then args[field] = ldoc[field] end
|
||||
end
|
||||
|
||||
-- aliases to existing tags can be defined. E.g. just 'p' for 'param'
|
||||
function ldoc.alias (a,tag)
|
||||
doc.add_alias(a,tag)
|
||||
|
@ -252,14 +256,14 @@ 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.
|
||||
|
||||
local function process_file (f, file_list)
|
||||
local function process_file (f, flist)
|
||||
local ext = path.extension(f)
|
||||
local ftype = file_types[ext]
|
||||
if ftype then
|
||||
if args.verbose then print(path.basename(f)) end
|
||||
local F,err = parse.file(f,ftype,args)
|
||||
if err then quit(err) end
|
||||
file_list:append(F)
|
||||
flist:append(F)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -308,6 +312,9 @@ else
|
|||
quit ("file or directory does not exist: "..quote(args.file))
|
||||
end
|
||||
|
||||
-- create the function that renders text (descriptions and summaries)
|
||||
override 'format'
|
||||
ldoc.markup = markup.create(ldoc, args.format)
|
||||
|
||||
local multiple_files = #file_list > 1
|
||||
local first_module
|
||||
|
@ -331,7 +338,7 @@ local function add_special_project_entity (f,tags,process)
|
|||
F:finish()
|
||||
file_list:append(F)
|
||||
item.body = text
|
||||
return item
|
||||
return item, F
|
||||
end
|
||||
|
||||
if type(ldoc.examples) == 'string' then
|
||||
|
@ -339,24 +346,26 @@ if type(ldoc.examples) == 'string' then
|
|||
end
|
||||
if type(ldoc.examples) == 'table' then
|
||||
local prettify = require 'ldoc.prettify'
|
||||
local formatter = markup.create(ldoc,'plain')
|
||||
prettify.resolve_inline_references = markup.resolve_inline_references
|
||||
|
||||
local function process_example (f, file_list)
|
||||
process_file_list (ldoc.examples, '*.lua', function(f)
|
||||
local item = add_special_project_entity(f,{
|
||||
class = 'example',
|
||||
})
|
||||
item.postprocess = prettify.lua
|
||||
end
|
||||
|
||||
process_file_list (ldoc.examples, '*.lua', process_example, file_list)
|
||||
-- wrap prettify for this example so it knows which file to blame
|
||||
-- if there's a problem
|
||||
item.postprocess = function(code) return prettify.lua(f,code) end
|
||||
end)
|
||||
end
|
||||
|
||||
if type(ldoc.readme) == 'string' then
|
||||
local item = add_special_project_entity(ldoc.readme,{
|
||||
local item, F = add_special_project_entity(ldoc.readme,{
|
||||
class = 'topic'
|
||||
}, markup.add_sections)
|
||||
item.postprocess = markup.create(ldoc, 'markdown')
|
||||
-- add_sections above has created sections corresponding to the 2nd level
|
||||
-- headers in the readme, which are attached to the File. So
|
||||
-- we pass the File to the postprocesser can insert the section markers
|
||||
-- and resolve inline @ references.
|
||||
item.postprocess = function(txt) return ldoc.markup(txt,F) end
|
||||
end
|
||||
|
||||
---- extract modules from the file objects, resolve references and sort appropriately ---
|
||||
|
@ -442,9 +451,6 @@ local function style_dir (sname)
|
|||
end
|
||||
end
|
||||
|
||||
local function override (field)
|
||||
if ldoc[field] then args[field] = ldoc[field] end
|
||||
end
|
||||
|
||||
-- the directories for template and stylesheet can be specified
|
||||
-- either by command-line '--template','--style' arguments or by 'template and
|
||||
|
@ -457,7 +463,6 @@ style_dir 'style'
|
|||
style_dir 'template'
|
||||
|
||||
-- can specify format, output, dir and ext in config.ld
|
||||
override 'format'
|
||||
override 'output'
|
||||
override 'dir'
|
||||
override 'ext'
|
||||
|
@ -490,9 +495,6 @@ if args.style == '!' or args.template == '!' then
|
|||
end
|
||||
end
|
||||
|
||||
-- create the function that renders text (descriptions and summaries)
|
||||
ldoc.markup = markup.create(ldoc, args.format)
|
||||
|
||||
|
||||
ldoc.single = not multiple_files and first_module or nil
|
||||
ldoc.log = print
|
||||
|
|
|
@ -150,10 +150,9 @@ function File:finish()
|
|||
local section_description
|
||||
if this_mod.section then
|
||||
item.section = this_mod.section.display_name
|
||||
-- if it was a class, then the name should be 'Class.foo'
|
||||
-- if it was a class, then the name should be 'Class:foo'
|
||||
if this_mod.section.type == 'type' then
|
||||
item.name = this_mod.section.name .. '.' .. item.name
|
||||
item.display_name = this_mod.section.name .. ':' .. item.name
|
||||
item.name = this_mod.section.name .. ':' .. item.name
|
||||
end
|
||||
section_description = this_mod.section.description
|
||||
else -- otherwise, just goes into the default sections (Functions,Tables,etc)
|
||||
|
|
|
@ -126,7 +126,7 @@ function html.generate_output(ldoc, args, project)
|
|||
for m in modules() do
|
||||
ldoc.module = m
|
||||
ldoc.body = m.body
|
||||
if ldoc.body then
|
||||
if ldoc.body and m.postprocess then
|
||||
ldoc.body = m.postprocess(ldoc.body)
|
||||
end
|
||||
out,err = template.substitute(module_template,{
|
||||
|
|
|
@ -58,56 +58,70 @@ function markup.insert_markdown_lines (txt)
|
|||
return res
|
||||
end
|
||||
|
||||
-- for readme text, the idea here is to insert module sections at ## so that
|
||||
-- they can appear in the contents list as a ToC
|
||||
function markup.add_sections(F, txt)
|
||||
local res, append = {}, table.insert
|
||||
for line in stringx.lines(txt) do
|
||||
local title = line:match '^##[^#]%s*(.+)'
|
||||
if title then
|
||||
local section = F:add_document_section(title)
|
||||
append(res,('<a id="%s"></a>\n'):format(section))
|
||||
append(res,line)
|
||||
else
|
||||
append(res,line)
|
||||
end
|
||||
end
|
||||
return concat(res,'\n')
|
||||
end
|
||||
|
||||
local function handle_reference (ldoc, name)
|
||||
-- inline <references> use same lookup as @see
|
||||
local function resolve_inline_references (ldoc, txt, item)
|
||||
return (txt:gsub('@{([^}]-)}',function (name)
|
||||
local qname,label = utils.splitv(name,'%s*|')
|
||||
if not qname then
|
||||
qname = name
|
||||
end
|
||||
local ref,err = markup.process_reference(qname)
|
||||
if not ref then
|
||||
if ldoc.item then ldoc.item:warning(err)
|
||||
err = err .. ' ' .. qname
|
||||
if item then item:warning(err)
|
||||
else
|
||||
io.stderr:write(err,'\n')
|
||||
io.stderr:write('nofile error: ',err,'\n')
|
||||
end
|
||||
return ''
|
||||
return '???'
|
||||
end
|
||||
if not label then
|
||||
label = ref.label
|
||||
end
|
||||
if not ldoc.plain then -- a nastiness with markdown.lua and underscores
|
||||
if not markup.plain then -- a nastiness with markdown.lua and underscores
|
||||
label = label:gsub('_','\\_')
|
||||
end
|
||||
local res = ('<a href="%s">%s</a>'):format(ldoc.href(ref),label)
|
||||
return res
|
||||
end))
|
||||
end
|
||||
|
||||
local ldoc_handle_reference
|
||||
|
||||
-- inline <references> use same lookup as @see
|
||||
local function resolve_inline_references (ldoc, txt)
|
||||
return (txt:gsub('@{([^}]-)}',ldoc_handle_reference))
|
||||
-- for readme text, the idea here is to create module sections at ## so that
|
||||
-- they can appear in the contents list as a ToC.
|
||||
function markup.add_sections(F, txt)
|
||||
local sections, L = {}, 1
|
||||
for line in stringx.lines(txt) do
|
||||
local title = line:match '^##[^#]%s*(.+)'
|
||||
if title then
|
||||
sections[L] = F:add_document_section(title)
|
||||
end
|
||||
L = L + 1
|
||||
end
|
||||
F.sections = sections
|
||||
return txt
|
||||
end
|
||||
|
||||
local function process_multiline_markdown(ldoc, txt, F)
|
||||
local res, L, append = {}, 1, table.insert
|
||||
local err_item = {
|
||||
warning = function (self,msg)
|
||||
io.stderr:write(F.filename..':'..L..': '..msg,'\n')
|
||||
end
|
||||
}
|
||||
for line in stringx.lines(txt) do
|
||||
line = resolve_inline_references(ldoc, line, err_item)
|
||||
local section = F.sections[L]
|
||||
if section then
|
||||
append(res,('<a name="%s"></a>'):format(section))
|
||||
end
|
||||
append(res,line)
|
||||
L = L + 1
|
||||
end
|
||||
return concat(res,'\n')
|
||||
end
|
||||
|
||||
|
||||
function markup.create (ldoc, format)
|
||||
local processor
|
||||
ldoc_handle_reference = utils.bind1(handle_reference,ldoc)
|
||||
markup.plain = true
|
||||
markup.process_reference = function(name)
|
||||
local mod = ldoc.single or ldoc.module
|
||||
|
@ -118,27 +132,31 @@ function markup.create (ldoc, format)
|
|||
end
|
||||
|
||||
if format == 'plain' then
|
||||
processor = function(txt)
|
||||
processor = function(txt, item)
|
||||
if txt == nil then return '' end
|
||||
return resolve_inline_references(ldoc, txt)
|
||||
return resolve_inline_references(ldoc, txt, item)
|
||||
end
|
||||
else
|
||||
local ok,formatter = pcall(require,format)
|
||||
if not ok then quit("cannot load formatter: "..format) end
|
||||
markup.plain = false
|
||||
processor = function (txt)
|
||||
processor = function (txt,item)
|
||||
if txt == nil then return '' end
|
||||
txt = resolve_inline_references(ldoc, txt)
|
||||
if utils.is_type(item,doc.File) then
|
||||
txt = process_multiline_markdown(ldoc, txt, item)
|
||||
else
|
||||
txt = resolve_inline_references(ldoc, txt, item)
|
||||
end
|
||||
if txt:find '\n' and ldoc.extended_markdown then -- multiline text
|
||||
txt = markup.insert_markdown_lines(txt)
|
||||
end
|
||||
txt = formatter (txt)
|
||||
txt = formatter(txt)
|
||||
-- We will add our own paragraph tags, if needed.
|
||||
return (txt:gsub('^%s*<p>(.+)</p>%s*$','%1'))
|
||||
end
|
||||
end
|
||||
markup.resolve_inline_references = function(txt)
|
||||
return resolve_inline_references(ldoc, txt)
|
||||
markup.resolve_inline_references = function(txt, errfn)
|
||||
return resolve_inline_references(ldoc, txt, errfn)
|
||||
end
|
||||
markup.processor = processor
|
||||
prettify.resolve_inline_references = markup.resolve_inline_references
|
||||
|
|
|
@ -25,19 +25,24 @@ end
|
|||
|
||||
local spans = {keyword=true,number=true,string=true,comment=true}
|
||||
|
||||
function prettify.lua (code)
|
||||
function prettify.lua (fname, code)
|
||||
local res = List()
|
||||
res:append(header)
|
||||
res:append '<pre>\n'
|
||||
|
||||
local tok = lexer.lua(code,{},{})
|
||||
local error_reporter = {
|
||||
warning = function (self,msg)
|
||||
io.stderr:write(fname..':'..tok:lineno()..': '..msg,'\n')
|
||||
end
|
||||
}
|
||||
local t,val = tok()
|
||||
if not t then return nil,"empty file" end
|
||||
while t do
|
||||
val = escape(val)
|
||||
if spans[t] then
|
||||
if t == 'comment' then -- may contain @{ref}
|
||||
val = prettify.resolve_inline_references(val)
|
||||
val = prettify.resolve_inline_references(val,error_reporter)
|
||||
end
|
||||
res:append(span(t,val))
|
||||
else
|
||||
|
|
Loading…
Reference in New Issue