Skip to content

Instantly share code, notes, and snippets.

@tizoc
Created April 2, 2011 23:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tizoc/900004 to your computer and use it in GitHub Desktop.
Save tizoc/900004 to your computer and use it in GitHub Desktop.
# -*- coding: utf-8 -*-
module Tpl
def self.new_proc(template, variables = [])
render_definition = "Proc.new do |__v, __o|\n __v ||= {}; __o ||= ''\n"
compile(template, variables, render_definition)
render_definition << "__o\nend"
eval(render_definition)
end
def self.new_module(template, variables = [], m = Module.new)
render_definition = "def self.render(__v = {}, __o = '')\n"
compile(template, variables, render_definition)
render_definition << "__o\nend"
m.module_eval(render_definition)
m
end
def self.compile(template, variables, render_definition)
i = 0
len = template.length
render_definition << variables.map{|v| "#{v} = __v[:#{v}]\n"}.join
loop do
start = template.index("<%", i)
unless start
render_definition << "__o << #{template[i..len].inspect}\n"
break
end
render_definition << "__o << #{template[i...start].inspect}\n"
stop = template.index("%>", start)
i = stop + 2
case template[start + 2, 1]
when "=" then
render_definition << "__r = (#{template[start+3..stop-1]}).to_s\n__o << __r\n"
when "#" then
# ignore, # is a comment
else
render_definition << "#{template[start+3..stop-1]}\n"
end
end
end
end
if $0 == __FILE__
tpl = Tpl.new_proc("The sum is <%=2+2%> Also substitute <%=myfield%> ok", %w(myfield))
puts tpl.call({:myfield => 10})
tpl2 = Tpl.new_proc("ñañaña")
puts tpl2.call
tpl3 = Tpl.new_proc("Testing loops: <% 3.times do %> * <% end %>")
puts tpl3.call
class Testing
def initialize(value)
@variable = value
tpl = Tpl.new_proc("@variable = <%= @variable %>")
puts instance_exec(&tpl)
end
end
Testing.new('some value')
module Helper
def the_helper
"helper returned value"
end
end
tpl4 = Tpl.new_module("Testing helper: <%= the_helper %>")
tpl4.extend(Helper)
puts tpl4.render
puts Tpl.new_module('<% var = 10 %>var is <%= var %>').render
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment