aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock8
-rw-r--r--src/main.rs63
2 files changed, 36 insertions, 35 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 6a286af..ea6bd9e 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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;
}
}