Created
August 23, 2010 17:31
-
-
Save matschaffer/545926 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'rubygems' | |
require 'erubis' | |
class TemplateRunner | |
class OutputBuffer < String | |
alias :append= :<< | |
alias :safe_concat :<< | |
end | |
class Eruby < Erubis::Eruby | |
def escape_text(text) | |
text | |
end | |
def escaped_expr(expr) | |
expr | |
end | |
def add_preamble(src) | |
src << "@output_buffer = TemplateRunner::OutputBuffer.new;" | |
end | |
def add_text(src, text) | |
return if text.empty? | |
src << "@output_buffer.safe_concat('" << escape_text(text) << "');" | |
end | |
BLOCK_EXPR = /\s+(do|\{)(\s*\|[^|]*\|)?\s*\Z/ | |
def add_expr_literal(src, code) | |
if code =~ BLOCK_EXPR | |
src << '@output_buffer.append= ' << code | |
else | |
src << '@output_buffer.append= (' << code << ');' | |
end | |
end | |
def add_stmt(src, code) | |
if code =~ BLOCK_EXPR | |
src << code | |
else | |
super | |
end | |
end | |
def add_expr_escaped(src, code) | |
src << '@output_buffer.append= ' << escaped_expr(code) << ';' | |
end | |
def add_postamble(src) | |
src << '@output_buffer.to_s' | |
end | |
end | |
def initialize | |
template = Eruby.new(<<-ERB) | |
Start of template | |
<%= simple_helper %> | |
<%= block_helper do %> | |
inside block | |
<% end %> | |
ERB | |
puts template.result(binding) | |
end | |
def simple_helper | |
"hey I'm a simple helper" | |
end | |
def block_helper(&block) | |
"Here's a block\n#{capture(&block)}\nEndBlock\n" | |
end | |
def capture | |
@output_buffer, original_buffer = TemplateRunner::OutputBuffer.new, @output_buffer | |
yield | |
@output_buffer, buffer = original_buffer, @output_buffer | |
buffer | |
end | |
end | |
TemplateRunner.new |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment