1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
use std::{env, ffi::OsString, fs, path::PathBuf};
use anyhow::{bail, Context};
use clap::Parser;
use log::debug;
use crate::{
cli::{
Args,
Command::New,
What::{Chapter, Section},
},
config_file::Config,
new::{chapter::generate_new_chapter, section::generate_new_section},
};
pub mod cli;
pub mod config_file;
pub mod new;
// The copyright header tells you, where this file is from.
pub mod file_tree;
fn main() -> anyhow::Result<()> {
env_logger::init();
let args = Args::parse();
let project_root = get_project_root_by_lmp_toml().context("Looking for the project root")?;
let config_file = fs::read_to_string(project_root.join("lpm.toml"))?;
let config: Config = toml::from_str(&config_file).context("Reading toml from string")?;
let file_tree = match args.cli {
New(new_command) => match new_command {
Section { name, chapter } => {
let chapter = if let Some(val) = chapter {
// The user probably has not added the preceeding chapter number to the chapter
// string
if val.starts_with(|c: char| c.is_numeric()) {
eprintln!(
"Your chapter name starts with a number, assuming \
that you have already added the chapter number"
);
val
} else {
bail!(
"Calculating the chapter number is not yet \
implemented, please add it yourself"
);
}
} else {
// The user thinks that they are already inside a chapter
get_upwards_chapter()?
};
generate_new_section(&config, name, &project_root, &chapter)?
}
Chapter { name } => generate_new_chapter(config, &project_root, name)?,
},
};
file_tree.materialize()?;
Ok(())
}
pub fn get_project_root_by_lmp_toml() -> anyhow::Result<PathBuf> {
let path = env::current_dir()?;
let mut path_ancestors = path.as_path().ancestors();
while let Some(path_segment) = path_ancestors.next() {
if fs::read_dir(path_segment)?.into_iter().any(|path_segment| {
path_segment
.expect("The read_dir shouldn't error out here")
.file_name()
== OsString::from("lpm.toml")
}) {
return Ok(PathBuf::from(path_segment));
}
}
bail!("Ran out of places to find lpm.toml")
}
fn get_upwards_chapter() -> anyhow::Result<String> {
let current_path = env::current_dir()?;
for anc in current_path.as_path().ancestors() {
debug!("Reading directory {}", anc.display());
for dir in fs::read_dir(anc)? {
let dir = dir?;
debug!("Checking path: {}", dir.file_name().to_string_lossy());
if dir.file_name() == OsString::from("chapter.tex") {
match anc
.file_name()
.expect("This should always be a file")
.to_str()
{
Some(str) => return Ok(str.to_owned()),
None => bail!(
"Failed to convert your path ('{}') to a string!",
dir.file_name().to_string_lossy()
),
}
}
}
}
bail!("Failed to get a chapter name, please specify one with the `--chapter` flag!")
}
|