module Liars class V attr_reader :stream def tag(*args, &b) @stream ||= "" tag_name = args.shift attrs = args.extract_options! attrs = attrs.collect {|k,v| "#{k}=\"#{v}\""}.join(" ") text = args[0] if block_given? @stream += "<#{tag_name} #{attrs}>#{text}" b.call @stream += "" else @stream += (text ? "<#{tag_name} #{attrs}>#{text}" : "<#{tag_name} #{attrs}/>") end @stream end %w[html body head title h1 h2 h3 form div p input table tr td tbody link a b span label hr br textarea].each do |tag_name| class_eval <<-EOF def #{tag_name}(*args, &b) tag(*(args.unshift('#{tag_name}')), &b) end EOF end end end