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