cmark_writer/ast/
html.rs

1//! HTML element definitions and utilities for CommonMark AST.
2//!
3//! This module contains definitions for HTML elements and attributes in the AST,
4//! along with utilities for safely handling HTML content.
5
6use super::Node;
7
8/// HTML attribute
9#[derive(Debug, Clone, PartialEq)]
10pub struct HtmlAttribute {
11    /// Attribute name
12    pub name: String,
13    /// Attribute value
14    pub value: String,
15}
16
17/// HTML element
18#[derive(Debug, Clone, PartialEq)]
19pub struct HtmlElement {
20    /// HTML tag name
21    pub tag: String,
22    /// HTML attributes
23    pub attributes: Vec<HtmlAttribute>,
24    /// Child nodes
25    pub children: Vec<Node>,
26    /// Whether this is a self-closing element
27    pub self_closing: bool,
28}
29
30impl HtmlElement {
31    /// Create a new HTML element
32    pub fn new(tag: &str) -> Self {
33        Self {
34            tag: tag.to_string(),
35            attributes: Vec::new(),
36            children: Vec::new(),
37            self_closing: false,
38        }
39    }
40
41    /// Add an attribute to the HTML element
42    pub fn with_attribute(mut self, name: &str, value: &str) -> Self {
43        self.attributes.push(HtmlAttribute {
44            name: name.to_string(),
45            value: value.to_string(),
46        });
47        self
48    }
49
50    /// Add multiple attributes to the HTML element
51    pub fn with_attributes(mut self, attrs: Vec<(&str, &str)>) -> Self {
52        for (name, value) in attrs {
53            self.attributes.push(HtmlAttribute {
54                name: name.to_string(),
55                value: value.to_string(),
56            });
57        }
58        self
59    }
60
61    /// Add child nodes to the HTML element
62    pub fn with_children(mut self, children: Vec<Node>) -> Self {
63        self.children = children;
64        self
65    }
66
67    /// Set whether the element is self-closing
68    pub fn self_closing(mut self, is_self_closing: bool) -> Self {
69        self.self_closing = is_self_closing;
70        self
71    }
72
73    /// Check if this element's tag matches any in the provided list (case-insensitive)
74    pub fn tag_matches_any(&self, tags: &[String]) -> bool {
75        tags.iter().any(|tag| tag.eq_ignore_ascii_case(&self.tag))
76    }
77}