Skip to content

Instantly share code, notes, and snippets.

@garybernhardt
Created June 26, 2012 03:06
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save garybernhardt/2993008 to your computer and use it in GitHub Desktop.
Save garybernhardt/2993008 to your computer and use it in GitHub Desktop.
Probably a really bad implementation of word wrapping
class Wrap
def self.wrap(s, max_length)
raise ArgumentError.new("Maximum wrap length can't be 0") if max_length == 0
return [""] if s.rstrip.empty?
# Split into words and whitespace blocks
blocks = s.split /(\s+|\S+)\b/
lines = []
line = ""
until blocks.empty?
# If we theoretically joined to the current line, would it still fit?
fits = line.length + blocks.first.rstrip.length <= max_length
# The block fits; add it and continue.
if fits
line += blocks.shift
end
if !fits && line.empty?
# The block doesn't fit and the line is empty. We'll have to split the
# current block to fit it.
block = blocks.shift
lines << block[0, max_length]
blocks.unshift block[max_length..-1]
elsif !fits
# The block doesn't fit, but we have stuff in the line. This line is done.
lines << line.rstrip
line = ""
end
end
# Consume any left-over line
lines << line.rstrip
lines.reject(&:empty?)
end
end
require_relative "../wrap"
describe Wrap do
it "wraps at word boundaries" do
Wrap.wrap("foo bar", 3).should == ["foo", "bar"]
Wrap.wrap("foo bar", 4).should == ["foo", "bar"]
Wrap.wrap("foo bar baz", 9).should == ["foo bar", "baz"]
end
it "errors when the wrap width is 0" do
expect { Wrap.wrap("foo", 0) }.to raise_error(ArgumentError)
end
it "doesn't wrap when it's not needed" do
Wrap.wrap("foo", 3).should == ["foo"]
Wrap.wrap("foo", 4).should == ["foo"]
Wrap.wrap("", 1).should == [""]
Wrap.wrap("", 2).should == [""]
Wrap.wrap(" ", 1).should == [""]
Wrap.wrap(" ", 2).should == [""]
Wrap.wrap("foo bar", 7).should == ["foo bar"]
end
it "doesn't left-strip lines" do
Wrap.wrap(" foo", 4).should == [" foo"]
Wrap.wrap(" foo bar", 4).should == [" foo", "bar"]
end
it "breaks words if necessary" do
Wrap.wrap("foobar", 3).should == ["foo", "bar"]
Wrap.wrap("foobar", 2).should == ["fo", "ob", "ar"]
Wrap.wrap("foobar ", 3).should == ["foo", "bar"]
Wrap.wrap(" foo", 3).should == ["foo"]
end
end
@jwreagor
Copy link

Wrap dem words yo. Wrap'n hard an wrapp'in'um good.

@chastell
Copy link

Ah, wrapping! Wrote a library to get it right(-ish), so far ending up with this to do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment