Refills a paragraph to fit within a maximum width, returning the formatted lines. This does not cut words half-way, which means that it may be impossible to fit certain words in the specified width. If that happens, lines will overflow.
(paragraph: &str, width: usize)
| 24 | /// This does not cut words half-way, which means that it may be impossible to fit certain words in |
| 25 | /// the specified width. If that happens, lines will overflow. |
| 26 | fn refill(paragraph: &str, width: usize) -> Vec<String> { |
| 27 | if paragraph.is_empty() { |
| 28 | return vec!["".to_owned()]; |
| 29 | } |
| 30 | |
| 31 | let mut lines = vec![]; |
| 32 | |
| 33 | let mut line = String::new(); |
| 34 | for word in paragraph.split_whitespace() { |
| 35 | if !line.is_empty() { |
| 36 | // Determine how many spaces to inject after a period. We want 2 spaces to separate |
| 37 | // different sentences and 1 otherwise. The heuristic here isn't great and it'd be |
| 38 | // better to respect the original spacing of the paragraph. |
| 39 | let spaces = if line.ends_with('.') { |
| 40 | let first = word.chars().next().expect("Words cannot be empty"); |
| 41 | if first == first.to_ascii_uppercase() { 2 } else { 1 } |
| 42 | } else { |
| 43 | 1 |
| 44 | }; |
| 45 | |
| 46 | if (line.len() + word.len() + spaces) >= width { |
| 47 | lines.push(line); |
| 48 | line = String::new(); |
| 49 | } else { |
| 50 | for _ in 0..spaces { |
| 51 | line.push(' '); |
| 52 | } |
| 53 | } |
| 54 | } |
| 55 | line.push_str(word); |
| 56 | } |
| 57 | if !line.is_empty() { |
| 58 | lines.push(line); |
| 59 | } |
| 60 | |
| 61 | lines |
| 62 | } |
| 63 | |
| 64 | /// Refills a collection of paragraphs, prefixing them with an optional `indent`. |
| 65 | fn refill_many<S: AsRef<str>, P: IntoIterator<Item = S>>( |