Struct textwrap::wrap_algorithms::OptimalFit [−][src]
pub struct OptimalFit { pub nline_penalty: i32, pub overflow_penalty: i32, pub short_last_line_fraction: usize, pub short_last_line_penalty: i32, pub hyphen_penalty: i32, }
Expand description
Wrap words using an advanced algorithm with look-ahead.
This wrapping algorithm considers the entire paragraph to find
optimal line breaks. When wrapping text, “penalties” are assigned
to line breaks based on the gaps left at the end of lines. The
penalties are given by this struct, with OptimalFit::default
assigning penalties that work well for monospace text.
If you are wrapping proportional text, you are advised to assign your own penalties according to your font size. See the individual penalties below for details.
The underlying wrapping algorithm is implemented by
wrap_optimal_fit
, please see that function for examples.
Note: Only available when the smawk
Cargo feature is
enabled.
Fields
nline_penalty: i32
Per-line penalty. This is added for every line, which makes it expensive to output more lines than the minimum required.
overflow_penalty: i32
Per-character cost for lines that overflow the target line width.
With a default value of 50², every single character costs as
much as leaving a gap of 50 characters behind. This is because
we assign as cost of gap * gap
to a short line. When
wrapping monospace text, we can overflow the line by 1
character in extreme cases:
use textwrap::wrap_algorithms::{wrap_optimal_fit, OptimalFit}; use textwrap::core::Word; let short = "foo "; let long = "x".repeat(50); let fragments = vec![Word::from(short), Word::from(&long)]; let penalties = OptimalFit::new(); // Perfect fit, both words are on a single line with no overflow. let wrapped = wrap_optimal_fit(&fragments, &[short.len() + long.len()], &penalties); assert_eq!(wrapped, vec![&[Word::from(short), Word::from(&long)]]); // The words no longer fit, yet we get a single line back. While // the cost of overflow (`1 * 2500`) is the same as the cost of the // gap (`50 * 50 = 2500`), the tie is broken by `nline_penalty` // which makes it cheaper to overflow than to use two lines. let wrapped = wrap_optimal_fit(&fragments, &[short.len() + long.len() - 1], &penalties); assert_eq!(wrapped, vec![&[Word::from(short), Word::from(&long)]]); // The cost of overflow would be 2 * 2500, whereas the cost of // the gap is only `49 * 49 + nline_penalty = 2401 + 1000 = // 3401`. We therefore get two lines. let wrapped = wrap_optimal_fit(&fragments, &[short.len() + long.len() - 2], &penalties); assert_eq!(wrapped, vec![&[Word::from(short)], &[Word::from(&long)]]);
This only happens if the overflowing word is 50 characters long and if the word overflows the line by exactly one character. If it overflows by more than one character, the overflow penalty will quickly outgrow the cost of the gap, as seen above.
short_last_line_fraction: usize
When should the last line be considered “short”?
If the last line of the text is shorter than 1 / short_last_line_fraction
of the line width, it will be
considered “short”. Short lines will have
short_last_line_penalty
added as an extra penalty.
The effect of this is to avoid a final line consisting of just
a single word. For example, with a short_last_line_penalty
of 25 (the default), a gap of up to 5 columns will be seen as
more desirable than having a final short line. So you get
This is a demo of the short last
line penalty.
instead of
This is a demo of the short last line
penalty.
short_last_line_penalty: i32
Penalty for a short last line.
Set this to zero if you do not want to penalize short last lines.
hyphen_penalty: i32
Penalty for lines ending with a hyphen.
Implementations
Trait Implementations
Auto Trait Implementations
impl RefUnwindSafe for OptimalFit
impl Send for OptimalFit
impl Sync for OptimalFit
impl Unpin for OptimalFit
impl UnwindSafe for OptimalFit
Blanket Implementations
Mutably borrows from an owned value. Read more