extract template renderer into own class

This commit is contained in:
leaf corcoran
2014-02-06 19:55:10 -08:00
parent 23f849374d
commit 513f0ef39c
2 changed files with 119 additions and 44 deletions

View File

@@ -54,6 +54,58 @@ pos_to_line = function(str, pos)
end
return line
end
local Renderer
do
local _base_0 = {
render = function(self)
return table.concat(self.buffer)
end,
push = function(self, str, ...)
local i = self.i + 1
self.buffer[i] = str
self.i = i
if ... then
return self:push(...)
end
end,
header = function(self)
return self:push("local _b, _b_i, _tostring, _concat, _escape = ...\n")
end,
footer = function(self)
return self:push("return _b")
end,
increment = function(self)
return self:push("_b_i = _b_i + 1\n")
end,
mark = function(self, pos)
return self:push("--[[", tostring(pos), "]] ")
end,
assign = function(self, ...)
self:push("_b[_b_i] = ", ...)
if ... then
return self:push("\n")
end
end
}
_base_0.__index = _base_0
local _class_0 = setmetatable({
__init = function(self)
self.buffer = { }
self.i = 0
end,
__base = _base_0,
__name = "Renderer"
}, {
__index = _base_0,
__call = function(cls, ...)
local _self_0 = setmetatable({}, _base_0)
cls.__init(_self_0, ...)
return _self_0
end
})
_base_0.__class = _class_0
Renderer = _class_0
end
local Parser
do
local _base_0 = {
@@ -272,15 +324,8 @@ do
return self:chunks_to_lua()
end,
chunks_to_lua = function(self)
local buffer = {
"local _b, _b_i, _tostring, _concat, _escape = ..."
}
local buffer_i = #buffer
local push
push = function(str)
buffer_i = buffer_i + 1
buffer[buffer_i] = str
end
local r = Renderer()
r:header()
local _list_0 = self.chunks
for _index_0 = 1, #_list_0 do
local chunk = _list_0[_index_0]
@@ -290,24 +335,26 @@ do
end
local _exp_0 = t
if "string" == _exp_0 then
push("_b_i = _b_i + 1")
push("_b[_b_i] = " .. tostring(("%q"):format(chunk)))
r:increment()
r:assign(("%q"):format(chunk))
elseif "code" == _exp_0 then
push("--[[" .. tostring(chunk[3]) .. "]] " .. chunk[2])
r:mark(chunk[3])
r:push(chunk[2], "\n")
elseif "=" == _exp_0 or "-" == _exp_0 then
local assign = "_tostring(" .. tostring(chunk[2]) .. ")"
r:increment()
r:mark()
r:assign()
if t == "=" and self.html_escape then
assign = "_escape(" .. assign .. ")"
r:push("_escape(_tostring(", chunk[2], "))\n")
else
r:push("_tostring(", chunk[2], ")\n")
end
assign = "_b[_b_i] = " .. assign
push("_b_i = _b_i + 1")
push("--[[" .. tostring(chunk[3]) .. "]] " .. assign)
else
error("unknown type " .. tostring(t))
end
end
push("return _b")
return concat(buffer, "\n")
r:footer()
return r:render()
end
}
_base_0.__index = _base_0
@@ -326,13 +373,14 @@ do
_base_0.__class = _class_0
Parser = _class_0
end
local compile = (function()
local compile
do
local _base_0 = Parser()
local _fn_0 = _base_0.compile
return function(...)
compile = function(...)
return _fn_0(_base_0, ...)
end
end)()
end
local render
render = function(str, ...)
local fn, err = compile(str)
@@ -346,5 +394,6 @@ return {
compile = compile,
render = render,
Parser = Parser,
Renderer = Renderer,
_version = VERSION
}

View File

@@ -39,6 +39,37 @@ pos_to_line = (str, pos) ->
line += 1
line
class Renderer
new: =>
@buffer = {}
@i = 0
render: =>
table.concat @buffer
push: (str, ...) =>
i = @i + 1
@buffer[i] = str
@i = i
@push ... if ...
header: =>
@push "local _b, _b_i, _tostring, _concat, _escape = ...\n"
footer: =>
@push "return _b"
increment: =>
@push "_b_i = _b_i + 1\n"
mark: (pos) =>
@push "--[[", tostring(pos), "]] "
assign: (...) =>
@push "_b[_b_i] = ", ...
@push "\n" if ...
class Parser
open_tag: "<%"
close_tag: "%>"
@@ -206,40 +237,35 @@ class Parser
-- generates the code of the template
chunks_to_lua: =>
-- todo: find a no-conflict name for locals
buffer = {
"local _b, _b_i, _tostring, _concat, _escape = ..."
}
buffer_i = #buffer
push = (str) ->
buffer_i += 1
buffer[buffer_i] = str
r = Renderer!
r\header!
for chunk in *@chunks
t = type chunk
t = chunk[1] if t == "table"
switch t
when "string"
push "_b_i = _b_i + 1"
push "_b[_b_i] = #{("%q")\format(chunk)}"
r\increment!
r\assign ("%q")\format(chunk)
when "code"
push "--[[#{chunk[3]}]] " .. chunk[2]
r\mark chunk[3]
r\push chunk[2], "\n"
when "=", "-"
assign = "_tostring(#{chunk[2]})"
r\increment!
r\mark!
r\assign!
if t == "=" and @html_escape
assign = "_escape(" .. assign .. ")"
assign = "_b[_b_i] = " .. assign
push "_b_i = _b_i + 1"
push "--[[#{chunk[3]}]] " .. assign
r\push "_escape(_tostring(", chunk[2], "))\n"
else
r\push "_tostring(", chunk[2], ")\n"
else
error "unknown type #{t}"
push "return _b"
concat buffer, "\n"
r\footer!
r\render!
compile = Parser!\compile
@@ -250,5 +276,5 @@ render = (str, ...) ->
else
nil, err
{ :compile, :render, :Parser, _version: VERSION }
{ :compile, :render, :Parser, :Renderer, _version: VERSION }