Write a function that format a long text breaking it up with newlines for a given width.
For example,
"Roses are red violets are blue".justify(20) should return
"Roses are red
violets are blue"
It should keep existing paragraphs (two and more newlines in a row), if there are.
"Poem 1
Roses are red
My name is Dave".justify(20) should return the same:
"Poem 1
Roses are red
violets are blue"
class String
def justify(len)
unless self.length < len
words = self.scan(/[\w,.-]+(?:\n{2,})?/)
actual_len = 0
output = ""
words.each do |w|
if actual_len >= len
output += "\n"
else
output += " " if output > "" and !output[-1].eql?"\n" and actual_len + w.length<=len
end
actual_len = 0 if output[-1].eql?"\n"
if (actual_len == 0) or actual_len + w.length<=len
output += w
actual_len += w.length + 1
else
output += "\n" + w
actual_len = w.length + 1
end
end
return output.rstrip
else
self
end
end
end
describe "Justify" do
it "Should format a long line of text breaking it up for a given width" do
Test.assert_equals( "Roses are red, violets are blue".justify(20), "Roses are red,\nviolets are blue")
Test.assert_equals( "Chapter 1\n\nRoses\nare red,\nviolets\nare blue".justify(20),
"Chapter 1\n\nRoses are red,\nviolets are blue", "should keep paragraphs")
Test.assert_equals( "a b c d e".justify(3), "a b\nc d\ne")
Test.assert_equals( "aa bb cc dd".justify(3), "aa\nbb\ncc\ndd")
Test.assert_equals( "a b c d e f".justify(5), "a b c\nd e f")
Test.assert_equals( "a b c d e".justify(9), "a b c d e", 'no extra spaces added')
Test.assert_equals( "a b c d e".justify(3), "a b\nc d\ne",
'no extra spaces added in multiline case')
Test.assert_equals( "a b c d e".justify(3).split("\n").map{|a| a.length }.max, 3,
'keeps line length less or equal to defined')
Test.assert_equals( "a basd c d e".justify(3), "a\nbasd\nc d\ne",
'extralong word goes to next line')
end
end