require 'enumerator'
module HTML
class Generator
attr_accessor :indentation, :stack, :buffer
def initialize(indentation=" ")
self.indentation=indentation
self.stack=[]
self.buffer=""
end
def write(text)
whitespace=(1..self.stack.size).collect{self.indentation}.join
self.buffer << whitespace+text.gsub("\n", "\n#{whitespace}")+"\n"
end
def start_tag(tag)
text="<#{tag}>"
self.write(text)
self.stack << tag
end
def text(text); self.write("#{text}"); end
def end_tag
tag=self.stack.pop()
text="#{tag}>"
self.write(text)
end
def process(obj)
proc=Proc.new do |head, tail|
if tail.class==Array
text=(0!=tail.size%2) ? tail.pop() : nil
if tail.empty?
self.start_tag(head)
self.text(text) unless text==nil
self.end_tag
else
self.start_tag(head)
tail.each_slice(2){|h, t|proc.call(h, t)}
self.text(text) unless text==nil
self.end_tag
end
else
self.start_tag(head)
self.text(tail)
self.end_tag
end
end
proc.call(obj[0], obj[1])
end
end
def HTML.generate(obj)
generator=HTML::Generator.new
generator.process(obj)
generator.buffer
end
end
puts HTML.generate(['html', ['head', ['title', "Here's the title"], 'body', ['h1', "Here's the body"]]])