lib/gara/html5_emitter.rb in gara-0.1.5 vs lib/gara/html5_emitter.rb in gara-0.1.6
- old
+ new
@@ -22,35 +22,82 @@
:span, :strong, :style, :sub, :sup, :summary, :svg,
:table, :tbody, :td, :textarea, :tfoot, :th, :thead, :time, :title,
:tr, :track,
:u, :ul,
:var, :video,
- :wbr, :<<]
+ :wbr]
class Html5Emitter
- module TagMethods
- Gara::HTML5_TAGS.each do |tag|
- Gara::Delegator.define_delegate tag, on: self
- end
+ def self.debug(msg)
+ puts msg if ENV['DEBUG']
end
- attr_accessor :target
def initialize
@doc = Nokogiri::HTML::DocumentFragment.parse("")
@gara_delegate = Nokogiri::HTML::Builder.with(@doc)
- extend TagMethods
end
- def registered_methods
- return TagMethods
+ def add_methods_to(context)
+
+ builder = @gara_delegate # create a local binding so we can access builder in an instance of Context
+ proc_hash = HTML5_TAGS.inject({}) do |hash, tag|
+ hash[tag] = -> (*args, &block) {
+ begin
+ builder.public_send(tag, *args) do # public send is necessary due to send accessing private method Kernel#p
+ unless block.nil?
+ result = block.call # necessary to make sure block executes in Context not Builder
+ if result.kind_of?(String)
+ self << result # add any string returned to the document so that: p { "works" } yields "<p>works</p>"
+ else
+ result
+ end
+ end
+ end
+ rescue Exception => e
+ binding.pry
+ end
+ }
+ hash
+ end
+
+
+ # Open the eigenclass of the passed in context so we can add the procs created above as tag methods
+ eigenclass_of_context =
+ class << context ; self ; end
+ proc_hash.each do |method_name, proc|
+ eigenclass_of_context.send(:define_method, method_name, &proc)
+ end
+ eigenclass_of_context.send(:define_method, :<<) do |string|
+ builder << string if string.kind_of?(String)
+ end
+
+ helper_methods = eigenclass_of_context.instance_methods
+ helper_methods -= HTML5_TAGS
+ helper_methods -= Object.instance_methods
+ helper_methods.reject! {|method| method.to_s.match(/(_\d+_\d+$)|(lookup_context)|(<<)/) }
+
+ helper_methods.each do |method|
+
+ eigenclass_of_context.class_eval do
+ define_method method do |*args, &block_for_helper|
+ result = super(*args, &block_for_helper)
+ if result.kind_of? String
+ self << result
+ else
+ result
+ end
+ end
+ end
+ end
+
end
def emit
nodes = @doc.children
if nodes.length.eql?(1) && nodes.first.name.eql?("html")
# necessary to include doctype - TODO: avoid calling to_html twice
- Nokogiri::HTML::Document.parse( @doc.to_html ).to_xhtml(indent: 2)
+ Nokogiri::HTML::Document.parse( @doc.to_html ).to_html
else
@doc.to_html
end
end
\ No newline at end of file