1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use terminal_size::{Width, Height, terminal_size};
fn wordify(s: &str) -> Vec<String> {
let mut words = Vec::new();
let splt = s.split_whitespace();
for w in splt {
words.push(w.to_string());
}
words
}
pub struct PPrint {
indent: u16,
hang: i16,
maxwidth: u16
}
impl PPrint {
pub fn new() -> Self {
let size = terminal_size();
let mut maxwidth: u16 = 80;
if let Some((Width(w), Height(_h))) = size {
maxwidth = w;
}
PPrint { indent: 0, hang: 0, maxwidth }
}
pub fn set_indent(&mut self, indent: u16) -> &mut Self {
self.indent = indent;
self
}
pub fn set_hang(&mut self, hang: i16) -> &mut Self {
self.hang = hang;
self
}
pub fn print_words<I, S>(&self, out: &mut dyn std::io::Write,
words: I)
where I: IntoIterator<Item=S>, S: AsRef<str> {
let mut firstline = true;
let mut newline = true;
let mut space: u16 = 0;
let mut col: u16 = 0;
for w in words.into_iter() {
let w = w.as_ref();
if col + space + w.len() as u16 > self.maxwidth {
out.write(b"\n").unwrap();
newline = true;
}
if newline {
let mut indent: i16 = 0;
indent += self.indent as i16;
if firstline {
indent += self.hang;
}
out.write(" ".repeat(indent as usize).as_bytes()).unwrap();
col = indent as u16;
newline = false;
space = 0;
firstline = false;
}
out.write(" ".repeat(space as usize).as_bytes()).unwrap();
col += space;
out.write(w.as_bytes()).unwrap();
col += w.len() as u16;
let ch = w.chars().last().unwrap();
match ch {
'.' | '?' | '!' => {
space = 2;
}
_ => {
space = 1;
}
}
}
out.write(b"\n").unwrap();
}
pub fn print_p(&self, out: &mut dyn std::io::Write, para: &str) {
let words = wordify(para);
self.print_words(out, &words);
}
pub fn print_plist<I, S>(&self, out: &mut dyn std::io::Write, parit: I)
where I: IntoIterator<Item=S>, S: AsRef<str> {
for p in parit {
self.print_p(out, p.as_ref());
}
}
}