Pretty-prints an XML document. This destroys whitespace in text nodes and will insert carriage returns and indentations.
TODO: Add an option to print attributes on new lines
Create a new pretty printer.
An object implementing '<<(String)', to which the output will be written.
An integer greater than 0. The indentation of each level will be this number of spaces. If this is < 1, the behavior of this object is undefined. Defaults to 2.
If true, the printer will insert whitespace before closing empty tags, thereby allowing Internet Explorer's XML parser to function. Defaults to false.
# File rexml/formatters/pretty.rb, line 30
def initialize( indentation=2, ie_hack=false )
@indentation = indentation
@level = 0
@ie_hack = ie_hack
@width = 80
@compact = false
end
# File rexml/formatters/pretty.rb, line 102
def write_cdata( node, output)
output << ' ' * @level
super
end
# File rexml/formatters/pretty.rb, line 97
def write_comment( node, output)
output << ' ' * @level
super
end
# File rexml/formatters/pretty.rb, line 107
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 == node.children[-1] and 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
# File rexml/formatters/pretty.rb, line 39
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