Add custom TextDecorator implementation
html2text’s PlainDecorator that is used to produce plain text prints all link targets at the end of a block. While this is generally useful, listing all local links makes the output hard to read. JavaScript and Rust plaground links are generally not very useful in this context. Therefore we implement a custom TextDecorator that only lists external links (http or https) and ignores links to the Rust playground.
This commit is contained in:
parent
5ce0365c7f
commit
7c228e5009
@ -1,19 +1,29 @@
|
||||
// SPDX-FileCopyrightText: 2020 Robin Krahl <robin.krahl@ireas.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use html2text::render::text_renderer;
|
||||
|
||||
use crate::doc;
|
||||
use crate::viewer;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct TextViewer {}
|
||||
|
||||
struct Decorator {
|
||||
links: Vec<String>,
|
||||
ignore_next_link: bool,
|
||||
}
|
||||
|
||||
impl TextViewer {
|
||||
pub fn new() -> Self {
|
||||
Self {}
|
||||
}
|
||||
|
||||
fn print(&self, s: &str) {
|
||||
println!("{}", html2text::from_read(s.as_bytes(), 100));
|
||||
println!(
|
||||
"{}",
|
||||
html2text::from_read_with_decorator(s.as_bytes(), 100, Decorator::new())
|
||||
);
|
||||
}
|
||||
|
||||
fn print_opt(&self, s: Option<&str>) {
|
||||
@ -31,3 +41,89 @@ impl viewer::Viewer for TextViewer {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Decorator {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
links: Vec::new(),
|
||||
ignore_next_link: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn show_link(&self, url: &str) -> bool {
|
||||
// only show absolute links -- local links are most likely not helpful
|
||||
(url.starts_with("http") || url.starts_with("https")) &&
|
||||
// ignore playground links -- typically, these links are too long to display in a
|
||||
// sensible fasshion
|
||||
!url.starts_with("http://play.rust-lang.org") &&
|
||||
!url.starts_with("https://play.rust-lang.org")
|
||||
}
|
||||
}
|
||||
|
||||
impl text_renderer::TextDecorator for Decorator {
|
||||
type Annotation = ();
|
||||
|
||||
fn decorate_link_start(&mut self, url: &str) -> (String, Self::Annotation) {
|
||||
if self.show_link(url) {
|
||||
self.ignore_next_link = false;
|
||||
self.links.push(url.to_string());
|
||||
("[".to_owned(), ())
|
||||
} else {
|
||||
self.ignore_next_link = true;
|
||||
(String::new(), ())
|
||||
}
|
||||
}
|
||||
|
||||
fn decorate_link_end(&mut self) -> String {
|
||||
if self.ignore_next_link {
|
||||
String::new()
|
||||
} else {
|
||||
format!("][{}]", self.links.len())
|
||||
}
|
||||
}
|
||||
|
||||
fn decorate_em_start(&mut self) -> (String, Self::Annotation) {
|
||||
("*".to_owned(), ())
|
||||
}
|
||||
|
||||
fn decorate_em_end(&mut self) -> String {
|
||||
"*".to_owned()
|
||||
}
|
||||
|
||||
fn decorate_strong_start(&mut self) -> (String, Self::Annotation) {
|
||||
("**".to_owned(), ())
|
||||
}
|
||||
|
||||
fn decorate_strong_end(&mut self) -> String {
|
||||
"**".to_owned()
|
||||
}
|
||||
|
||||
fn decorate_code_start(&mut self) -> (String, Self::Annotation) {
|
||||
("`".to_owned(), ())
|
||||
}
|
||||
|
||||
fn decorate_code_end(&mut self) -> String {
|
||||
"`".to_owned()
|
||||
}
|
||||
|
||||
fn decorate_preformat_first(&mut self) -> Self::Annotation {}
|
||||
fn decorate_preformat_cont(&mut self) -> Self::Annotation {}
|
||||
|
||||
fn decorate_image(&mut self, title: &str) -> (String, Self::Annotation) {
|
||||
(format!("[{}]", title), ())
|
||||
}
|
||||
|
||||
fn finalise(self) -> Vec<text_renderer::TaggedLine<()>> {
|
||||
self.links
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(idx, s)| {
|
||||
text_renderer::TaggedLine::from_string(format!("[{}] {}", idx + 1, s), &())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn make_subblock_decorator(&self) -> Self {
|
||||
Decorator::new()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user