1use super::StructuredPrinter;
2use super::TagHandler;
3
4use markup5ever_rcdom::{Handle, NodeData};
5
6#[derive(Default)]
7pub struct StyleHandler {
8 start_pos: usize,
9 style_type: String,
10}
11
12fn 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 fn handle(&mut self, tag: &Handle, printer: &mut StructuredPrinter) {
20 self.start_pos = printer.data.len();
21 self.style_type = match tag.data {
22 NodeData::Element { ref name, .. } => name.local.to_string(),
23 _ => String::new(),
24 };
25 }
26
27 fn after_handle(&mut self, printer: &mut StructuredPrinter) {
28 let non_space_offset = printer.data[self.start_pos..].find(|ch: char| !ch.is_whitespace());
29 if non_space_offset.is_none() {
30 return;
32 }
33
34 let first_non_space_pos = self.start_pos + non_space_offset.unwrap();
35 let last_non_space_pos = printer
36 .data
37 .trim_end_matches(|ch: char| ch.is_whitespace())
38 .len();
39
40 match self.style_type.as_ref() {
42 "b" | "strong" => {
43 apply_at_bounds(printer, first_non_space_pos, last_non_space_pos, "**")
44 }
45 "i" | "em" => apply_at_bounds(printer, first_non_space_pos, last_non_space_pos, "*"),
46 "s" | "del" => apply_at_bounds(printer, first_non_space_pos, last_non_space_pos, "~~"),
47 "u" | "ins" => apply_at_bounds(printer, first_non_space_pos, last_non_space_pos, "__"),
48 _ => {}
49 }
50 }
51}