use crate::renderable::Renderable;
use crate::Result;
use crate::{highlight, page::PageInfo};
use std::fs::{create_dir_all, File};
use std::io::prelude::*;
use std::path::Path;
pub struct Renderer {
title: String,
footer: String,
}
impl Renderer {
pub fn new(title: String, footer: String) -> Self {
Renderer { title, footer }
}
pub fn render<T: Renderable>(&self, renderable: &T, path: &Path) -> Result<PageInfo> {
let slug = renderable.get_slug();
let title = renderable.get_title();
let output_dir = path.join(&slug);
let output_path = output_dir.join("index.html");
create_dir_all(&output_dir)?;
let style_path = format!("{}/style.css", renderable.path_to_root());
let script_path = format!("{}/search.js", renderable.path_to_root());
let mut file = File::create(&output_path)?;
write!(
file,
r#"<html>
<head>
<title>{}</title>
<meta name="viewport" content="width=700">
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css?family=Merriweather|Open+Sans" rel="stylesheet">
<link rel="stylesheet" href="{}">
<script src="{}"></script>"#,
title, style_path, script_path
)?;
highlight::get_hilighter().write_header(&mut file)?;
write!(
file,
r#"
</head>
<body>"#
)?;
renderable.write_header(&mut file, &self.title)?;
renderable.write_body(&mut file)?;
write!(file, "<footer>{}</footer></body></html>", self.footer)?;
Ok(PageInfo {
title: title.into(),
slug,
path: output_path,
search_index: renderable.get_search_index(),
})
}
}