use crate::visualization::svg::Svg;
#[derive(Debug, Clone)]
pub struct Html {
pub title: String,
pub svg: Svg,
pub css: String,
pub javascript: String,
}
impl std::fmt::Display for Html {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "<!DOCTYPE html>")?;
writeln!(f, "<html>")?;
writeln!(f, "<head>")?;
writeln!(f, " <meta charset=\"UTF-8\">")?;
writeln!(
f,
" <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">"
)?;
writeln!(f, " <title>{}</title>", html_escape(&self.title))?;
writeln!(f, " <style>")?;
writeln!(f, "{}", self.css)?;
writeln!(f, " </style>")?;
writeln!(f, "</head>")?;
writeln!(f, "<body>")?;
writeln!(f, " <div id=\"search-box\" class=\"hidden\">")?;
writeln!(
f,
" <input id=\"search-input\" type=\"text\" placeholder=\"Search\u{2026}\" autocomplete=\"off\" spellcheck=\"false\" />"
)?;
writeln!(f, " <span id=\"search-count\"></span>")?;
writeln!(
f,
" <button id=\"search-prev\" title=\"Previous (Shift+Enter)\">\u{2191}</button>"
)?;
writeln!(
f,
" <button id=\"search-next\" title=\"Next (Enter)\">\u{2193}</button>"
)?;
writeln!(
f,
" <button id=\"search-close\" title=\"Close (Esc)\">\u{00d7}</button>"
)?;
writeln!(f, " </div>")?;
writeln!(f, " <div id=\"viewport\">")?;
writeln!(f, " <div id=\"canvas\">")?;
write!(f, "{}", self.svg_with_viewbox())?;
writeln!(f, " </div>")?;
writeln!(f, " </div>")?;
writeln!(f, " <script>")?;
writeln!(f, "{}", self.javascript)?;
writeln!(f, " </script>")?;
writeln!(f, "</body>")?;
writeln!(f, "</html>")
}
}
impl Html {
fn svg_with_viewbox(&self) -> String {
let svg = &self.svg;
let mut output = String::new();
output.push_str(&format!(
r#"<svg viewBox="0 0 {} {}" preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg">"#,
svg.width, svg.height
));
output.push('\n');
for element in &svg.elements {
output.push_str(&format!("{}", element));
}
output.push_str("</svg>\n");
output
}
}
fn html_escape(s: &str) -> String {
s.replace('&', "&")
.replace('<', "<")
.replace('>', ">")
.replace('"', """)
.replace('\'', "'")
}