Skip to content

Commit

Permalink
Merge pull request #234 from mgeisler/optimal-fit-algorithm
Browse files Browse the repository at this point in the history
Introduce wrapping using an optimal-fit algorithm
  • Loading branch information
mgeisler authored Dec 3, 2020
2 parents 674d540 + bde9dee commit 695a560
Show file tree
Hide file tree
Showing 5 changed files with 484 additions and 20 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ name = "linear"
harness = false

[dependencies]
smawk = "0.3"
unicode-width = "0.1"
terminal_size = { version = "0.1", optional = true }
hyphenation = { version = "0.8", optional = true, features = ["embed_en-us"] }
Expand Down
26 changes: 21 additions & 5 deletions benches/linear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,28 @@ pub fn benchmark(c: &mut Criterion) {
let mut group = c.benchmark_group("String lengths");
for length in [100, 200, 400, 800, 1600, 3200, 6400].iter() {
let text = lorem_ipsum(*length);
let options = textwrap::Options::new(LINE_LENGTH);
group.bench_with_input(BenchmarkId::new("fill", length), &text, |b, text| {
b.iter(|| textwrap::fill(text, &options));
});
let options = textwrap::Options::new(LINE_LENGTH)
.wrap_algorithm(textwrap::core::WrapAlgorithm::OptimalFit);
group.bench_with_input(
BenchmarkId::new("fill_optimal_fit", length),
&text,
|b, text| {
b.iter(|| textwrap::fill(text, &options));
},
);

let options = textwrap::Options::new(LINE_LENGTH)
.wrap_algorithm(textwrap::core::WrapAlgorithm::FirstFit);
group.bench_with_input(
BenchmarkId::new("fill_first_fit", length),
&text,
|b, text| {
b.iter(|| textwrap::fill(text, &options));
},
);

let options: textwrap::Options = options.splitter(Box::new(textwrap::HyphenSplitter));
let options: textwrap::Options =
textwrap::Options::new(LINE_LENGTH).splitter(Box::new(textwrap::HyphenSplitter));
group.bench_with_input(BenchmarkId::new("fill_boxed", length), &text, |b, text| {
b.iter(|| textwrap::fill(text, &options));
});
Expand Down
17 changes: 17 additions & 0 deletions examples/interactive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ mod unix_only {
use termion::raw::{IntoRawMode, RawTerminal};
use termion::screen::AlternateScreen;
use termion::{color, cursor, style};
use textwrap::core::WrapAlgorithm::{FirstFit, OptimalFit};
use textwrap::{wrap, HyphenSplitter, NoHyphenation, Options, WordSplitter};

#[cfg(feature = "hyphenation")]
Expand Down Expand Up @@ -101,6 +102,16 @@ mod unix_only {
)?;
left_row += 1;

write!(
stdout,
"{}- algorithm: {}{:?}{} (toggle with Ctrl-o)",
cursor::Goto(left_col, left_row),
style::Bold,
options.wrap_algorithm,
style::Reset,
)?;
left_row += 1;

let now = std::time::Instant::now();
let mut lines = wrap(text, options);
let elapsed = now.elapsed();
Expand Down Expand Up @@ -232,6 +243,12 @@ mod unix_only {
Key::Left => options.width = options.width.saturating_sub(1),
Key::Right => options.width = options.width.saturating_add(1),
Key::Ctrl('b') => options.break_words = !options.break_words,
Key::Ctrl('o') => {
options.wrap_algorithm = match options.wrap_algorithm {
OptimalFit => FirstFit,
FirstFit => OptimalFit,
}
}
Key::Ctrl('s') => {
let idx = idx_iter.next().unwrap();
std::mem::swap(&mut options.splitter, &mut splitters[idx]);
Expand Down
Loading

0 comments on commit 695a560

Please sign in to comment.