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