1extern crate marksman_escape;
2use self::marksman_escape::Escape;
3
4use {DomNode, DomNodes, DomValue};
5use processors::DomNodeProcessor;
6
7use std::marker::PhantomData;
9use std::fmt;
10use std::io;
11
12#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
17pub struct HtmlWriter<W: io::Write>(PhantomData<W>);
18impl<'a, M, W: io::Write> DomNodeProcessor<'a, M> for HtmlWriter<W> {
19 type Acc = W;
20 type Error = io::Error;
21
22 fn get_processor<T: DomNode<M>>() -> fn(&mut Self::Acc, &T) -> Result<(), Self::Error> {
23 fn add_node<M, W, T>(w: &mut W, node: &T) -> Result<(), io::Error>
24 where W: io::Write, T: DomNode<M> {
25 match node.value() {
26 DomValue::Element { tag: tagname } => {
27 write!(w, "<{}", tagname)?;
28 for attr in node.attributes() {
29 write!(w, " {}=\"{}\"", attr.0, attr.1)?;
30 }
31 write!(w, ">")?;
32 node.children().process_all::<HtmlWriter<W>>(w)?;
33 write!(w, "</{}>", tagname)
34 }
35 DomValue::Text(text) => {
36 for escaped_u8 in Escape::new(text.bytes()) {
37 w.write(&[escaped_u8])?;
38 }
39 Ok(())
40 }
41 }
42 }
43 add_node
44 }
45}
46
47#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
49pub struct HtmlDisplayable<'a, M, T: DomNode<M> + 'a>(pub &'a T, pub PhantomData<M>);
50
51impl<'a, M, T: DomNode<M>> fmt::Display for HtmlDisplayable<'a, M, T> {
52 fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
53 let mut string_buffer = Vec::new();
55 self.0.write_html(&mut string_buffer)
56 .map_err(|_| fmt::Error)?;
57 let string = String::from_utf8(string_buffer)
58 .map_err(|_| fmt::Error)?;
59 formatter.write_str(&string)
60 }
61}