1use crate::common::get_tag_attr;
2use crate::dummy::IdentityHandler;
3use percent_encoding::percent_decode_str;
4
5use super::StructuredPrinter;
6use super::TagHandler;
7
8use markup5ever_rcdom::{Handle, NodeData};
9
10#[derive(Default)]
11pub struct AnchorHandler {
12 start_pos: usize,
13 url: String,
14 emit_unchanged: bool,
15}
16
17impl TagHandler for AnchorHandler {
18 fn handle(&mut self, tag: &Handle, printer: &mut StructuredPrinter) {
19 if get_tag_attr(tag, "name").is_some() {
22 let mut identity = IdentityHandler;
23 identity.handle(tag, printer);
24 self.emit_unchanged = true;
25 }
26
27 self.start_pos = printer.data.len();
28
29 self.url = match tag.data {
31 NodeData::Element { ref attrs, .. } => {
32 let attrs = attrs.borrow();
33 let href = attrs
34 .iter()
35 .find(|attr| attr.name.local.to_string() == "href");
36 match href {
37 Some(link) => {
38 let link = &*link.value;
39 let link = percent_decode_str(link).decode_utf8().unwrap_or_default();
40
41 if link.contains(|c: char| c.is_ascii_whitespace()) {
42 format!("<{}>", link)
43 } else {
44 link.to_string()
45 }
46 }
47 None => String::new(),
48 }
49 }
50 _ => String::new(),
51 };
52 }
53
54 fn after_handle(&mut self, printer: &mut StructuredPrinter) {
55 if !self.emit_unchanged {
56 printer.insert_str(self.start_pos, "[");
58 printer.append_str(&format!("]({})", self.url))
59 }
60 }
61}