diff options
-rw-r--r-- | Cargo.lock | 8 | ||||
-rw-r--r-- | src/main.rs | 63 |
2 files changed, 36 insertions, 35 deletions
@@ -2,9 +2,9 @@ # It is not intended for manual editing. [[package]] name = "adler32" -version = "1.0.4" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" +checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d" [[package]] name = "arc-swap" @@ -414,9 +414,9 @@ dependencies = [ [[package]] name = "xmlparser" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccb4240203dadf40be2de9369e5c6dec1bf427528115b030baca3334c18362d7" +checksum = "52613e655f6f11f63c0fe7d1c3b5ef69e44d96df9b65dab296b441ed0e1125f5" [[package]] name = "zip" diff --git a/src/main.rs b/src/main.rs index 1d16440..69d6b04 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,51 +13,52 @@ use crossterm::{ mod epub; +// XXX assumes a char is i unit wide fn wrap(text: &str, width: usize) -> Vec<(usize, String)> { - // XXX assumes a char is 1 unit wide let mut lines = Vec::new(); - + // bytes let mut start = 0; let mut end = 0; + // chars after the break + let mut after = 0; + // chars in unbroken line let mut len = 0; - let mut word = 0; - let mut skip = 0; + // are we breaking on whitespace? + let mut skip = false; for (i, c) in text.char_indices() { len += 1; match c { - ' ' => { + '\n' => { + after = 0; end = i; - skip = 1; - word = 0; + skip = true; + len = width + 1; } - '-' | '—' => { - if len > width { - // `end = i + len` is a hack that breaks here - word += 1; - } else { - end = i + c.len_utf8(); - skip = 0; - word = 0; - } + ' ' => { + after = 0; + end = i; + skip = true; } - _ => { - word += 1; + '-' | '—' if len <= width => { + after = 0; + end = i + c.len_utf8(); + skip = false; } + _ => after += 1, } - if c == '\n' { - lines.push((start, String::from(&text[start..i]))); - start = i + 1; - len = 0; - } else if len > width { - let line = if word == len { - &text[start..i] - } else { - &text[start..end] - }; - lines.push((start, String::from(line))); - start = end + skip; - len = word; + if len > width { + if len == after { + after = 1; + end = i; + skip = false; + } + lines.push((start, String::from(&text[start..end]))); + start = end; + if skip { + start += 1; + } + len = after; } } |