html2md/
styles.rs

1use super::TagHandler;
2use super::StructuredPrinter;
3
4use markup5ever_rcdom::{Handle,NodeData};
5
6#[derive(Default)]
7pub struct StyleHandler {
8    start_pos: usize,
9    style_type: String
10}
11
12/// Applies givem `mark` at both start and end indices, updates printer position to the end of text
13fn apply_at_bounds(printer: &mut StructuredPrinter, start: usize, end: usize, mark: &str) {
14    printer.data.insert_str(end, mark);
15    printer.data.insert_str(start, mark);
16}
17
18impl TagHandler for StyleHandler {
19    
20    fn handle(&mut self, tag: &Handle, printer: &mut StructuredPrinter) {
21        self.start_pos = printer.data.len();
22        self.style_type = match tag.data {
23            NodeData::Element { ref name, .. } => name.local.to_string(),
24            _ => String::new()
25        };
26    }
27
28    fn after_handle(&mut self, printer: &mut StructuredPrinter) {
29        let non_space_offset = printer.data[self.start_pos..].find(|ch: char| !ch.is_whitespace());
30        if non_space_offset.is_none() {
31            // only spaces or no text at all
32            return;
33        }
34
35        let first_non_space_pos = self.start_pos + non_space_offset.unwrap();
36        let last_non_space_pos = printer.data.trim_end_matches(|ch: char| ch.is_whitespace()).len();
37        
38        // finishing markup
39        match self.style_type.as_ref() {
40            "b" | "strong" => apply_at_bounds(printer, first_non_space_pos, last_non_space_pos, "**"),
41            "i" | "em" => apply_at_bounds(printer, first_non_space_pos, last_non_space_pos, "*"),
42            "s" | "del" => apply_at_bounds(printer, first_non_space_pos, last_non_space_pos, "~~"),
43            "u" | "ins" => apply_at_bounds(printer, first_non_space_pos, last_non_space_pos, "__"),
44            _ => {}
45        }
46    }
47}