use std::{
env, fs,
io::{self, Write},
path::{Path, PathBuf},
};
use crate::{
config::PersistentConfig, ctry, document::Document, errmsg, errors::Result,
status::StatusBackend,
};
#[derive(Debug)]
pub struct Workspace {
root_dir: PathBuf,
doc: Document,
}
impl Workspace {
pub fn first_document(&self) -> &Document {
&self.doc
}
pub fn first_document_mut(&mut self) -> &mut Document {
&mut self.doc
}
pub fn open_from_environment() -> Result<Self> {
let mut root_dir = env::current_dir()?;
root_dir.push("tmp");
while root_dir.pop() {
root_dir.push("Tectonic.toml");
let mut doc_file = match fs::File::open(&root_dir) {
Ok(f) => f,
Err(ref e) if e.kind() == io::ErrorKind::NotFound => {
root_dir.pop(); continue; }
Err(e) => return Err(e.into()),
};
root_dir.pop();
let mut doc_build_dir = root_dir.clone();
doc_build_dir.push("build");
let doc = Document::new_from_toml(root_dir.clone(), doc_build_dir, &mut doc_file)?;
return Ok(Workspace { root_dir, doc });
}
Err(errmsg!(
"No `Tectonic.toml` found in current directory or any of its parents"
))
}
}
#[derive(Debug)]
pub struct WorkspaceCreator {
root_dir: PathBuf,
}
impl WorkspaceCreator {
pub fn new<P: Into<PathBuf>>(root_dir: P) -> Self {
WorkspaceCreator {
root_dir: root_dir.into(),
}
}
pub fn create(
self,
config: &PersistentConfig,
status: &mut dyn StatusBackend,
) -> Result<Workspace> {
let doc = Document::new_for_creator(&self, config, status)?;
let mut tex_dir = self.root_dir.clone();
tex_dir.push("src");
ctry!(
fs::create_dir_all(&tex_dir);
"couldn\'t create workspace directory `{}`", tex_dir.display()
);
doc.create_toml()?;
{
tex_dir.push("_preamble.tex");
let mut f = fs::File::create(&tex_dir)?;
f.write_all(
br#"\documentclass{article}
\title{My Title}
\begin{document}
"#,
)?;
tex_dir.pop();
}
{
tex_dir.push("index.tex");
let mut f = fs::File::create(&tex_dir)?;
f.write_all(
br#"Hello, world.
"#,
)?;
tex_dir.pop();
}
{
tex_dir.push("_postamble.tex");
let mut f = fs::File::create(&tex_dir)?;
f.write_all(
br#"\end{document}
"#,
)?;
tex_dir.pop();
}
Ok(Workspace {
root_dir: self.root_dir,
doc,
})
}
pub fn root_dir(&self) -> &Path {
&self.root_dir
}
}