1extern crate fixed;
2extern crate text_layout;
3
4use fixed::types::I16F16;
5use std::fmt::{self, Write};
6use text_layout::{Fixed, Item, KnuthPlass, ParagraphLayout};
7
8type F = Fixed<I16F16>;
9
10fn layout_paragraph<'a, P: ParagraphLayout<(), (), (), F>>(
11 paragraph: &'a str,
12 layout: &P,
13 max_width: F,
14) -> Vec<&'a str> {
15 let mut items = Vec::new();
17 for c in paragraph.chars() {
18 items.push(if c.is_whitespace() && items.len() != 0 {
19 Item::Glue {
20 width: F::from_num(1),
21 stretch: F::from_num(1),
22 shrink: F::from_num(0),
23 data: (),
24 }
25 } else {
26 Item::Box {
27 width: F::from_num(1),
28 data: (),
29 }
30 });
31 }
32 items.push(Item::Glue {
33 width: F::from_num(0),
34 stretch: F::MAX,
35 shrink: F::from_num(0),
36 data: (),
37 });
38 items.push(Item::Penalty {
39 width: F::from_num(0),
40 cost: F::MIN,
41 flagged: true,
42 data: (),
43 });
44
45 let breaks = layout.layout_paragraph(&items, max_width);
47
48 let mut cursor = 0;
50 let mut lines = Vec::new();
51 let mut start = 0;
52 for (i, _) in paragraph.chars().enumerate() {
53 if i == breaks[cursor].break_at {
54 lines.push(¶graph[start..i]);
55 start = i + 1;
56 cursor += 1;
57 }
58 }
59 lines.push(¶graph[start..]);
60 lines
61}
62
63fn layout_text() -> Result<String, fmt::Error> {
64 let text = " Far out in the uncharted backwaters of the unfashionable end of the western spiral arm of the Galaxy lies a small unregarded yellow sun. Orbiting this at a distance of roughly ninety-two million miles is an utterly insignificant little blue-green planet whose ape-descended life forms are so amazingly primitive that they still think digital watches are a pretty neat idea.";
65 let knuth_plass = KnuthPlass::new().with_threshold(F::MAX);
66 let lines = layout_paragraph(&text, &knuth_plass, F::from_num(80));
67 let mut result = String::new();
68 writeln!(&mut result, "┏{}┓", "━".repeat(80))?;
69 for l in lines {
70 let pad = 80 - l.chars().count();
71 writeln!(&mut result, "┃{}{}┃", l, " ".repeat(pad))?;
72 }
73 writeln!(&mut result, "┗{}┛", "━".repeat(80))?;
74 Ok(result)
75}
76
77fn main() -> Result<(), fmt::Error> {
78 print!("{}", layout_text()?);
79 Ok(())
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 #[test]
87 fn fixed() {
88 let expected = r#"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
89┃ Far out in the uncharted backwaters of the unfashionable end of the western ┃
90┃spiral arm of the Galaxy lies a small unregarded yellow sun. Orbiting this at a ┃
91┃distance of roughly ninety-two million miles is an utterly insignificant little ┃
92┃blue-green planet whose ape-descended life forms are so amazingly primitive that┃
93┃they still think digital watches are a pretty neat idea. ┃
94┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
95"#;
96 let actual = layout_text().unwrap();
97 assert!(actual == expected);
98 }
99}