require 'rack' module Goliath module Rack module Formatters # A simple HTML formatter. This doesn't try to be fancy and just turns # Hashes into tables, Arrays into ordered lists and strings are output # as HTML escaped strings. # # @example # use Goliath::Rack::Formatters::HTML class HTML # Called by the framework to create the formatter. # # @param app The application # @return [Goliath::Rack::Formatters::HTML] The HTML formatter def initialize(app) @app = app end def call(env) async_cb = env['async.callback'] env['async.callback'] = Proc.new do |status, headers, body| async_cb.call(post_process(status, headers, body)) end status, headers, body = @app.call(env) post_process(status, headers, body) end def post_process(status, headers, body) body = [to_html(body, false)] if html_response?(headers) [status, headers, body] end def html_response?(headers) headers['Content-Type'] =~ %r{^text/html} end def to_html(content, fragment=true) html_string = '' html_string += html_header unless fragment html_string += case(content.class.to_s) when "Hash" then hash_to_html(content) when "Array" then array_to_html(content) when "String" then string_to_html(content) else string_to_html(content) end html_string += html_footer unless fragment html_string end def string_to_html(content) ::Rack::Utils.escape_html(content.to_s) end def hash_to_html(content) html_string = "\n" if content.key?('meta') html_string += "\n" content.delete('meta') end content.each_pair { |key, value| html_string += "\n" } html_string += "
meta\n" html_string += to_html(content['meta']) html_string += "
#{to_html(key)}#{to_html(value)}
\n" html_string end def array_to_html(content) html_string = '
    \n' content.each { |value| html_string += "
  1. #{to_html(value)}
  2. \n" } html_string +="
\n" html_string end def html_header "" end def html_footer "" end end end end end