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