use crate::{css, Ast, CommonOpt, ConvertSubcommand};
use log::*;
use std::{ffi::OsStr, io, path::Path};
use vimwiki::*;
use walkdir::WalkDir;
pub fn convert(
cmd: ConvertSubcommand,
opt: CommonOpt,
config: HtmlConfig,
mut ast: Ast,
) -> io::Result<()> {
if cmd.extra_paths.is_empty() {
for (_, wiki) in
config.wikis.iter().enumerate().filter(|(idx, wiki)| {
opt.filter_by_wiki_idx_and_name(*idx, wiki.name.as_deref())
})
{
process_path(
config.clone(),
&mut ast,
wiki.path.as_path(),
opt.cache.as_path(),
opt.no_cache,
cmd.stdout,
&wiki.ext,
)?;
if !cmd.stdout && cmd.include_vimwiki_css {
let css_path =
wiki.path_html.join(HtmlWikiConfig::default_css_name());
debug!("Writing css to {:?}", css_path);
std::fs::write(css_path, css::DEFAULT_STYLE_FILE)?;
}
}
}
for path in cmd.extra_paths {
let path = match path.canonicalize() {
Ok(path) => path,
Err(x) => {
error!("{:?} failed to canonicalize: {}", path, x);
return Err(x);
}
};
process_path(
config.clone(),
&mut ast,
path.as_path(),
opt.cache.as_path(),
opt.no_cache,
cmd.stdout,
&HtmlWikiConfig::default_ext(),
)?;
if !cmd.stdout && cmd.include_vimwiki_css {
let wiki = config.runtime.to_tmp_wiki();
let css_path = wiki.path_html.join("style.css");
debug!("Writing css to {:?}", css_path);
std::fs::write(css_path, css::DEFAULT_STYLE_FILE)?;
}
}
Ok(())
}
fn process_path(
config: HtmlConfig,
ast: &mut Ast,
input_path: &Path,
cache: &Path,
no_cache: bool,
stdout: bool,
ext: &str,
) -> io::Result<()> {
trace!(
"process_path(_, input_path = {:?}, stdout = {}, ext = {})",
input_path,
stdout,
ext
);
for entry in WalkDir::new(input_path)
.into_iter()
.filter_map(|e| e.ok())
.filter(|e| {
e.file_type().is_file()
&& e.path().extension().and_then(OsStr::to_str) == Some(ext)
})
{
let mut config = config.clone();
let page_path = entry.path().to_path_buf();
let wiki_index = config.find_wiki_index_by_path(page_path.as_path());
debug!("{:?}: Wiki {:?}", page_path, wiki_index);
config.map_runtime(|mut rt| {
rt.page = page_path.to_path_buf();
rt.wiki_index = wiki_index;
rt
});
process_file(
config,
ast,
page_path.as_path(),
cache,
no_cache,
stdout,
)?;
}
Ok(())
}
fn process_file(
config: HtmlConfig,
ast: &mut Ast,
input_path: &Path,
cache: &Path,
no_cache: bool,
stdout: bool,
) -> io::Result<()> {
trace!(
"process_file(_, input_path = {:?}, stdout = {})",
input_path,
stdout
);
let maybe_wiki = if !stdout {
config.find_wiki_by_path(input_path).cloned()
} else {
None
};
let html = if let Some(file) = ast.find_file_by_path(input_path) {
debug!("{:?} :: loaded from cache!", input_path);
file.data.to_html_page(config).map_err(|x| {
io::Error::new(io::ErrorKind::InvalidData, x.to_string())
})?
} else {
let file = ast.load_file(input_path, cache, no_cache)?;
file.data.to_html_page(config).map_err(|x| {
io::Error::new(io::ErrorKind::InvalidData, x.to_string())
})?
};
debug!("{:?} :: html generated!", input_path);
if stdout {
println!("{}", html);
} else {
let path = maybe_wiki
.unwrap_or_default()
.make_output_path(input_path, "html");
info!("Writing to {:?}", path);
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(path, html)?;
}
Ok(())
}