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
use core::fmt;
use askama_escape::{escape, Html as AskamaHtml};
use stylish_core::{Style, Write};
use crate::util;
#[derive(Clone, Debug, Default)]
pub struct Html<T: core::fmt::Write> {
inner: T,
current: Style,
}
impl<T: core::fmt::Write> Html<T> {
pub fn new(inner: T) -> Self {
Self {
inner,
current: Style::default(),
}
}
pub fn write_fmt(&mut self, args: stylish_core::Arguments<'_>) -> fmt::Result {
stylish_core::Write::write_fmt(self, args)
}
pub fn finish(mut self) -> Result<T, fmt::Error> {
if self.current != Style::default() {
self.inner.write_str("</span>")?;
}
Ok(self.inner)
}
}
impl<T: fmt::Write> Write for Html<T> {
fn write_str(&mut self, s: &str, style: Style) -> fmt::Result {
if style == Style::default() {
if self.current != Style::default() {
self.inner.write_str("</span>")?;
}
} else if style != self.current {
let diff = style.diff_from(Style::default());
let segments = [
diff.foreground.map(util::foreground),
diff.background.map(util::background),
diff.intensity.map(util::intensity),
];
let mut segments = segments.iter().filter_map(|&s| s);
if let Some(segment) = segments.next() {
if self.current != Style::default() {
self.inner.write_str("</span>")?;
}
self.inner.write_str("<span style=")?;
self.inner.write_str(segment)?;
for segment in segments {
self.inner.write_str(";")?;
self.inner.write_str(segment)?;
}
self.inner.write_str(">")?;
}
}
self.current = style;
write!(self.inner, "{}", escape(s, AskamaHtml))?;
Ok(())
}
}