This is an interesting technique to use Iguana itself to serve the documentation of it’s own API (see comments in the code). If you are interested in this you may also want to checkout using _G to discover the entire API of the Translator. Also see the Iguana Translator modules reference.
If you are curious about some ideas to document your own interfaces you might want to check out documenting an HL7 interface.
First make a channel with a Translator component (a To Translator is easiest).
Paste in the following code:
-- fetch help info from all functions -- by calling them with no params and reaping the error message -- PROBLEM some functions are missed because they have no params -- eg iguana.isTest() and json.createObject() -- HACK call that tries to guarantee invalid params -- 2ND HACK in response to error introduced by first caused by -- logic added to identify error and give improved feedback... local G=util.guid(128) local function createHelp(Input) print(G) local out = {} for i,v in pairs(Input) do if (type(v) == 'function') then -- some functions are missed = have no params --local test,err = pcall(v) -- HACK try to guarantee invalid call local test,err = pcall(v,{G=1},G,{G=G},asdf,'ÄdÉfÍ',[[n#@]]) --HACK print(err) if err:find("@@Unknown parameter: 'G'") then -- 2ND HACK test,err = pcall(v) end if not test then local sentinel = '%@%@%<%>%<%>ifware%-error%<%>%<%>%@%@' print(sentinel) local err_fixed = err:gsub(sentinel,'') out[i] = tostring(err_fixed) end elseif (type(v) == 'table') then print(v) local NextSet = createHelp(v) if (#NextSet) then out[i] = NextSet end end end return out end -- similar to pairs(), but gives a sorted set local function pairsByKeys (t, f) local a = {} for n in pairs(t) do table.insert(a, n) end table.sort(a, f) local i = 0 -- iterator variable local iter = function () -- iterator function i = i + 1 if a[i] == nil then return nil else return a[i], t[a[i]] end end return iter end -- writes out several files, in a hierachical fashion local function writeHelpFiles(Doc,Key,BaseDir) -- write this, and links local out = '<HTML><TITLE>'..Key..'</TITLE><BODY>' out = out..'<H3>'..Key..'</H3><UL>' for i,v in pairsByKeys(Doc) do out = out..'<li>' if type(v) == 'table' then out = out..'<a href="'..Key..'.'..i..'.html">'..i..'</a>' --do one level down out = out..'<table>' for j,k in pairsByKeys(v) do local summary = '' if type(k) == 'string' then local pattern = '([^n]*)(.*)' _,_,summary = k:find(pattern) end out = out..'<tr><td width="20"></td><td width="80"><a href="' ..Key..'.'..i..'.html#'..j..'">'..j..'</a></td><td>'..summary..'</td></tr>' end out = out..'</table>' writeHelpFiles(v,Key..'.'..i,BaseDir) else out = out..'<a name="'..i..'"><b>'..i..'</b></a><br><pre>'..v..'</pre>' end out = out..'</li>' end out = out..'</UL></BODY></HTML>' local fd = io.open(BaseDir..''..Key..'.html','wb') fd:write(out) fd:close() end -- writes everything to a single html string local function writeAll(Doc,Key,Parent) Parent = Parent or 'base' local out = '' out = out..'<a name="'..Parent..'.'..Key..'"><H2>'..Key..'</H2></a><UL>' for i,v in pairsByKeys(Doc) do out = out..'<li>' if type(v) == 'table' then --do sub levels out = out..writeAll(v,i,Key) else out = out..'<a name="'..Parent..'.'..Key..'.'..i..'"><b>'..i..'</b></a><br><pre>'..v..'</pre>' end out = out..'</li>' end out = out..'</UL>' return out end -- writes a table of contents for the top of the OneHelpFile local function writeToc(Doc,Key,Parent) Parent = Parent or 'base' local out = '' out = out..'<a href="#'..Parent..'.'..Key..'">'..Key..'</a><UL>' for i,v in pairsByKeys(Doc) do out = out..'<li>' if type(v) == 'table' then --do sub levels out = out..writeToc(v,i,Key) else local summary = '' local pattern = '([^n]*)(.*)' _,_,summary = v:find(pattern) out = out..'<a href="#'..Parent..'.'..Key..'.'..i..'">'..i..'</a> : '..summary end out = out..'</li>' end out = out..'</UL>' return out end -- write a single file local function writeOneHelpFile(Doc,Key,BaseDir) local out = '<HTML><TITLE>'..Key..'</TITLE><BODY>' out = out..writeToc(Doc,Key) out = out..writeAll(Doc,Key) out = out..'</UL></BODY></HTML>' local fd = io.open(BaseDir..''..Key..'_all.html','wb') fd:write(out) fd:close() end local function deepcopy(object) local lookup_table = {} local function _copy(object) if type(object) ~= "table" then return object elseif lookup_table[object] then return lookup_table[object] end local new_table = {} lookup_table[object] = new_table for index, value in pairs(object) do new_table[_copy(index)] = _copy(value) end return setmetatable(new_table, getmetatable(object)) end return _copy(object) end -- copy _G and remove Lua stuff so only Iguan modules remain local function getIguanaModules() local my_G=deepcopy(_G) -- remove Lua stuff my_G.xpcall=nil my_G.string=nil my_G.tostring=nil my_G.package=nil my_G.os=nil my_G.unpack=nil my_G.require=nil my_G.print=nil my_G.getfenv=nil my_G.next=nil my_G.assert=nil my_G.setmetatable=nil my_G.setfenv=nil my_G.tonumber=nil my_G.gcinfo=nil my_G.io=nil my_G.rawequal=nil my_G._VERSION=nil my_G.collectgarbage=nil my_G.debug=nil my_G.getmetatable=nil my_G.collectgarbage=nil my_G.module=nil my_G.collectgarbage=nil my_G.cache=nil my_G.rawset=nil my_G.math=nil my_G.load=nil my_G.pcall=nil my_G.table=nil my_G.newproxy=nil my_G.type=nil my_G.coroutine=nil my_G._G=nil my_G.select=nil my_G.pairs=nil my_G.rawget=nil my_G.loadstring=nil my_G.ipairs=nil my_G.main=nil my_G.dofile=nil my_G.IntellisenseObject=nil my_G.error=nil my_G.loadfile=nil my_G._=nil return my_G end -- remove known Iguana modules so new ones can be identified -- and then can be documented local function getNewIguanaModules() local my_G=getIguanaModules() --remove known Iguana modules my_G.ack=nil my_G.queue=nil my_G.net=nil my_G.iguana=nil my_G.util=nil my_G.xml=nil my_G.db=nil my_G.node=nil my_G.hl7=nil my_G.x12=nil my_G.json=nil my_G.chm=nil my_G.filter=nil return my_G end function main(Data) -- list out all namespaces in our code that we want to print -- note that this won't work with the _G table, because some -- functions will work with no parameters, and proceed to block indefinitely -- so we narrow down what we want to print -- HACK: see createHelp() - now uses weird params to catch *no-param* fn()s -- does not work with _G as it overflows the stack -- NOTE: use table annotation with print(_G) to inspect global environment -- use it to check for new modules and -- check you have printed out all functions in a module -- get all Iguana Modules getIguanaModules() -- get all NEW Iguana Modules -- add to list below getNewIguanaModules() local ifware = { -- remember to add new Iguana modules to list (see above) --['ack']=ack, --['xml']=xml, --['util'] = util, --['queue'] = queue, --['iguana'] = iguana, -- iguana.isTest() has no params ['node']=node, --['x12']=x12, --['chm']=chm --['hl7'] = hl7, --['db'] = db, --['net'] = net, --['json'] = json, -- json.createObject() has no params --['filter'] = filter, --['NEW modules'] = getNewIguanaModules(), --['ALL modules'] = getIguanaModules(), --['_G']=[_G] -- overflows the the stack - try it } print(_G) -- inspect global environment table local output_dir = [[c:program filesiNTERFACEWAREiguanaweb_docsdocs]] local base_name = 'iguana' -- collect up all the help info local out = createHelp(ifware,base_name) --write out a hierachical set of html files writeHelpFiles(out,base_name,output_dir) --write a single html file called <base_name>_all.html writeOneHelpFile(out,base_name,output_dir) end
You may have some errors initially, just turn off annotations for now.
Then in the main function:
- Modify the base directory so that it points to the iguana installation location. E.g., if you have installed Iguana in c:iguana, change the base directory to ‘c:iguanaweb_docsdocs’
- Go to the install directory, and there will be a web_docs subdirectory. In web_docs, make a docs folder.
Now turn on annotations, and make sure that it runs with no errors.
Now go back to the dashboard, and go to
http://<my ip>:<my iguana port>/docs/iguana_all.html
or
http://<my ip>:<my iguana port>/docs/iguana.html
or you can just open the files from the doc directory…
And you should see the API’s documented!