simple_rsx/
lib.rs

1//! Simple RSX - A lightweight JSX-like library for Rust
2//!
3//! This crate provides a simple way to write HTML-like components in Rust using JSX-style syntax.
4//! It's perfect for building user interfaces or generating HTML content with a familiar, component-based approach.
5//!
6//! # Quick Start
7//!
8//! ```rust
9//! use simple_rsx::*;
10//!
11//! // Create a simple component
12//! let greeting = rsx!(
13//!     <div class="greeting">
14//!         <h1>Hello, World!</h1>
15//!         <p>Welcome to Simple RSX</p>
16//!     </div>
17//! );
18//!
19//! // Convert to HTML string
20//! println!("{}", greeting); // Outputs the HTML
21//! ```
22//!
23//! # Features
24//!
25//! - JSX-like syntax with the `rsx!` macro
26//! - Component-based architecture
27//! - Type-safe attributes and children
28//! - Easy conversion to HTML strings
29//! - Support for custom components
30//!
31//! # Custom Components
32//!
33//! ```rust
34//! use simple_rsx::*;
35//!
36//! #[derive(Default)]
37//! struct ButtonProps {
38//!     text: String,
39//!     children: Vec<Node>,
40//! }
41//!
42//! #[component]
43//! fn Button(props: ButtonProps) -> Node {
44//!     rsx!(
45//!         <button class="btn">
46//!             {props.text}
47//!             {props.children}
48//!         </button>
49//!     )
50//! }
51//! ```
52
53use indexmap::IndexMap;
54pub use simple_rsx_macros::{component, either, rsx};
55use std::fmt::Display;
56
57/// A trait for converting values into HTML attribute strings.
58///
59/// This trait is automatically implemented for any type that implements `ToString`,
60/// making it easy to use various types as attribute values.
61///
62/// # Example
63///
64/// ```rust
65/// use simple_rsx::*;
66///
67/// let element = rsx!(<div id="my-id" hidden={true} />);
68/// ```
69pub trait Attribute {
70    fn value(&self) -> String;
71}
72
73/// A trait for handling optional attribute values.
74///
75/// This trait is automatically implemented for `Option<T>` where T implements `ToString`.
76/// It allows for graceful handling of optional attributes, rendering them as empty strings when None.
77///
78/// # Example
79///
80/// ```rust
81/// use simple_rsx::*;
82///
83/// let maybe_title = Some("Hello".to_string());
84/// let element = rsx!(<div title={maybe_title} />);
85/// ```
86pub trait OptionAttribute {
87    fn value(&self) -> String;
88}
89
90impl<T: ToString> Attribute for T {
91    fn value(&self) -> String {
92        self.to_string()
93    }
94}
95
96impl<T: ToString> OptionAttribute for Option<T> {
97    fn value(&self) -> String {
98        match self {
99            Some(t) => t.to_string(),
100            None => String::new(),
101        }
102    }
103}
104
105/// Represents an HTML element with its tag name, attributes, and children.
106///
107/// Elements are the building blocks of the RSX tree structure. Each element
108/// can have attributes (like class, id, etc.) and can contain other elements
109/// or text nodes as children.
110///
111/// You typically won't create Elements directly, but rather use the `rsx!` macro:
112///
113/// ```rust
114/// use simple_rsx::*;
115///
116/// let element = rsx!(
117///     <div class="container">
118///         <p>Hello world!</p>
119///     </div>
120/// );
121/// ```
122#[derive(Clone)]
123pub struct Element {
124    tag: String,
125    attributes: IndexMap<String, String>,
126    children: Vec<Node>,
127}
128
129impl Element {
130    /// Creates a new Element node with the specified tag name.
131    ///
132    /// # Example
133    ///
134    /// ```rust
135    /// use simple_rsx::*;
136    ///
137    /// let element = Element::new("div");
138    /// assert!(matches!(element, Node::Element(_)));
139    /// ```
140    pub fn new(tag: &str) -> Node {
141        Node::Element(Element {
142            tag: tag.to_string(),
143            attributes: IndexMap::new(),
144            children: Vec::new(),
145        })
146    }
147
148    /// Sets an attribute on the element.
149    ///
150    /// # Example
151    ///
152    /// ```rust
153    /// use simple_rsx::*;
154    ///
155    /// let mut node = Element::new("div");
156    /// let mut element = node.as_element_mut().unwrap();
157    /// element.set_attribute("class", "container");
158    /// ```
159    pub fn set_attribute(&mut self, name: &str, value: impl Attribute) {
160        self.attributes.insert(name.to_string(), value.value());
161    }
162
163    /// Adds a child node to this element.
164    ///
165    /// # Example
166    ///
167    /// ```rust
168    /// use simple_rsx::*;
169    ///
170    /// let mut parent_node = Element::new("div");
171    /// let mut parent = parent_node.as_element_mut().unwrap();
172    /// parent.append_child(Element::new("p"));
173    /// ```
174    pub fn append_child(&mut self, node: Node) {
175        self.children.push(node);
176    }
177}
178
179impl Node {
180    /// Attempts to get a mutable reference to the underlying Element if this node is an Element.
181    ///
182    /// Returns None if the node is not an Element (e.g., if it's Text or Fragment).
183    pub fn as_element_mut(&mut self) -> Option<&mut Element> {
184        match self {
185            Node::Element(el) => Some(el),
186            _ => None,
187        }
188    }
189
190    /// Adds a child node if this node is an Element.
191    ///
192    /// This method has no effect if the node is not an Element.
193    pub fn append_child(&mut self, node: Node) {
194        if let Node::Element(el) = self {
195            el.children.push(node);
196        }
197    }
198}
199
200/// A trait for creating reusable components.
201///
202/// Components are the heart of RSX's reusability model. They allow you to create
203/// custom elements with their own logic and state.
204///
205/// # Example
206///
207/// ```rust
208/// use simple_rsx::*;
209///
210/// struct Card;
211/// #[derive(Default)]
212/// struct CardProps {
213///     title: String,
214///     children: Vec<Node>,
215/// }
216///
217/// impl Component for Card {
218///     type Props = CardProps;
219///     fn render(props: Self::Props) -> Node {
220///         rsx!(
221///             <div class="card">
222///                 <h2>{props.title}</h2>
223///                 <div class="card-content">{props.children}</div>
224///             </div>
225///         )
226///     }
227/// }
228/// ```
229pub trait Component {
230    /// The type of props this component accepts
231    type Props;
232
233    /// Renders the component with the given props
234    fn render(props: Self::Props) -> Node;
235}
236
237/// Represents a node in the RSX tree.
238///
239/// Nodes are the fundamental building blocks of RSX. They can be:
240/// - Elements (like `<div>` or `<p>`)
241/// - Text content
242/// - Fragments (groups of nodes)
243/// - Comments
244///
245/// # Example
246///
247/// ```rust
248/// use simple_rsx::*;
249///
250/// let text_node = Node::Text("Hello".to_string());
251/// let element_node = Element::new("div");
252/// let fragment = Node::Fragment(vec![text_node, element_node]);
253/// ```
254#[derive(Clone)]
255pub enum Node {
256    /// An HTML element with a tag name, attributes, and children
257    Element(Element),
258    /// Plain text content
259    Text(String),
260    /// A group of nodes without a wrapper element
261    Fragment(Vec<Node>),
262    /// An HTML comment
263    Comment(String),
264}
265
266impl From<String> for Node {
267    fn from(value: String) -> Self {
268        Node::Text(value)
269    }
270}
271
272impl From<&String> for Node {
273    fn from(value: &String) -> Self {
274        Node::Text(value.to_string())
275    }
276}
277
278impl From<&str> for Node {
279    fn from(value: &str) -> Self {
280        Node::Text(value.to_string())
281    }
282}
283
284impl From<&&str> for Node {
285    fn from(value: &&str) -> Self {
286        Node::Text(value.to_string())
287    }
288}
289
290impl<T: ToString> From<Vec<T>> for Node {
291    fn from(value: Vec<T>) -> Self {
292        Node::Fragment(
293            value
294                .into_iter()
295                .map(|t| Node::Text(t.to_string()))
296                .collect(),
297        )
298    }
299}
300
301impl<T: ToString> From<Option<T>> for Node {
302    fn from(value: Option<T>) -> Self {
303        match value {
304            Some(t) => Node::Text(t.to_string()),
305            _ => Node::Text("".to_string()),
306        }
307    }
308}
309
310impl From<&Vec<String>> for Node {
311    fn from(value: &Vec<String>) -> Self {
312        Node::Fragment(
313            value
314                .iter()
315                .map(|item| Node::Text(item.to_string()))
316                .collect(),
317        )
318    }
319}
320
321impl From<i32> for Node {
322    fn from(value: i32) -> Self {
323        Node::Text(value.to_string())
324    }
325}
326
327impl From<u32> for Node {
328    fn from(value: u32) -> Self {
329        Node::Text(value.to_string())
330    }
331}
332
333impl From<u64> for Node {
334    fn from(value: u64) -> Self {
335        Node::Text(value.to_string())
336    }
337}
338
339impl FromIterator<u32> for Node {
340    fn from_iter<T: IntoIterator<Item = u32>>(iter: T) -> Self {
341        let mut result = Vec::new();
342        for item in iter {
343            result.push(Node::Text(item.to_string()));
344        }
345        Node::Fragment(result)
346    }
347}
348
349impl FromIterator<u64> for Node {
350    fn from_iter<T: IntoIterator<Item = u64>>(iter: T) -> Self {
351        let mut result = Vec::new();
352        for item in iter {
353            result.push(Node::Text(item.to_string()));
354        }
355        Node::Fragment(result)
356    }
357}
358
359impl FromIterator<i32> for Node {
360    fn from_iter<T: IntoIterator<Item = i32>>(iter: T) -> Self {
361        let mut result = Vec::new();
362        for item in iter {
363            result.push(Node::Text(item.to_string()));
364        }
365        Node::Fragment(result)
366    }
367}
368
369impl From<f32> for Node {
370    fn from(value: f32) -> Self {
371        Node::Text(value.to_string())
372    }
373}
374
375impl From<bool> for Node {
376    fn from(value: bool) -> Self {
377        Node::Text(value.to_string())
378    }
379}
380
381impl<I, F, R> From<std::iter::Map<I, F>> for Node
382where
383    I: Iterator,
384    F: FnMut(I::Item) -> R,
385    R: Into<Node>,
386    Vec<Node>: FromIterator<R>,
387{
388    fn from(iter: std::iter::Map<I, F>) -> Self {
389        let nodes: Vec<Node> = iter.collect();
390        Node::from(nodes)
391    }
392}
393
394impl Display for Node {
395    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
396        match self {
397            Node::Element(el) => {
398                write!(f, "<{}", el.tag)?;
399                for (key, value) in &el.attributes {
400                    write!(f, " {}=\"{}\"", key, value)?;
401                }
402                write!(f, ">")?;
403                for child in &el.children {
404                    write!(f, "{}", child)?;
405                }
406                write!(f, "</{}>", el.tag)?;
407                Ok(())
408            }
409            Node::Text(text) => {
410                write!(f, "{}", text)?;
411                Ok(())
412            }
413            Node::Fragment(nodes) => {
414                for node in nodes {
415                    write!(f, "{}", node)?;
416                }
417                Ok(())
418            }
419            Node::Comment(comment) => {
420                write!(f, "<!--{}-->", comment)?;
421                Ok(())
422            }
423        }
424    }
425}
426
427macro_rules! derive_elements {
428    (
429        $(
430            $(#[$tag_meta:meta])*
431            $tag:ident {
432                $(
433                    $(#[$attr_meta:meta])*
434                    $attr_name:ident : $attr_value:ty
435                ),* $(,)?
436            }
437        )*
438    ) => {
439        $(
440            #[allow(non_camel_case_types)]
441            $(#[$tag_meta])*
442            pub struct $tag;
443
444            paste::paste! {
445                #[derive(Default)]
446                #[allow(non_snake_case)]
447                pub struct [<HTML $tag:camel Element Props>] {
448                    // Global HTML attributes
449
450                    /// The child nodes of the element
451                    pub children: Vec<Node>,
452
453                    /// The id attribute specifies a unique id for an HTML element
454                    pub id: String,
455
456                    /// A unique key to identify the element
457                    pub key: String,
458
459                    /// The class attribute specifies one or more class names for an HTML element
460                    pub class: String,
461
462                    /// The style attribute specifies an inline CSS style for an element
463                    pub style: String,
464
465                    /// The title attribute specifies extra information about an element (displayed as a tooltip)
466                    pub title: Option<String>,
467                    /// The width attribute specifies the width of the image
468                    pub width: Option<String>,
469                    /// The height attribute specifies the height of the image
470                    pub height: Option<String>,
471
472                    /// Specifies whether an element is draggable or not
473                    pub draggable: bool,
474
475                    /// Specifies visibility of an element (hidden or visible)
476                    pub hidden: bool,
477
478                    /// Specifies a shortcut key to activate/focus an element
479                    pub accesskey: String,
480
481                    /// Specifies whether the content of an element is editable or not
482                    pub contenteditable: bool,
483
484                    /// Specifies the text direction for the content in an element
485                    pub dir: String,
486
487                    /// Specifies the tabbing order of an element (when the tab button is used)
488                    pub tabindex: Option<i32>,
489
490                    /// Specifies whether the element is to have its spelling and grammar checked
491                    pub spellcheck: bool,
492
493                    /// Specifies the language of the element's content
494                    pub lang: String,
495
496                    /// Specifies whether an element is translateable or not
497                    pub translate: bool,
498
499                    /// Controls whether and how text input is automatically capitalized
500                    pub autocapitalize: String,
501
502                    /// Specifies an inline CSS style for an element
503                    pub role: String,
504
505                    /// Custom data attributes (data-*)
506                    pub r#data: std::collections::HashMap<String, String>,
507
508                    // ARIA Accessibility attributes
509
510                    /// Identifies the current element within a set
511                    pub aria_current: String,
512
513                    /// Defines a string value that labels the current element
514                    pub aria_label: Option<String>,
515
516                    /// Identifies the element that labels the current element
517                    pub aria_labelledby: Option<String>,
518
519                    /// Identifies the element that describes the current element
520                    pub aria_describedby: Option<String>,
521
522                    /// Indicates whether an element is expanded or collapsed
523                    pub aria_expanded: bool,
524
525                    /// Indicates the element that represents the current item within a container or set
526                    pub aria_selected: bool,
527
528                    /// Indicates whether the element is checked, unchecked, or represents mixed mode
529                    pub aria_checked: String,
530
531                    /// Indicates whether an element and its subtree are hidden
532                    pub aria_hidden: bool,
533
534                    /// Indicates the availability and type of interactive popup element
535                    pub aria_haspopup: String,
536
537                    /// Defines an element's role
538                    pub aria_role: String,
539
540                    // Element specific attributes
541                    $(
542                        pub $attr_name: $attr_value,
543                    )*
544                }
545
546                impl [<HTML $tag:camel Element Props>] {
547                    fn to_attributes(&self) -> IndexMap<String, String> {
548                        #[allow(unused_mut)]
549                        let mut attributes = IndexMap::new();
550                        $(
551                            if !self.$attr_name.value().is_empty() {
552                                let mut key = stringify!($attr_name);
553                                if let Some(last_char) = key.chars().last() {
554                                    if last_char == '_' {
555                                        key = &key[..key.len() - 1];
556                                    }
557                                }
558                                attributes.insert(key.replace('_', "-"), self.$attr_name.value());
559                            }
560                        )*
561                        if !self.id.value().is_empty() {
562                            attributes.insert("id".to_string(), self.id.value());
563                        }
564                        if !self.class.value().is_empty() {
565                            attributes.insert("class".to_string(), self.class.value());
566                        }
567                        if !self.style.value().is_empty() {
568                            attributes.insert("style".to_string(), self.style.value());
569                        }
570                        if !self.title.value().is_empty() {
571                            attributes.insert("title".to_string(), self.title.value());
572                        }
573                        if self.draggable {
574                            attributes.insert("draggable".to_string(), "true".to_string());
575                        }
576                        if self.hidden {
577                            attributes.insert("hidden".to_string(), "true".to_string());
578                        }
579                        if !self.accesskey.value().is_empty() {
580                            attributes.insert("accesskey".to_string(), self.accesskey.value());
581                        }
582                        if self.contenteditable {
583                            attributes.insert("contenteditable".to_string(), "true".to_string());
584                        }
585                        if !self.dir.value().is_empty() {
586                            attributes.insert("dir".to_string(), self.dir.value());
587                        }
588                        if let Some(tabindex) = self.tabindex {
589                            attributes.insert("tabindex".to_string(), tabindex.to_string());
590                        }
591                        if self.spellcheck {
592                            attributes.insert("spellcheck".to_string(), "true".to_string());
593                        }
594                        if !self.lang.value().is_empty() {
595                            attributes.insert("lang".to_string(), self.lang.value());
596                        }
597                        if self.translate {
598                            attributes.insert("translate".to_string(), "true".to_string());
599                        }
600                        if !self.autocapitalize.value().is_empty() {
601                            attributes.insert("autocapitalize".to_string(), self.autocapitalize.value());
602                        }
603                        if !self.role.value().is_empty() {
604                            attributes.insert("role".to_string(), self.role.value());
605                        }
606                        if !self.aria_current.value().is_empty() {
607                            attributes.insert("aria-current".to_string(), self.aria_current.value());
608                        }
609                        if !self.aria_label.value().is_empty() {
610                            attributes.insert("aria-label".to_string(), self.aria_label.value());
611                        }
612                        if !self.aria_labelledby.value().is_empty() {
613                            attributes.insert("aria-labelledby".to_string(), self.aria_labelledby.value());
614                        }
615                        if !self.aria_describedby.value().is_empty() {
616                            attributes.insert("aria-describedby".to_string(), self.aria_describedby.value());
617                        }
618                        if self.aria_expanded {
619                            attributes.insert("aria-expanded".to_string(), "true".to_string());
620                        }
621                        if self.aria_selected {
622                            attributes.insert("aria-selected".to_string(), "true".to_string());
623                        }
624                        if !self.aria_checked.value().is_empty() {
625                            attributes.insert("aria-checked".to_string(), self.aria_checked.value());
626                        }
627                        if self.aria_hidden {
628                            attributes.insert("aria-hidden".to_string(), "true".to_string());
629                        }
630                        if !self.aria_haspopup.value().is_empty() {
631                            attributes.insert("aria-haspopup".to_string(), self.aria_haspopup.value());
632                        }
633                        if !self.aria_role.value().is_empty() {
634                            attributes.insert("aria-role".to_string(), self.aria_role.value());
635                        }
636                        // Add data-* attributes
637                        for (key, value) in &self.r#data {
638                            if key.starts_with("data_") {
639                                attributes.insert(key.replace("_", "-"), value.clone());
640                            } else {
641                                attributes.insert(format!("data-{}", key), value.clone());
642                            }
643                        }
644
645                        attributes
646                    }
647                }
648
649                impl Component for $tag {
650                    type Props = [<HTML $tag:camel Element Props>];
651
652                    fn render(props: Self::Props) -> Node {
653                        Node::Element(Element {
654                            tag: stringify!($tag).to_string(),
655                            attributes: props.to_attributes(),
656                            children: props.children,
657                        })
658                    }
659                }
660            }
661        )*
662    };
663}
664
665pub mod elements {
666    use super::*;
667    derive_elements! {
668        /// HTML `<html>` element - Root element of an HTML document
669        html {
670        }
671        /// HTML `<body>` element - Represents the content of an HTML document
672        ///
673        /// Example:
674        ///
675        /// ```<body>Content goes here</body>```
676        body {
677        }
678        /// HTML `<head>` element - Contains metadata about the document
679        ///
680        /// Example:
681        ///
682        /// ```<head><title>Document Title</title></head>```
683        head {
684        }
685        /// HTML `<title>` element - Defines the title of the document
686        ///
687        /// Example:
688        ///
689        /// ```<title>Document Title</title>```
690        title {
691        }
692        /// HTML `<meta` element - Provides metadata about the document
693        ///
694        /// Example:
695        ///
696        /// ```<meta charset="UTF-8">```
697        meta {
698            /// The character encoding of the document
699            charset: String,
700            /// The HTTP response status code
701            http_equiv: String,
702            /// The content of the document
703            content: String,
704            /// The name of the metadata
705            name: String,
706            /// The property of the metadata
707            property: String,
708        }
709        /// HTML `<style>` element - Defines style information for a document
710        ///
711        /// Example:
712        ///
713        /// ```<style>body { background-color: #f0f0f0; }</style>```
714        style {
715        }
716        /// HTML `<script>` element - Embeds executable code or data
717        ///
718        /// Example:
719        ///
720        /// ```<script src="script.js"></script>```
721        script {
722            /// The URL of the external script file
723            src: String,
724            /// The type of the script
725            type_: String,
726            /// The language of the script
727            language: String,
728            /// The character encoding of the script
729            charset: String,
730            /// The defer attribute specifies that the script will be executed after the document is finished parsing
731            defer: bool,
732            /// The async attribute specifies that the script will be executed asynchronously
733            async_: bool,
734        }
735        /// HTML `<link>` element - Specifies relationships between the current document and an external resource
736        ///
737        /// Example:
738        ///
739        /// ```<link rel="stylesheet" href="style.css">```
740        link {
741            /// The relationship between the current document and the linked resource
742            rel: String,
743            /// The URL of the linked resource
744            href: String,
745            /// The type of the linked resource
746            type_: String,
747            /// The character encoding of the linked resource
748            charset: String,
749            /// crossorigin attribute specifies that the element will request a cross-origin Isolation of its browsing context
750            crossorigin: String,
751            /// The referrerpolicy attribute specifies the referrer policy for the linked resource
752            referrerpolicy: String,
753        }
754        /// HTML `<div>` element - Container element for grouping and styling content
755        ///
756        /// Example:
757        ///
758        /// ```<div class="container">Content goes here</div>```
759        div {
760        }
761
762        /// HTML `<p>` element - Represents a paragraph of text
763        ///
764        /// Example:
765        ///
766        /// ```<p>This is a paragraph of text.</p>```
767        p {
768        }
769
770        /// HTML `<span>` element - Inline container for targeting text with styles
771        ///
772        /// Example:
773        ///
774        /// ```<span class="highlight">Highlighted text</span>```
775        span {
776        }
777
778        /// HTML `<a>` element - Creates a hyperlink to other web pages or resources
779        ///
780        /// Example:
781        ///
782        /// ```<a href="https://example.com" target="_blank">Visit Example</a>```
783        a {
784            /// The href attribute specifies the URL of the page the link goes to
785            /// Example: href="https://example.com"
786            href: String,
787            /// The target attribute specifies where to open the linked document
788            /// Example: target="_blank" (opens in new tab)
789            target: String,
790            /// The rel attribute specifies the relationship between the current document and the linked document
791            /// Example: rel="nofollow" (tells search engines not to follow this link)
792            rel: String,
793            /// The download attribute indicates the browser to download the URL instead of navigating
794            /// Example: download="filename.pdf"
795            download: String,
796            /// The hreflang attribute specifies the language of the linked document
797            /// Example: hreflang="en" (English)
798            hreflang: String,
799            /// The type attribute specifies the media type of the linked document
800            /// Example: type="text/html"
801            type_: String,
802            /// The media attribute specifies what media/device the linked document is optimized for
803            /// Example: media="print" (for print stylesheets)
804            media: String,
805            /// The referrerpolicy attribute specifies which referrer information to send
806            /// Example: referrerpolicy="no-referrer"
807            referrerpolicy: String,
808            /// The ping attribute specifies URLs to be notified when the link is followed
809            /// Example: ping="https://example.com/track"
810            ping: String,
811        }
812
813        /// HTML <h1> element - First level heading (most important)
814        ///
815        /// Example:
816        ///
817        /// ```<h1>Main Page Title</h1>```
818        h1 {
819        }
820
821        /// HTML <h2> element - Second level heading
822        ///
823        /// Example:
824        ///
825        /// ```<h2>Section Heading</h2>```
826        h2 {
827        }
828
829        /// HTML <h3> element - Third level heading
830        ///
831        /// Example:
832        ///
833        /// ```<h3>Subsection Heading</h3>```
834        h3 {
835        }
836
837        /// HTML <h4> element - Fourth level heading
838        ///
839        /// Example:
840        ///
841        /// ```<h4>Sub-subsection Heading</h4>```
842        h4 {
843        }
844
845        /// HTML <h5> element - Fifth level heading
846        ///
847        /// Example:
848        ///
849        /// ```<h5>Minor Heading</h5>```
850        h5 {
851        }
852
853        /// HTML <h6> element - Sixth level heading (least important)
854        ///
855        /// Example:
856        ///
857        /// ```<h6>Fine Detail Heading</h6>```
858        h6 {
859        }
860
861        /// HTML `<img>` element - Embeds an image into the document
862        ///
863        /// Example:
864        ///
865        /// ```<img src="image.jpg" alt="Description of image">```
866        img {
867            /// The src attribute specifies the URL/path to the image
868            /// Example: src="images/logo.png"
869            src: String,
870            /// The alt attribute provides alternative text for screen readers and if image fails to load
871            /// Example: alt="Company Logo"
872            alt: String,
873            /// The loading attribute indicates how the browser should load the image
874            /// Example: loading="lazy" (defers loading until it's near viewport)
875            loading: String,
876        }
877
878        /// HTML `<br>` element - Produces a line break in text
879        ///
880        /// Example:
881        ///
882        /// ```<br>```
883        br {}
884
885        /// HTML `<hr>` element - Creates a horizontal rule (divider)
886        ///
887        /// Example:
888        ///
889        /// ```<hr>```
890        hr {
891        }
892
893        /// HTML `<ul>` element - Unordered list with bullet points
894        ///
895        /// Example:
896        ///
897        /// ```<ul><li>Item 1</li><li>Item 2</li></ul>```
898        ul {
899            /// The type attribute specifies the bullet style (disc, circle, square)
900            /// Example: type="square"
901            type_: String,
902        }
903
904        /// HTML `<li>` element - List item within ordered or unordered lists
905        ///
906        /// Example:
907        ///
908        /// ```<li>List item content</li>```
909        li {
910            /// The value attribute specifies the start value of the list item (for ol)
911            /// Example: value="3" (starts this item at number 3)
912            value: Option<i32>,
913        }
914
915        /// HTML `<ol>` element - Ordered (numbered) list
916        ///
917        /// Example:
918        ///
919        /// ```<ol start="5" type="A"><li>Item E</li><li>Item F</li></ol>```
920        ol {
921            /// The type attribute specifies the numbering type (1, A, a, I, i)
922            /// Example: type="A" (uses capital letters)
923            type_: String,
924            /// The start attribute specifies the start value of the list
925            /// Example: start="5" (starts counting from 5)
926            start: i32,
927            /// The reversed attribute specifies that list should be in descending order
928            /// Example: reversed (counts down instead of up)
929            reversed: bool,
930        }
931
932        /// HTML `<table>` element - Creates a data table with rows and columns
933        ///
934        /// Example:
935        ///
936        /// ```<table border="1"><tr><th>Header</th></tr><tr><td>Data</td></tr></table>```
937        table {
938            /// The border attribute specifies the width of the border around the table
939            /// Example: border="1" (1 pixel border)
940            border: i32,
941            /// The cellpadding attribute specifies the space between cell content and borders
942            /// Example: cellpadding="5" (5 pixels of padding)
943            cellpadding: i32,
944            /// The cellspacing attribute specifies the space between cells
945            /// Example: cellspacing="2" (2 pixels between cells)
946            cellspacing: i32,
947        }
948
949        /// HTML `<tr>` element - Table row container
950        ///
951        /// Example:
952        ///
953        /// ```<tr><td>Cell 1</td><td>Cell 2</td></tr>```
954        tr {
955        }
956
957        /// HTML `<td>` element - Table data cell
958        ///
959        /// Example:
960        ///
961        /// ```<td colspan="2">This cell spans two columns</td>```
962        td {
963            /// The colspan attribute specifies how many columns a cell should span
964            /// Example: colspan="3" (cell spans 3 columns)
965            colspan: i32,
966            /// The rowspan attribute specifies how many rows a cell should span
967            /// Example: rowspan="2" (cell spans 2 rows)
968            rowspan: i32,
969            /// The headers attribute associates data cells with header cells
970            /// Example: headers="col1 row1" (associates with those header IDs)
971            headers: String,
972            /// The scope attribute specifies whether header cells are for rows or columns
973            /// Example: scope="col" (header applies to whole column)
974            scope: String,
975        }
976
977        /// HTML `<th>` element - Table header cell
978        ///
979        /// Example:
980        ///
981        /// ```<th scope="col">Column Header</th>```
982        th {
983            /// The colspan attribute specifies how many columns a cell should span
984            /// Example: colspan="3" (header spans 3 columns)
985            colspan: i32,
986            /// The rowspan attribute specifies how many rows a cell should span
987            /// Example: rowspan="2" (header spans 2 rows)
988            rowspan: i32,
989            /// The headers attribute associates data cells with header cells
990            /// Example: headers="col1 row1" (associates with those header IDs)
991            headers: String,
992            /// The scope attribute specifies whether the header cell is for a row, column, etc.
993            /// Example: scope="row" (header applies to whole row)
994            scope: String,
995        }
996
997        /// HTML `<tbody>` element - Groups body content in a table
998        ///
999        /// Example:
1000        ///
1001        /// ```<table><tbody><tr><td>Data</td></tr></tbody></table>```
1002        tbody {
1003        }
1004
1005        /// HTML `<thead>` element - Groups header content in a table
1006        ///
1007        /// Example:
1008        ///
1009        /// ```<table><thead><tr><th>Header</th></tr></thead><tbody>...</tbody></table>```
1010        thead {
1011        }
1012
1013        /// HTML `<tfoot>` element - Groups footer content in a table
1014        ///
1015        /// Example:
1016        ///
1017        /// ```<table><thead>...</thead><tbody>...</tbody><tfoot><tr><td>Summary</td></tr></tfoot></table>```
1018        tfoot {
1019        }
1020
1021        /// HTML `<form>` element - Container for interactive inputs to collect user data
1022        ///
1023        /// Example:
1024        ///
1025        /// ```<form action="/submit" method="post"><input type="text"><button type="submit">Submit</button></form>```
1026        form {
1027            /// The action attribute specifies where to send form data when submitted
1028            ///
1029            /// Example: action="/process-form.php"
1030            action: String,
1031            /// The method attribute specifies HTTP method for sending data (GET/POST)
1032            ///
1033            /// Example: method="post" (sends data in request body)
1034            method: String,
1035            /// The target attribute specifies where to display the response
1036            ///
1037            /// Example: target="_blank" (opens response in new tab)
1038            target: String,
1039            /// The enctype attribute specifies how form data should be encoded
1040            ///
1041            /// Example: enctype="multipart/form-data" (needed for file uploads)
1042            enctype: String,
1043            /// The novalidate attribute disables browser's built-in form validation
1044            ///
1045            /// Example: novalidate (skips validation)
1046            novalidate: bool,
1047            /// The autocomplete attribute controls browser autofill behavior
1048            ///
1049            /// Example: autocomplete="off" (disables autofill)
1050            autocomplete: String,
1051            /// The accept attribute specifies file types the server accepts (for file inputs)
1052            ///
1053            /// Example: accept=".jpg,.png" (accepts only those image formats)
1054            accept: String,
1055            /// Example: name="contact-form"
1056            name: String,
1057        }
1058
1059        /// HTML `<input>` element - Creates interactive controls for forms
1060        ///
1061        /// Example:
1062        ///
1063        /// ```<input type="text" placeholder="Enter your name" required>```
1064        input {
1065            /// The type attribute specifies the input type (text, password, email, etc.)
1066            ///
1067            /// Example: type="email" (validates as email address)
1068            type_: String,
1069            /// The placeholder attribute shows hint text when field is empty
1070            ///
1071            /// Example: placeholder="Enter your email"
1072            placeholder: String,
1073            /// The required attribute makes the field mandatory
1074            ///
1075            /// Example: required (field must be filled)
1076            required: bool,
1077            /// The value attribute specifies the default/current value
1078            ///
1079            /// Example: value="Default text"
1080            value: String,
1081            /// The name attribute specifies the name of the input (for form submission)
1082            ///
1083            /// Example: name="email"
1084            name: String,
1085            /// The disabled attribute disables the input
1086            ///
1087            /// Example: disabled (user cannot interact with input)
1088            disabled: bool,
1089            /// The readonly attribute makes the input read-only
1090            ///
1091            /// Example: readonly (user cannot modify but can focus/select)
1092            readonly: bool,
1093            /// The min attribute specifies minimum value for number/date inputs
1094            ///
1095            /// Example: min="1" (number input minimum value)
1096            min: String,
1097            /// The max attribute specifies maximum value for number/date inputs
1098            ///
1099            /// Example: max="100" (number input maximum value)
1100            max: String,
1101            /// The pattern attribute specifies a regex pattern for validation
1102            ///
1103            /// Example: pattern="[0-9]{3}" (requires exactly 3 digits)
1104            pattern: String,
1105            /// The autocomplete attribute controls browser autofill for this field
1106            ///
1107            /// Example: autocomplete="current-password"
1108            autocomplete: String,
1109        }
1110
1111        /// HTML `<textarea>` element - Multi-line text input control
1112        ///
1113        /// Example:
1114        ///
1115        /// ```<textarea rows="4" cols="50" placeholder="Your message here"></textarea>```
1116        textarea {
1117            /// The placeholder attribute shows hint text when field is empty
1118            /// Example: placeholder="Enter your comments"
1119            placeholder: String,
1120            /// The required attribute makes the field mandatory
1121            /// Example: required (must be filled before submission)
1122            required: bool,
1123            /// The value attribute specifies the default/current text content
1124            /// Example: value="Default text in the textarea"
1125            value: String,
1126            /// The rows attribute specifies visible number of text lines
1127            /// Example: rows="10" (shows 10 lines of text)
1128            rows: i32,
1129            /// The cols attribute specifies visible width in average characters
1130            /// Example: cols="40" (about 40 characters wide)
1131            cols: i32,
1132            /// The name attribute specifies the name of the textarea (for form submission)
1133            /// Example: name="comments"
1134            name: String,
1135            /// The disabled attribute disables the textarea
1136            /// Example: disabled (user cannot interact)
1137            disabled: bool,
1138            /// The readonly attribute makes the textarea read-only
1139            /// Example: readonly (user cannot modify but can focus/select)
1140            readonly: bool,
1141            /// The maxlength attribute specifies maximum character count
1142            /// Example: maxlength="500" (limits to 500 characters)
1143            maxlength: i32,
1144        }
1145
1146        /// HTML `<button>` element - Clickable button control
1147        ///
1148        /// Example:
1149        ///
1150        /// ```<button type="submit">Click Me</button>```
1151        button {
1152            /// The type attribute specifies button function (submit, reset, button)
1153            /// Example: type="submit" (submits the form)
1154            type_: String,
1155            /// The value attribute specifies the value associated with the button
1156            /// Example: value="btn1" (for form processing)
1157            value: String,
1158            /// The disabled attribute disables the button
1159            /// Example: disabled (button cannot be clicked)
1160            disabled: bool,
1161            /// The name attribute specifies the name of the button (for form submission)
1162            /// Example: name="submit-button"
1163            name: String,
1164            /// The formaction attribute overrides form's action for this button
1165            /// Example: formaction="/alternative-submit"
1166            formaction: String,
1167            /// The formmethod attribute overrides form's method for this button
1168            /// Example: formmethod="get"
1169            formmethod: String,
1170        }
1171
1172        /// HTML `<select>` element - Dropdown selection list
1173        ///
1174        /// Example:
1175        ///
1176        /// ```<select><option value="1">Option 1</option><option value="2">Option 2</option></select>```
1177        select {
1178            /// The multiple attribute allows selecting multiple options
1179            /// Example: multiple (user can select multiple items)
1180            multiple: bool,
1181            /// The disabled attribute disables the dropdown
1182            /// Example: disabled (user cannot interact)
1183            disabled: bool,
1184            /// The value attribute specifies the selected value
1185            /// Example: value="option2" (preselects this option)
1186            value: String,
1187            /// The name attribute specifies the name of the select (for form submission)
1188            /// Example: name="country"
1189            name: String,
1190            /// The size attribute specifies number of visible options
1191            /// Example: size="5" (shows 5 options at once)
1192            size: i32,
1193            /// The required attribute makes selection mandatory
1194            /// Example: required (user must select an option)
1195            required: bool,
1196        }
1197
1198        /// HTML `<option>` element - Defines option in a select dropdown
1199        ///
1200        /// Example:
1201        ///
1202        /// ```<option value="blue" selected>Blue</option>```
1203        option {
1204            /// The value attribute specifies the value to be sent to server
1205            /// Example: value="NY" (value sent when this option is selected)
1206            value: String,
1207            /// The selected attribute preselects this option when page loads
1208            /// Example: selected (this option is selected by default)
1209            selected: bool,
1210            /// The disabled attribute makes this option unselectable
1211            /// Example: disabled (cannot be chosen)
1212            disabled: bool,
1213        }
1214
1215        /// HTML `<label>` element - Caption for a form control
1216        ///
1217        /// Example:
1218        ///
1219        /// ```<label for="username">Username:</label><input id="username">```
1220        label {
1221            /// The for attribute connects the label to a form control by ID
1222            /// Example: for="email" (associates with input having id="email")
1223            for_: String,
1224        }
1225
1226        /// HTML `<iframe>` element - Embeds another document within the current HTML document
1227        ///
1228        /// Example:
1229        ///
1230        /// ```<iframe src="https://example.com" title="Example Site"></iframe>```
1231        iframe {
1232            /// The src attribute specifies the URL of the embedded document
1233            /// Example: src="https://maps.google.com"
1234            src: String,
1235            /// The frameborder attribute specifies whether to display a border
1236            /// Example: frameborder="0" (no border)
1237            frameborder: String,
1238            /// The allow attribute specifies features allowed in the iframe
1239            /// Example: allow="camera; microphone" (permits access to these devices)
1240            allow: String,
1241            /// The allowfullscreen attribute allows iframe content to go fullscreen
1242            /// Example: allowfullscreen (allows fullscreen mode)
1243            allowfullscreen: bool,
1244            /// The sandbox attribute restricts iframe capabilities for security
1245            /// Example: sandbox="allow-scripts" (only allows scripts to run)
1246            sandbox: String,
1247        }
1248
1249        /// HTML `<video>` element - Embeds video content in the document
1250        ///
1251        /// Example:
1252        ///
1253        /// ```<video src="movie.mp4" controls width="500">Video not supported</video>```
1254        video {
1255            /// The src attribute specifies URL/path of the video
1256            /// Example: src="videos/intro.mp4"
1257            src: String,
1258            /// The controls attribute displays video playback controls
1259            /// Example: controls (shows play/pause/volume controls)
1260            controls: bool,
1261            /// The autoplay attribute starts playing video automatically
1262            /// Example: autoplay (video plays when page loads)
1263            autoplay: bool,
1264            /// The loop attribute makes the video replay when finished
1265            /// Example: loop (continuously replays)
1266            loop_: bool,
1267            /// The poster attribute specifies an image shown before video plays
1268            /// Example: poster="thumbnail.jpg"
1269            poster: String,
1270            /// The muted attribute mutes the audio by default
1271            /// Example: muted (starts with no sound)
1272            muted: bool,
1273            /// The preload attribute hints how to preload the video
1274            /// Example: preload="auto" (preload entire video)
1275            preload: String,
1276            /// The playsinline attribute plays inline on iOS (instead of fullscreen)
1277            /// Example: playsinline (important for iPhone users)
1278            playsinline: bool,
1279        }
1280
1281        /// HTML `<audio>` element - Embeds sound content in the document
1282        ///
1283        /// Example:
1284        ///
1285        /// ```<audio src="song.mp3" controls>Audio not supported</audio>```
1286        audio {
1287            /// The src attribute specifies URL/path of the audio file
1288            /// Example: src="audio/background-music.mp3"
1289            src: String,
1290            /// The controls attribute displays audio playback controls
1291            /// Example: controls (shows play/pause/volume controls)
1292            controls: bool,
1293            /// The autoplay attribute starts playing audio automatically
1294            /// Example: autoplay (audio plays when page loads)
1295            autoplay: bool,
1296            /// The loop attribute makes the audio replay when finished
1297            /// Example: loop (continuously replays)
1298            loop_: bool,
1299            /// The muted attribute mutes the audio by default
1300            /// Example: muted (starts with no sound)
1301            muted: bool,
1302            /// The preload attribute hints how to preload the audio
1303            /// Example: preload="none" (doesn't preload)
1304            preload: String,
1305        }
1306
1307        /// HTML `<source>` element - Defines media resources for video/audio elements
1308        ///
1309        /// Example:
1310        ///
1311        /// ```<video><source src="movie.mp4" type="video/mp4"><source src="movie.webm" type="video/webm"></video>```
1312        source {
1313            /// The src attribute specifies URL/path of the media resource
1314            /// Example: src="audio/song.ogg"
1315            src: String,
1316            /// The type attribute specifies the MIME type of the resource
1317            /// Example: type="video/webm" (defines file format)
1318            type_: String,
1319            /// The media attribute specifies for which media the resource is intended
1320            /// Example: media="(min-width: 600px)" (responsive resources)
1321            media: String,
1322        }
1323
1324        /// HTML `<canvas>` element - Container for graphics rendered with JavaScript
1325        ///
1326        /// Example:
1327        ///
1328        /// ```<canvas id="myCanvas" width="200" height="100">Your browser does not support canvas</canvas>```
1329        canvas {
1330        }
1331
1332        /// HTML `<svg>` element - Container for SVG graphics
1333        ///
1334        /// Example:
1335        ///
1336        /// ```<svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="red" /></svg>```
1337        svg {
1338            /// The viewBox attribute defines coordinate system and aspect ratio
1339            /// Example: viewBox="0 0 800 600" (x, y, width, height)
1340            viewBox: String,
1341            /// The preserveAspectRatio attribute controls scaling behavior
1342            /// Example: preserveAspectRatio="xMidYMid meet" (center and scale)
1343            preserve_aspect_ratio: String,
1344            /// The xmlns attribute defines the XML namespace (required for standalone SVG)
1345            /// Example: xmlns="http://www.w3.org/2000/svg"
1346            xmlns: String,
1347            /// The fill attribute specifies the fill color
1348            /// Example: fill="#3498db" (blue fill)
1349            fill: String,
1350            /// The stroke attribute specifies the outline color
1351            /// Example: stroke="#e74c3c" (red outline)
1352            stroke: String,
1353            /// The stroke-width attribute specifies the width of the outline
1354            /// Example: stroke-width="3" (3 units thick)
1355            stroke_width: String,
1356            /// The stroke-linecap attribute specifies line end style
1357            /// Example: stroke-linecap="round" (rounded ends)
1358            stroke_linecap: String,
1359            /// The stroke-linejoin attribute specifies how line joins are rendered
1360            /// Example: stroke-linejoin="miter" (pointed corners)
1361            stroke_linejoin: String,
1362            /// The stroke-miterlimit attribute limits the length of miters
1363            /// Example: stroke-miterlimit="4" (limits pointy corners)
1364            stroke_miterlimit: String,
1365            /// The stroke-dasharray attribute creates dashed lines
1366            /// Example: stroke-dasharray="5,5" (5 units on, 5 units off)
1367            stroke_dasharray: String,
1368            /// The stroke-dashoffset attribute adjusts dash pattern start
1369            /// Example: stroke-dashoffset="10" (starts 10 units into pattern)
1370            stroke_dashoffset: String,
1371            /// The stroke-opacity attribute sets stroke transparency
1372            /// Example: stroke-opacity="0.5" (50% transparent)
1373            stroke_opacity: String,
1374            /// The fill-opacity attribute sets fill transparency
1375            /// Example: fill-opacity="0.7" (70% opaque)
1376            fill_opacity: String,
1377        }
1378
1379        /// HTML `<path>` element - Defines a path in SVG graphics
1380        ///
1381        /// Example:
1382        ///
1383        /// ```<path d="M10 10 H 90 V 90 H 10 Z" fill="transparent" stroke="black" />```
1384        path {
1385            /// The d attribute defines the path to be drawn
1386            /// Example: d="M20,20 L80,20 L80,80 L20,80 Z" (square path)
1387            d: String,
1388            /// The fill attribute specifies the fill color
1389            /// Example: fill="#3498db" (blue fill)
1390            fill: String,
1391            /// The stroke attribute specifies the outline color
1392            /// Example: stroke="#e74c3c" (red outline)
1393            stroke: String,
1394            /// The stroke-width attribute specifies the width of the outline
1395            /// Example: stroke-width="3" (3 units thick)
1396            stroke_width: String,
1397            /// The stroke-linecap attribute specifies line end style
1398            /// Example: stroke-linecap="round" (rounded ends)
1399            stroke_linecap: String,
1400            /// The stroke-linejoin attribute specifies how line joins are rendered
1401            /// Example: stroke-linejoin="miter" (pointed corners)
1402            stroke_linejoin: String,
1403            /// The stroke-miterlimit attribute limits the length of miters
1404            /// Example: stroke-miterlimit="4" (limits pointy corners)
1405            stroke_miterlimit: String,
1406            /// The stroke-dasharray attribute creates dashed lines
1407            /// Example: stroke-dasharray="5,5" (5 units on, 5 units off)
1408            stroke_dasharray: String,
1409            /// The stroke-dashoffset attribute adjusts dash pattern start
1410            /// Example: stroke-dashoffset="10" (starts 10 units into pattern)
1411            stroke_dashoffset: String,
1412            /// The stroke-opacity attribute sets stroke transparency
1413            /// Example: stroke-opacity="0.5" (50% transparent)
1414            stroke_opacity: String,
1415            /// The fill-opacity attribute sets fill transparency
1416            /// Example: fill-opacity="0.7" (70% opaque)
1417            fill_opacity: String,
1418        }
1419
1420        /// HTML `<rect>` element - Draws a rectangle in SVG
1421        ///
1422        /// Example:
1423        ///
1424        /// ```<rect x="10" y="10" width="100" height="50" fill="blue" />```
1425        rect {
1426            /// The x attribute specifies the x-coordinate of the rectangle
1427            /// Example: x="25" (25 units from the left)
1428            x: String,
1429            /// The y attribute specifies the y-coordinate of the rectangle
1430            /// Example: y="50" (50 units from the top)
1431            y: String,
1432            /// The rx attribute specifies the horizontal corner radius
1433            /// Example: rx="10" (rounded corners)
1434            rx: String,
1435            /// The ry attribute specifies the vertical corner radius
1436            /// Example: ry="10" (rounded corners)
1437            ry: String,
1438            /// The fill attribute specifies the fill color
1439            /// Example: fill="#2ecc71" (green fill)
1440            fill: String,
1441            /// The stroke attribute specifies the outline color
1442            /// Example: stroke="#27ae60" (darker green outline)
1443            stroke: String,
1444            /// The stroke-width attribute specifies the width of the outline
1445            /// Example: stroke-width="2" (2 units thick)
1446            stroke_width: String,
1447        }
1448
1449        /// HTML `<circle>` element - Draws a circle in SVG
1450        ///
1451        /// Example:
1452        ///
1453        /// ```<circle cx="50" cy="50" r="40" fill="red" />```
1454        circle {
1455            /// The cx attribute specifies the x-coordinate of the center
1456            /// Example: cx="100" (center x at 100 units)
1457            cx: String,
1458            /// The cy attribute specifies the y-coordinate of the center
1459            /// Example: cy="100" (center y at 100 units)
1460            cy: String,
1461            /// The r attribute specifies the radius of the circle
1462            /// Example: r="75" (75 units radius)
1463            r: String,
1464            /// The fill attribute specifies the fill color
1465            /// Example: fill="#9b59b6" (purple fill)
1466            fill: String,
1467            /// The stroke attribute specifies the outline color
1468            /// Example: stroke="#8e44ad" (darker purple outline)
1469            stroke: String,
1470            /// The stroke-width attribute specifies the width of the outline
1471            /// Example: stroke-width="3" (3 units thick)
1472            stroke_width: String,
1473        }
1474
1475        /// HTML `<ellipse>` element - Draws an ellipse in SVG
1476        ///
1477        /// Example:
1478        ///
1479        /// ```<ellipse cx="100" cy="50" rx="100" ry="50" fill="yellow" />```
1480        ellipse {
1481            /// The cx attribute specifies the x-coordinate of the center
1482            /// Example: cx="150" (center x at 150 units)
1483            cx: String,
1484            /// The cy attribute specifies the y-coordinate of the center
1485            /// Example: cy="75" (center y at 75 units)
1486            cy: String,
1487            /// The rx attribute specifies the horizontal radius
1488            /// Example: rx="100" (100 units horizontal radius)
1489            rx: String,
1490            /// The ry attribute specifies the vertical radius
1491            /// Example: ry="50" (50 units vertical radius)
1492            ry: String,
1493            /// The fill attribute specifies the fill color
1494            /// Example: fill="#f1c40f" (yellow fill)
1495            fill: String,
1496            /// The stroke attribute specifies the outline color
1497            /// Example: stroke="#f39c12" (darker yellow outline)
1498            stroke: String,
1499            /// The stroke-width attribute specifies the width of the outline
1500            /// Example: stroke-width="2" (2 units thick)
1501            stroke_width: String,
1502        }
1503
1504        /// HTML `<line>` element - Draws a line in SVG
1505        ///
1506        /// Example:
1507        ///
1508        /// ```<line x1="0" y1="0" x2="100" y2="100" stroke="black" />```
1509        line {
1510            /// The x1 attribute specifies the x-coordinate of the start point
1511            /// Example: x1="10" (starts 10 units from left)
1512            x1: String,
1513            /// The y1 attribute specifies the y-coordinate of the start point
1514            /// Example: y1="10" (starts 10 units from top)
1515            y1: String,
1516            /// The x2 attribute specifies the x-coordinate of the end point
1517            /// Example: x2="200" (ends 200 units from left)
1518            x2: String,
1519            /// The y2 attribute specifies the y-coordinate of the end point
1520            /// Example: y2="200" (ends 200 units from top)
1521            y2: String,
1522            /// The stroke attribute specifies the line color
1523            /// Example: stroke="#34495e" (dark blue line)
1524            stroke: String,
1525            /// The stroke-width attribute specifies the width of the line
1526            /// Example: stroke-width="5" (5 units thick)
1527            stroke_width: String,
1528            /// The stroke-linecap attribute specifies line end style
1529            /// Example: stroke-linecap="round" (rounded ends)
1530            stroke_linecap: String,
1531            /// The stroke-dasharray attribute creates dashed lines
1532            /// Example: stroke-dasharray="10,5" (10 units on, 5 units off)
1533            stroke_dasharray: String,
1534        }
1535
1536        /// HTML `<polyline>` element - Draws connected straight lines in SVG
1537        ///
1538        /// Example:
1539        ///
1540        /// ```<polyline points="20,20 40,25 60,40 80,120 120,140 200,180" stroke="orange" fill="none" />```
1541        polyline {
1542            /// The points attribute specifies coordinates for each point
1543            /// Example: points="0,0 50,50 100,25" (series of x,y pairs)
1544            points: String,
1545            /// The fill attribute specifies the fill color between lines
1546            /// Example: fill="none" (transparent fill)
1547            fill: String,
1548            /// The stroke attribute specifies the line color
1549            /// Example: stroke="#e67e22" (orange line)
1550            stroke: String,
1551            /// The stroke-width attribute specifies the width of the lines
1552            /// Example: stroke-width="3" (3 units thick)
1553            stroke_width: String,
1554            /// The stroke-linejoin attribute specifies how lines are joined
1555            /// Example: stroke-linejoin="round" (rounded corners)
1556            stroke_linejoin: String,
1557        }
1558
1559        /// HTML `<polygon>` element - Draws a closed shape with straight lines in SVG
1560        ///
1561        /// Example:
1562        ///
1563        /// ```<polygon points="200,10 250,190 160,210" fill="green" />```
1564        polygon {
1565            /// The points attribute specifies coordinates for each point
1566            /// Example: points="50,50 150,50 100,150" (triangle coordinates)
1567            points: String,
1568            /// The fill attribute specifies the fill color of the shape
1569            /// Example: fill="#1abc9c" (teal fill)
1570            fill: String,
1571            /// The stroke attribute specifies the outline color
1572            /// Example: stroke="#16a085" (darker teal outline)
1573            stroke: String,
1574            /// The stroke-width attribute specifies the width of the outline
1575            /// Example: stroke-width="2" (2 units thick)
1576            stroke_width: String,
1577            /// The fill-rule attribute specifies how to fill shapes with holes
1578            /// Example: fill-rule="evenodd" (alternates fill for nested shapes)
1579            fill_rule: String,
1580        }
1581
1582        /// HTML `<g>` element - Groups SVG elements together
1583        ///
1584        /// Example:
1585        ///
1586        /// ```<g transform="rotate(45 50 50)"><rect x="20" y="20" width="60" height="60" /></g>```
1587        g {
1588            /// The transform attribute applies transformations to the group
1589            /// Example: transform="translate(100,50) scale(2)" (moves and scales)
1590            transform: String,
1591            /// The fill attribute specifies the fill color for all elements in the group
1592            /// Example: fill="#3498db" (blue fill for all children)
1593            fill: String,
1594            /// The stroke attribute specifies the outline color for all elements in the group
1595            /// Example: stroke="#2980b9" (darker blue outline for all children)
1596            stroke: String,
1597        }
1598
1599        /// HTML `<use>` element - Reuses an SVG element defined elsewhere
1600        ///
1601        /// Example:
1602        ///
1603        /// ```<r#use href="#myCircle" x="10" y="10" fill="blue" />```
1604        r#use {
1605            /// The href attribute specifies which element to reuse
1606            /// Example: href="#icon-star" (references element with id="icon-star")
1607            href: String,
1608            /// The x attribute specifies the x-coordinate where to place the reused element
1609            /// Example: x="100" (100 units from left)
1610            x: String,
1611            /// The y attribute specifies the y-coordinate where to place the reused element
1612            /// Example: y="50" (50 units from top)
1613            y: String,
1614        }
1615
1616        /// HTML <foreignObject> element - Includes non-SVG elements inside SVG
1617        ///
1618        /// Example:
1619        ///
1620        /// ```<foreignObject x="20" y="20" width="160" height="160"><div>HTML content inside SVG</div></foreignObject>```
1621        foreignObject {
1622            /// The x attribute specifies the x-coordinate of the foreign object
1623            /// Example: x="25" (25 units from left)
1624            x: String,
1625            /// The y attribute specifies the y-coordinate of the foreign object
1626            /// Example: y="25" (25 units from top)
1627            y: String,
1628        }
1629
1630        /// HTML `<defs>` element - Container for reusable SVG elements
1631        ///
1632        /// Example:
1633        ///
1634        /// ```<defs><circle id="myCircle" cx="5" cy="5" r="4" /></defs>```
1635        defs {
1636        }
1637
1638        /// HTML <linearGradient> element - Defines a linear gradient for SVG fills
1639        ///
1640        /// Example:
1641        ///
1642        /// ```<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" style="stop-color:rgb(255,255,0)" /></linearGradient>```
1643        linearGradient {
1644            /// The x1 attribute defines the start point of the gradient (x-coordinate)
1645            /// Example: x1="0%" (starts at left edge)
1646            x1: String,
1647            /// The y1 attribute defines the start point of the gradient (y-coordinate)
1648            /// Example: y1="0%" (starts at top edge)
1649            y1: String,
1650            /// The x2 attribute defines the end point of the gradient (x-coordinate)
1651            /// Example: x2="100%" (ends at right edge)
1652            x2: String,
1653            /// The y2 attribute defines the end point of the gradient (y-coordinate)
1654            /// Example: y2="100%" (ends at bottom edge)
1655            y2: String,
1656            /// The gradientUnits attribute defines the coordinate system for the gradient
1657            /// Example: gradientUnits="userSpaceOnUse" (uses absolute coordinates)
1658            gradientUnits: String,
1659            /// The spreadMethod attribute defines how the gradient fills beyond its bounds
1660            /// Example: spreadMethod="reflect" (gradient reflects at boundaries)
1661            spreadMethod: String,
1662        }
1663
1664        /// HTML `<stop>` element - Defines color transitions in gradients
1665        ///
1666        /// Example:
1667        ///
1668        /// ```<stop offset="0%" style="stop-color:rgb(255,0,0);stop-opacity:1" />```
1669        stop {
1670            /// The offset attribute defines where along the gradient this color appears
1671            /// Example: offset="50%" (color positioned halfway through gradient)
1672            offset: String,
1673            /// The stop-color attribute defines the color at this stop
1674            /// Example: stop-color="#3498db" (blue color)
1675            stop_color: String,
1676            /// The stop-opacity attribute defines the opacity at this stop
1677            /// Example: stop-opacity="0.5" (50% transparent)
1678            stop_opacity: String,
1679        }
1680
1681        /// HTML <radialGradient> element - Defines a radial gradient for SVG fills
1682        ///
1683        /// Example:
1684        ///
1685        /// ```<radialGradient id="grad2" cx="50%" cy="50%" r="50%"><stop offset="0%" style="stop-color:red" /></radialGradient>```
1686        radialGradient {
1687            /// The cx attribute defines the x-coordinate of the center point
1688            /// Example: cx="50%" (center of the area horizontally)
1689            cx: String,
1690            /// The cy attribute defines the y-coordinate of the center point
1691            /// Example: cy="50%" (center of the area vertically)
1692            cy: String,
1693            /// The r attribute defines the radius of the gradient
1694            /// Example: r="75%" (extends to 75% of the reference area)
1695            r: String,
1696            /// The fx attribute defines the x-coordinate of the focal point
1697            /// Example: fx="60%" (focal point slightly right of center)
1698            fx: String,
1699            /// The fy attribute defines the y-coordinate of the focal point
1700            /// Example: fy="40%" (focal point slightly above center)
1701            fy: String,
1702            /// The fr attribute defines the radius of the focal point
1703            /// Example: fr="5%" (small focal point)
1704            fr: String,
1705            /// The gradientUnits attribute defines the coordinate system for the gradient
1706            /// Example: gradientUnits="objectBoundingBox" (relative to object)
1707            gradientUnits: String,
1708            /// The spreadMethod attribute defines how the gradient fills beyond its bounds
1709            /// Example: spreadMethod="pad" (uses edge color beyond boundaries)
1710            spreadMethod: String,
1711        }
1712
1713        /// HTML `<mask>` element - Defines an area where SVG elements are partially or fully hidden
1714        ///
1715        /// Example:
1716        ///
1717        /// ```<mask id="myMask"><rect width="100%" height="100%" fill="white" opacity="0.5" /></mask>```
1718        mask {
1719            /// The maskUnits attribute specifies the coordinate system for mask positioning
1720            /// Example: maskUnits="userSpaceOnUse" (absolute coordinates)
1721            mask_units: String,
1722            /// The maskContentUnits attribute specifies the coordinate system for mask content
1723            /// Example: maskContentUnits="objectBoundingBox" (relative to object)
1724            mask_content_units: String,
1725            /// The x attribute specifies the x-coordinate of the mask
1726            /// Example: x="0" (starts at left edge)
1727            x: String,
1728            /// The y attribute specifies the y-coordinate of the mask
1729            /// Example: y="0" (starts at top edge)
1730            y: String,
1731        }
1732        /// HTML `<article>` element - Defines an independent, self-contained content
1733        ///
1734        /// Example:
1735        ///
1736        /// ```<article><h1>Article Title</h1><p>Article content goes here...</p></article>```
1737        article {
1738        }
1739
1740        /// HTML `<aside>` element - Defines content aside from the page content
1741        ///
1742        /// Example:
1743        ///
1744        /// ```<aside><p>Sidebar content goes here...</p></aside>```
1745        aside {
1746        }
1747
1748        /// HTML `<details>` element - Defines additional details that the user can view or hide
1749        ///
1750        /// Example:
1751        ///
1752        /// ```<details><summary>Click to view details</summary><p>Details content goes here...</p></details>```
1753        details {
1754        }
1755
1756        /// HTML `<figcaption>` element - Defines a caption for a `<figure>` element
1757        ///
1758        /// Example:
1759        ///
1760        /// ```<figure><img src="image.jpg" alt="Image description" /><figcaption>Caption goes here...</figcaption></figure>```
1761        figcaption {
1762        }
1763
1764        /// HTML `<figure>` element - Specifies self-contained content, like illustrations, diagrams, photos, code listings, etc.
1765        ///
1766        /// Example:
1767        ///
1768        /// ```<figure><img src="image.jpg" alt="Image description" /><figcaption>Caption goes here...</figcaption></figure>```
1769        figure {
1770        }
1771
1772        /// HTML `<footer>` element - Defines a footer for a document or section
1773        ///
1774        /// Example:
1775        ///
1776        /// ```<footer><p>Footer content goes here...</p></footer>```
1777        footer {
1778        }
1779
1780        /// HTML `<header>` element - Defines a container for introductory content or a set of navigational links
1781        ///
1782        /// Example:
1783        ///
1784        /// ```<header><h1>Header content goes here...</h1></header>```
1785        header {
1786        }
1787
1788        /// HTML `<main>` element - Specifies the main content of a document
1789        ///
1790        /// Example:
1791        ///
1792        /// ```<main><p>Main content goes here...</p></main>```
1793        main {
1794        }
1795
1796        /// HTML `<mark>` element - Defines marked/highlighted text
1797        ///
1798        /// Example:
1799        ///
1800        /// ```<p>Some <mark>marked</mark> text.</p>```
1801        mark {
1802        }
1803
1804        /// HTML `<nav>` element - Defines navigation links
1805        ///
1806        /// Example:
1807        ///
1808        /// ```<nav><a href="#home">Home</a> <a href="#about">About</a> <a href="#contact">Contact</a></nav>```
1809        nav {
1810        }
1811
1812        /// HTML `<section>` element - Defines a section in a document
1813        ///
1814        /// Example:
1815        ///
1816        /// ```<section><h2>Section Title</h2><p>Section content goes here...</p></section>```
1817        section {
1818        }
1819
1820        /// HTML `<summary>` element - Defines a visible heading for a `<details>` element
1821        ///
1822        /// Example:
1823        ///
1824        /// ```<details><summary>Click to view details</summary><p>Details content goes here...</p></details>```
1825        summary {
1826        }
1827
1828        /// HTML `<time>` element - Defines a date/time
1829        ///
1830        /// Example:
1831        ///
1832        /// ```<p>Published on <time datetime="2023-08-01">August 1, 2023</time></p>```
1833        time {
1834            /// The datetime attribute specifies the date/time
1835            /// Example: datetime="2023-08-01" (August 1, 2023)
1836            datetime: String,
1837            /// The pubdate attribute specifies that the content is published
1838            /// Example: pubdate="pubdate" (content is published)
1839            pubdate: String,
1840        }
1841
1842        /// HTML `<wbr>` element - Inserts a line break opportunity
1843        ///
1844        /// Example:
1845        ///
1846        /// ```<p>Here is a long word:<wbr>supercalifragilisticexpialidocious</p>```
1847        wbr {
1848        }
1849
1850        /// HTML `<address>` element - Defines contact information for the author/owner of a document
1851        ///
1852        /// Example:
1853        ///
1854        /// ```<address>Contact us at <a href="mailto:="mail="mailto:EMAIL"EMAILample.com</a></address>```
1855        address {
1856        }
1857
1858        /// HTML `<bdi>` element - Defines a term/name within a description list
1859        ///
1860        /// Example:
1861        ///
1862        /// ```<dl><dt><bdi>Name</bdi></dt><dd>John Doe</dd></dl>```
1863        bdi {
1864        }
1865
1866        /// HTML `<bdo>` element - Overrides the current text direction
1867        ///
1868        /// Example:
1869        ///
1870        /// ```<p><bdo dir="rtl">This text is written from right to left</bdo></p>```
1871        bdo {
1872        }
1873
1874        /// HTML `<cite>` element - Defines the title of a work
1875        ///
1876        /// Example:
1877        ///
1878        /// ```<p>To learn more about <cite>HTML</cite>, visit <a href="```<p>To learn more about <cite>HTML</cite>, visit <a href="URL_ADDRESS.w3.org/TR/html52/">W3C</a>.</p>```
1879        cite {
1880        }
1881
1882        /// HTML `<dfn>` element - Defines a definition
1883        ///
1884        /// Example:
1885        ///
1886        /// ```<p>The <dfn>HTML</dfn> element is used to define a section in a document.</p>```
1887        dfn {
1888        }
1889
1890        /// HTML `<em>` element - Defines emphasized text
1891        ///
1892        /// Example:
1893        ///
1894        /// ```<p>He is <em>very</em> angry.</p>```
1895        em {
1896        }
1897
1898        /// HTML `<i>` element - Defines a part of text in an alternate voice or mood
1899        ///
1900        /// Example:
1901        ///
1902        /// ```<p><i>This text is in italics.</i></p>```
1903        i {
1904        }
1905
1906        /// HTML `<kbd>` element - Defines keyboard input
1907        ///
1908        /// Example:
1909        ///
1910        /// ```<p>Press <kbd>Ctrl</kbd> + <kbd>C</kbd> to copy.</p>```
1911        kbd {
1912        }
1913
1914        /// HTML `<meter>` element - Defines a scalar measurement within a known range (a gauge)
1915        ///
1916        /// Example:
1917        ///
1918        /// ```<meter value="75" min="0" max="100"></meter>```
1919        meter {
1920            /// The value attribute specifies the current value
1921            /// Example: value="75" (current value is 75)
1922            value: String,
1923            /// The min attribute specifies the minimum value
1924            /// Example: min="0" (minimum value is 0)
1925            min: String,
1926            /// The max attribute specifies the maximum value
1927            /// Example: max="100" (maximum value is 100)
1928            max: String,
1929            /// The low attribute specifies the low value
1930            /// Example: low="33" (low value is 33)
1931            low: String,
1932            /// The high attribute specifies the high value
1933            /// Example: high="66" (high value is 66)
1934            high: String,
1935            /// The optimum attribute specifies the optimum value
1936            /// Example: optimum="50" (optimum value is 50)
1937            optimum: String,
1938        }
1939
1940        /// HTML `<output>` element - Defines the result of a calculation
1941        ///
1942        /// Example:
1943        ///
1944        /// ```<form><input type="number" id="num1" /><input type="number" id="num2" /><button onclick="calculate()">Calculate</button><output id="result"></output></form>```
1945        output {
1946        }
1947
1948        /// HTML `<progress>` element - Defines the progress of a task
1949        ///
1950        /// Example:
1951        ///
1952        /// ```<progress value="75" max="100"></progress>```
1953        progress {
1954            /// The value attribute specifies the current value
1955            /// Example: value="75" (current value is 75)
1956            value: String,
1957            /// The max attribute specifies the maximum value
1958            /// Example: max="100" (maximum value is 100)
1959            max: String,
1960        }
1961
1962        /// HTML `<q>` element - Defines a short inline quotation
1963        ///
1964        /// Example:
1965        ///
1966        /// ```<p><q>We are the so-called "Vikings" from the north.</q></p>```
1967        q {
1968        }
1969
1970        /// HTML `<rp>` element - Defines a parenthesis for browsers that do not support `<ruby>`
1971        ///
1972        /// Example:
1973        ///
1974        /// ```<ruby><rb>漢</rb><rp>(</rp><rt>han</rt><rp>)</rp></ruby>```
1975        rp {
1976        }
1977
1978        /// HTML `<rt>` element - Defines a ruby text
1979        ///
1980        /// Example:
1981        ///
1982        /// ```<ruby><rb>漢</rb><rt>han</rt></ruby>```
1983        rt {
1984        }
1985
1986        /// HTML `<ruby>` element - Defines a ruby annotation (for East Asian typography)
1987        ///
1988        /// Example:
1989        ///
1990        /// ```<ruby><rb>漢</rb><rt>han</rt></ruby>```
1991        ruby {
1992        }
1993
1994        /// HTML `<s>` element - Defines strikethrough text
1995        ///
1996        /// Example:
1997        ///
1998        /// ```<p>Price: <s>$100</s> $50</p>```
1999        s {
2000        }
2001
2002        /// HTML `<samp>` element - Defines sample output from a computer program
2003        ///
2004        /// Example:
2005        ///
2006        /// ```<samp>Hello, World!</samp>```
2007        samp {
2008        }
2009
2010        /// HTML `<small>` element - Defines smaller text
2011        ///
2012        /// Example:
2013        ///
2014        /// ```<p><small>This is some smaller text.</small></p>```
2015        small {
2016        }
2017
2018        /// HTML `<strong>` element - Defines important text
2019        ///
2020        /// Example:
2021        ///
2022        /// ```<p><strong>This is important!</strong></p>```
2023        strong {
2024        }
2025
2026        /// HTML `<sub>` element - Defines subscript text
2027        ///
2028        /// Example:
2029        ///
2030        /// ```<p>H<sub>2</sub>O</p>```
2031        sub {
2032        }
2033
2034        /// HTML `<sup>` element - Defines superscript text
2035        ///
2036        /// Example:
2037        ///
2038        /// ```<p>X<sup>2</sup></p>```
2039        sup {
2040        }
2041
2042        /// HTML `<var>` element - Defines a variable
2043        ///
2044        /// Example:
2045        ///
2046        /// ```<p>The area is <var>x</var> times <var>y</var>.</p>```
2047        var {
2048        }
2049
2050        /// HTML `<template>` element - Defines a container for content that is not to be rendered when a page is loaded
2051        ///
2052        /// Example:
2053        ///
2054        /// ```<template><p>This content will not be rendered.</p></template>```
2055        template {
2056        }
2057
2058        /// HTML `<u>` element - Defines text that should be rendered as underlined
2059        ///
2060        /// Example:
2061        ///
2062        /// ```<p><u>This text is underlined.</u></p>```
2063        u {
2064        }
2065
2066        /// HTML `<noscript>` element - Defines content that is displayed to users with disabled scripts
2067        ///
2068        /// Example:
2069        ///
2070        /// ```<noscript><p>JavaScript is disabled.</p></noscript>```
2071        noscript {
2072        }
2073
2074        /// HTML `<legend>` element - Defines a caption for a `<fieldset>` element
2075        ///
2076        /// Example:
2077        ///
2078        /// ```<fieldset><legend>Personal Information</legend><input type="text" name="name" /><input type="email" name="email" /></fieldset>```
2079        legend {
2080        }
2081
2082        /// HTML `<optgroup>` element - Defines a group of related `<option>` elements in a `<select>` element
2083        ///
2084        /// Example:
2085        ///
2086        /// ```<select><optgroup label="Fruits"><option value="apple">Apple</option><option value="banana">Banana</option></optgroup><optgroup label="Vegetables"><option value="carrot">Carrot</option><option value="potato">Potato</option></optgroup></select>```
2087        optgroup {
2088            /// The label attribute specifies a label for the group
2089            /// Example: label="Fruits" (label for the group is "Fruits")
2090            label: String,
2091        }
2092
2093        /// HTML `<dialog>` element - Defines a dialog box or other interactive component
2094        ///
2095        /// Example:
2096        ///
2097        /// ```<dialog><p>Dialog content goes here...</p><button onclick="closeDialog()">Close</button></dialog>```
2098        dialog {
2099            /// The open attribute specifies whether the dialog is open or closed
2100            /// Example: open="open" (dialog is open)
2101            open: String,
2102        }
2103
2104        /// HTML `<blockquote>` element - Defines a section that is quoted from another source
2105        ///
2106        /// Example:
2107        ///
2108        /// ```<blockquote><p>This is a quote.</p><footer>- John Doe</footer></blockquote>```
2109        blockquote {
2110        }
2111
2112        /// HTML `<dd>` element - Defines a description/value pair within a `<dl>` element
2113        ///
2114        /// Example:
2115        ///
2116        /// ```<dl><dt>Coffee</dt><dd>Black hot drink</dd><dt>Milk</dt><dd>White cold drink</dd></dl>```
2117        dd {
2118        }
2119
2120        /// HTML `<dl>` element - Defines a description list
2121        ///
2122        /// Example:
2123        ///
2124        /// ```<dl><dt>Coffee</dt><dd>Black hot drink</dd><dt>Milk</dt><dd>White cold drink</dd></dl>```
2125        dl {
2126        }
2127
2128        /// HTML `<dt>` element - Defines a term/name in a description list
2129        ///
2130        /// Example:
2131        ///
2132        /// ```<dl><dt>Coffee</dt><dd>Black hot drink</dd><dt>Milk</dt><dd>White cold drink</dd></dl>```
2133        dt {
2134        }
2135
2136        /// HTML `<base>` element - Specifies the base URL/target for all relative URLs in a document
2137        ///
2138        /// Example:
2139        ///
2140        /// ```<base href="```<base href="URL_ADDRESS.example.com/" target="_blank">```
2141        base {
2142            /// The href attribute specifies the base URL
2143            /// ```<base href="URL_ADDR```<base href="URL_ADDRESS.example.com/" target="_blank">```
2144            href: String,
2145            /// The target attribute specifies the target for all relative URLs
2146            /// ```<base href="URL_ADDRESS.example.com/" target="_blank">```
2147            target: String,
2148        }
2149    }
2150}