# PrettyXML # Thomas Sawyer (transami) # May 2002 require 'rexml/document' module PrettyXML # Returns the pretty result formatted into html def PrettyXML.pretty_in_html(source) out = PrettyXML.pretty(source) out.gsub!(/&/n, '&') out.gsub!(/>/n, '>') out.gsub!(/') out.gsub!(/\t/,'  ') out.gsub!(/\"/n, '"') return out end # Return source all pretty'd up. # tab specifies indention # tab = 0 for "\t" or a positive integer for ' ' * tab spaces def PrettyXML.pretty(source, tab=0) @pretty_listener = PrettyListener.new(tab) REXML::Document.parse_stream(source, @pretty_listener) return @pretty_listener.prettyxml end # private ----------------------------------------------- class PrettyListener def initialize(tab=0) @buildxml = "" @depth = 0 if tab == 0 then @tb = "\t" else @tb = ' ' * tab end end def xmldecl(ver, enc, stand) @buildxml = "#{@buildxml}" end def doctype(name, *contents) @buildxml = "#{@buildxml}\n" end def instruction(name, instruction) @buildxml = "#{@buildxml}\n" end def comment(comment) @buildxml = "#{@buildxml}\n" end def tag_start(name, attributes) @buildxml = "#{@buildxml}\n" + @tb * @depth + "<#{name}" attributes.each do |a| @buildxml = "#{@buildxml} #{attr_to_s(a)}" end @buildxml = "#{@buildxml}>" @depth += 1 @closed_element = false end def tag_end(name) @depth -= 1 if @closed_element then @buildxml = "#{@buildxml}\n" + @tb * @depth + "" else @buildxml = "#{@buildxml}" end @closed_element = true end def text(text) if text =~ /\n/ text = "\n" + text text = text.gsub(/(\n)/, "\n" + @tb * @depth) text.strip! #text = text + "\n" + @tb * (@depth - 1) end @buildxml = "#{@buildxml}#{text}" #@closed_element = false end def method_missing(a, *b) raise "Method Missing: #{a}, #{b}" end # def attr_to_s attr return(attr[0] + "=" + attr[1]) end # def prettyxml return @buildxml end end end