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
|
# if ldoc.body then -- verbatim HTML as contents; 'non-code' entries
|
||||||
$(ldoc.body)
|
$(ldoc.body)
|
||||||
# elseif module then -- module documentation
|
# elseif module then -- module documentation
|
||||||
# ldoc.item = module -- context for M()
|
<p>$(M(module.summary,module))</p>
|
||||||
<p>$(M(module.summary))</p>
|
<p>$(M(module.description,module))</p>
|
||||||
<p>$(M(module.description))</p>
|
|
||||||
|
|
||||||
# if not ldoc.no_summary then
|
# if not ldoc.no_summary then
|
||||||
# -- bang out the tables of item types for this module (e.g Functions, Tables, etc)
|
# -- 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
|
# for item in items() do
|
||||||
<tr>
|
<tr>
|
||||||
<td class="name" nowrap><a href="#$(item.name)">$(display_name(item))</a></td>
|
<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>
|
</tr>
|
||||||
# end -- for items
|
# end -- for items
|
||||||
</table>
|
</table>
|
||||||
|
@ -117,21 +116,21 @@ return [==[
|
||||||
# local show_parms = show_return
|
# local show_parms = show_return
|
||||||
# for kind, items in module.kinds() do
|
# for kind, items in module.kinds() do
|
||||||
<h2><a name="$(no_spaces(kind))"></a>$(kind)</h2>
|
<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">
|
<dl class="function">
|
||||||
# for item in items() do ldoc.item = item -- provides context for M()
|
# for item in items() do
|
||||||
<dt>
|
<dt>
|
||||||
<a name = "$(item.name)"></a>
|
<a name = "$(item.name)"></a>
|
||||||
<strong>$(display_name(item))</strong>
|
<strong>$(display_name(item))</strong>
|
||||||
</dt>
|
</dt>
|
||||||
<dd>
|
<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
|
# if show_parms and item.params and #item.params > 0 then
|
||||||
<h3>$(module.kinds:type_of(item).subnames):</h3>
|
<h3>$(module.kinds:type_of(item).subnames):</h3>
|
||||||
<ul>
|
<ul>
|
||||||
# for p in iter(item.params) do
|
# 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
|
# end -- for
|
||||||
</ul>
|
</ul>
|
||||||
# end -- if params
|
# end -- if params
|
||||||
|
@ -151,7 +150,7 @@ return [==[
|
||||||
<h3>Returns:</h3>
|
<h3>Returns:</h3>
|
||||||
<ol>
|
<ol>
|
||||||
# for r in iter(item.ret) do
|
# for r in iter(item.ret) do
|
||||||
$(li)$(M(r))$(il)
|
$(li)$(M(r,item))$(il)
|
||||||
# end -- for
|
# end -- for
|
||||||
</ol>
|
</ol>
|
||||||
# end -- if returns
|
# end -- if returns
|
||||||
|
@ -173,7 +172,7 @@ return [==[
|
||||||
# else -- if module; project-level contents
|
# else -- if module; project-level contents
|
||||||
|
|
||||||
# if ldoc.description then
|
# if ldoc.description then
|
||||||
<p>$(M(ldoc.description))</p>
|
<p>$(M(ldoc.description,nil))</p>
|
||||||
# end
|
# end
|
||||||
|
|
||||||
# for kind, mods in ldoc.kinds() do
|
# for kind, mods in ldoc.kinds() do
|
||||||
|
@ -183,7 +182,7 @@ return [==[
|
||||||
# for m in mods() do
|
# for m in mods() do
|
||||||
<tr>
|
<tr>
|
||||||
<td class="name" nowrap><a href="$(no_spaces(kind))/$(m.name).html">$(m.name)</a></td>
|
<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>
|
</tr>
|
||||||
# end -- for modules
|
# end -- for modules
|
||||||
</table>
|
</table>
|
||||||
|
@ -193,7 +192,7 @@ return [==[
|
||||||
</div> <!-- id="content" -->
|
</div> <!-- id="content" -->
|
||||||
</div> <!-- id="main" -->
|
</div> <!-- id="main" -->
|
||||||
<div id="about">
|
<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="about" -->
|
||||||
</div> <!-- id="container" -->
|
</div> <!-- id="container" -->
|
||||||
</body>
|
</body>
|
||||||
|
|
40
ldoc.lua
40
ldoc.lua
|
@ -91,6 +91,10 @@ local file_types = {
|
||||||
local ldoc = {}
|
local ldoc = {}
|
||||||
local add_language_extension
|
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'
|
-- aliases to existing tags can be defined. E.g. just 'p' for 'param'
|
||||||
function ldoc.alias (a,tag)
|
function ldoc.alias (a,tag)
|
||||||
doc.add_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
|
-- 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.
|
-- 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 ext = path.extension(f)
|
||||||
local ftype = file_types[ext]
|
local ftype = file_types[ext]
|
||||||
if ftype then
|
if ftype then
|
||||||
if args.verbose then print(path.basename(f)) end
|
if args.verbose then print(path.basename(f)) end
|
||||||
local F,err = parse.file(f,ftype,args)
|
local F,err = parse.file(f,ftype,args)
|
||||||
if err then quit(err) end
|
if err then quit(err) end
|
||||||
file_list:append(F)
|
flist:append(F)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -308,6 +312,9 @@ else
|
||||||
quit ("file or directory does not exist: "..quote(args.file))
|
quit ("file or directory does not exist: "..quote(args.file))
|
||||||
end
|
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 multiple_files = #file_list > 1
|
||||||
local first_module
|
local first_module
|
||||||
|
@ -331,7 +338,7 @@ local function add_special_project_entity (f,tags,process)
|
||||||
F:finish()
|
F:finish()
|
||||||
file_list:append(F)
|
file_list:append(F)
|
||||||
item.body = text
|
item.body = text
|
||||||
return item
|
return item, F
|
||||||
end
|
end
|
||||||
|
|
||||||
if type(ldoc.examples) == 'string' then
|
if type(ldoc.examples) == 'string' then
|
||||||
|
@ -339,24 +346,26 @@ if type(ldoc.examples) == 'string' then
|
||||||
end
|
end
|
||||||
if type(ldoc.examples) == 'table' then
|
if type(ldoc.examples) == 'table' then
|
||||||
local prettify = require 'ldoc.prettify'
|
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,{
|
local item = add_special_project_entity(f,{
|
||||||
class = 'example',
|
class = 'example',
|
||||||
})
|
})
|
||||||
item.postprocess = prettify.lua
|
-- wrap prettify for this example so it knows which file to blame
|
||||||
end
|
-- if there's a problem
|
||||||
|
item.postprocess = function(code) return prettify.lua(f,code) end
|
||||||
process_file_list (ldoc.examples, '*.lua', process_example, file_list)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
if type(ldoc.readme) == 'string' then
|
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'
|
class = 'topic'
|
||||||
}, markup.add_sections)
|
}, 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
|
end
|
||||||
|
|
||||||
---- extract modules from the file objects, resolve references and sort appropriately ---
|
---- extract modules from the file objects, resolve references and sort appropriately ---
|
||||||
|
@ -442,9 +451,6 @@ local function style_dir (sname)
|
||||||
end
|
end
|
||||||
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
|
-- the directories for template and stylesheet can be specified
|
||||||
-- either by command-line '--template','--style' arguments or by 'template and
|
-- either by command-line '--template','--style' arguments or by 'template and
|
||||||
|
@ -457,7 +463,6 @@ style_dir 'style'
|
||||||
style_dir 'template'
|
style_dir 'template'
|
||||||
|
|
||||||
-- can specify format, output, dir and ext in config.ld
|
-- can specify format, output, dir and ext in config.ld
|
||||||
override 'format'
|
|
||||||
override 'output'
|
override 'output'
|
||||||
override 'dir'
|
override 'dir'
|
||||||
override 'ext'
|
override 'ext'
|
||||||
|
@ -490,9 +495,6 @@ if args.style == '!' or args.template == '!' then
|
||||||
end
|
end
|
||||||
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.single = not multiple_files and first_module or nil
|
||||||
ldoc.log = print
|
ldoc.log = print
|
||||||
|
|
|
@ -150,10 +150,9 @@ function File:finish()
|
||||||
local section_description
|
local section_description
|
||||||
if this_mod.section then
|
if this_mod.section then
|
||||||
item.section = this_mod.section.display_name
|
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
|
if this_mod.section.type == 'type' then
|
||||||
item.name = this_mod.section.name .. '.' .. item.name
|
item.name = this_mod.section.name .. ':' .. item.name
|
||||||
item.display_name = this_mod.section.name .. ':' .. item.name
|
|
||||||
end
|
end
|
||||||
section_description = this_mod.section.description
|
section_description = this_mod.section.description
|
||||||
else -- otherwise, just goes into the default sections (Functions,Tables,etc)
|
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
|
for m in modules() do
|
||||||
ldoc.module = m
|
ldoc.module = m
|
||||||
ldoc.body = m.body
|
ldoc.body = m.body
|
||||||
if ldoc.body then
|
if ldoc.body and m.postprocess then
|
||||||
ldoc.body = m.postprocess(ldoc.body)
|
ldoc.body = m.postprocess(ldoc.body)
|
||||||
end
|
end
|
||||||
out,err = template.substitute(module_template,{
|
out,err = template.substitute(module_template,{
|
||||||
|
|
|
@ -58,56 +58,70 @@ function markup.insert_markdown_lines (txt)
|
||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
|
|
||||||
-- for readme text, the idea here is to insert module sections at ## so that
|
-- inline <references> use same lookup as @see
|
||||||
-- they can appear in the contents list as a ToC
|
local function resolve_inline_references (ldoc, txt, item)
|
||||||
function markup.add_sections(F, txt)
|
return (txt:gsub('@{([^}]-)}',function (name)
|
||||||
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)
|
|
||||||
local qname,label = utils.splitv(name,'%s*|')
|
local qname,label = utils.splitv(name,'%s*|')
|
||||||
if not qname then
|
if not qname then
|
||||||
qname = name
|
qname = name
|
||||||
end
|
end
|
||||||
local ref,err = markup.process_reference(qname)
|
local ref,err = markup.process_reference(qname)
|
||||||
if not ref then
|
if not ref then
|
||||||
if ldoc.item then ldoc.item:warning(err)
|
err = err .. ' ' .. qname
|
||||||
|
if item then item:warning(err)
|
||||||
else
|
else
|
||||||
io.stderr:write(err,'\n')
|
io.stderr:write('nofile error: ',err,'\n')
|
||||||
end
|
end
|
||||||
return ''
|
return '???'
|
||||||
end
|
end
|
||||||
if not label then
|
if not label then
|
||||||
label = ref.label
|
label = ref.label
|
||||||
end
|
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('_','\\_')
|
label = label:gsub('_','\\_')
|
||||||
end
|
end
|
||||||
local res = ('<a href="%s">%s</a>'):format(ldoc.href(ref),label)
|
local res = ('<a href="%s">%s</a>'):format(ldoc.href(ref),label)
|
||||||
return res
|
return res
|
||||||
|
end))
|
||||||
end
|
end
|
||||||
|
|
||||||
local 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.
|
||||||
-- inline <references> use same lookup as @see
|
function markup.add_sections(F, txt)
|
||||||
local function resolve_inline_references (ldoc, txt)
|
local sections, L = {}, 1
|
||||||
return (txt:gsub('@{([^}]-)}',ldoc_handle_reference))
|
for line in stringx.lines(txt) do
|
||||||
|
local title = line:match '^##[^#]%s*(.+)'
|
||||||
|
if title then
|
||||||
|
sections[L] = F:add_document_section(title)
|
||||||
end
|
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)
|
function markup.create (ldoc, format)
|
||||||
local processor
|
local processor
|
||||||
ldoc_handle_reference = utils.bind1(handle_reference,ldoc)
|
|
||||||
markup.plain = true
|
markup.plain = true
|
||||||
markup.process_reference = function(name)
|
markup.process_reference = function(name)
|
||||||
local mod = ldoc.single or ldoc.module
|
local mod = ldoc.single or ldoc.module
|
||||||
|
@ -118,17 +132,21 @@ function markup.create (ldoc, format)
|
||||||
end
|
end
|
||||||
|
|
||||||
if format == 'plain' then
|
if format == 'plain' then
|
||||||
processor = function(txt)
|
processor = function(txt, item)
|
||||||
if txt == nil then return '' end
|
if txt == nil then return '' end
|
||||||
return resolve_inline_references(ldoc, txt)
|
return resolve_inline_references(ldoc, txt, item)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local ok,formatter = pcall(require,format)
|
local ok,formatter = pcall(require,format)
|
||||||
if not ok then quit("cannot load formatter: "..format) end
|
if not ok then quit("cannot load formatter: "..format) end
|
||||||
markup.plain = false
|
markup.plain = false
|
||||||
processor = function (txt)
|
processor = function (txt,item)
|
||||||
if txt == nil then return '' end
|
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
|
if txt:find '\n' and ldoc.extended_markdown then -- multiline text
|
||||||
txt = markup.insert_markdown_lines(txt)
|
txt = markup.insert_markdown_lines(txt)
|
||||||
end
|
end
|
||||||
|
@ -137,8 +155,8 @@ function markup.create (ldoc, format)
|
||||||
return (txt:gsub('^%s*<p>(.+)</p>%s*$','%1'))
|
return (txt:gsub('^%s*<p>(.+)</p>%s*$','%1'))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
markup.resolve_inline_references = function(txt)
|
markup.resolve_inline_references = function(txt, errfn)
|
||||||
return resolve_inline_references(ldoc, txt)
|
return resolve_inline_references(ldoc, txt, errfn)
|
||||||
end
|
end
|
||||||
markup.processor = processor
|
markup.processor = processor
|
||||||
prettify.resolve_inline_references = markup.resolve_inline_references
|
prettify.resolve_inline_references = markup.resolve_inline_references
|
||||||
|
|
|
@ -25,19 +25,24 @@ end
|
||||||
|
|
||||||
local spans = {keyword=true,number=true,string=true,comment=true}
|
local spans = {keyword=true,number=true,string=true,comment=true}
|
||||||
|
|
||||||
function prettify.lua (code)
|
function prettify.lua (fname, code)
|
||||||
local res = List()
|
local res = List()
|
||||||
res:append(header)
|
res:append(header)
|
||||||
res:append '<pre>\n'
|
res:append '<pre>\n'
|
||||||
|
|
||||||
local tok = lexer.lua(code,{},{})
|
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()
|
local t,val = tok()
|
||||||
if not t then return nil,"empty file" end
|
if not t then return nil,"empty file" end
|
||||||
while t do
|
while t do
|
||||||
val = escape(val)
|
val = escape(val)
|
||||||
if spans[t] then
|
if spans[t] then
|
||||||
if t == 'comment' then -- may contain @{ref}
|
if t == 'comment' then -- may contain @{ref}
|
||||||
val = prettify.resolve_inline_references(val)
|
val = prettify.resolve_inline_references(val,error_reporter)
|
||||||
end
|
end
|
||||||
res:append(span(t,val))
|
res:append(span(t,val))
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue