Skip to content

Commit

Permalink
modified Emmanuel code after merging to follow old coding style
Browse files Browse the repository at this point in the history
  • Loading branch information
antirez committed Apr 4, 2011
1 parent 537fc9b commit 0165f7d
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 205 deletions.
28 changes: 8 additions & 20 deletions bench.rb
@@ -1,3 +1,5 @@
load "nolate.rb"

def bench(descr, times)
start = Time.now.to_f
times.times { yield }
Expand Down Expand Up @@ -29,23 +31,9 @@ def bench(descr, times)

TIMES = 30_000

if ARGV[0] == "n"
load 'nolate.rb'
puts("nolate")
bench("empty template" , TIMES) { nolate("") }
bench("small constant template" , TIMES) { nolate("nosub") }
bench("simple substitution" , TIMES) { nolate("simple <%= 'sub' %>") }
bench("hash substitution" , TIMES) { nolate("hash sub <%#x%>") }
bench("testview2 file template" , TIMES) { nlt(:testview2) }
bench("big template (#{TEMPLATE.length} bytes)", TIMES) { @x = 1; nolate(TEMPLATE, :x => 1) }
else
load 'nolatep.rb'
include Nolatep
puts("\nnolate with 'parser'")
t = nlt_parse("") ; bench("empty template" , TIMES) { nlt_eval(t) }
t = nlt_parse("nosub") ; bench("small constant template" , TIMES) { nlt_eval(t) }
t = nlt_parse("simple <%= 'sub' %>") ; bench("simple substitution" , TIMES) { nlt_eval(t) }
t = nlt_parse("hash sub <%#x%>") ; bench("hash substitution" , TIMES) { nlt_eval(t) }
bench("testview2 file template" , TIMES) { Nolatep.nlt(:testview2) }
t = nlt_parse(TEMPLATE) ; bench("big template (#{TEMPLATE.length} bytes)", TIMES) { @x = 1; nlt_eval(t, :x => 1) }
end
bench("empty template" , TIMES) { nolate("") }
bench("small constant template" , TIMES) { nolate("nosub") }
bench("simple substitution" , TIMES) { nolate("simple <%= 'sub' %>") }
bench("hash substitution" , TIMES) { nolate("hash sub <%#x%>") }
bench("testview2 file template" , TIMES) { nlt(:testview2) }
bench("big template (#{TEMPLATE.length} bytes)", TIMES) { @x = 1; nolate(TEMPLATE, :x => 1) }
93 changes: 39 additions & 54 deletions nolate.rb
Expand Up @@ -28,71 +28,56 @@
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#

$nlt_templates = {}

def nolate_empty_binding
def nlt_empty_binding
return binding()
end

def nolate_compile(__template,__sub={})
__i = 0
__l = __template.length
__result = '__nolate_html=""'+"\n"
while __i < __l
# Find start: <%
__start = __template.index("<%",__i)
# Emit everything from the last index to the start as a plain string.
if __start != 0 or !__start
__s = __start ? __start-1 : -1
__content = __template[(__i..__s)]
__content.chop! if __content[-1..-1] == "\n"
__content.chop! if __content[-1..-1] == "\r"
__result << "__nolate_html += "+__content.inspect+"\n"
break if !__start
end
# Find stop: %>
__i = __start+2
__stop = __template.index("%>",__i)
__stop = __l+1 if !__stop # Implicit %> at end of string...
__i = __stop+2 # In the next iteration we start immediately after %>
# Now we have the string to interpolate, <% ... %>
# What we need to do is to check the first character to understand
# The kind of interpolation to perform:
# <%= ... %> means to eval the expression and substitute the result
# <%#foo%> means to substitute with sub[:foo]
if __template[__start+2] == 61 or __template[__start+2] == '='
__inter = __template[(__start+3)..(__stop-1)]
__result << "__nolate_html += (\n"+__inter+"\n).to_s\n"
elsif __template[__start+2] == 35 or __template[__start+2] == '#'
__inter = __template[(__start+3)..(__stop-1)]
__result << "__nolate_html += __sub["+(__inter.to_sym.inspect)+"].to_s\n"
else
__inter = __template[(__start+2)..(__stop-1)]
__result << __inter+"\n"
def nlt_templates
@templates ||= {}
end

def nlt_flush_templates
@templates = {}
end

def nlt_parse(str)
i = -1 # I wish I had map.with_index in 1.8 :(
str.split(/<%(.*?)%>/m).map do |s|
i, first_char = i + 1, s[0..0]
if i % 2 == 0 then [s.inspect]
elsif first_char == "=" then [:evalo, s[1..-1]]
elsif first_char == "#" then [:sub, s[1..-1].to_sym]
else [:eval, s]
end
end
__result << '__nolate_html'+"\n"
return __result
end

def nolate(__template,__sub={})
compiled = nolate_compile(__template,__sub)
return eval(compiled)
def nlt_eval(template, sub = {}, b = nlt_empty_binding)
s = "__=[]\n"
template.each do |action, param|
case action
when :evalo then s << "__<<(#{param}).to_s\n"
when :eval then s << "#{param}\n"
when :sub then s << "__<<#{sub[param].to_s.inspect}\n"
else s << "__<<#{action}\n"
end
end
eval(s << "__.join", b, __FILE__, __LINE__)
end

def nlt(viewname,sub={})
viewname = viewname.to_s+".nlt" if viewname.is_a?(Symbol)
if !$nlt_templates[viewname]
filename = "views/"+viewname
if !File.exists?(filename)
raise "NOLATE error: no template at #{filename}"
end
$nlt_templates[viewname] = File.read(filename)
def nlt(viewname, sub={}, b = nlt_empty_binding)
viewname = "#{viewname}.nlt" if viewname.is_a?(Symbol)
unless nlt_templates[viewname]
filename = "views/#{viewname}"
raise "NOLATE error: no template at #{filename}" \
unless File.exists?(filename)
nlt_templates[viewname] = nlt_parse(File.read(filename).chomp)
end
nolate($nlt_templates[viewname],sub)
nlt_eval(nlt_templates[viewname], sub, b)
end

def nlt_flush_templates
$nlt_templates = {}
def nolate(str, sub={})
nlt_eval(nlt_parse(str), sub, binding)
end
85 changes: 0 additions & 85 deletions nolatep.rb

This file was deleted.

16 changes: 14 additions & 2 deletions test.rb
@@ -1,7 +1,6 @@
require 'test/unit'
load 'nolate.rb'


class MyExampleClass
def method_one
@x = "Hello"
Expand All @@ -23,9 +22,22 @@ def test_basic
assert_equal(nolate("just ev<% 'sub' %>al"),"just eval")
assert_equal(nlt(:testview),"test 4 view")
assert_equal(nlt("testview.nlt"),"test 4 view")
assert_equal(nlt(:testview2),"<html>\n<body>4\n</body>\n</html>")
assert_equal(nlt(:testview2),"<html>\n<body>\n4\n</body>\n</html>")
assert_equal(nolate("<%x=2%><%=x+1%>"),"3")
assert_equal(MyExampleClass.new.method_one,"Hello")
assert_equal(MyExampleClass.new.method_two,"World")
end

def test_iter
assert_equal(<<-OUTPUT, nlt(:testview4))
Number 1
Number 2
Number 3
Number 4
OUTPUT
end
end
44 changes: 0 additions & 44 deletions testp.rb

This file was deleted.

0 comments on commit 0165f7d

Please sign in to comment.