Mon, 20 Jul 2009 11:42:54 +0100
Improve 'create' command - now automatically fills in metadata and opens an editor
module("templates", package.seeall) local tpl = {}; local tpl_mt = { __index = tpl }; local tplutil = {}; local tplutil_mt = { __index = tplutil }; function tpl:saverender(fn, vars) local f, err = io.open(fn, "w+"); if not f then return f,err; end f:write(self:render(vars)); f:close(); return true end function tpl:render(vars) local tpl = self.tpl or self.file:read("*a"); self.tpl = tpl; if not vars then return tpl; end return (tpl:gsub("%b{}", function (cap) local v = cap:match("^%{%{%s*(.-)%s*%}%}*$") if not v then return cap; end local chunk, err = loadstring("return "..v); if not chunk then chunk, err = loadstring(v); if not chunk then error(err); end end setfenv(chunk, vars); local ok, ret = pcall(chunk); if not ok then error(ret); end do return ret or ""; end local v = cap:match("^%{%{%s*([%w_%.]+)%s*%}%}*$") if v then local _vars = vars; local ret, subs = v:gsub("(%w+)%.", function (var) if _vars then _vars = _vars[var]; end end); if _vars and _vars ~= vars then return _vars[v:match("%w+$")] or cap; end return vars[v] or cap; end local v = cap:match("^%{*[%w_]+%(.*%}*$"); if v then local chunk, err = loadstring("return "..v:sub(2,-2)); if not chunk then error("error in template: "..tostring(err)); end setfenv(chunk, setmetatable(vars, tplutil_mt)); local success, ret = pcall(chunk); if success then return ret; else error("error in template: "..ret); end end end)); end -- -- -- -- local function escape(s) return s; end function tplutil.kvlist(t) if #t > 0 then -- Assume an array if type(t[1]) == "table" then -- Assume a table of tables else -- Assume a straight list end else -- assume a k->v list local b = { "<table>" }; end end function tplutil.ulist(t) -- assume a list/array local b = { "<ul>\n" }; for _, v in ipairs(t) do table.insert(b, " <li>"..escape(v).."</li>\n"); end table.insert(b, "</ul>\n"); return table.concat(b); end function init(file) local f, err = io.open(file); if not f then return nil, "Couldn't open template file: "..err; end return setmetatable({ file = f }, tpl_mt); end function load(template) return setmetatable({ tpl = template }, tpl_mt); end