html_editor/lib.rs
1//! `html_editor` is a simple html parser and editor.
2//!
3//! Quick Start:
4//! ```
5//! use html_editor::operation::*;
6//! use html_editor::{parse, Node};
7//!
8//! // You can create DOM nodes by parsing html string.
9//! let html = r#"
10//! <!doctype html>
11//! <html>
12//! <head>
13//! </head>
14//! <body>
15//! </body>
16//! </html>
17//! "#;
18//! let mut dom = parse(html).unwrap();
19//!
20//! // Or you can create a node by some built-in methods like below.
21//! let app: Node = Node::new_element("div", vec![("id", "app")], vec![]);
22//!
23//! // Here shows how to edit the nodes and turn it back to html.
24//! let html = dom
25//! .remove_by(&Selector::from("head"))
26//! .insert_to(&Selector::from("body"), app)
27//! .trim()
28//! .html();
29//!
30//! assert_eq!(
31//! html,
32//! r#"<!DOCTYPE html><html><body><div id="app"></div></body></html>"#
33//! );
34//! ```
35
36mod data;
37mod parse;
38
39pub mod operation;
40
41pub use parse::parse;
42pub use parse::try_parse;
43
44/// Doctype of Html or Xml
45#[derive(Clone, Debug)]
46pub enum Doctype {
47 Html,
48 Xml { version: String, encoding: String },
49}
50
51/// Node of DOM
52#[derive(Debug, Clone)]
53pub enum Node {
54 Element(Element),
55 Text(String),
56 Comment(String),
57 Doctype(Doctype),
58}
59
60impl Node {
61 /// Check if it is an element node.
62 ///
63 /// ```
64 /// use html_editor::Node;
65 ///
66 /// assert_eq!(Node::new_element("div", vec![("id", "app")], vec![]).is_element(), true);
67 /// assert_eq!(Node::Text("Lorem Ipsum".to_string()).is_element(), false);
68 /// ```
69 pub fn is_element(&self) -> bool {
70 matches!(self, Node::Element { .. })
71 }
72
73 #[deprecated(note = "Please use `is_element` instead")]
74 pub fn into_element(self) -> Element {
75 match self {
76 Node::Element(element) => element,
77 _ => panic!("{:?} is not an element", self),
78 }
79 }
80
81 /// Convert the node into an element.
82 ///
83 /// Returns `None` if the node is not an element.
84 ///
85 /// Example:
86 /// ```
87 /// use html_editor::{Node, Element};
88 ///
89 /// let a: Node = Node::new_element("div", vec![("id", "app")], vec![]);
90 /// assert!(a.as_element().is_some());
91 ///
92 /// let b: Node = Node::Text("hello".to_string());
93 /// assert!(b.as_element().is_none());
94 /// ```
95 pub fn as_element(&self) -> Option<&Element> {
96 match self {
97 Node::Element(element) => Some(element),
98 _ => None,
99 }
100 }
101
102 /// Convert the node into a mutable element.
103 ///
104 /// Returns `None` if the node is not an element.
105 ///
106 /// Example:
107 /// ```
108 /// use html_editor::{Node, Element};
109 ///
110 /// let mut a: Node = Node::new_element("div", vec![("id", "app")], vec![]);
111 /// assert!(a.as_element_mut().is_some());
112 ///
113 /// let mut b: Node = Node::Text("hello".to_string());
114 /// assert!(b.as_element_mut().is_none());
115 /// ```
116 pub fn as_element_mut(&mut self) -> Option<&mut Element> {
117 match self {
118 Node::Element(element) => Some(element),
119 _ => None,
120 }
121 }
122
123 /// Create a new element node.
124 ///
125 /// ```
126 /// use html_editor::Node;
127 ///
128 /// let node: Node = Node::new_element(
129 /// "h1",
130 /// vec![("class", "title")],
131 /// vec![
132 /// Node::Text("Hello, world!".to_string()),
133 /// ]
134 /// );
135 /// ```
136 pub fn new_element(name: &str, attrs: Vec<(&str, &str)>, children: Vec<Node>) -> Node {
137 Element {
138 name: name.to_string(),
139 attrs: attrs
140 .into_iter()
141 .map(|(k, v)| (k.to_string(), v.to_string()))
142 .collect(),
143 children,
144 }
145 .into_node()
146 }
147}
148
149/// HTML Element
150#[derive(Debug, Clone)]
151pub struct Element {
152 pub name: String,
153 pub attrs: Vec<(String, String)>,
154 pub children: Vec<Node>,
155}
156
157impl Element {
158 /// Create a new element.
159 pub fn new(name: &str, attrs: Vec<(&str, &str)>, children: Vec<Node>) -> Self {
160 Self {
161 name: name.to_string(),
162 attrs: attrs
163 .into_iter()
164 .map(|(k, v)| (k.to_string(), v.to_string()))
165 .collect(),
166 children,
167 }
168 }
169}
170
171impl Element {
172 pub fn into_node(self) -> Node {
173 Node::Element(self)
174 }
175}
176
177impl From<Element> for Node {
178 fn from(element: Element) -> Self {
179 Node::Element(element)
180 }
181}