class REXML::Formatters::Pretty

TODO: Add an option to print attributes on new lines
and will insert carriage returns and indentations.
Pretty-prints an XML document. This destroys whitespace in text nodes

def indent_text(string, level=1, style="\t", indentfirstline=true)

def indent_text(string, level=1, style="\t", indentfirstline=true)
  return string if level < 0
  string.gsub(/\n/, "\n#{style*level}")
end

def initialize( indentation=2, ie_hack=false )

function. Defaults to false.
tags, thereby allowing Internet Explorer's XML parser to
If true, the printer will insert whitespace before closing empty
ie_hack::
is undefined. Defaults to 2.
this number of spaces. If this is < 1, the behavior of this object
An integer greater than 0. The indentation of each level will be
indentation::
An object implementing '<<(String)', to which the output will be written.
output::

Create a new pretty printer.
def initialize( indentation=2, ie_hack=false )
  @indentation = indentation
  @level = 0
  @ie_hack = ie_hack
  @width = 80
  @compact = false
end

def wrap(string, width)

def wrap(string, width)
  parts = []
  while string.length > width and place = string.rindex(' ', width)
    parts << string[0...place]
    string = string[place+1..-1]
  end
  parts << string
  parts.join("\n")
end

def write_cdata( node, output)

def write_cdata( node, output)
  output << ' ' * @level
  super
end

def write_comment( node, output)

def write_comment( node, output)
  output << ' ' * @level
  super
end

def write_document( node, output )

def write_document( node, output )
  # Ok, this is a bit odd.  All XML documents have an XML declaration,
  # but it may not write itself if the user didn't specifically add it,
  # either through the API or in the input document.  If it doesn't write
  # itself, then we don't need a carriage return... which makes this
  # logic more complex.
  node.children.each { |child|
    next if child.instance_of?(Text)
    unless child == node.children[0] or child.instance_of?(Text) or
      (child == node.children[1] and !node.children[0].writethis)
      output << "\n"
    end
    write( child, output )
  }
end

def write_element(node, output)

def write_element(node, output)
  output << ' '*@level
  output << "<#{node.expanded_name}"
  node.attributes.each_attribute do |attr|
    output << " "
    attr.write( output )
  end unless node.attributes.empty?
  if node.children.empty?
    if @ie_hack
      output << " "
    end
    output << "/"
  else
    output << ">"
    # If compact and all children are text, and if the formatted output
    # is less than the specified width, then try to print everything on
    # one line
    skip = false
    if compact
      if node.children.inject(true) {|s,c| s & c.kind_of?(Text)}
        string = +""
        old_level = @level
        @level = 0
        node.children.each { |child| write( child, string ) }
        @level = old_level
        if string.length < @width
          output << string
          skip = true
        end
      end
    end
    unless skip
      output << "\n"
      @level += @indentation
      node.children.each { |child|
        next if child.kind_of?(Text) and child.to_s.strip.length == 0
        write( child, output )
        output << "\n"
      }
      @level -= @indentation
      output << ' '*@level
    end
    output << "</#{node.expanded_name}"
  end
  output << ">"
end

def write_text( node, output )

def write_text( node, output )
  s = node.to_s()
  s.gsub!(/\s/,' ')
  s.squeeze!(" ")
  s = wrap(s, @width - @level)
  s = indent_text(s, @level, " ", true)
  output << (' '*@level + s)
end