lua-users home
lua-l archive

Re: doxygen and lua modules

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


 > I'm currently exploring the idea of generating documentation for the
 > Lua interface of a Lua module with doxygen...
 > 
 > In addition, I'd also like to generate some source files that will add
 > in-application help strings to the module table. Something like
 > module.__help = { functionx = "functionx does x", ... etc.}. I'm
 > wondering also if other people have done this and if perhaps there is
 > some kind of agreed upon field to put this in and format for the help
 > strings.
Fidelis Assis and I have done something like this for the upcoming
new version of OSBF-Lua (which will never be released because I can't
stop tinkering with it!). We've been focusing on internal
documentation; we have commands such as
 osbf internals
 osbf internals util
 osbf internals util.die
This thing has been a lifesaver, especially if we have to go off and
do real work for a couple of weeks and forget everything.
The implementation uses the convention that every module has an
internal value called __doc. The 'internals' module is attached to
this message. We use the same mechanism to document the C APIs
except they live in a Lua module of their own.
We have desultory ambitions in the direction of user documentation but
until things stabilize it won't happen soon. 
Oh, and everything is simple ASCII. We thought html would be nice but
for us it's more important that the sources be readable and that it
work instantly on the command line. Eventually a wiki-like markup
might be a good compromise, but at the moment we're more in the
mail-handling business than in the documentation business :-)
And a distinct advantage is that there's no separate step for
extracting the doco; it's always just right there.
Norman
local modname = ...
local osbfname = string.gsub(modname, '%..-$', '')
local util = require(osbfname .. '.util')
local osbf = _G[osbfname]
local function internals(out, s)
 local function show(what, t)
 local l = table.sorted_keys(t)
 if #l > 0 then
 out:write('\n', what, ':\n')
 for _, m in ipairs(l) do out:write(' ', m, '\n') end
 end
 end
 local function undoc(modname, m, ufuns)
 local doc = assert(m.__doc)
 ufuns = ufuns or { }
 for f in pairs(m) do
 if not string.find(f, '^_') and not doc[f] then
 ufuns[modname .. '.' .. f] = true
 end
 end
 return ufuns
 end
 
 if not s then
 local documented, undocumented, ufuns = { }, { }, { }
 for k, v in pairs(osbf) do
 if package.loaded[osbfname .. '.' .. k] == v then
 (v.__doc and documented or undocumented)[k] = true
 if v.__doc then
 undoc(k, v, ufuns)
 end
 end
 end
 show('Documented modules', documented)
 show('Undocumented modules', undocumented)
 show('Undocumented functions', ufuns)
 else
 local module, member
 if osbf[s] then
 module, member = s, nil
 else
 module, member = string.match(s, '^([^%.]+)%.([^%.]+)$')
 end
 if not module then
 out:write("There is no internal module called ", s, '\n')
 return
 end
 if not osbf[module] then
 out:write('There is no such internal module as ', module, '\n')
 return
 end
 local doc = osbf[module].__doc
 local function final_newline(s)
 return string.match(s, '\n$') and '' or '\n'
 end
 local function document(k)
 if string.find(k, '^__') then return end
 local d = string.gsub(doc[k], '\n\n', '\n \n')
 d = string.gsub(d, '\n(.)', '\n %1')
 local exported = osbf[module][k] ~= nil
 if not exported then
 d = string.gsub(d, '^%s*function', 'local function')
 end
 out:write('\n', module, exported and '.' or ': ', k, ' = ', d, final_newline(d))
 end
 if not doc then
 out:write('Internal module ', module, ' is not documented\n')
 elseif not member then -- document the whole module
 local first = doc.__order or { }
 local sorted = table.sorted_keys(doc)
 local written = { }
 if doc.__overview then
 out:write('=============== Overview of module ', s, ' ===============\n\n')
 out:write(doc.__overview, final_newline(doc.__overview))
 out:write('===================================', string.gsub(s, '.', '='),
 '===============\n')
 end
 for _, k in ipairs(first) do
 written[k] = true
 document(k)
 end
 for _, k in ipairs(sorted) do
 if not written[k] then
 document(k)
 end
 end
 show('Undocumented functions', undoc(module, osbf[module]))
 else -- document just the member
 if doc[member] then
 document(member)
 elseif osbf[module][member] then
 out:write(s, " seems to exist, but it's not documented")
 else
 out:write('There is no such thing as ', s, '\n')
 end
 end
 end
end
return internals

AltStyle によって変換されたページ (->オリジナル) /