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 "<" 1.147 + elseif char == '>' then 1.148 + return ">" 1.149 + elseif char == '&' then 1.150 + return "&" 1.151 + elseif char == '"' then 1.152 + return """ 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