html_node/
lib.rs

1//! A HTML to [`Node`] macro powered by [rstml](https://github.com/rs-tml/rstml).
2//!
3//! Values returned from braced blocks (`{ ... }`) are expected to return
4//! something that implements [`Into<Node>`]. This is already implemented for
5//! anything that implements [`IntoIterator<Item = Node>`](IntoIterator), so you
6//! can return something like a [`Vec<Node>`] or an
7//! [`Iterator<Item = Node>`](Iterator) directly.
8//!
9//! Due to Rust's trait implementation rules, you cannot directly return
10//! [`String`]s. Instead, you can use the [`text!`] macro to convert the
11//! [`String`] to a [`Node::Text`].
12//!
13//! [`Node`] implements [`Display`][std::fmt::Display] (and by extension
14//! [`ToString`]), so you can turn it into a string representation easily using
15//! [`Node::to_string()`][ToString::to_string].
16//!
17//! # Typed HTML
18//!
19//! This crate also supports typed HTML, which is all nested into the [`typed`]
20//! module. note that the feature `typed` must be enabled to use it.
21//!
22//! # Examples
23//!
24//! ## Basic
25//!
26//! ```rust
27//! use html_node::{html, text};
28//!
29//! let shopping_list = vec!["milk", "eggs", "bread"];
30//!
31//! let html = html! {
32//!     <div>
33//!         <h1>Shopping List</h1>
34//!         <ul>
35//!             { shopping_list.into_iter().zip(1..).map(|(item, i)| html! {
36//!                 <li class="item">
37//!                     <input type="checkbox" id={format!("item-{i}")}>
38//!                     <label for={format!("item-{i}")}>{text!("{item}")}</label>
39//!                 </li>
40//!             }) }
41//!         </ul>
42//!     </div>
43//! };
44//!
45//! let expected = "\
46//! <div>\
47//!     <h1>Shopping List</h1>\
48//!     <ul>\
49//!         <li class=\"item\">\
50//!             <input type=\"checkbox\" id=\"item-1\">\
51//!             <label for=\"item-1\">milk</label>\
52//!         </li>\
53//!         <li class=\"item\">\
54//!             <input type=\"checkbox\" id=\"item-2\">\
55//!             <label for=\"item-2\">eggs</label>\
56//!         </li>\
57//!         <li class=\"item\">\
58//!             <input type=\"checkbox\" id=\"item-3\">\
59//!             <label for=\"item-3\">bread</label>\
60//!         </li>\
61//!     </ul>\
62//! </div>\
63//! ";
64//!
65//! assert_eq!(html.to_string(), expected);
66//! ```
67//!
68//! ## Pretty-Printing
69//!
70//! Pretty-printing is supported by default when formatting a [`Node`] using the
71//! alternate formatter, specified by a `#` in the format string.
72//!
73//! If you want to avoid specifying the alternate formatter, enabling the
74//! `pretty` feature will provide a convenience method [`Node::pretty()`] that
75//! returns a wrapper around the node that will always be pretty-printed.
76//!
77//! ```rust
78//! use html_node::{html, text};
79//!
80//! let html = html! {
81//!     <div>
82//!         <h1>Shopping List</h1>
83//!        <ul>
84//!            <li>Eggs</li>
85//!            <li>Milk</li>
86//!            <li>Bread</li>
87//!        </ul>
88//!     </div>
89//! };
90//!
91//! let expected = "\
92//! <div>
93//!     <h1>
94//!         Shopping List
95//!     </h1>
96//!     <ul>
97//!         <li>
98//!             Eggs
99//!         </li>
100//!         <li>
101//!             Milk
102//!         </li>
103//!         <li>
104//!             Bread
105//!         </li>
106//!     </ul>
107//! </div>\
108//! ";
109//!
110//! // Note the `#` in the format string, which enables pretty-printing
111//! let formatted_html = format!("{html:#}");
112//!
113//! assert_eq!(formatted_html, expected);
114//!
115//! # #[cfg(feature = "pretty")]
116//! # {
117//! // Wrap the HTML node in a pretty-printing wrapper.
118//! let pretty = html.pretty();
119//!
120//! // Get the pretty-printed HTML as a string by invoking the [`Display`][std::fmt::Display] trait.
121//! let pretty_html_string = pretty.to_string();
122//! // Note the '#' is not required here.
123//! let pretty_html_format = format!("{pretty}");
124//!
125//! assert_eq!(pretty_html_string, expected);
126//! assert_eq!(pretty_html_format, expected);
127//! assert_eq!(pretty_html_string, pretty_html_format);
128//! # }
129//! ```
130
131#![cfg_attr(docsrs, feature(doc_auto_cfg))]
132
133mod macros;
134#[cfg(feature = "typed")]
135pub mod typed;
136
137#[cfg(feature = "pretty")]
138pub use html_node_core::pretty;
139pub use html_node_core::{Comment, Doctype, Element, Fragment, Node, Text, UnsafeText};
140/// The HTML to [`Node`] macro.
141///
142/// See the [crate-level documentation](crate) for more information.
143pub use html_node_macro::html;
144
145pub use self::macros::*;