This topic contains 1 reply, has 2 voices, and was last updated by  Eliot Muir 4 years, 7 months ago.

A helper for the new help functions

  • I’m trying out the new help functions that are new in Iguana 5.5. I’ve found filling in the help_data manually to be cumbersome, so I created a function to help. I’d appreciate any improvements.

    This will only generate help info once the function is executed, so that’s a significant limitation. There’s probably a better way using metatables.

    --[[A function to help fill in Iguana help for functions.
    Written by Mark Brighton (mark@brightsoftwaredesign.com)
    --]]
    
    -- Import Section:
    -- declare everything that this module needs from the outside
    local error = error
    local debug = debug
    local help = help
    local ipairs = ipairs
    local pairs = pairs
    local string = string
    local table = table
    local tostring = tostring
    local type = type
    module(...)
    
    function create(text, hd, func, name)
       if type(debug) ~= 'table' then
          error("The debug table seems to have been overwritten.  "..
          "Has a debug() function been defined? ")
          return
       end
    
       local self = debug.getinfo(2)
       local info = debug.getinfo(func or 3)
       info.name = info.name or name
       info.func = info.func or func
       -- Create the help for this function.  
       -- Just don't recurse endlessly!
       if false or info.name ~= self.name then
          create([[A helper function for filling in Iguana's
             help table.  It's similar to the JavaDoc format.
             Params:
              - text: a string containing three sections:
                  * The desciption of the function.
                  * A listing of parameters.  This must begin with
                   "Params:" on a line by itself. Each parameter should
                   start on a new line.  The parameter name should be
                   prefixed by '-' and followed by ":".  The text
                   following will be used as its description.  If the
                   "Default:" is found inside of parenthesis, the "Opt" flag
                   will be set for this function.  Variable parameters
                   can be indicated using a parameter name of "***".
                  * A listing of return values.  This must begin with
                   "Returns:" on a line by itself. Each return value
                   should start on a new line.  It should be
                   prefixed by '-'.  The text following will be
                   used as its description.
              - hd: a help_data table.  Any keys that have values in this
                table will be used instead of the text generated by this
                function.  (Default: {})
              - func: if you're not calling this from the function you
                want the help string for, you have to supply the function
                object here.  (Default: nil)
              - name: if you're not calling this from the function you
                want the help string for, you have to supply the function's
                name here.  (Default: nil)
             Returns:
             ]])
       end
       if help.get(info.func) ~= nil then
          -- Don't bother creating the help if it already exists.
          return
       end
       local hd = hd or {}
       hd.Title = hd.Title or ((info.source or '')..'.'..
          (info.name or ''))
       local s, e, returns = text:find("\n%s+Returns:%s+(.-)%s*$")
       returns = returns or ''
       local s, e, params = text:sub(1,s):find("\n%s+Params:%s+(.-)%s*$")
       params = params or ''
       local desc = text:sub(1,s)
       desc = desc or ''
       hd.Desc = hd.Desc or desc:match("^%s*(.-)%s*$"):gsub('%s+', ' ')
       
       if hd.Parameters == nil then
          hd.Parameters = {}
          params = '\n'..params
          for i, ptext in ipairs(params:split('\n%s*-%s*')) do
             _, _, pname, pdesc = ptext:find('(%w+):%s*(.+)%s*')
             if not pname then
                -- Use the three periods Lua symbol to indicate
                -- variable parameters.
                _, _, pname, pdesc = ptext:find('(...):%s*(.+)%s*')
             end
             if pname then
                pd = {}
                pd[pname] = {Desc=pdesc:gsub('%s+', ' ')}
                -- Look for "(Default:" in the text as an indicator that
                -- this parameter is optional.
                _, _, pdefault = ptext:find('%(Default:%s*(.+)%s*%)')
                if pdefault then
                   pd[pname].Opt = pdefault ~= nil
                end
                hd.Parameters[#hd.Parameters+1] = pd
             end
          end
       end
       
       if hd.Returns == nil then
          hd.Returns = {}
          returns = '\n'..returns
          for i, rtext in ipairs(returns:split('\n%s*-%s*')) do
             rtext = rtext:match("^%s*(.-)%s*$")
             if #rtext > 0 then
                hd.Returns[#hd.Returns+1] = {Desc=rtext:gsub('%s+', ' ')}
             end
          end
       end
       
       if true or hd.Usage == nil then
          local parts = {}
          parts = {hd.Title,
             '(',
          }
    
          local pnames = {}
          for i, pinfo in ipairs(hd.Parameters) do
             for pname, pdata in pairs(pinfo) do
                pnames[#pnames+1] = pname
             end
          end
          parts[#parts+1] = table.concat(pnames, ', ')
          
          parts[#parts+1] = ')'
          hd.Usage = table.concat(parts)
       end
       
       help.set{input_function=info.func, help_data=hd}   
    end

    Thanks for sharing this Mark – that really nice of you!

You must be logged in to reply to this topic.