webmcp

diff framework/bin/autodoc.lua @ 0:9fdfb27f8e67

Version 1.0.0
author jbe/bsw
date Sun Oct 25 12:00:00 2009 +0100 (2009-10-25)
parents
children 3d43a5cf17c1
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/framework/bin/autodoc.lua	Sun Oct 25 12:00:00 2009 +0100
     1.3 @@ -0,0 +1,216 @@
     1.4 +#!/usr/bin/env lua
     1.5 +
     1.6 +local args = {...}
     1.7 +
     1.8 +if not args[1] or string.match(args[1], "^%-") then
     1.9 +  print("Usage: autodoc.lua srcdir/ > documentation.html")
    1.10 +  os.exit(1)
    1.11 +end
    1.12 +
    1.13 +local entries = {}
    1.14 +
    1.15 +for idx, srcdir in ipairs(args) do
    1.16 +  local find_proc = io.popen('find "' .. srcdir .. '" -name \\*.lua', "r")
    1.17 +  for filename in find_proc:lines() do
    1.18 +    local synopsis, comment, source
    1.19 +    local mode
    1.20 +    local function reset()
    1.21 +      synopsis, comment, source = {}, {}, {}
    1.22 +      mode = "idle"
    1.23 +    end
    1.24 +    reset()
    1.25 +    local function strip(tbl)
    1.26 +      while true do
    1.27 +        local line = tbl[#tbl]
    1.28 +        if line and string.find(line, "^%s*$") then
    1.29 +          tbl[#tbl] = nil
    1.30 +        else
    1.31 +          break
    1.32 +        end
    1.33 +      end
    1.34 +      if #tbl > 0 then
    1.35 +        local min_indent = math.huge
    1.36 +        for idx, line in ipairs(tbl) do
    1.37 +          local spaces = string.match(line, "^(%s*)")
    1.38 +          if min_indent > #spaces then
    1.39 +            min_indent = #spaces
    1.40 +          end
    1.41 +        end
    1.42 +        local pattern_parts = { "^" }
    1.43 +        for i = 1, min_indent do
    1.44 +          pattern_parts[#pattern_parts+1] = "%s"
    1.45 +        end
    1.46 +        pattern_parts[#pattern_parts+1] = "(.-)%s*$"
    1.47 +        local pattern = table.concat(pattern_parts)
    1.48 +        for idx, line in ipairs(tbl) do
    1.49 +          tbl[idx] = string.match(line, pattern)
    1.50 +        end
    1.51 +      end
    1.52 +    end
    1.53 +    local function entry_done()
    1.54 +      if #synopsis > 0 then
    1.55 +        strip(synopsis)
    1.56 +        strip(comment)
    1.57 +        strip(source)
    1.58 +        local stripped_synopsis = {}
    1.59 +        for idx, line in ipairs(synopsis) do
    1.60 +          local stripped_line = string.match(line, "^(.-)%-%-") or line
    1.61 +          stripped_line = string.match(stripped_line, "^(.-)%s*$")
    1.62 +          stripped_synopsis[#stripped_synopsis+1] = stripped_line
    1.63 +        end
    1.64 +        local concatted_synopsis = string.gsub(
    1.65 +          table.concat(stripped_synopsis, " "), "[%s]+", " "
    1.66 +        )
    1.67 +        local func_call = string.match(
    1.68 +          concatted_synopsis, "^[A-Za-z0-9_, ]+= ?(.-) ?$"
    1.69 +        )
    1.70 +        if not func_call then
    1.71 +          func_call = string.match(
    1.72 +            concatted_synopsis,
    1.73 +            "^ ?for[A-Za-z0-9_, ]+in (.-) ? do[ %.]+end ?$"
    1.74 +          )
    1.75 +        end
    1.76 +        if not func_call then
    1.77 +          func_call = string.match(concatted_synopsis, "^ ?(.-) ?$")
    1.78 +        end
    1.79 +        func_call = string.gsub(
    1.80 +          func_call,
    1.81 +          "^([^({]*)[({].*[,;].*[,;].*[,;].*[)}]$",
    1.82 +          function(base)
    1.83 +            return base .. "{ ... }"
    1.84 +          end
    1.85 +        )
    1.86 +        if entries[func_call] then
    1.87 +          error("Multiple occurrences of: " .. func_call)
    1.88 +        end
    1.89 +        entries[func_call] = {
    1.90 +          func_call   = func_call,
    1.91 +          synopsis    = synopsis,
    1.92 +          comment     = comment,
    1.93 +          source      = source
    1.94 +        }
    1.95 +      end
    1.96 +      reset()
    1.97 +    end
    1.98 +    for line in io.lines(filename, "r") do
    1.99 +      local function add_to(tbl)
   1.100 +        if #tbl > 0 or not string.match(line, "^%s*$") then
   1.101 +          tbl[#tbl+1] = line
   1.102 +        end
   1.103 +      end
   1.104 +      if mode == "idle" then
   1.105 +        if string.find(line, "^%s*%-%-%[%[%-%-%s*$") then
   1.106 +          mode = "synopsis"
   1.107 +        end
   1.108 +      elseif mode == "synopsis" then
   1.109 +        if string.find(line, "^%s*$") and #synopsis > 0 then
   1.110 +          mode = "comment"
   1.111 +        elseif string.find(line, "^%s*%-%-]]%-%-%s*$") then
   1.112 +          mode = "source"
   1.113 +        else
   1.114 +          add_to(synopsis)
   1.115 +        end
   1.116 +      elseif mode == "comment" then
   1.117 +        if string.find(line, "^%s*%-%-]]%-%-%s*$") then
   1.118 +          mode = "source"
   1.119 +        else
   1.120 +          add_to(comment)
   1.121 +        end
   1.122 +      elseif mode == "source" then
   1.123 +        if string.find(line, "^%s*%-%-//%-%-%s*$") then
   1.124 +          entry_done()
   1.125 +        else
   1.126 +          add_to(source)
   1.127 +        end
   1.128 +      end
   1.129 +    end
   1.130 +    entry_done()
   1.131 +  end
   1.132 +  find_proc:close()
   1.133 +end
   1.134 +
   1.135 +
   1.136 +function output(...)
   1.137 +  return io.stdout:write(...)
   1.138 +end
   1.139 +
   1.140 +function encode(text)
   1.141 +  return (
   1.142 +    string.gsub(
   1.143 +      text, '[<>&"]',
   1.144 +      function(char)
   1.145 +        if char == '<' then
   1.146 +          return "&lt;"
   1.147 +        elseif char == '>' then
   1.148 +          return "&gt;"
   1.149 +        elseif char == '&' then
   1.150 +          return "&amp;"
   1.151 +        elseif char == '"' then
   1.152 +          return "&quot;"
   1.153 +        end
   1.154 +      end
   1.155 +    )
   1.156 +  )
   1.157 +end
   1.158 +
   1.159 +function output_lines(tbl)
   1.160 +  for idx, line in ipairs(tbl) do
   1.161 +    if idx == 1 then
   1.162 +      output('<pre>')
   1.163 +    end
   1.164 +    local command, comment = string.match(line, "^(.-)(%-%-.*)$")
   1.165 +    if command then
   1.166 +      output(
   1.167 +        encode(command),
   1.168 +        '<span class="autodoc_comment_tail">', encode(comment), '</span>'
   1.169 +      )
   1.170 +    else
   1.171 +      output(encode(line))
   1.172 +    end
   1.173 +    if idx == #tbl then
   1.174 +      output('</pre>')
   1.175 +    end
   1.176 +    output('\n')
   1.177 +  end
   1.178 +end
   1.179 +
   1.180 +keys = {}
   1.181 +for key in pairs(entries) do
   1.182 +  keys[#keys+1] = key
   1.183 +end
   1.184 +table.sort(keys)
   1.185 +for idx, key in ipairs(keys) do
   1.186 +  local entry = entries[key]
   1.187 +  output('<li class="autodoc_entry">\n')
   1.188 +  output(
   1.189 +    '  <div class="short_synopsis"',
   1.190 +    ' onclick="document.getElementById(\'autodoc_details_',
   1.191 +    idx,
   1.192 +    '\').style.display = document.getElementById(\'autodoc_details_',
   1.193 +    idx,
   1.194 +    '\').style.display ? \'\' : \'none\';">\n'
   1.195 +  )
   1.196 +  output('    ', encode(entry.func_call), '\n')
   1.197 +  output('  </div>\n')
   1.198 +  output(
   1.199 +    '  <div id="autodoc_details_',
   1.200 +    idx,
   1.201 +    '" class="autodoc_details" style="display: none;">\n'
   1.202 +  )
   1.203 +  output('    <div class="autodoc_synopsis">\n')
   1.204 +  output_lines(entry.synopsis)
   1.205 +  output('    </div>\n')
   1.206 +  output('    <div class="autodoc_comment">')
   1.207 +  for idx, line in ipairs(entry.comment) do
   1.208 +    output(encode(line))
   1.209 +    if idx < #entry.comment then
   1.210 +      output('<br/>')
   1.211 +    end
   1.212 +  end
   1.213 +  output('    </div>\n')
   1.214 +  output('    <div class="autodoc_source">\n')
   1.215 +  output_lines(entry.source)
   1.216 +  output('    </div>\n')
   1.217 +  output('  </div>\n')
   1.218 +  output('</li>\n')
   1.219 +end
   1.220 \ No newline at end of file

Impressum / About Us