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(&mut self, 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 None => 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 // ARIA Accessibility attributes
506
507 /// Identifies the current element within a set
508 pub aria_current: String,
509
510 /// Defines a string value that labels the current element
511 pub aria_label: Option<String>,
512
513 /// Identifies the element that labels the current element
514 pub aria_labelledby: Option<String>,
515
516 /// Identifies the element that describes the current element
517 pub aria_describedby: Option<String>,
518
519 /// Indicates whether an element is expanded or collapsed
520 pub aria_expanded: bool,
521
522 /// Indicates the element that represents the current item within a container or set
523 pub aria_selected: bool,
524
525 /// Indicates whether the element is checked, unchecked, or represents mixed mode
526 pub aria_checked: String,
527
528 /// Indicates whether an element and its subtree are hidden
529 pub aria_hidden: bool,
530
531 /// Indicates the availability and type of interactive popup element
532 pub aria_haspopup: String,
533
534 /// Defines an element's role
535 pub aria_role: String,
536
537 // Element specific attributes
538 $(
539 pub $attr_name: $attr_value,
540 )*
541 }
542
543 impl [<HTML $tag:camel Element Props>] {
544 fn to_attributes(&self) -> IndexMap<String, String> {
545 #[allow(unused_mut)]
546 let mut attributes = IndexMap::new();
547 $(
548 if !self.$attr_name.value().is_empty() {
549 let mut key = stringify!($attr_name);
550 if let Some(last_char) = key.chars().last() {
551 if last_char == '_' {
552 key = &key[..key.len() - 1];
553 }
554 }
555 attributes.insert(key.replace('_', "-"), self.$attr_name.value());
556 }
557 )*
558 if !self.id.value().is_empty() {
559 attributes.insert("id".to_string(), self.id.value());
560 }
561 if !self.class.value().is_empty() {
562 attributes.insert("class".to_string(), self.class.value());
563 }
564 if !self.style.value().is_empty() {
565 attributes.insert("style".to_string(), self.style.value());
566 }
567 if !self.title.value().is_empty() {
568 attributes.insert("title".to_string(), self.title.value());
569 }
570 if self.draggable {
571 attributes.insert("draggable".to_string(), "true".to_string());
572 }
573 if self.hidden {
574 attributes.insert("hidden".to_string(), "true".to_string());
575 }
576 if !self.accesskey.value().is_empty() {
577 attributes.insert("accesskey".to_string(), self.accesskey.value());
578 }
579 if self.contenteditable {
580 attributes.insert("contenteditable".to_string(), "true".to_string());
581 }
582 if !self.dir.value().is_empty() {
583 attributes.insert("dir".to_string(), self.dir.value());
584 }
585 if let Some(tabindex) = self.tabindex {
586 attributes.insert("tabindex".to_string(), tabindex.to_string());
587 }
588 if self.spellcheck {
589 attributes.insert("spellcheck".to_string(), "true".to_string());
590 }
591 if !self.lang.value().is_empty() {
592 attributes.insert("lang".to_string(), self.lang.value());
593 }
594 if self.translate {
595 attributes.insert("translate".to_string(), "true".to_string());
596 }
597 if !self.autocapitalize.value().is_empty() {
598 attributes.insert("autocapitalize".to_string(), self.autocapitalize.value());
599 }
600 if !self.role.value().is_empty() {
601 attributes.insert("role".to_string(), self.role.value());
602 }
603 if !self.aria_current.value().is_empty() {
604 attributes.insert("aria-current".to_string(), self.aria_current.value());
605 }
606 if !self.aria_label.value().is_empty() {
607 attributes.insert("aria-label".to_string(), self.aria_label.value());
608 }
609 if !self.aria_labelledby.value().is_empty() {
610 attributes.insert("aria-labelledby".to_string(), self.aria_labelledby.value());
611 }
612 if !self.aria_describedby.value().is_empty() {
613 attributes.insert("aria-describedby".to_string(), self.aria_describedby.value());
614 }
615 if self.aria_expanded {
616 attributes.insert("aria-expanded".to_string(), "true".to_string());
617 }
618 if self.aria_selected {
619 attributes.insert("aria-selected".to_string(), "true".to_string());
620 }
621 if !self.aria_checked.value().is_empty() {
622 attributes.insert("aria-checked".to_string(), self.aria_checked.value());
623 }
624 if self.aria_hidden {
625 attributes.insert("aria-hidden".to_string(), "true".to_string());
626 }
627 if !self.aria_haspopup.value().is_empty() {
628 attributes.insert("aria-haspopup".to_string(), self.aria_haspopup.value());
629 }
630 if !self.aria_role.value().is_empty() {
631 attributes.insert("aria-role".to_string(), self.aria_role.value());
632 }
633
634 attributes
635 }
636 }
637
638 impl Component for $tag {
639 type Props = [<HTML $tag:camel Element Props>];
640
641 fn render(props: Self::Props) -> Node {
642 Node::Element(Element {
643 tag: stringify!($tag).to_string(),
644 attributes: props.to_attributes(),
645 children: props.children,
646 })
647 }
648 }
649 }
650 )*
651 };
652}
653
654pub mod elements {
655 use super::*;
656 derive_elements! {
657 /// HTML `<html>` element - Root element of an HTML document
658 html {
659 }
660 /// HTML `<body>` element - Represents the content of an HTML document
661 ///
662 /// Example:
663 ///
664 /// ```<body>Content goes here</body>```
665 body {
666 }
667 /// HTML `<head>` element - Contains metadata about the document
668 ///
669 /// Example:
670 ///
671 /// ```<head><title>Document Title</title></head>```
672 head {
673 }
674 /// HTML `<title>` element - Defines the title of the document
675 ///
676 /// Example:
677 ///
678 /// ```<title>Document Title</title>```
679 title {
680 }
681 /// HTML `<meta` element - Provides metadata about the document
682 ///
683 /// Example:
684 ///
685 /// ```<meta charset="UTF-8">```
686 meta {
687 /// The character encoding of the document
688 charset: String,
689 /// The HTTP response status code
690 http_equiv: String,
691 /// The content of the document
692 content: String,
693 /// The name of the metadata
694 name: String,
695 /// The property of the metadata
696 property: String,
697 }
698 /// HTML `<style>` element - Defines style information for a document
699 ///
700 /// Example:
701 ///
702 /// ```<style>body { background-color: #f0f0f0; }</style>```
703 style {
704 }
705 /// HTML `<script>` element - Embeds executable code or data
706 ///
707 /// Example:
708 ///
709 /// ```<script src="script.js"></script>```
710 script {
711 /// The URL of the external script file
712 src: String,
713 /// The type of the script
714 type_: String,
715 /// The language of the script
716 language: String,
717 /// The character encoding of the script
718 charset: String,
719 /// The defer attribute specifies that the script will be executed after the document is finished parsing
720 defer: bool,
721 /// The async attribute specifies that the script will be executed asynchronously
722 async_: bool,
723 }
724 /// HTML `<link>` element - Specifies relationships between the current document and an external resource
725 ///
726 /// Example:
727 ///
728 /// ```<link rel="stylesheet" href="style.css">```
729 link {
730 /// The relationship between the current document and the linked resource
731 rel: String,
732 /// The URL of the linked resource
733 href: String,
734 /// The type of the linked resource
735 type_: String,
736 /// The character encoding of the linked resource
737 charset: String,
738 /// crossorigin attribute specifies that the element will request a cross-origin Isolation of its browsing context
739 crossorigin: String,
740 /// The referrerpolicy attribute specifies the referrer policy for the linked resource
741 referrerpolicy: String,
742 }
743 /// HTML `<div>` element - Container element for grouping and styling content
744 ///
745 /// Example:
746 ///
747 /// ```<div class="container">Content goes here</div>```
748 div {
749 }
750
751 /// HTML `<p>` element - Represents a paragraph of text
752 ///
753 /// Example:
754 ///
755 /// ```<p>This is a paragraph of text.</p>```
756 p {
757 }
758
759 /// HTML `<span>` element - Inline container for targeting text with styles
760 ///
761 /// Example:
762 ///
763 /// ```<span class="highlight">Highlighted text</span>```
764 span {
765 }
766
767 /// HTML `<a>` element - Creates a hyperlink to other web pages or resources
768 ///
769 /// Example:
770 ///
771 /// ```<a href="https://example.com" target="_blank">Visit Example</a>```
772 a {
773 /// The href attribute specifies the URL of the page the link goes to
774 /// Example: href="https://example.com"
775 href: String,
776 /// The target attribute specifies where to open the linked document
777 /// Example: target="_blank" (opens in new tab)
778 target: String,
779 /// The rel attribute specifies the relationship between the current document and the linked document
780 /// Example: rel="nofollow" (tells search engines not to follow this link)
781 rel: String,
782 /// The download attribute indicates the browser to download the URL instead of navigating
783 /// Example: download="filename.pdf"
784 download: String,
785 /// The hreflang attribute specifies the language of the linked document
786 /// Example: hreflang="en" (English)
787 hreflang: String,
788 /// The type attribute specifies the media type of the linked document
789 /// Example: type="text/html"
790 type_: String,
791 /// The media attribute specifies what media/device the linked document is optimized for
792 /// Example: media="print" (for print stylesheets)
793 media: String,
794 /// The referrerpolicy attribute specifies which referrer information to send
795 /// Example: referrerpolicy="no-referrer"
796 referrerpolicy: String,
797 /// The ping attribute specifies URLs to be notified when the link is followed
798 /// Example: ping="https://example.com/track"
799 ping: String,
800 }
801
802 /// HTML <h1> element - First level heading (most important)
803 ///
804 /// Example:
805 ///
806 /// ```<h1>Main Page Title</h1>```
807 h1 {
808 }
809
810 /// HTML <h2> element - Second level heading
811 ///
812 /// Example:
813 ///
814 /// ```<h2>Section Heading</h2>```
815 h2 {
816 }
817
818 /// HTML <h3> element - Third level heading
819 ///
820 /// Example:
821 ///
822 /// ```<h3>Subsection Heading</h3>```
823 h3 {
824 }
825
826 /// HTML <h4> element - Fourth level heading
827 ///
828 /// Example:
829 ///
830 /// ```<h4>Sub-subsection Heading</h4>```
831 h4 {
832 }
833
834 /// HTML <h5> element - Fifth level heading
835 ///
836 /// Example:
837 ///
838 /// ```<h5>Minor Heading</h5>```
839 h5 {
840 }
841
842 /// HTML <h6> element - Sixth level heading (least important)
843 ///
844 /// Example:
845 ///
846 /// ```<h6>Fine Detail Heading</h6>```
847 h6 {
848 }
849
850 /// HTML `<img>` element - Embeds an image into the document
851 ///
852 /// Example:
853 ///
854 /// ```<img src="image.jpg" alt="Description of image">```
855 img {
856 /// The src attribute specifies the URL/path to the image
857 /// Example: src="images/logo.png"
858 src: String,
859 /// The alt attribute provides alternative text for screen readers and if image fails to load
860 /// Example: alt="Company Logo"
861 alt: String,
862 /// The loading attribute indicates how the browser should load the image
863 /// Example: loading="lazy" (defers loading until it's near viewport)
864 loading: String,
865 }
866
867 /// HTML `<br>` element - Produces a line break in text
868 ///
869 /// Example:
870 ///
871 /// ```<br>```
872 br {}
873
874 /// HTML `<hr>` element - Creates a horizontal rule (divider)
875 ///
876 /// Example:
877 ///
878 /// ```<hr>```
879 hr {
880 }
881
882 /// HTML `<ul>` element - Unordered list with bullet points
883 ///
884 /// Example:
885 ///
886 /// ```<ul><li>Item 1</li><li>Item 2</li></ul>```
887 ul {
888 /// The type attribute specifies the bullet style (disc, circle, square)
889 /// Example: type="square"
890 type_: String,
891 }
892
893 /// HTML `<li>` element - List item within ordered or unordered lists
894 ///
895 /// Example:
896 ///
897 /// ```<li>List item content</li>```
898 li {
899 /// The value attribute specifies the start value of the list item (for ol)
900 /// Example: value="3" (starts this item at number 3)
901 value: Option<i32>,
902 }
903
904 /// HTML `<ol>` element - Ordered (numbered) list
905 ///
906 /// Example:
907 ///
908 /// ```<ol start="5" type="A"><li>Item E</li><li>Item F</li></ol>```
909 ol {
910 /// The type attribute specifies the numbering type (1, A, a, I, i)
911 /// Example: type="A" (uses capital letters)
912 type_: String,
913 /// The start attribute specifies the start value of the list
914 /// Example: start="5" (starts counting from 5)
915 start: i32,
916 /// The reversed attribute specifies that list should be in descending order
917 /// Example: reversed (counts down instead of up)
918 reversed: bool,
919 }
920
921 /// HTML `<table>` element - Creates a data table with rows and columns
922 ///
923 /// Example:
924 ///
925 /// ```<table border="1"><tr><th>Header</th></tr><tr><td>Data</td></tr></table>```
926 table {
927 /// The border attribute specifies the width of the border around the table
928 /// Example: border="1" (1 pixel border)
929 border: i32,
930 /// The cellpadding attribute specifies the space between cell content and borders
931 /// Example: cellpadding="5" (5 pixels of padding)
932 cellpadding: i32,
933 /// The cellspacing attribute specifies the space between cells
934 /// Example: cellspacing="2" (2 pixels between cells)
935 cellspacing: i32,
936 }
937
938 /// HTML `<tr>` element - Table row container
939 ///
940 /// Example:
941 ///
942 /// ```<tr><td>Cell 1</td><td>Cell 2</td></tr>```
943 tr {
944 }
945
946 /// HTML `<td>` element - Table data cell
947 ///
948 /// Example:
949 ///
950 /// ```<td colspan="2">This cell spans two columns</td>```
951 td {
952 /// The colspan attribute specifies how many columns a cell should span
953 /// Example: colspan="3" (cell spans 3 columns)
954 colspan: i32,
955 /// The rowspan attribute specifies how many rows a cell should span
956 /// Example: rowspan="2" (cell spans 2 rows)
957 rowspan: i32,
958 /// The headers attribute associates data cells with header cells
959 /// Example: headers="col1 row1" (associates with those header IDs)
960 headers: String,
961 /// The scope attribute specifies whether header cells are for rows or columns
962 /// Example: scope="col" (header applies to whole column)
963 scope: String,
964 }
965
966 /// HTML `<th>` element - Table header cell
967 ///
968 /// Example:
969 ///
970 /// ```<th scope="col">Column Header</th>```
971 th {
972 /// The colspan attribute specifies how many columns a cell should span
973 /// Example: colspan="3" (header spans 3 columns)
974 colspan: i32,
975 /// The rowspan attribute specifies how many rows a cell should span
976 /// Example: rowspan="2" (header spans 2 rows)
977 rowspan: i32,
978 /// The headers attribute associates data cells with header cells
979 /// Example: headers="col1 row1" (associates with those header IDs)
980 headers: String,
981 /// The scope attribute specifies whether the header cell is for a row, column, etc.
982 /// Example: scope="row" (header applies to whole row)
983 scope: String,
984 }
985
986 /// HTML `<tbody>` element - Groups body content in a table
987 ///
988 /// Example:
989 ///
990 /// ```<table><tbody><tr><td>Data</td></tr></tbody></table>```
991 tbody {
992 }
993
994 /// HTML `<thead>` element - Groups header content in a table
995 ///
996 /// Example:
997 ///
998 /// ```<table><thead><tr><th>Header</th></tr></thead><tbody>...</tbody></table>```
999 thead {
1000 }
1001
1002 /// HTML `<tfoot>` element - Groups footer content in a table
1003 ///
1004 /// Example:
1005 ///
1006 /// ```<table><thead>...</thead><tbody>...</tbody><tfoot><tr><td>Summary</td></tr></tfoot></table>```
1007 tfoot {
1008 }
1009
1010 /// HTML `<form>` element - Container for interactive inputs to collect user data
1011 ///
1012 /// Example:
1013 ///
1014 /// ```<form action="/submit" method="post"><input type="text"><button type="submit">Submit</button></form>```
1015 form {
1016 /// The action attribute specifies where to send form data when submitted
1017 ///
1018 /// Example: action="/process-form.php"
1019 action: String,
1020 /// The method attribute specifies HTTP method for sending data (GET/POST)
1021 ///
1022 /// Example: method="post" (sends data in request body)
1023 method: String,
1024 /// The target attribute specifies where to display the response
1025 ///
1026 /// Example: target="_blank" (opens response in new tab)
1027 target: String,
1028 /// The enctype attribute specifies how form data should be encoded
1029 ///
1030 /// Example: enctype="multipart/form-data" (needed for file uploads)
1031 enctype: String,
1032 /// The novalidate attribute disables browser's built-in form validation
1033 ///
1034 /// Example: novalidate (skips validation)
1035 novalidate: bool,
1036 /// The autocomplete attribute controls browser autofill behavior
1037 ///
1038 /// Example: autocomplete="off" (disables autofill)
1039 autocomplete: String,
1040 /// The accept attribute specifies file types the server accepts (for file inputs)
1041 ///
1042 /// Example: accept=".jpg,.png" (accepts only those image formats)
1043 accept: String,
1044 /// Example: name="contact-form"
1045 name: String,
1046 }
1047
1048 /// HTML `<input>` element - Creates interactive controls for forms
1049 ///
1050 /// Example:
1051 ///
1052 /// ```<input type="text" placeholder="Enter your name" required>```
1053 input {
1054 /// The type attribute specifies the input type (text, password, email, etc.)
1055 ///
1056 /// Example: type="email" (validates as email address)
1057 type_: String,
1058 /// The placeholder attribute shows hint text when field is empty
1059 ///
1060 /// Example: placeholder="Enter your email"
1061 placeholder: String,
1062 /// The required attribute makes the field mandatory
1063 ///
1064 /// Example: required (field must be filled)
1065 required: bool,
1066 /// The value attribute specifies the default/current value
1067 ///
1068 /// Example: value="Default text"
1069 value: String,
1070 /// The name attribute specifies the name of the input (for form submission)
1071 ///
1072 /// Example: name="email"
1073 name: String,
1074 /// The disabled attribute disables the input
1075 ///
1076 /// Example: disabled (user cannot interact with input)
1077 disabled: bool,
1078 /// The readonly attribute makes the input read-only
1079 ///
1080 /// Example: readonly (user cannot modify but can focus/select)
1081 readonly: bool,
1082 /// The min attribute specifies minimum value for number/date inputs
1083 ///
1084 /// Example: min="1" (number input minimum value)
1085 min: String,
1086 /// The max attribute specifies maximum value for number/date inputs
1087 ///
1088 /// Example: max="100" (number input maximum value)
1089 max: String,
1090 /// The pattern attribute specifies a regex pattern for validation
1091 ///
1092 /// Example: pattern="[0-9]{3}" (requires exactly 3 digits)
1093 pattern: String,
1094 /// The autocomplete attribute controls browser autofill for this field
1095 ///
1096 /// Example: autocomplete="current-password"
1097 autocomplete: String,
1098 }
1099
1100 /// HTML `<textarea>` element - Multi-line text input control
1101 ///
1102 /// Example:
1103 ///
1104 /// ```<textarea rows="4" cols="50" placeholder="Your message here"></textarea>```
1105 textarea {
1106 /// The placeholder attribute shows hint text when field is empty
1107 /// Example: placeholder="Enter your comments"
1108 placeholder: String,
1109 /// The required attribute makes the field mandatory
1110 /// Example: required (must be filled before submission)
1111 required: bool,
1112 /// The value attribute specifies the default/current text content
1113 /// Example: value="Default text in the textarea"
1114 value: String,
1115 /// The rows attribute specifies visible number of text lines
1116 /// Example: rows="10" (shows 10 lines of text)
1117 rows: i32,
1118 /// The cols attribute specifies visible width in average characters
1119 /// Example: cols="40" (about 40 characters wide)
1120 cols: i32,
1121 /// The name attribute specifies the name of the textarea (for form submission)
1122 /// Example: name="comments"
1123 name: String,
1124 /// The disabled attribute disables the textarea
1125 /// Example: disabled (user cannot interact)
1126 disabled: bool,
1127 /// The readonly attribute makes the textarea read-only
1128 /// Example: readonly (user cannot modify but can focus/select)
1129 readonly: bool,
1130 /// The maxlength attribute specifies maximum character count
1131 /// Example: maxlength="500" (limits to 500 characters)
1132 maxlength: i32,
1133 }
1134
1135 /// HTML `<button>` element - Clickable button control
1136 ///
1137 /// Example:
1138 ///
1139 /// ```<button type="submit">Click Me</button>```
1140 button {
1141 /// The type attribute specifies button function (submit, reset, button)
1142 /// Example: type="submit" (submits the form)
1143 type_: String,
1144 /// The value attribute specifies the value associated with the button
1145 /// Example: value="btn1" (for form processing)
1146 value: String,
1147 /// The disabled attribute disables the button
1148 /// Example: disabled (button cannot be clicked)
1149 disabled: bool,
1150 /// The name attribute specifies the name of the button (for form submission)
1151 /// Example: name="submit-button"
1152 name: String,
1153 /// The formaction attribute overrides form's action for this button
1154 /// Example: formaction="/alternative-submit"
1155 formaction: String,
1156 /// The formmethod attribute overrides form's method for this button
1157 /// Example: formmethod="get"
1158 formmethod: String,
1159 }
1160
1161 /// HTML `<select>` element - Dropdown selection list
1162 ///
1163 /// Example:
1164 ///
1165 /// ```<select><option value="1">Option 1</option><option value="2">Option 2</option></select>```
1166 select {
1167 /// The multiple attribute allows selecting multiple options
1168 /// Example: multiple (user can select multiple items)
1169 multiple: bool,
1170 /// The disabled attribute disables the dropdown
1171 /// Example: disabled (user cannot interact)
1172 disabled: bool,
1173 /// The value attribute specifies the selected value
1174 /// Example: value="option2" (preselects this option)
1175 value: String,
1176 /// The name attribute specifies the name of the select (for form submission)
1177 /// Example: name="country"
1178 name: String,
1179 /// The size attribute specifies number of visible options
1180 /// Example: size="5" (shows 5 options at once)
1181 size: i32,
1182 /// The required attribute makes selection mandatory
1183 /// Example: required (user must select an option)
1184 required: bool,
1185 }
1186
1187 /// HTML `<option>` element - Defines option in a select dropdown
1188 ///
1189 /// Example:
1190 ///
1191 /// ```<option value="blue" selected>Blue</option>```
1192 option {
1193 /// The value attribute specifies the value to be sent to server
1194 /// Example: value="NY" (value sent when this option is selected)
1195 value: String,
1196 /// The selected attribute preselects this option when page loads
1197 /// Example: selected (this option is selected by default)
1198 selected: bool,
1199 /// The disabled attribute makes this option unselectable
1200 /// Example: disabled (cannot be chosen)
1201 disabled: bool,
1202 }
1203
1204 /// HTML `<label>` element - Caption for a form control
1205 ///
1206 /// Example:
1207 ///
1208 /// ```<label for="username">Username:</label><input id="username">```
1209 label {
1210 /// The for attribute connects the label to a form control by ID
1211 /// Example: for="email" (associates with input having id="email")
1212 for_: String,
1213 }
1214
1215 /// HTML `<iframe>` element - Embeds another document within the current HTML document
1216 ///
1217 /// Example:
1218 ///
1219 /// ```<iframe src="https://example.com" title="Example Site"></iframe>```
1220 iframe {
1221 /// The src attribute specifies the URL of the embedded document
1222 /// Example: src="https://maps.google.com"
1223 src: String,
1224 /// The frameborder attribute specifies whether to display a border
1225 /// Example: frameborder="0" (no border)
1226 frameborder: String,
1227 /// The allow attribute specifies features allowed in the iframe
1228 /// Example: allow="camera; microphone" (permits access to these devices)
1229 allow: String,
1230 /// The allowfullscreen attribute allows iframe content to go fullscreen
1231 /// Example: allowfullscreen (allows fullscreen mode)
1232 allowfullscreen: bool,
1233 /// The sandbox attribute restricts iframe capabilities for security
1234 /// Example: sandbox="allow-scripts" (only allows scripts to run)
1235 sandbox: String,
1236 }
1237
1238 /// HTML `<video>` element - Embeds video content in the document
1239 ///
1240 /// Example:
1241 ///
1242 /// ```<video src="movie.mp4" controls width="500">Video not supported</video>```
1243 video {
1244 /// The src attribute specifies URL/path of the video
1245 /// Example: src="videos/intro.mp4"
1246 src: String,
1247 /// The controls attribute displays video playback controls
1248 /// Example: controls (shows play/pause/volume controls)
1249 controls: bool,
1250 /// The autoplay attribute starts playing video automatically
1251 /// Example: autoplay (video plays when page loads)
1252 autoplay: bool,
1253 /// The loop attribute makes the video replay when finished
1254 /// Example: loop (continuously replays)
1255 loop_: bool,
1256 /// The poster attribute specifies an image shown before video plays
1257 /// Example: poster="thumbnail.jpg"
1258 poster: String,
1259 /// The muted attribute mutes the audio by default
1260 /// Example: muted (starts with no sound)
1261 muted: bool,
1262 /// The preload attribute hints how to preload the video
1263 /// Example: preload="auto" (preload entire video)
1264 preload: String,
1265 /// The playsinline attribute plays inline on iOS (instead of fullscreen)
1266 /// Example: playsinline (important for iPhone users)
1267 playsinline: bool,
1268 }
1269
1270 /// HTML `<audio>` element - Embeds sound content in the document
1271 ///
1272 /// Example:
1273 ///
1274 /// ```<audio src="song.mp3" controls>Audio not supported</audio>```
1275 audio {
1276 /// The src attribute specifies URL/path of the audio file
1277 /// Example: src="audio/background-music.mp3"
1278 src: String,
1279 /// The controls attribute displays audio playback controls
1280 /// Example: controls (shows play/pause/volume controls)
1281 controls: bool,
1282 /// The autoplay attribute starts playing audio automatically
1283 /// Example: autoplay (audio plays when page loads)
1284 autoplay: bool,
1285 /// The loop attribute makes the audio replay when finished
1286 /// Example: loop (continuously replays)
1287 loop_: bool,
1288 /// The muted attribute mutes the audio by default
1289 /// Example: muted (starts with no sound)
1290 muted: bool,
1291 /// The preload attribute hints how to preload the audio
1292 /// Example: preload="none" (doesn't preload)
1293 preload: String,
1294 }
1295
1296 /// HTML `<source>` element - Defines media resources for video/audio elements
1297 ///
1298 /// Example:
1299 ///
1300 /// ```<video><source src="movie.mp4" type="video/mp4"><source src="movie.webm" type="video/webm"></video>```
1301 source {
1302 /// The src attribute specifies URL/path of the media resource
1303 /// Example: src="audio/song.ogg"
1304 src: String,
1305 /// The type attribute specifies the MIME type of the resource
1306 /// Example: type="video/webm" (defines file format)
1307 type_: String,
1308 /// The media attribute specifies for which media the resource is intended
1309 /// Example: media="(min-width: 600px)" (responsive resources)
1310 media: String,
1311 }
1312
1313 /// HTML `<canvas>` element - Container for graphics rendered with JavaScript
1314 ///
1315 /// Example:
1316 ///
1317 /// ```<canvas id="myCanvas" width="200" height="100">Your browser does not support canvas</canvas>```
1318 canvas {
1319 }
1320
1321 /// HTML `<svg>` element - Container for SVG graphics
1322 ///
1323 /// Example:
1324 ///
1325 /// ```<svg viewBox="0 0 100 100"><circle cx="50" cy="50" r="40" fill="red" /></svg>```
1326 svg {
1327 /// The viewBox attribute defines coordinate system and aspect ratio
1328 /// Example: viewBox="0 0 800 600" (x, y, width, height)
1329 viewBox: String,
1330 /// The preserveAspectRatio attribute controls scaling behavior
1331 /// Example: preserveAspectRatio="xMidYMid meet" (center and scale)
1332 preserve_aspect_ratio: String,
1333 /// The xmlns attribute defines the XML namespace (required for standalone SVG)
1334 /// Example: xmlns="http://www.w3.org/2000/svg"
1335 xmlns: String,
1336 /// The fill attribute specifies the fill color
1337 /// Example: fill="#3498db" (blue fill)
1338 fill: String,
1339 /// The stroke attribute specifies the outline color
1340 /// Example: stroke="#e74c3c" (red outline)
1341 stroke: String,
1342 /// The stroke-width attribute specifies the width of the outline
1343 /// Example: stroke-width="3" (3 units thick)
1344 stroke_width: String,
1345 /// The stroke-linecap attribute specifies line end style
1346 /// Example: stroke-linecap="round" (rounded ends)
1347 stroke_linecap: String,
1348 /// The stroke-linejoin attribute specifies how line joins are rendered
1349 /// Example: stroke-linejoin="miter" (pointed corners)
1350 stroke_linejoin: String,
1351 /// The stroke-miterlimit attribute limits the length of miters
1352 /// Example: stroke-miterlimit="4" (limits pointy corners)
1353 stroke_miterlimit: String,
1354 /// The stroke-dasharray attribute creates dashed lines
1355 /// Example: stroke-dasharray="5,5" (5 units on, 5 units off)
1356 stroke_dasharray: String,
1357 /// The stroke-dashoffset attribute adjusts dash pattern start
1358 /// Example: stroke-dashoffset="10" (starts 10 units into pattern)
1359 stroke_dashoffset: String,
1360 /// The stroke-opacity attribute sets stroke transparency
1361 /// Example: stroke-opacity="0.5" (50% transparent)
1362 stroke_opacity: String,
1363 /// The fill-opacity attribute sets fill transparency
1364 /// Example: fill-opacity="0.7" (70% opaque)
1365 fill_opacity: String,
1366 }
1367
1368 /// HTML `<path>` element - Defines a path in SVG graphics
1369 ///
1370 /// Example:
1371 ///
1372 /// ```<path d="M10 10 H 90 V 90 H 10 Z" fill="transparent" stroke="black" />```
1373 path {
1374 /// The d attribute defines the path to be drawn
1375 /// Example: d="M20,20 L80,20 L80,80 L20,80 Z" (square path)
1376 d: String,
1377 /// The fill attribute specifies the fill color
1378 /// Example: fill="#3498db" (blue fill)
1379 fill: String,
1380 /// The stroke attribute specifies the outline color
1381 /// Example: stroke="#e74c3c" (red outline)
1382 stroke: String,
1383 /// The stroke-width attribute specifies the width of the outline
1384 /// Example: stroke-width="3" (3 units thick)
1385 stroke_width: String,
1386 /// The stroke-linecap attribute specifies line end style
1387 /// Example: stroke-linecap="round" (rounded ends)
1388 stroke_linecap: String,
1389 /// The stroke-linejoin attribute specifies how line joins are rendered
1390 /// Example: stroke-linejoin="miter" (pointed corners)
1391 stroke_linejoin: String,
1392 /// The stroke-miterlimit attribute limits the length of miters
1393 /// Example: stroke-miterlimit="4" (limits pointy corners)
1394 stroke_miterlimit: String,
1395 /// The stroke-dasharray attribute creates dashed lines
1396 /// Example: stroke-dasharray="5,5" (5 units on, 5 units off)
1397 stroke_dasharray: String,
1398 /// The stroke-dashoffset attribute adjusts dash pattern start
1399 /// Example: stroke-dashoffset="10" (starts 10 units into pattern)
1400 stroke_dashoffset: String,
1401 /// The stroke-opacity attribute sets stroke transparency
1402 /// Example: stroke-opacity="0.5" (50% transparent)
1403 stroke_opacity: String,
1404 /// The fill-opacity attribute sets fill transparency
1405 /// Example: fill-opacity="0.7" (70% opaque)
1406 fill_opacity: String,
1407 }
1408
1409 /// HTML `<rect>` element - Draws a rectangle in SVG
1410 ///
1411 /// Example:
1412 ///
1413 /// ```<rect x="10" y="10" width="100" height="50" fill="blue" />```
1414 rect {
1415 /// The x attribute specifies the x-coordinate of the rectangle
1416 /// Example: x="25" (25 units from the left)
1417 x: String,
1418 /// The y attribute specifies the y-coordinate of the rectangle
1419 /// Example: y="50" (50 units from the top)
1420 y: String,
1421 /// The rx attribute specifies the horizontal corner radius
1422 /// Example: rx="10" (rounded corners)
1423 rx: String,
1424 /// The ry attribute specifies the vertical corner radius
1425 /// Example: ry="10" (rounded corners)
1426 ry: String,
1427 /// The fill attribute specifies the fill color
1428 /// Example: fill="#2ecc71" (green fill)
1429 fill: String,
1430 /// The stroke attribute specifies the outline color
1431 /// Example: stroke="#27ae60" (darker green outline)
1432 stroke: String,
1433 /// The stroke-width attribute specifies the width of the outline
1434 /// Example: stroke-width="2" (2 units thick)
1435 stroke_width: String,
1436 }
1437
1438 /// HTML `<circle>` element - Draws a circle in SVG
1439 ///
1440 /// Example:
1441 ///
1442 /// ```<circle cx="50" cy="50" r="40" fill="red" />```
1443 circle {
1444 /// The cx attribute specifies the x-coordinate of the center
1445 /// Example: cx="100" (center x at 100 units)
1446 cx: String,
1447 /// The cy attribute specifies the y-coordinate of the center
1448 /// Example: cy="100" (center y at 100 units)
1449 cy: String,
1450 /// The r attribute specifies the radius of the circle
1451 /// Example: r="75" (75 units radius)
1452 r: String,
1453 /// The fill attribute specifies the fill color
1454 /// Example: fill="#9b59b6" (purple fill)
1455 fill: String,
1456 /// The stroke attribute specifies the outline color
1457 /// Example: stroke="#8e44ad" (darker purple outline)
1458 stroke: String,
1459 /// The stroke-width attribute specifies the width of the outline
1460 /// Example: stroke-width="3" (3 units thick)
1461 stroke_width: String,
1462 }
1463
1464 /// HTML `<ellipse>` element - Draws an ellipse in SVG
1465 ///
1466 /// Example:
1467 ///
1468 /// ```<ellipse cx="100" cy="50" rx="100" ry="50" fill="yellow" />```
1469 ellipse {
1470 /// The cx attribute specifies the x-coordinate of the center
1471 /// Example: cx="150" (center x at 150 units)
1472 cx: String,
1473 /// The cy attribute specifies the y-coordinate of the center
1474 /// Example: cy="75" (center y at 75 units)
1475 cy: String,
1476 /// The rx attribute specifies the horizontal radius
1477 /// Example: rx="100" (100 units horizontal radius)
1478 rx: String,
1479 /// The ry attribute specifies the vertical radius
1480 /// Example: ry="50" (50 units vertical radius)
1481 ry: String,
1482 /// The fill attribute specifies the fill color
1483 /// Example: fill="#f1c40f" (yellow fill)
1484 fill: String,
1485 /// The stroke attribute specifies the outline color
1486 /// Example: stroke="#f39c12" (darker yellow outline)
1487 stroke: String,
1488 /// The stroke-width attribute specifies the width of the outline
1489 /// Example: stroke-width="2" (2 units thick)
1490 stroke_width: String,
1491 }
1492
1493 /// HTML `<line>` element - Draws a line in SVG
1494 ///
1495 /// Example:
1496 ///
1497 /// ```<line x1="0" y1="0" x2="100" y2="100" stroke="black" />```
1498 line {
1499 /// The x1 attribute specifies the x-coordinate of the start point
1500 /// Example: x1="10" (starts 10 units from left)
1501 x1: String,
1502 /// The y1 attribute specifies the y-coordinate of the start point
1503 /// Example: y1="10" (starts 10 units from top)
1504 y1: String,
1505 /// The x2 attribute specifies the x-coordinate of the end point
1506 /// Example: x2="200" (ends 200 units from left)
1507 x2: String,
1508 /// The y2 attribute specifies the y-coordinate of the end point
1509 /// Example: y2="200" (ends 200 units from top)
1510 y2: String,
1511 /// The stroke attribute specifies the line color
1512 /// Example: stroke="#34495e" (dark blue line)
1513 stroke: String,
1514 /// The stroke-width attribute specifies the width of the line
1515 /// Example: stroke-width="5" (5 units thick)
1516 stroke_width: String,
1517 /// The stroke-linecap attribute specifies line end style
1518 /// Example: stroke-linecap="round" (rounded ends)
1519 stroke_linecap: String,
1520 /// The stroke-dasharray attribute creates dashed lines
1521 /// Example: stroke-dasharray="10,5" (10 units on, 5 units off)
1522 stroke_dasharray: String,
1523 }
1524
1525 /// HTML `<polyline>` element - Draws connected straight lines in SVG
1526 ///
1527 /// Example:
1528 ///
1529 /// ```<polyline points="20,20 40,25 60,40 80,120 120,140 200,180" stroke="orange" fill="none" />```
1530 polyline {
1531 /// The points attribute specifies coordinates for each point
1532 /// Example: points="0,0 50,50 100,25" (series of x,y pairs)
1533 points: String,
1534 /// The fill attribute specifies the fill color between lines
1535 /// Example: fill="none" (transparent fill)
1536 fill: String,
1537 /// The stroke attribute specifies the line color
1538 /// Example: stroke="#e67e22" (orange line)
1539 stroke: String,
1540 /// The stroke-width attribute specifies the width of the lines
1541 /// Example: stroke-width="3" (3 units thick)
1542 stroke_width: String,
1543 /// The stroke-linejoin attribute specifies how lines are joined
1544 /// Example: stroke-linejoin="round" (rounded corners)
1545 stroke_linejoin: String,
1546 }
1547
1548 /// HTML `<polygon>` element - Draws a closed shape with straight lines in SVG
1549 ///
1550 /// Example:
1551 ///
1552 /// ```<polygon points="200,10 250,190 160,210" fill="green" />```
1553 polygon {
1554 /// The points attribute specifies coordinates for each point
1555 /// Example: points="50,50 150,50 100,150" (triangle coordinates)
1556 points: String,
1557 /// The fill attribute specifies the fill color of the shape
1558 /// Example: fill="#1abc9c" (teal fill)
1559 fill: String,
1560 /// The stroke attribute specifies the outline color
1561 /// Example: stroke="#16a085" (darker teal outline)
1562 stroke: String,
1563 /// The stroke-width attribute specifies the width of the outline
1564 /// Example: stroke-width="2" (2 units thick)
1565 stroke_width: String,
1566 /// The fill-rule attribute specifies how to fill shapes with holes
1567 /// Example: fill-rule="evenodd" (alternates fill for nested shapes)
1568 fill_rule: String,
1569 }
1570
1571 /// HTML `<g>` element - Groups SVG elements together
1572 ///
1573 /// Example:
1574 ///
1575 /// ```<g transform="rotate(45 50 50)"><rect x="20" y="20" width="60" height="60" /></g>```
1576 g {
1577 /// The transform attribute applies transformations to the group
1578 /// Example: transform="translate(100,50) scale(2)" (moves and scales)
1579 transform: String,
1580 /// The fill attribute specifies the fill color for all elements in the group
1581 /// Example: fill="#3498db" (blue fill for all children)
1582 fill: String,
1583 /// The stroke attribute specifies the outline color for all elements in the group
1584 /// Example: stroke="#2980b9" (darker blue outline for all children)
1585 stroke: String,
1586 }
1587
1588 /// HTML `<use>` element - Reuses an SVG element defined elsewhere
1589 ///
1590 /// Example:
1591 ///
1592 /// ```<r#use href="#myCircle" x="10" y="10" fill="blue" />```
1593 r#use {
1594 /// The href attribute specifies which element to reuse
1595 /// Example: href="#icon-star" (references element with id="icon-star")
1596 href: String,
1597 /// The x attribute specifies the x-coordinate where to place the reused element
1598 /// Example: x="100" (100 units from left)
1599 x: String,
1600 /// The y attribute specifies the y-coordinate where to place the reused element
1601 /// Example: y="50" (50 units from top)
1602 y: String,
1603 }
1604
1605 /// HTML <foreignObject> element - Includes non-SVG elements inside SVG
1606 ///
1607 /// Example:
1608 ///
1609 /// ```<foreignObject x="20" y="20" width="160" height="160"><div>HTML content inside SVG</div></foreignObject>```
1610 foreignObject {
1611 /// The x attribute specifies the x-coordinate of the foreign object
1612 /// Example: x="25" (25 units from left)
1613 x: String,
1614 /// The y attribute specifies the y-coordinate of the foreign object
1615 /// Example: y="25" (25 units from top)
1616 y: String,
1617 }
1618
1619 /// HTML `<defs>` element - Container for reusable SVG elements
1620 ///
1621 /// Example:
1622 ///
1623 /// ```<defs><circle id="myCircle" cx="5" cy="5" r="4" /></defs>```
1624 defs {
1625 }
1626
1627 /// HTML <linearGradient> element - Defines a linear gradient for SVG fills
1628 ///
1629 /// Example:
1630 ///
1631 /// ```<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%"><stop offset="0%" style="stop-color:rgb(255,255,0)" /></linearGradient>```
1632 linearGradient {
1633 /// The x1 attribute defines the start point of the gradient (x-coordinate)
1634 /// Example: x1="0%" (starts at left edge)
1635 x1: String,
1636 /// The y1 attribute defines the start point of the gradient (y-coordinate)
1637 /// Example: y1="0%" (starts at top edge)
1638 y1: String,
1639 /// The x2 attribute defines the end point of the gradient (x-coordinate)
1640 /// Example: x2="100%" (ends at right edge)
1641 x2: String,
1642 /// The y2 attribute defines the end point of the gradient (y-coordinate)
1643 /// Example: y2="100%" (ends at bottom edge)
1644 y2: String,
1645 /// The gradientUnits attribute defines the coordinate system for the gradient
1646 /// Example: gradientUnits="userSpaceOnUse" (uses absolute coordinates)
1647 gradientUnits: String,
1648 /// The spreadMethod attribute defines how the gradient fills beyond its bounds
1649 /// Example: spreadMethod="reflect" (gradient reflects at boundaries)
1650 spreadMethod: String,
1651 }
1652
1653 /// HTML `<stop>` element - Defines color transitions in gradients
1654 ///
1655 /// Example:
1656 ///
1657 /// ```<stop offset="0%" style="stop-color:rgb(255,0,0);stop-opacity:1" />```
1658 stop {
1659 /// The offset attribute defines where along the gradient this color appears
1660 /// Example: offset="50%" (color positioned halfway through gradient)
1661 offset: String,
1662 /// The stop-color attribute defines the color at this stop
1663 /// Example: stop-color="#3498db" (blue color)
1664 stop_color: String,
1665 /// The stop-opacity attribute defines the opacity at this stop
1666 /// Example: stop-opacity="0.5" (50% transparent)
1667 stop_opacity: String,
1668 }
1669
1670 /// HTML <radialGradient> element - Defines a radial gradient for SVG fills
1671 ///
1672 /// Example:
1673 ///
1674 /// ```<radialGradient id="grad2" cx="50%" cy="50%" r="50%"><stop offset="0%" style="stop-color:red" /></radialGradient>```
1675 radialGradient {
1676 /// The cx attribute defines the x-coordinate of the center point
1677 /// Example: cx="50%" (center of the area horizontally)
1678 cx: String,
1679 /// The cy attribute defines the y-coordinate of the center point
1680 /// Example: cy="50%" (center of the area vertically)
1681 cy: String,
1682 /// The r attribute defines the radius of the gradient
1683 /// Example: r="75%" (extends to 75% of the reference area)
1684 r: String,
1685 /// The fx attribute defines the x-coordinate of the focal point
1686 /// Example: fx="60%" (focal point slightly right of center)
1687 fx: String,
1688 /// The fy attribute defines the y-coordinate of the focal point
1689 /// Example: fy="40%" (focal point slightly above center)
1690 fy: String,
1691 /// The fr attribute defines the radius of the focal point
1692 /// Example: fr="5%" (small focal point)
1693 fr: String,
1694 /// The gradientUnits attribute defines the coordinate system for the gradient
1695 /// Example: gradientUnits="objectBoundingBox" (relative to object)
1696 gradientUnits: String,
1697 /// The spreadMethod attribute defines how the gradient fills beyond its bounds
1698 /// Example: spreadMethod="pad" (uses edge color beyond boundaries)
1699 spreadMethod: String,
1700 }
1701
1702 /// HTML `<mask>` element - Defines an area where SVG elements are partially or fully hidden
1703 ///
1704 /// Example:
1705 ///
1706 /// ```<mask id="myMask"><rect width="100%" height="100%" fill="white" opacity="0.5" /></mask>```
1707 mask {
1708 /// The maskUnits attribute specifies the coordinate system for mask positioning
1709 /// Example: maskUnits="userSpaceOnUse" (absolute coordinates)
1710 mask_units: String,
1711 /// The maskContentUnits attribute specifies the coordinate system for mask content
1712 /// Example: maskContentUnits="objectBoundingBox" (relative to object)
1713 mask_content_units: String,
1714 /// The x attribute specifies the x-coordinate of the mask
1715 /// Example: x="0" (starts at left edge)
1716 x: String,
1717 /// The y attribute specifies the y-coordinate of the mask
1718 /// Example: y="0" (starts at top edge)
1719 y: String,
1720 }
1721 /// HTML `<article>` element - Defines an independent, self-contained content
1722 ///
1723 /// Example:
1724 ///
1725 /// ```<article><h1>Article Title</h1><p>Article content goes here...</p></article>```
1726 article {
1727 }
1728
1729 /// HTML `<aside>` element - Defines content aside from the page content
1730 ///
1731 /// Example:
1732 ///
1733 /// ```<aside><p>Sidebar content goes here...</p></aside>```
1734 aside {
1735 }
1736
1737 /// HTML `<details>` element - Defines additional details that the user can view or hide
1738 ///
1739 /// Example:
1740 ///
1741 /// ```<details><summary>Click to view details</summary><p>Details content goes here...</p></details>```
1742 details {
1743 }
1744
1745 /// HTML `<figcaption>` element - Defines a caption for a `<figure>` element
1746 ///
1747 /// Example:
1748 ///
1749 /// ```<figure><img src="image.jpg" alt="Image description" /><figcaption>Caption goes here...</figcaption></figure>```
1750 figcaption {
1751 }
1752
1753 /// HTML `<figure>` element - Specifies self-contained content, like illustrations, diagrams, photos, code listings, etc.
1754 ///
1755 /// Example:
1756 ///
1757 /// ```<figure><img src="image.jpg" alt="Image description" /><figcaption>Caption goes here...</figcaption></figure>```
1758 figure {
1759 }
1760
1761 /// HTML `<footer>` element - Defines a footer for a document or section
1762 ///
1763 /// Example:
1764 ///
1765 /// ```<footer><p>Footer content goes here...</p></footer>```
1766 footer {
1767 }
1768
1769 /// HTML `<header>` element - Defines a container for introductory content or a set of navigational links
1770 ///
1771 /// Example:
1772 ///
1773 /// ```<header><h1>Header content goes here...</h1></header>```
1774 header {
1775 }
1776
1777 /// HTML `<main>` element - Specifies the main content of a document
1778 ///
1779 /// Example:
1780 ///
1781 /// ```<main><p>Main content goes here...</p></main>```
1782 main {
1783 }
1784
1785 /// HTML `<mark>` element - Defines marked/highlighted text
1786 ///
1787 /// Example:
1788 ///
1789 /// ```<p>Some <mark>marked</mark> text.</p>```
1790 mark {
1791 }
1792
1793 /// HTML `<nav>` element - Defines navigation links
1794 ///
1795 /// Example:
1796 ///
1797 /// ```<nav><a href="#home">Home</a> <a href="#about">About</a> <a href="#contact">Contact</a></nav>```
1798 nav {
1799 }
1800
1801 /// HTML `<section>` element - Defines a section in a document
1802 ///
1803 /// Example:
1804 ///
1805 /// ```<section><h2>Section Title</h2><p>Section content goes here...</p></section>```
1806 section {
1807 }
1808
1809 /// HTML `<summary>` element - Defines a visible heading for a `<details>` element
1810 ///
1811 /// Example:
1812 ///
1813 /// ```<details><summary>Click to view details</summary><p>Details content goes here...</p></details>```
1814 summary {
1815 }
1816
1817 /// HTML `<time>` element - Defines a date/time
1818 ///
1819 /// Example:
1820 ///
1821 /// ```<p>Published on <time datetime="2023-08-01">August 1, 2023</time></p>```
1822 time {
1823 /// The datetime attribute specifies the date/time
1824 /// Example: datetime="2023-08-01" (August 1, 2023)
1825 datetime: String,
1826 /// The pubdate attribute specifies that the content is published
1827 /// Example: pubdate="pubdate" (content is published)
1828 pubdate: String,
1829 }
1830
1831 /// HTML `<wbr>` element - Inserts a line break opportunity
1832 ///
1833 /// Example:
1834 ///
1835 /// ```<p>Here is a long word:<wbr>supercalifragilisticexpialidocious</p>```
1836 wbr {
1837 }
1838
1839 /// HTML `<address>` element - Defines contact information for the author/owner of a document
1840 ///
1841 /// Example:
1842 ///
1843 /// ```<address>Contact us at <a href="mailto:="mail="mailto:EMAIL"EMAILample.com</a></address>```
1844 address {
1845 }
1846
1847 /// HTML `<bdi>` element - Defines a term/name within a description list
1848 ///
1849 /// Example:
1850 ///
1851 /// ```<dl><dt><bdi>Name</bdi></dt><dd>John Doe</dd></dl>```
1852 bdi {
1853 }
1854
1855 /// HTML `<bdo>` element - Overrides the current text direction
1856 ///
1857 /// Example:
1858 ///
1859 /// ```<p><bdo dir="rtl">This text is written from right to left</bdo></p>```
1860 bdo {
1861 }
1862
1863 /// HTML `<cite>` element - Defines the title of a work
1864 ///
1865 /// Example:
1866 ///
1867 /// ```<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>```
1868 cite {
1869 }
1870
1871 /// HTML `<dfn>` element - Defines a definition
1872 ///
1873 /// Example:
1874 ///
1875 /// ```<p>The <dfn>HTML</dfn> element is used to define a section in a document.</p>```
1876 dfn {
1877 }
1878
1879 /// HTML `<em>` element - Defines emphasized text
1880 ///
1881 /// Example:
1882 ///
1883 /// ```<p>He is <em>very</em> angry.</p>```
1884 em {
1885 }
1886
1887 /// HTML `<i>` element - Defines a part of text in an alternate voice or mood
1888 ///
1889 /// Example:
1890 ///
1891 /// ```<p><i>This text is in italics.</i></p>```
1892 i {
1893 }
1894
1895 /// HTML `<kbd>` element - Defines keyboard input
1896 ///
1897 /// Example:
1898 ///
1899 /// ```<p>Press <kbd>Ctrl</kbd> + <kbd>C</kbd> to copy.</p>```
1900 kbd {
1901 }
1902
1903 /// HTML `<meter>` element - Defines a scalar measurement within a known range (a gauge)
1904 ///
1905 /// Example:
1906 ///
1907 /// ```<meter value="75" min="0" max="100"></meter>```
1908 meter {
1909 /// The value attribute specifies the current value
1910 /// Example: value="75" (current value is 75)
1911 value: String,
1912 /// The min attribute specifies the minimum value
1913 /// Example: min="0" (minimum value is 0)
1914 min: String,
1915 /// The max attribute specifies the maximum value
1916 /// Example: max="100" (maximum value is 100)
1917 max: String,
1918 /// The low attribute specifies the low value
1919 /// Example: low="33" (low value is 33)
1920 low: String,
1921 /// The high attribute specifies the high value
1922 /// Example: high="66" (high value is 66)
1923 high: String,
1924 /// The optimum attribute specifies the optimum value
1925 /// Example: optimum="50" (optimum value is 50)
1926 optimum: String,
1927 }
1928
1929 /// HTML `<output>` element - Defines the result of a calculation
1930 ///
1931 /// Example:
1932 ///
1933 /// ```<form><input type="number" id="num1" /><input type="number" id="num2" /><button onclick="calculate()">Calculate</button><output id="result"></output></form>```
1934 output {
1935 }
1936
1937 /// HTML `<progress>` element - Defines the progress of a task
1938 ///
1939 /// Example:
1940 ///
1941 /// ```<progress value="75" max="100"></progress>```
1942 progress {
1943 /// The value attribute specifies the current value
1944 /// Example: value="75" (current value is 75)
1945 value: String,
1946 /// The max attribute specifies the maximum value
1947 /// Example: max="100" (maximum value is 100)
1948 max: String,
1949 }
1950
1951 /// HTML `<q>` element - Defines a short inline quotation
1952 ///
1953 /// Example:
1954 ///
1955 /// ```<p><q>We are the so-called "Vikings" from the north.</q></p>```
1956 q {
1957 }
1958
1959 /// HTML `<rp>` element - Defines a parenthesis for browsers that do not support `<ruby>`
1960 ///
1961 /// Example:
1962 ///
1963 /// ```<ruby><rb>漢</rb><rp>(</rp><rt>han</rt><rp>)</rp></ruby>```
1964 rp {
1965 }
1966
1967 /// HTML `<rt>` element - Defines a ruby text
1968 ///
1969 /// Example:
1970 ///
1971 /// ```<ruby><rb>漢</rb><rt>han</rt></ruby>```
1972 rt {
1973 }
1974
1975 /// HTML `<ruby>` element - Defines a ruby annotation (for East Asian typography)
1976 ///
1977 /// Example:
1978 ///
1979 /// ```<ruby><rb>漢</rb><rt>han</rt></ruby>```
1980 ruby {
1981 }
1982
1983 /// HTML `<s>` element - Defines strikethrough text
1984 ///
1985 /// Example:
1986 ///
1987 /// ```<p>Price: <s>$100</s> $50</p>```
1988 s {
1989 }
1990
1991 /// HTML `<samp>` element - Defines sample output from a computer program
1992 ///
1993 /// Example:
1994 ///
1995 /// ```<samp>Hello, World!</samp>```
1996 samp {
1997 }
1998
1999 /// HTML `<small>` element - Defines smaller text
2000 ///
2001 /// Example:
2002 ///
2003 /// ```<p><small>This is some smaller text.</small></p>```
2004 small {
2005 }
2006
2007 /// HTML `<strong>` element - Defines important text
2008 ///
2009 /// Example:
2010 ///
2011 /// ```<p><strong>This is important!</strong></p>```
2012 strong {
2013 }
2014
2015 /// HTML `<sub>` element - Defines subscript text
2016 ///
2017 /// Example:
2018 ///
2019 /// ```<p>H<sub>2</sub>O</p>```
2020 sub {
2021 }
2022
2023 /// HTML `<sup>` element - Defines superscript text
2024 ///
2025 /// Example:
2026 ///
2027 /// ```<p>X<sup>2</sup></p>```
2028 sup {
2029 }
2030
2031 /// HTML `<var>` element - Defines a variable
2032 ///
2033 /// Example:
2034 ///
2035 /// ```<p>The area is <var>x</var> times <var>y</var>.</p>```
2036 var {
2037 }
2038
2039 /// HTML `<template>` element - Defines a container for content that is not to be rendered when a page is loaded
2040 ///
2041 /// Example:
2042 ///
2043 /// ```<template><p>This content will not be rendered.</p></template>```
2044 template {
2045 }
2046
2047 /// HTML `<u>` element - Defines text that should be rendered as underlined
2048 ///
2049 /// Example:
2050 ///
2051 /// ```<p><u>This text is underlined.</u></p>```
2052 u {
2053 }
2054
2055 /// HTML `<noscript>` element - Defines content that is displayed to users with disabled scripts
2056 ///
2057 /// Example:
2058 ///
2059 /// ```<noscript><p>JavaScript is disabled.</p></noscript>```
2060 noscript {
2061 }
2062
2063 /// HTML `<legend>` element - Defines a caption for a `<fieldset>` element
2064 ///
2065 /// Example:
2066 ///
2067 /// ```<fieldset><legend>Personal Information</legend><input type="text" name="name" /><input type="email" name="email" /></fieldset>```
2068 legend {
2069 }
2070
2071 /// HTML `<optgroup>` element - Defines a group of related `<option>` elements in a `<select>` element
2072 ///
2073 /// Example:
2074 ///
2075 /// ```<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>```
2076 optgroup {
2077 /// The label attribute specifies a label for the group
2078 /// Example: label="Fruits" (label for the group is "Fruits")
2079 label: String,
2080 }
2081
2082 /// HTML `<dialog>` element - Defines a dialog box or other interactive component
2083 ///
2084 /// Example:
2085 ///
2086 /// ```<dialog><p>Dialog content goes here...</p><button onclick="closeDialog()">Close</button></dialog>```
2087 dialog {
2088 /// The open attribute specifies whether the dialog is open or closed
2089 /// Example: open="open" (dialog is open)
2090 open: String,
2091 }
2092
2093 /// HTML `<blockquote>` element - Defines a section that is quoted from another source
2094 ///
2095 /// Example:
2096 ///
2097 /// ```<blockquote><p>This is a quote.</p><footer>- John Doe</footer></blockquote>```
2098 blockquote {
2099 }
2100
2101 /// HTML `<dd>` element - Defines a description/value pair within a `<dl>` element
2102 ///
2103 /// Example:
2104 ///
2105 /// ```<dl><dt>Coffee</dt><dd>Black hot drink</dd><dt>Milk</dt><dd>White cold drink</dd></dl>```
2106 dd {
2107 }
2108
2109 /// HTML `<dl>` element - Defines a description list
2110 ///
2111 /// Example:
2112 ///
2113 /// ```<dl><dt>Coffee</dt><dd>Black hot drink</dd><dt>Milk</dt><dd>White cold drink</dd></dl>```
2114 dl {
2115 }
2116
2117 /// HTML `<dt>` element - Defines a term/name in a description list
2118 ///
2119 /// Example:
2120 ///
2121 /// ```<dl><dt>Coffee</dt><dd>Black hot drink</dd><dt>Milk</dt><dd>White cold drink</dd></dl>```
2122 dt {
2123 }
2124
2125 /// HTML `<base>` element - Specifies the base URL/target for all relative URLs in a document
2126 ///
2127 /// Example:
2128 ///
2129 /// ```<base href="```<base href="URL_ADDRESS.example.com/" target="_blank">```
2130 base {
2131 /// The href attribute specifies the base URL
2132 /// ```<base href="URL_ADDR```<base href="URL_ADDRESS.example.com/" target="_blank">```
2133 href: String,
2134 /// The target attribute specifies the target for all relative URLs
2135 /// ```<base href="URL_ADDRESS.example.com/" target="_blank">```
2136 target: String,
2137 }
2138 }
2139}