templates.lua

Sat, 10 Nov 2012 04:02:30 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Sat, 10 Nov 2012 04:02:30 +0000
changeset 18
a96836139ff9
parent 0
b40ca010c49c
permissions
-rwxr-xr-x

parsers.markdown: Make module callable, to allow parsing text as a module


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

mercurial