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
use alloc::borrow::Cow;
use alloc::string::String;
use alloc::vec::Vec;
use core::borrow::Borrow;
use crate::table::Table;
use crate::renderer::{pad, wrap, Renderer, NEWLINE, RenderHint};
use crate::style::{HAlign, Style};
#[derive(Default)]
pub struct Markdown();
impl Renderer for Markdown {
type Output = String;
fn render_with_hints(&self, table: &Table, _: &[RenderHint]) -> Self::Output {
assert!(!table.is_empty(), "table cannot be empty");
let col_widths = table.col_widths(self);
let mut buf = String::new();
print_row(self, table, &col_widths, 0, &mut buf);
print_header_format(table, &col_widths, &mut buf);
for row in 1..table.num_rows() {
print_row(self, table, &col_widths, row, &mut buf);
}
buf
}
}
fn print_header_format(table: &Table, col_widths: &[usize], buf: &mut String) {
buf.push('|');
for (col, &width) in col_widths.iter().enumerate() {
let col = table.col(col);
let styles = col.blended_styles();
let alignment = HAlign::resolve_or_default(&styles);
let alignment = alignment.borrow();
match alignment {
HAlign::Left | HAlign::Right => {
let width = usize::max(2, width);
buf.push_str(&pad(":", '-', width, alignment));
}
HAlign::Centred => {
let width = usize::max(3, width);
buf.push(':');
(2..width).for_each(|_| buf.push('-'));
buf.push(':');
}
}
buf.push('|');
}
buf.push_str(NEWLINE);
}
fn print_row(renderer: &Markdown, table: &Table, col_widths: &[usize], row: usize, buf: &mut String) {
let cell_lines = (0..col_widths.len())
.into_iter()
.map(|col| {
let cell = table.cell(col, row);
let data = cell.as_ref().map_or(Cow::Borrowed(""), |cell| cell.data().render(renderer));
wrap(&data, col_widths[col])
})
.collect::<Vec<_>>();
let cell_styles = (0..col_widths.len())
.into_iter()
.map(|col| {
let cell = table.cell(col, row);
cell.blended_styles()
})
.collect::<Vec<_>>();
let max_lines = cell_lines.iter().map(Vec::len).max().unwrap();
for line in 0..max_lines {
buf.push('|');
for col in 0..col_widths.len() {
let line = cell_lines[col].get(line).map_or("", |line| &line[..]);
let styles = &cell_styles[col];
let alignment = HAlign::resolve_or_default(styles);
let line = pad(line, ' ', col_widths[col], &alignment);
buf.push_str(&line);
buf.push('|');
}
buf.push_str(NEWLINE);
}
}