use std::path::Path;
use crate::config::Config;
use crate::errors::*;
use crate::site::markdown::{self, SyntaxTheme};
use crate::paths::determine_path;
use crate::site::templates::Templates;
use axoasset::SourceFile;
use camino::Utf8PathBuf;
use minijinja::context;
use minijinja::value::Value;
use serde::Serialize;
pub mod source;
#[derive(Debug)]
pub struct Page {
pub contents: String,
pub filename: String,
}
impl Page {
pub fn new_from_template<T: Serialize>(
filename: &str,
templates: &Templates,
template_name: &str,
context: &T,
) -> Result<Self> {
let contents =
templates.render_to_string(template_name, Value::from_serializable(context))?;
Ok(Self {
contents,
filename: filename.to_string(),
})
}
pub fn new_from_markdown(
path: &str,
templates: &Templates,
config: &Config,
fail_fast: bool,
) -> Result<Self> {
let body = Self::load_and_render_contents(path, &config.styles.syntax_theme)?;
let contents = if let Some(body) = body {
templates.render_to_string("markdown_page.html", context!(body))?
} else {
if fail_fast {
return Err(OrandaError::PathDoesNotExist {
path: path.to_string(),
});
}
templates.render_to_string("markdown_page.html", context!())?
};
let relpath = if let Some(path) = pathdiff::diff_paths(path, std::env::current_dir()?) {
path
} else {
path.into()
};
Ok(Self {
contents,
filename: relpath.display().to_string(),
})
}
pub fn new_from_both<T: Serialize>(
path: &str,
filename: &str,
templates: &Templates,
template_name: &str,
context: T,
config: &Config,
) -> Result<Self> {
let body = Self::load_and_render_contents(path, &config.styles.syntax_theme)?;
if body.is_none() {
tracing::warn!("{} could not be found on disk!", path);
}
let template = templates.get(template_name)?;
let context =
context!(layout => templates.layout, page => context, markdown_content => body);
let contents = template.render(context)?;
Ok(Self {
contents,
filename: filename.to_string(),
})
}
fn load_and_render_contents(
source: &str,
syntax_theme: &SyntaxTheme,
) -> Result<Option<String>> {
let src_path = Utf8PathBuf::from_path_buf(std::env::current_dir()?)
.expect("Current directory is not UTF-8");
let path = determine_path(src_path, &None::<Utf8PathBuf>, source)?;
if let Some(path) = path {
let source = SourceFile::load_local(path)?;
let contents = source.contents();
Ok(Some(markdown::to_html(contents, syntax_theme)?))
} else {
Ok(None)
}
}
pub fn filename(source: &str) -> String {
let file_stem = Path::new(source).file_stem().expect("source file exists");
format!("{}.html", file_stem.to_string_lossy())
}
}