rst_renderer/
html.rs
1mod elems_cats;
2mod multi;
3#[cfg(test)]
4pub mod tests;
5
6use std::io::Write;
7
8use anyhow::Error;
9
10use document_tree::{Document, HasChildren};
12
13pub fn render_html<W>(document: &Document, stream: W, standalone: bool) -> Result<(), Error>
20where
21 W: Write,
22{
23 let mut renderer = HTMLRenderer { stream, level: 0 };
24 if standalone {
25 document.render_html(&mut renderer)
26 } else {
27 document.children().render_html(&mut renderer)
28 }
29}
30
31fn escape_html(text: &str) -> String {
32 text.replace('&', "&")
33 .replace('<', "<")
34 .replace('>', ">")
35 .replace('"', """)
36}
37
38struct HTMLRenderer<W>
39where
40 W: Write,
41{
42 stream: W,
43 level: u8,
44}
45
46trait HTMLRender {
47 fn render_html<W>(&self, renderer: &mut HTMLRenderer<W>) -> Result<(), Error>
48 where
49 W: Write;
50}
51
52static HEAD: &str = r#"<head>
53<meta charset="utf-8">
54<meta name="color-scheme" content="dark light">
55<meta name="viewport" content="width=device-width, initial-scale=1">
56<style>
57li.symbol {{ list-style-type: symbols(symbolic '*' '†' '‡' '§' '¶' '#' '♠' '♥' '♦' '♣'); }}
58</style>
59</head>"#;
60
61impl HTMLRender for Document {
62 fn render_html<W>(&self, renderer: &mut HTMLRenderer<W>) -> Result<(), Error>
63 where
64 W: Write,
65 {
66 writeln!(renderer.stream, "<!doctype html>\n<html>\n{HEAD}\n<body>")?;
67 self.children().render_html(renderer)?;
68 writeln!(renderer.stream, "</body>\n</html>")?;
69 Ok(())
70 }
71}
72
73