How to break long text to smaller lines by words? Ideally, I need method like
def text_splitter(text, line_size = 5)
# ...
end
text_splitter("a b c d e text longword") # => ["a b c", "d e ", "text ", "longword"]
Rails comes with the word_wrap helper which can split long lines based on a given line width. It always splits at whitespace so long words won't get split / cut.
In rails/console:
lines = helper.word_wrap("a b c d e text longword", line_width: 5)
#=> "a b c\nd e\ntext\nlongword"
puts lines
Output:
a b c
d e
text
longword
Note that it returns a string, not an array.
That can be done in pure-Ruby as follows1.
def text_splitter(text, line_size)
text.gsub(/(?:.{1,#{line_size}}|\S+)\K(?:$|\s)/, "\n")
end
text = "Beware the Jabberwock, my son! The jaws that bite, the claws that catch!"
puts text_splitter(text, 30)
0 1 2 3
123456789012345678901234567890
Beware the Jabberwock, my son!
The jaws that bite, the claws
that catch!
puts text_splitter(text, 20)
0 1 2
12345678901234567890
Beware the
Jabberwock, my son!
The jaws that bite,
the claws that
catch!
puts text_splitter(text, 10)
0 1
1234567890
Beware the
Jabberwock,
my son!
The jaws
that bite,
the claws
that
catch!
puts text_splitter(text, 8)
0
12345678
Beware
the
Jabberwock,
my son!
The jaws
that
bite,
the
claws
that
catch!
The regular expression can be broken down as follows (for line_size = 10):
(?: # begin non-capture group
.{1,10} # match 1-10 chars
| # or
\S+ # match >= 1 non-whitespace chars
) # end non-capture group
\K # reset start of match and discard all chars previously matched
(?:$|\s) # match the end of the string or a whitespace chars
1. Sample text is from Lewis Carrol's peom, "Jabberwocky".