Skip to content

Instantly share code, notes, and snippets.

@ryanong
Last active August 29, 2015 14:18
Show Gist options
  • Save ryanong/543f3551f1aab922adff to your computer and use it in GitHub Desktop.
Save ryanong/543f3551f1aab922adff to your computer and use it in GitHub Desktop.
Show source of a block from a rails ERB file
class ERBSource
ERB = ::ActionView::Template::Handlers::ERB
def self.for(block)
new(block).source
end
attr_reader :block, :file, :line_number
def initialize(block)
@block = block
@file, @line_number = *block.source_location
@line_number += 1
end
def source
lines = File.readlines(file)
relevant_lines = lines[(line_number - 1)..-1] || []
extract_first_expression(relevant_lines)
end
private
def extract_first_expression(lines)
code = ""
lines.each do |v|
code << v
return code if correct_syntax?(compile_erb(code))
end
raise SyntaxError, "unexpected $end"
end
def correct_syntax?(code)
stderr = $stderr
$stderr.reopen(IO::NULL)
RubyVM::InstructionSequence.compile(code)
$stderr.reopen(stderr)
true
rescue Exception
$stderr.reopen(stderr)
false
end
def compile_erb(code)
ERB.erb_implementation.new(
code,
:escape => false,
:trim => (ERB.erb_trim_mode == "-")
).src
end
end
<%= render_example "article" do %>
<% article title: "Settings", text: "description of settings" do %>
<%= text_field_tag :name %>
<%= text_field_tag :description %>
<%- end %>
<% end %>
module StyleGuideHelper
def render_example(name, &block)
code = ERBSource.for(block)
content_tag(:h2, name) +
content_tag(:div, &block) +
content_tag(:pre, content_tag(:code, code))
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment