evobench_tools/utillib/
html_util.rs1use ahtml::{AId, AllocatorType, HtmlAllocator, Node, ToASlice, att, flat::Flat};
4use anyhow::Result;
5
6pub fn flat_len<T: AllocatorType>(slf: &Flat<T>) -> u32 {
10 match slf {
11 Flat::None => 0,
12 Flat::One(_) => 1,
13 Flat::Two(_, _) => 2,
14 Flat::Slice(s) => s.len(),
15 }
16}
17
18pub fn flat_get<'t>(slf: &Flat<Node>, index: u32, html: &'t HtmlAllocator) -> Option<&'t Node> {
19 match slf {
20 Flat::None => None,
21 Flat::One(v) => {
22 if index == 0 {
23 html.get_node(*v)
24 } else {
25 None
26 }
27 }
28 Flat::Two(a, b) => {
29 let v = match index {
30 0 => a,
31 1 => b,
32 _ => return None,
33 };
34 html.get_node(*v)
35 }
36 Flat::Slice(s) => html.get_node(s.get(index, html)?),
37 }
38}
39
40pub fn extract_paragraph_body(
47 node: AId<Node>,
48 keep_if_attributes: bool,
49 html: &HtmlAllocator,
50) -> Flat<Node> {
51 let mut body = Flat::One(node);
52 loop {
53 if flat_len(&body) == 1 {
56 let node = flat_get(&body, 0, html).expect("checked len is 1");
57 if let Some(element) = node.as_element() {
58 match element.meta.tag_name.as_str() {
59 "div" | "p" => {
60 if (!keep_if_attributes) || element.attr.len() == 0 {
61 body = Flat::Slice(element.body)
62 } else {
63 break;
64 }
65 }
66 _ => break,
67 }
68 } else {
69 break;
70 }
71 } else {
72 break;
73 }
74 }
75 body
76}
77
78pub fn anchor(
80 anchor_name: &str,
81 body: impl ToASlice<Node>,
82 html: &HtmlAllocator,
83) -> Result<AId<Node>> {
84 html.a([att("name", anchor_name), att("id", anchor_name)], body)
85}