Use text-style crate to format text

This patch replaces the direct text formatting with ansi_term with the
text-style crate.  This also allows us to directly convert the syntect
annotations to styled strings.
This commit is contained in:
Robin Krahl 2020-10-02 13:34:17 +02:00
parent ecb3d40c59
commit 9458b280d4
No known key found for this signature in database
GPG Key ID: 8E9B0870524F69D8
3 changed files with 56 additions and 56 deletions

12
Cargo.lock generated
View File

@ -780,6 +780,7 @@ dependencies = [
"syntect 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"terminal_size 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
"text-style 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -999,6 +1000,7 @@ dependencies = [
"serde_derive 1.0.114 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.56 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"yaml-rust 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1041,6 +1043,15 @@ dependencies = [
"libc 0.2.72 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "text-style"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)",
"syntect 4.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "textwrap"
version = "0.11.0"
@ -1301,6 +1312,7 @@ dependencies = [
"checksum tendril 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "707feda9f2582d5d680d733e38755547a3e8fb471e7ba11452ecfd9ce93a5d3b"
"checksum terminal_size 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9a14cd9f8c72704232f0bfc8455c0e861f0ad4eb60cc9ec8a170e231414c1e13"
"checksum termios 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6f0fcee7b24a25675de40d5bb4de6e41b0df07bc9856295e7e2b3a3600c400c2"
"checksum text-style 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "01ecc55ab699ed1b4d0ebe64d7a8ee2611f55d0de4042e9c1ee5a81dee89e332"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thin-slice 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
"checksum time 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"

View File

@ -48,6 +48,10 @@ version = "4.3.0"
default-features = false
features = ["parsing", "regex-onig", "assets", "dump-load"]
[dependencies.text-style]
version = "0.2.0"
features = ["ansi_term", "syntect"]
[dev-dependencies]
assert_cmd = "1.0.1"
insta = "0.16.1"

View File

@ -35,12 +35,8 @@ impl utils::ManRenderer for RichTextRenderer {
fn print_title(&mut self, left: &str, middle: &str, right: &str) -> io::Result<()> {
let title = super::format_title(self.line_length, left, middle, right);
writeln!(
io::stdout(),
"{}",
ansi_term::Style::new().bold().paint(title)
)?;
writeln!(io::stdout())
render(text_style::StyledStr::plain(&title).bold())?;
writeln!(io::stdout(), "\n")
}
fn print_text(&mut self, indent: u8, s: &doc::Text) -> io::Result<()> {
@ -53,11 +49,14 @@ impl utils::ManRenderer for RichTextRenderer {
let lines = html2text::from_read_rich(s.html.as_bytes(), self.line_length - indent);
for line in lines {
write!(io::stdout(), "{}", " ".repeat(indent))?;
for element in line.iter() {
if let text_renderer::TaggedLineElement::Str(ts) = element {
write!(io::stdout(), "{}", style_rich_string(ts))?;
}
}
render_iter(
line.iter()
.filter_map(|tle| match tle {
text_renderer::TaggedLineElement::Str(ts) => Some(ts),
_ => None,
})
.map(style_rich_string),
)?;
writeln!(io::stdout())?;
}
Ok(())
@ -72,10 +71,11 @@ impl utils::ManRenderer for RichTextRenderer {
for line in syntect::util::LinesWithEndings::from(code.as_ref()) {
let ranges = h.highlight(line, &self.syntax_set);
write!(io::stdout(), "{}", " ".repeat(indent))?;
for (style, text) in ranges {
let content = style_syntect_string(style, text);
write!(io::stdout(), "{}", content)?;
}
// We remove the background as we want to use the terminal background
render_iter(ranges.iter().map(text_style::StyledStr::from).map(|mut s| {
s.style_mut().bg = None;
s
}))?;
}
writeln!(io::stdout())?;
} else {
@ -88,8 +88,9 @@ impl utils::ManRenderer for RichTextRenderer {
}
fn print_heading(&mut self, indent: u8, s: &str) -> io::Result<()> {
let text = ansi_term::Style::new().bold().paint(s);
writeln!(io::stdout(), "{}{}", " ".repeat(usize::from(indent)), text)
write!(io::stdout(), "{}", " ".repeat(usize::from(indent)))?;
render(text_style::StyledStr::plain(s).bold())?;
writeln!(io::stdout())
}
fn println(&mut self) -> io::Result<()> {
@ -97,54 +98,37 @@ impl utils::ManRenderer for RichTextRenderer {
}
}
pub fn style_syntect_string(
style: syntect::highlighting::Style,
s: &str,
) -> ansi_term::ANSIString<'_> {
use syntect::highlighting::FontStyle;
let mut text_style = ansi_term::Style::new();
text_style.foreground = Some(ansi_term::Color::RGB(
style.foreground.r,
style.foreground.g,
style.foreground.b,
));
if style.font_style.contains(FontStyle::BOLD) {
text_style.is_bold = true;
}
if style.font_style.contains(FontStyle::UNDERLINE) {
text_style.is_underline = true;
}
if style.font_style.contains(FontStyle::ITALIC) {
text_style.is_italic = true;
}
text_style.paint(s)
}
pub fn style_rich_string(ts: &RichString) -> ansi_term::ANSIString<'_> {
pub fn style_rich_string(ts: &RichString) -> text_style::StyledStr<'_> {
use text_renderer::RichAnnotation;
let mut style = ansi_term::Style::new();
let mut s = text_style::StyledStr::plain(&ts.s);
for annotation in &ts.tag {
match annotation {
RichAnnotation::Default => {}
RichAnnotation::Link(_) => {
style.is_underline = true;
}
RichAnnotation::Link(_) => s.style_mut().set_bold(true),
RichAnnotation::Image => {}
RichAnnotation::Emphasis => {
style.is_italic = true;
}
RichAnnotation::Strong => {
style.is_bold = true;
}
RichAnnotation::Code => {
style.foreground = Some(ansi_term::Color::Yellow);
}
RichAnnotation::Emphasis => s.style_mut().set_italic(true),
RichAnnotation::Strong => s.style_mut().set_bold(true),
RichAnnotation::Code => s.style_mut().set_fg(text_style::AnsiColor::Yellow.dark()),
RichAnnotation::Preformat(_) => {}
}
}
style.paint(&ts.s)
s
}
fn render<'a, S>(s: S) -> io::Result<()>
where
S: Into<text_style::StyledStr<'a>>,
{
text_style::ansi_term::render(io::stdout(), s)
}
fn render_iter<'a, I, S>(i: I) -> io::Result<()>
where
I: IntoIterator<Item = S>,
S: Into<text_style::StyledStr<'a>>,
{
text_style::ansi_term::render_iter(io::stdout(), i)
}