lib/trenni/template.rb in trenni-1.4.5 vs lib/trenni/template.rb in trenni-1.5.0
- old
+ new
@@ -46,28 +46,30 @@
@parts = []
end
attr :parts
+ # Output raw text to the template.
def text(text)
- text = text.gsub('\\', '\\\\\\').gsub('@', '\\@')
-
- @parts << "#{OUT} << %q@#{text}@ ; "
+ @parts << "#{OUT}<<#{text.dump};"
end
+ # Output a ruby expression (or part of).
def expression(text)
- @parts << "#{text} ; "
+ @parts << "#{text};"
end
-
- def output(text)
- @parts << "#{OUT} << (#{text}) ; "
+
+ # Output a string interpolation.
+ def interpolation(text)
+ @parts << "#{OUT}<<(#{text});"
end
- def code
- parts = ["#{OUT} = [] ; "] + @parts + ["#{OUT}"]
+ CODE_PREFIX = "#{OUT}=[];".freeze
+ CODE_POSTFIX = "#{OUT}".freeze
- return parts.join
+ def code
+ return [CODE_PREFIX, *@parts, CODE_POSTFIX].join
end
end
class Scanner < StringScanner
TEXT = /([^<#]|<(?!\?r)|#(?!\{)){1,1024}/m
@@ -124,11 +126,11 @@
level -= 1
end
end
if level == 0
- @callback.output(code)
+ @callback.interpolation(code)
else
raise StandardError.new "Could not find end of expression #{self}!"
end
elsif scan(/<\?r/)
if scan_until(/(.*?)\?>/m)
@@ -138,48 +140,53 @@
end
end
end
end
- def self.load(path)
- return self.new(File.read(path), path)
+ def self.load_file(path)
+ self.new(File.read(path), path)
end
- def initialize(template, filename = '<Trenni>')
- @template = template
- @filename = filename
+ def self.load(io, path = io.inspect)
+ self.new(io.read, path)
end
- def to_string(scope = nil)
+ def initialize(text, path = '<Trenni>')
+ @text = text
+ @path = path
+ end
+
+ def to_string(scope = Object.new)
to_array(scope).join
end
# Legacy functions:
alias evaluate to_string
alias result to_string
def to_array(scope)
if Binding === scope
- eval(code, scope, @filename)
+ # Slow code path, evaluate the code string in the given binding (scope).
+ eval(code, scope, @path)
else
- # This can sometimes be a bit faster:
+ # Faster code path, use instance_eval on a compiled Proc.
scope.instance_eval(&to_proc)
end
end
def to_proc
- @compiled_proc ||= eval("proc{\n#{code}\n}", binding, @filename, 0)
+ @compiled_proc ||= eval("proc{\n#{code}\n}", binding, @path, 0)
end
protected
def code
@code ||= compile!
end
def compile!
buffer = Buffer.new
- scanner = Scanner.new(buffer, @template)
+ scanner = Scanner.new(buffer, @text)
scanner.parse
buffer.code
end