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

Default penalties for monospace text.

The penalties here work well for monospace text. This is because they expect the gaps at the end of lines to be roughly in the range 0..100. If the gaps are larger, the overflow_penalty and hyphen_penalty become insignificant.

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Returns the “default value” for a type. Read more

Wrap words according to line widths. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

recently added

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.