use std::io;
use std::io::*;
use urlencoding;
pub fn write_html(w: &mut dyn Write, code: &str) -> io::Result<()> {
write!(w, "{}", code)
}
pub fn write_html_ln(w: &mut dyn Write, code: &str) -> io::Result<()> {
write!(w, "{}", code)?;
write!(w, "\n")
}
pub fn write_html_text(w: &mut dyn Write, text: &str) -> io::Result<()> {
write!(w, "{}", encode_html_text(text))
}
const HTTP_PROTOCOL: &str = "http://";
const HTTPS_PROTOCOL: &str = "https://";
pub fn write_html_link(w: &mut dyn Write, uri: &str, text: &str) -> io::Result<()> {
write_html(w, "<a href=\"")?;
if uri.starts_with("#") {
write_html(w, "#")?;
write_html(w, &urlencoding::encode(&uri[1..]).to_owned())?;
} else if uri.starts_with(HTTP_PROTOCOL) {
write_html(w, HTTP_PROTOCOL)?;
write_html(w, &urlencoding::encode(&uri[HTTP_PROTOCOL.len() ..]).to_owned())?;
} else if uri.starts_with(HTTPS_PROTOCOL) {
write_html(w, HTTPS_PROTOCOL)?;
write_html(w, &urlencoding::encode(&uri[HTTPS_PROTOCOL.len() ..]).to_owned())?;
} else {
write_html(w, &urlencoding::encode(uri).to_owned())?;
}
write_html(w, "\">")?;
write_html_text(w, text)?;
write_html(w, "</a>")
}
pub fn write_html_image(w: &mut dyn Write, uri: &str) -> io::Result<()> {
write_html(w, "<img src=\"")?;
if uri.starts_with(HTTP_PROTOCOL) {
write_html(w, HTTP_PROTOCOL)?;
write_html(w, &urlencoding::encode(&uri[HTTP_PROTOCOL.len() ..]).to_owned())?;
} else if uri.starts_with(HTTPS_PROTOCOL) {
write_html(w, HTTPS_PROTOCOL)?;
write_html(w, &urlencoding::encode(&uri[HTTPS_PROTOCOL.len() ..]).to_owned())?;
} else {
write_html(w, &urlencoding::encode(uri).to_owned())?;
}
write_html(w, "\" />")
}
pub fn begin_html_paragraph(w: &mut dyn Write) -> io::Result<()> {
write_html_ln(w, "<p>")
}
pub fn begin_html_paragraph_by_id(w: &mut dyn Write, id: &str) -> io::Result<()> {
write_html(w, "<p id=\"")?;
write_html(w, &urlencoding::encode(id).to_owned())?;
write_html_ln(w, "\">")
}
pub fn end_html_paragraph(w: &mut dyn Write) -> io::Result<()> {
write_html_ln(w, "</p>")
}
pub fn write_html_header1(w: &mut dyn Write, text: &str) -> io::Result<()> {
write_html(w, "<h1>")?;
write_html_text(w, text)?;
write_html_ln(w, "</h1>")
}
pub fn write_html_header1_by_id(w: &mut dyn Write, id: &str, text: &str) -> io::Result<()> {
write_html(w, "<h1 id=\"")?;
write_html(w, &urlencoding::encode(id).to_owned())?;
write_html(w, "\">")?;
write_html_text(w, text)?;
write_html_ln(w, "</h1>")
}
pub fn write_html_header2(w: &mut dyn Write, text: &str) -> io::Result<()> {
write_html(w, "<h2>")?;
write_html_text(w, text)?;
write_html_ln(w, "</h2>")
}
pub fn write_html_header2_by_id(w: &mut dyn Write, id: &str, text: &str) -> io::Result<()> {
write_html(w, "<h2 id=\"")?;
write_html(w, &urlencoding::encode(id).to_owned())?;
write_html(w, "\">")?;
write_html_text(w, text)?;
write_html_ln(w, "</h2>")
}
pub fn write_html_header3(w: &mut dyn Write, text: &str) -> io::Result<()> {
write_html(w, "<h3>")?;
write_html_text(w, text)?;
write_html_ln(w, "</h3>")
}
pub fn write_html_header3_by_id(w: &mut dyn Write, id: &str, text: &str) -> io::Result<()> {
write_html(w, "<h3 id=\"")?;
write_html(w, &urlencoding::encode(id).to_owned())?;
write_html(w, "\">")?;
write_html_text(w, text)?;
write_html_ln(w, "</h3>")
}
pub fn write_html_header4(w: &mut dyn Write, text: &str) -> io::Result<()> {
write_html(w, "<h4>")?;
write_html_text(w, text)?;
write_html_ln(w, "</h4>")
}
pub fn write_html_header4_by_id(w: &mut dyn Write, id: &str, text: &str) -> io::Result<()> {
write_html(w, "<h4 id=\"")?;
write_html(w, &urlencoding::encode(id).to_owned())?;
write_html(w, "\">")?;
write_html_text(w, text)?;
write_html_ln(w, "</h4>")
}
pub fn write_html_header5(w: &mut dyn Write, text: &str) -> io::Result<()> {
write_html(w, "<h5>")?;
write_html_text(w, text)?;
write_html_ln(w, "</h5>")
}
pub fn write_html_header5_by_id(w: &mut dyn Write, id: &str, text: &str) -> io::Result<()> {
write_html(w, "<h5 id=\"")?;
write_html(w, &urlencoding::encode(id).to_owned())?;
write_html(w, "\">")?;
write_html_text(w, text)?;
write_html_ln(w, "</h5>")
}
pub fn write_html_header6(w: &mut dyn Write, text: &str) -> io::Result<()> {
write_html(w, "<h6>")?;
write_html_text(w, text)?;
write_html_ln(w, "</h6>")
}
pub fn write_html_header6_by_id(w: &mut dyn Write, id: &str, text: &str) -> io::Result<()> {
write_html(w, "<h6 id=\"")?;
write_html(w, &urlencoding::encode(id).to_owned())?;
write_html(w, "\">")?;
write_html_text(w, text)?;
write_html_ln(w, "</h6>")
}
pub fn write_html_break(w: &mut dyn Write) -> io::Result<()> {
write_html_ln(w, "<br />")
}
pub fn begin_html_list(w: &mut dyn Write) -> io::Result<()> {
write_html_ln(w, "<ul>")
}
pub fn end_html_list(w: &mut dyn Write) -> io::Result<()> {
write_html_ln(w, "</ul>")
}
pub fn begin_html_list_item(w: &mut dyn Write) -> io::Result<()> {
write_html(w, "<li>")
}
pub fn end_html_list_item(w: &mut dyn Write) -> io::Result<()> {
write_html_ln(w, "</li>")
}
pub fn begin_html_document(w: &mut dyn Write, title: &str) -> io::Result<()> {
write_html_ln(w, "<html>")?;
write_html_ln(w, "<head>")?;
write_html_ln(w, "<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />")?;
write_html(w, "<title>")?;
write_html_text(w, title)?;
write_html_ln(w, "</title>")?;
write_html_css(w)?;
write_html_ln(w, "</head>")?;
write_html_ln(w, "<body>")?;
write_html_header1(w, title)
}
pub fn end_html_document(w: &mut dyn Write) -> io::Result<()> {
write_html_break(w)?;
begin_html_paragraph(w)?;
write_html(w, "<font size=\"-1\">Automatically generated by ")?;
write_html(w, "<a href='https://gitflic.ru/project/dsorokin/dvcompute'>DVCompute Simulator</a>")?;
write_html_ln(w, "</font>")?;
end_html_paragraph(w)?;
write_html_ln(w, "</body>")?;
write_html_ln(w, "</html>")
}
fn write_html_css(w: &mut dyn Write) -> io::Result<()> {
write_html_ln(w, "<style type=\"text/css\">")?;
write_html_ln(w, "* { margin: 0; padding: 0 }")?;
write_html_ln(w, "")?;
write_html_ln(w, "html {")?;
write_html_ln(w, " background-color: white;")?;
write_html_ln(w, " width: 100%;")?;
write_html_ln(w, " height: 100%;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "body {")?;
write_html_ln(w, " background: white;")?;
write_html_ln(w, " color: black;")?;
write_html_ln(w, " text-align: left;")?;
write_html_ln(w, " min-height: 100%;")?;
write_html_ln(w, " width: 90%;")?;
write_html_ln(w, " margin: 0px auto 0px auto;")?;
write_html_ln(w, " position: relative;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "p {")?;
write_html_ln(w, " margin: 0.8em 0;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "ul, ol {")?;
write_html_ln(w, " margin: 0.8em 0 0.8em 2em;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "dl {")?;
write_html_ln(w, " margin: 0.8em 0;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "dt {")?;
write_html_ln(w, " font-weight: bold;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "dd {")?;
write_html_ln(w, " margin-left: 2em;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "a { text-decoration: none; }")?;
write_html_ln(w, "a[href]:link { color: rgb(196,69,29); }")?;
write_html_ln(w, "a[href]:visited { color: rgb(171,105,84); }")?;
write_html_ln(w, "a[href]:hover { text-decoration:underline; }")?;
write_html_ln(w, "")?;
write_html_ln(w, "body {")?;
write_html_ln(w, " font-size:medium;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "h1 { font-size: 146.5%; /* 19pt */ } ")?;
write_html_ln(w, "h2 { font-size: 131%; /* 17pt */ }")?;
write_html_ln(w, "h3 { font-size: 116%; /* 15pt */ }")?;
write_html_ln(w, "h4 { font-size: 100%; /* 13pt */ }")?;
write_html_ln(w, "h5 { font-size: 100%; /* 13pt */ }")?;
write_html_ln(w, "")?;
write_html_ln(w, "select, input, button, textarea {")?;
write_html_ln(w, " font:99% sans-serif;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "table {")?;
write_html_ln(w, " font-size:inherit;")?;
write_html_ln(w, " font:100%;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "pre, code, kbd, samp, tt, .src {")?;
write_html_ln(w, " font-family:monospace;")?;
write_html_ln(w, " *font-size:108%;")?;
write_html_ln(w, " line-height: 124%;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, ".links, .link {")?;
write_html_ln(w, " font-size: 85%; /* 11pt */")?;
write_html_ln(w, "}")?;
write_html_ln(w, ".info {")?;
write_html_ln(w, " font-size: 85%; /* 11pt */")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, ".caption, h1, h2, h3, h4, h5, h6 { ")?;
write_html_ln(w, " font-weight: bold;")?;
write_html_ln(w, " color: rgb(78,98,114);")?;
write_html_ln(w, " margin: 0.8em 0 0.4em;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "* + h1, * + h2, * + h3, * + h4, * + h5, * + h6 {")?;
write_html_ln(w, " margin-top: 2em;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "h1 + h2, h2 + h3, h3 + h4, h4 + h5, h5 + h6 {")?;
write_html_ln(w, " margin-top: inherit;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "ul.links {")?;
write_html_ln(w, " list-style: none;")?;
write_html_ln(w, " text-align: left;")?;
write_html_ln(w, " float: right;")?;
write_html_ln(w, " display: inline-table;")?;
write_html_ln(w, " margin: 0 0 0 1em;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "ul.links li {")?;
write_html_ln(w, " display: inline;")?;
write_html_ln(w, " border-left: 1px solid #d5d5d5; ")?;
write_html_ln(w, " white-space: nowrap;")?;
write_html_ln(w, " padding: 0;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "")?;
write_html_ln(w, "ul.links li a {")?;
write_html_ln(w, " padding: 0.2em 0.5em;")?;
write_html_ln(w, "}")?;
write_html_ln(w, "</style>")
}
fn encode_html_text(s: &str) -> String {
s.chars()
.map(|c| { escape_html_char(c)} )
.collect::<String>()
}
fn escape_html_char(c: char) -> String {
match c {
'<' => "<".to_string(),
'>' => ">".to_string(),
'&' => "&".to_string(),
'"' => """.to_string(),
'\'' => "'".to_string(),
c => c.to_string()
}
}