pub fn wrap<'a, S, Opt>(text: &str, width_or_options: Opt) -> Vec<Cow<'_, str>>where
S: WordSplitter,
Opt: Into<Options<'a, S>>,
Expand description
Wrap a line of text at a given width.
The result is a vector of lines, each line is of type Cow<'_, str>
, which means that the line will borrow from the input
&str
if possible. The lines do not have a trailing '\n'
. Use
the fill
function if you need a String
instead.
The easiest way to use this function is to pass an integer for
width_or_options
:
use textwrap::wrap;
let lines = wrap("Memory safety without garbage collection.", 15);
assert_eq!(lines, &[
"Memory safety",
"without garbage",
"collection.",
]);
If you need to customize the wrapping, you can pass an Options
instead of an usize
:
use textwrap::{wrap, Options};
let options = Options::new(15)
.initial_indent("- ")
.subsequent_indent(" ");
let lines = wrap("Memory safety without garbage collection.", &options);
assert_eq!(lines, &[
"- Memory safety",
" without",
" garbage",
" collection.",
]);
Optimal-Fit Wrapping
By default, wrap
will try to ensure an even right margin by
finding breaks which avoid short lines. We call this an
“optimal-fit algorithm” since the line breaks are computed by
considering all possible line breaks. The alternative is a
“first-fit algorithm” which simply accumulates words until they no
longer fit on the line.
As an example, using the first-fit algorithm to wrap the famous Hamlet quote “To be, or not to be: that is the question” in a narrow column with room for only 10 characters looks like this:
To be, or
not to be:
that is
the
question
Notice how the second to last line is quite narrow because “question” was too large to fit? The greedy first-fit algorithm doesn’t look ahead, so it has no other option than to put “question” onto its own line.
With the optimal-fit wrapping algorithm, the previous lines are shortened slightly in order to make the word “is” go into the second last line:
To be,
or not to
be: that
is the
question
Please see core::WrapAlgorithm
for details.
Examples
The returned iterator yields lines of type Cow<'_, str>
. If
possible, the wrapped lines will borrow from the input string. As
an example, a hanging indentation, the first line can borrow from
the input, but the subsequent lines become owned strings:
use std::borrow::Cow::{Borrowed, Owned};
use textwrap::{wrap, Options};
let options = Options::new(15).subsequent_indent("....");
let lines = wrap("Wrapping text all day long.", &options);
let annotated = lines
.iter()
.map(|line| match line {
Borrowed(text) => format!("[Borrowed] {}", text),
Owned(text) => format!("[Owned] {}", text),
})
.collect::<Vec<_>>();
assert_eq!(
annotated,
&[
"[Borrowed] Wrapping text",
"[Owned] ....all day",
"[Owned] ....long.",
]
);