Display link targets in rich viewer
Previously, we only used the underline effect to highlight links in the rich viewer, but we did not provide any information about their target. With this patch, we print a list of link at the end of a block, similar to the plain text viewer.
This commit is contained in:
parent
6ea5f070d2
commit
4260aab85a
@ -70,6 +70,18 @@ fn ignore_pipe_error(error: io::Error) -> io::Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Decides whether a link to the given URL should be included in the link list that is displayed
|
||||
/// at the end of the block.
|
||||
///
|
||||
/// We only list absolute URLs because relative URLs are not useful in a non-interactive viewer.
|
||||
/// Also, we skip links to the Rust playground because they are typically very long and therefore
|
||||
/// hard to read and display.
|
||||
pub fn list_link(url: &str) -> bool {
|
||||
(url.starts_with("http") || url.starts_with("https"))
|
||||
&& !url.starts_with("http://play.rust-lang.org")
|
||||
&& !url.starts_with("https://play.rust-lang.org")
|
||||
}
|
||||
|
||||
pub fn format_title(line_length: usize, left: &str, middle: &str, right: &str) -> String {
|
||||
let mut s = String::with_capacity(line_length);
|
||||
|
||||
|
@ -69,22 +69,13 @@ impl Decorator {
|
||||
pub fn new() -> Self {
|
||||
Decorator::default()
|
||||
}
|
||||
|
||||
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) {
|
||||
if super::list_link(url) {
|
||||
self.ignore_next_link = false;
|
||||
self.links.push(url.to_string());
|
||||
("[".to_owned(), ())
|
||||
|
@ -40,8 +40,9 @@ impl utils::ManRenderer for RichTextRenderer {
|
||||
} else {
|
||||
indent
|
||||
};
|
||||
let decorator = utils::RichDecorator::new(super::list_link);
|
||||
let lines = html2text::parse(s.html.as_bytes())
|
||||
.render(self.line_length - indent, utils::RichDecorator)
|
||||
.render(self.line_length - indent, decorator)
|
||||
.into_lines();
|
||||
for line in utils::highlight_html(&lines, self.highlighter.as_ref()) {
|
||||
write!(io::stdout(), "{}", " ".repeat(indent))?;
|
||||
|
@ -287,20 +287,44 @@ fn print_heading<M: ManRenderer + ?Sized>(
|
||||
|
||||
/// A decorator that generates rich text.
|
||||
#[derive(Clone)]
|
||||
pub struct RichDecorator;
|
||||
pub struct RichDecorator {
|
||||
link_filter: fn(&str) -> bool,
|
||||
ignore_next_link: bool,
|
||||
links: Vec<String>,
|
||||
}
|
||||
|
||||
impl RichDecorator {
|
||||
pub fn new(link_filter: fn(&str) -> bool) -> RichDecorator {
|
||||
RichDecorator {
|
||||
link_filter,
|
||||
ignore_next_link: false,
|
||||
links: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl text_renderer::TextDecorator for RichDecorator {
|
||||
type Annotation = text_renderer::RichAnnotation;
|
||||
|
||||
fn decorate_link_start(&mut self, url: &str) -> (String, Self::Annotation) {
|
||||
self.ignore_next_link = !(self.link_filter)(url);
|
||||
if self.ignore_next_link {
|
||||
(String::new(), text_renderer::RichAnnotation::Default)
|
||||
} else {
|
||||
self.links.push(url.to_owned());
|
||||
(
|
||||
"".to_string(),
|
||||
text_renderer::RichAnnotation::Link(url.to_string()),
|
||||
"[".to_owned(),
|
||||
text_renderer::RichAnnotation::Link(url.to_owned()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn decorate_link_end(&mut self) -> String {
|
||||
"".to_string()
|
||||
if self.ignore_next_link {
|
||||
String::new()
|
||||
} else {
|
||||
format!("][{}]", self.links.len() - 1)
|
||||
}
|
||||
}
|
||||
|
||||
fn decorate_em_start(&mut self) -> (String, Self::Annotation) {
|
||||
@ -348,11 +372,24 @@ impl text_renderer::TextDecorator for RichDecorator {
|
||||
}
|
||||
|
||||
fn finalise(self) -> Vec<text_renderer::TaggedLine<text_renderer::RichAnnotation>> {
|
||||
Vec::new()
|
||||
let mut lines = Vec::new();
|
||||
for (idx, link) in self.links.into_iter().enumerate() {
|
||||
let mut line = text_renderer::TaggedLine::new();
|
||||
line.push_str(text_renderer::TaggedString {
|
||||
s: format!("[{}] ", idx),
|
||||
tag: text_renderer::RichAnnotation::Default,
|
||||
});
|
||||
line.push_str(text_renderer::TaggedString {
|
||||
s: link.clone(),
|
||||
tag: text_renderer::RichAnnotation::Link(link),
|
||||
});
|
||||
lines.push(line);
|
||||
}
|
||||
lines
|
||||
}
|
||||
|
||||
fn make_subblock_decorator(&self) -> Self {
|
||||
RichDecorator
|
||||
RichDecorator::new(self.link_filter)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user