Project

General

Profile

Bug #5892 ยป XML_text_wrapping.rb

Code with defect and possible bug fix - dimitri-lo2u (Dimitri Geshef), 01/13/2012 10:42 PM

 
# encoding: utf-8
# Purpose: Show issue with unwanted line wrapping of tag text.
# REXML doesn't take the value of the width attribute of the formatter into account.
# This is best understood by redictering the output to a text file.


require "rexml/document"
=begin
Issue detected with REXML version
REXML VERSION = "3.1.7.3"
REXML REVISION = 26193
=end


# Build root XML element
root = REXML::Element.new('msg')
root.add_namespace("http://www.example.com/xml/foo")

# Build a child tag having a lengthyyyyyyyyyyyyyyyyyyyyyy text
repeated_digits = '123456789 ' * 20 # Build a 200 characters long text containing spaces
son = REXML::Element.new('foo:bar')
son.add_text(repeated_digits)
root.add_element(son)

# Build XML document
xml_doc = REXML::Document.new
xml_doc << REXML::XMLDecl.new("1.0", "UTF-8")
xml_doc.add_element(root)

# Build a pretty formatter
formatter = REXML::Formatters::Pretty.new(2) # Select indentation of 2 positions
formatter.compact = false

# Generate default text representation of XML document.
# REXML does a line wrapping when the 80 characters limit is reached.
formatter.write(xml_doc, $stdout) # Text in foo:bar tag is wrapped at column 80


# Re-generate text representation, now with a very large 'page width'
# The idea is to prevent line wrapping in the tag text.
formatter.width = 1000 # Change the width of a page. According to the documentation this is used for formatting text
formatter.write(xml_doc, $stdout) # Oddly enough... text in foo:bar tag is still wrapped at column 80

=begin
The bug is located in the REXML::Formatters::Pretty::write_text method.
Re-open REXML::Formatters::Pretty class for method maonkey patching
=end
module REXML
module Formatters
class Pretty
# Bug fix. Override existing implementation.
def write_text( node, output )
# The code is based on original one
s = node.to_s()
s.gsub!(/\s/,' ')
s.squeeze!(" ")
# Our fix: next line is replaced.
#s = wrap(s, 80-@level) # Original line: hardcoded line wrapping at 80 characters limit
s = wrap(s, self.width-@level) # Changed line: line wrapping occurs once width limit has been reached.
s = indent_text(s, @level, " ", true)
output << (' '*@level + s)
end
end # class
end # module
end # module

formatter.write(xml_doc, $stdout) # Now the long text is not wrapped (as expected)
# End of file

    (1-1/1)