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