Skip to content

Commit 408e026

Browse files
committed
to html
1 parent c0c6975 commit 408e026

3 files changed

Lines changed: 100 additions & 1 deletion

File tree

src/dom/element.rs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::node::Node;
1+
use super::node::{Node, write_html_list};
22
#[cfg(feature = "source-span")]
33
use super::span::SourceSpan;
44
use crate::dom::for_each::ForEach;
@@ -81,3 +81,59 @@ impl<'a> ForEach<'a> for Element<'a> {
8181
self.children.as_mut_slice()
8282
}
8383
}
84+
85+
impl Element<'_> {
86+
#[inline(always)]
87+
pub fn to_html(&self) -> String {
88+
let mut result = String::new();
89+
self.write_html(&mut result);
90+
result
91+
}
92+
93+
pub fn write_html(&self, writer: &mut String) {
94+
let e = self;
95+
96+
writer.push('<');
97+
writer.push_str(&e.name);
98+
if !e.classes.is_empty() {
99+
writer.push_str(" class=\"");
100+
writer.push_str(
101+
&e.classes
102+
.iter()
103+
.map(|c| c.as_str())
104+
.collect::<Vec<_>>()
105+
.join(" "),
106+
);
107+
writer.push('"');
108+
}
109+
if let Some(id) = &e.id {
110+
writer.push(' ');
111+
writer.push_str("id");
112+
writer.push('=');
113+
writer.push('"');
114+
writer.push_str(id);
115+
writer.push('"');
116+
}
117+
for (k, v) in e.attributes.iter() {
118+
writer.push(' ');
119+
writer.push_str(k);
120+
if let Some(v) = v {
121+
writer.push('=');
122+
writer.push('"');
123+
writer.push_str(v);
124+
writer.push('"');
125+
}
126+
}
127+
if e.variant == ElementVariant::Normal {
128+
writer.push('>');
129+
write_html_list(writer, &e.children);
130+
writer.push('<');
131+
writer.push('/');
132+
writer.push_str(&e.name);
133+
writer.push('>');
134+
} else {
135+
writer.push('/');
136+
writer.push('>');
137+
}
138+
}
139+
}

src/dom/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub mod vecmap;
2020
pub mod vecset;
2121

2222
use crate::dom::for_each::ForEach;
23+
use crate::dom::node::write_html_list;
2324
#[cfg(feature = "source-span")]
2425
use crate::dom::span::SourceSpan;
2526
use element::{Element, ElementVariant};
@@ -370,6 +371,18 @@ impl<'a> Dom<'a> {
370371
}
371372
Ok(attribute)
372373
}
374+
375+
#[inline(always)]
376+
pub fn to_html(&self) -> String {
377+
let mut result = String::new();
378+
self.write_html(&mut result);
379+
result
380+
}
381+
382+
#[inline(always)]
383+
pub fn write_html(&self, writer: &mut String) {
384+
write_html_list(writer, self.children.as_slice());
385+
}
373386
}
374387

375388
impl<'a> ForEach<'a> for Dom<'a> {

src/dom/node.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,36 @@ impl<'a> ForEach<'a> for Node<'a> {
6262
}
6363
}
6464

65+
impl Node<'_> {
66+
#[inline]
67+
pub fn to_html(&self) -> String {
68+
let mut result = String::new();
69+
self.write_html(&mut result);
70+
result
71+
}
72+
73+
#[inline]
74+
pub fn write_html(&self, writer: &mut String) {
75+
match self {
76+
Node::Text(s) => {
77+
writer.push_str(s);
78+
}
79+
Node::Element(e) => e.write_html(writer),
80+
Node::Comment(c) => {
81+
writer.push_str("<!--");
82+
writer.push_str(c);
83+
writer.push_str("-->");
84+
}
85+
}
86+
}
87+
}
88+
89+
pub(crate) fn write_html_list(writer: &mut String, list: &[Node]) {
90+
for n in list {
91+
n.write_html(writer);
92+
}
93+
}
94+
6595
impl<'a> IntoIterator for &'a Node<'a> {
6696
type Item = &'a Node<'a>;
6797
type IntoIter = NodeIntoIterator<'a>;

0 commit comments

Comments
 (0)