erebus/render/
break_line.rs

1use crate::Style;
2
3use super::print_gap;
4
5#[must_use]
6/// Breaks text into a series of lines, each of which is no longer than `width` characters.  
7/// Breaks text in-between words, if possible.
8pub fn break_line(text: &str, indent: usize, ln_width: Option<usize>, style: &Style) -> String {
9    let mut result = String::new();
10    let mut line = String::new();
11    let indent_str = ln_width.map_or_else(
12        || " ".repeat(indent),
13        |ln_width| {
14            let mut result = String::new();
15            print_gap(&mut result, ln_width, style);
16            result
17        },
18    );
19    for c in text.chars() {
20        if c == '\n' {
21            result.push_str(&line);
22            result.push('\n');
23            line.clear();
24        } else {
25            line.push(c);
26            if c == ' ' && line.len() + indent > style.max_width {
27                let mut last_space = 0;
28                for (i, c) in line.chars().enumerate() {
29                    if c == ' ' {
30                        last_space = i;
31                    }
32                    if i == style.max_width - indent {
33                        result.push_str(&indent_str);
34                        result.push_str(&line[..last_space]);
35                        result.push('\n');
36                        line = line[last_space + 1..].to_string();
37                        break;
38                    }
39                }
40            }
41        }
42    }
43    if !line.trim().is_empty() {
44        if line.len() > style.max_width + indent {
45            let mut last_space = 0;
46            for (i, c) in line.chars().enumerate() {
47                if c == ' ' {
48                    last_space = i;
49                }
50                if i == style.max_width - indent {
51                    result.push_str(&indent_str);
52                    result.push_str(&line[..last_space]);
53                    result.push('\n');
54                    line = line[last_space + 1..].to_string();
55                    break;
56                }
57            }
58        }
59        result.push_str(&indent_str);
60        result.push_str(&line);
61    }
62    result.trim_start_matches(&indent_str).to_string()
63}