1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
|
local gio = require("lgi").Gio
local gobject = require("lgi").GObject
local glib = require("lgi").GLib
local name_attr = gio.FILE_ATTRIBUTE_STANDARD_NAME
local type_attr = gio.FILE_ATTRIBUTE_STANDARD_TYPE
local module = {}
-- Like pairs(), but iterate over keys in a sorted manner. Does not support
-- modifying the table while iterating.
local function sorted_pairs(t)
-- Collect all keys
local keys = {}
for k in pairs(t) do
table.insert(keys, k)
end
table.sort(keys)
-- return iterator function
local i = 0
return function()
i = i + 1
if keys[i] then
return keys[i], t[keys[i]]
end
end
end
-- Recursive file scanner
local function get_all_files(path, ext, ret)
ret = ret or {}
local enumerator = gio.File.new_for_path(path):enumerate_children(
table.concat({name_attr, type_attr}, ",") , 0, nil, nil
)
for file in function() return enumerator:next_file() end do
local file_name = file:get_attribute_as_string(name_attr)
local file_type = file:get_file_type()
local match_ext = file_name:match("[.]"..ext.."$" or "")
local fpath = enumerator:get_child(file):get_path()
local is_test = fpath:match("/tests/")
if file_type == "REGULAR" and match_ext and not is_test then
table.insert(ret, fpath)
elseif file_type == "DIRECTORY" then
get_all_files(enumerator:get_child(file):get_path(), ext, ret)
end
end
return ret
end
local function path_to_module(path)
if path:match("[.]c$") then
return path:gmatch("/([^./]+)[.]c$")()
end
for _, module in ipairs {
"awful", "wibox", "gears", "naughty", "menubar", "beautiful"
} do
local match = path:match("/"..module.."/([^.]+).lua")
if match then
return module.."."..match:gsub("/",".")
end
end
error("Cannot figure out module for " .. tostring(path))
end
function module.path_to_html(path)
local mod = path_to_module(path):gsub(".init", "")
local f = assert(io.open(path))
while true do
local line = f:read()
if not line then break end
if line:match("@classmod") then
f:close()
return "../classes/".. mod ..".html#"
end
if line:match("@module") or line:match("@submodule") then
f:close()
return "../libraries/".. mod ..".html#"
end
end
f:close()
error("Cannot figure out if module or class: " .. tostring(path))
end
local function get_link(file, element, element_name)
return table.concat {
"<a href='",
module.path_to_html(file),
element,
"'>",
element_name,
"</a>"
}
end
local function parse_files(paths, property_name, matcher, name_matcher)
local exp1 = "[-*]*[ ]*@".. property_name .." ([^ \n]*)"
local exp2 = matcher or "[-*]*[ ]*".. property_name ..".(.+)"
local exp3 = name_matcher or "[. ](.+)"
local ret = {}
table.sort(paths)
-- Find all @beautiful doc entries
for _,file in ipairs(paths) do
local f = io.open(file)
local buffer = ""
for line in f:lines() do
local var = line:gmatch(exp1)()
-- There is no backward/forward pattern in lua
if #line <= 1 then
buffer = ""
elseif #buffer and not var then
buffer = buffer.."\n"..line
elseif line:sub(1,3) == "---" or line:sub(1,3) == "/**" then
buffer = line
end
if var then
-- Get the @param, @see and @usage
local params = ""
for line in f:lines() do
if line:sub(1,2) ~= "--" and line:sub(1,2) ~= " *" then
break
else
params = params.."\n"..line
end
end
local name = var:gmatch(exp2)()
if not name then
print("WARNING:", var,
"seems to be misformatted. Use `beautiful.namespace_name`"
)
else
table.insert(ret, {
file = file,
name = name:gsub("_", "\\_"),
link = get_link(file, var, var:match(exp3):gsub("_", "\\_")),
desc = buffer:gmatch("[-*/ \n]+([^\n.]*)")() or "",
mod = path_to_module(file),
})
end
buffer = ""
end
end
end
return ret
end
local function create_table(entries, columns, prefix)
prefix = prefix or ""
local lines = {}
for _, entry in ipairs(entries) do
local line = " <tr>"
for _, column in ipairs(columns) do
line = line.."<td>"..entry[column].."</td>"
end
table.insert(lines, prefix..line.."</tr>\n")
end
return [[--<table class='widget_list' border=1>
]]..prefix..[[<tr>
]]..prefix..[[ <th align='center'>Name</th>
]]..prefix..[[ <th align='center'>Description</th>
]]..prefix..[[</tr>
]] .. table.concat(lines) .. prefix .."</table>\n"
end
module.create_table = create_table
module.parse_files = parse_files
module.sorted_pairs = sorted_pairs
module.get_all_files = get_all_files
return module
|