aboutsummaryrefslogtreecommitdiffstats
path: root/src/new
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/new/chapter.rs143
-rw-r--r--src/new/mod.rs95
-rw-r--r--src/new/project.rs111
-rw-r--r--src/new/section.rs100
4 files changed, 142 insertions, 307 deletions
diff --git a/src/new/chapter.rs b/src/new/chapter.rs
index 88f2a85..749202f 100644
--- a/src/new/chapter.rs
+++ b/src/new/chapter.rs
@@ -1,67 +1,108 @@
-use std::{
- fs::{self, File},
- io::{self, Write},
-};
+use std::{fs, path::Path};
use convert_case::{Case, Casing};
-use crate::data::Data;
+use crate::{
+ config_file::Config,
+ file_tree::{FileTree, GeneratedFile},
+};
-use super::{get_project_root, CHAPTER};
+pub fn generate_new_chapter(
+ config: Config,
+ project_root: &Path,
+ name: String,
+) -> anyhow::Result<FileTree> {
+ let mut file_tree = FileTree::new();
+ file_tree.add_file(new_main_file(project_root, &config, &name)?);
+ file_tree.add_file(new_chapter_file(&config, &name, project_root));
+ file_tree.add_file(new_lpm_toml_file(config, name, project_root));
-pub fn generate_new_chapter(name: String) -> io::Result<()> {
- let project_root = get_project_root().unwrap();
+ Ok(file_tree)
+}
- let raw_data_file = fs::read_to_string(project_root.join("lpm.toml")).unwrap();
- let mut data_file: Data = toml::from_str(&raw_data_file).unwrap();
- let mut main_file = fs::read_to_string(project_root.join("main.tex")).unwrap();
+fn new_lpm_toml_file(mut config: Config, name: String, project_root: &Path) -> GeneratedFile {
+ config.last_chapter.user_name = name.to_case(Case::Snake);
+ config.last_chapter.number += 1;
- fs::create_dir(project_root.join(format!("content/{}", name.to_case(Case::Snake),))).unwrap();
- let mut new_chapter = File::create(project_root.join(format!(
- "content/{}/chapter_{:02}.tex",
- name.to_case(Case::Snake),
- data_file.last_chapter.number + 1
- )))
- .unwrap();
- new_chapter
- .write_all(CHAPTER.replace("REPLACEMENT_CHAPTER", &name).as_bytes())
- .unwrap();
+ GeneratedFile::new(
+ project_root.join("lpm.toml"),
+ toml::to_string(&config).expect("We changed it ourselfes, the conversion should work"),
+ )
+}
- fs::create_dir(project_root.join(format!("content/{}/sections", name.to_case(Case::Snake),)))
- .unwrap();
+fn new_chapter_file(config: &Config, name: &str, project_root: &Path) -> GeneratedFile {
+ let chapter_text = config
+ .templates
+ .chapter
+ .replace("REPLACEMENT_CHAPTER", &name);
- main_file = main_file.replace(
- &format!(
- "\\includeonly{{content/{}/{}}}",
- &data_file.last_chapter.user_name,
- &format!("chapter_{:02}", data_file.last_chapter.number)
- ),
- &format!(
- "\\includeonly{{content/{}/{}}}",
- name.to_case(Case::Snake),
- &format!("chapter_{:02}", data_file.last_chapter.number + 1)
- ),
- );
- let find_index = main_file.find("% NEXT_CHAPTER").unwrap();
- main_file.insert_str(
+ GeneratedFile::new(
+ project_root
+ .join("content")
+ .join(format! {"{:02}_{}", config.last_chapter.number + 1, name.to_case(Case::Snake)})
+ .join("chapter.tex"),
+ chapter_text,
+ )
+}
+
+fn new_main_file(
+ project_root: &Path,
+ config: &Config,
+ name: &str,
+) -> anyhow::Result<GeneratedFile> {
+ let mut main_text = fs::read_to_string(project_root.join("main.tex"))?;
+
+ if &config.last_chapter.user_name == "static" && config.last_chapter.number == 0 {
+ // This is the first added chapter; The `\includeonly` will be empty.
+ main_text = main_text.replace(
+ "\\includeonly{}",
+ &format!(
+ "\\includeonly{{content/{}/{}}}",
+ &format!(
+ "{:02}_{}",
+ config.last_chapter.number + 1,
+ &name.to_case(Case::Snake)
+ ),
+ "chapter.tex",
+ ),
+ )
+ } else {
+ main_text = main_text.replace(
+ &format!(
+ "\\includeonly{{content/{}/{}}}",
+ &format!(
+ "{:02}_{}",
+ config.last_chapter.number, &config.last_chapter.user_name
+ ),
+ "chapter.tex",
+ ),
+ &format!(
+ "\\includeonly{{content/{}/{}}}",
+ &format!(
+ "{:02}_{}",
+ config.last_chapter.number + 1,
+ &name.to_case(Case::Snake)
+ ),
+ "chapter.tex",
+ ),
+ )
+ };
+
+ let find_index = main_text
+ .find("% NEXT_CHAPTER")
+ .expect("The % NEXT_CHAPTER maker must exist");
+ main_text.insert_str(
find_index,
&format!(
"\\include{{content/{}/{}}}\n ",
- name.to_case(Case::Snake),
- &format!("chapter_{:02}", data_file.last_chapter.number + 1)
+ &format!(
+ "{:02}_{}",
+ config.last_chapter.number + 1,
+ &name.to_case(Case::Snake)
+ ),
+ "chapter.tex",
),
);
- data_file.last_chapter.user_name = name.to_case(Case::Snake);
- data_file.last_chapter.number += 1;
-
- fs::write(
- project_root.join("lpm.toml"),
- toml::to_string(&data_file).expect("We changed it ourselfes, the conversion should work"),
- )
- .unwrap();
-
- fs::write(project_root.join("main.tex"), main_file).unwrap();
-
- Ok(())
+ Ok(GeneratedFile::new(project_root.join("main.tex"), main_text))
}
diff --git a/src/new/mod.rs b/src/new/mod.rs
index 33783c4..a85187c 100644
--- a/src/new/mod.rs
+++ b/src/new/mod.rs
@@ -1,97 +1,2 @@
pub mod chapter;
-pub mod project;
pub mod section;
-
-use std::{
- env,
- ffi::OsString,
- fs::read_dir,
- io::{self, ErrorKind},
- path::PathBuf,
-};
-
-const SECTION: &'static str = r#"%! TEX root = ../../../main.tex
-% LTeX: language=de-DE
-
-\lesson{REPLACMENT_SECTION_TITLE}{DATE}{}
-Dies ist etwas Text
-"#;
-
-const CHAPTER: &'static str = r#"%! TEX root = ../main.tex
-% LTeX: language=de-DE
-
-\chapter{REPLACEMENT_CHAPTER}
-"#;
-
-const TITLE_FILE: &'static str = r#"% LTeX: language=de-DE
-
-\maketitle
-\tableofcontents
-\vspace*{\fill}
-\makeatletter
-Copyright \textcopyright{} \@authors{} \@years{}\\
-\ \\
-Dieses Werk ist lizenziert unter den Bedingungen der CC BY-SA 4.0.
-Der Lizenztext ist online unter \url{http://creativecommons.org/licenses/by-sa/4.0/legalcode} abrufbar.
-\makeatother
-\clearpage
-"#;
-
-const MAIN_FILE: &'static str = r#"%\documentclass[a4paper, 12pt, nosolutions]{report}
-\documentclass[a4paper, 12pt]{report}
-% LTeX: language=de-DE
-\input{headers/preamble.tex}
-\input{headers/preamble_local.tex}
-
-
-\title{\textbf{Titel}}
-\author{Name\thanks{Beispiel}}
-\authors{Name}
-\years{2022 - 2023}
-\date{\DTMDate{2002-12-4}}
-
-\includeonly{content/REPLACEMENT_CHAPTER/chapter_01}
-
-\begin{document}
- \input{content/static/title}
-
- \include{content/REPLACEMENT_CHAPTER/chapter_01}
- % NEXT_CHAPTER
-
- \printbibliography\relax
-\end{document}
-"#;
-
-pub fn get_project_root() -> io::Result<PathBuf> {
- let path = env::current_dir()?;
- let mut path_ancestors = path.as_path().ancestors();
-
- while let Some(path_segment) = path_ancestors.next() {
- if 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));
- }
- }
- Err(io::Error::new(
- ErrorKind::NotFound,
- "Ran out of places to find lpm.toml",
- ))
-}
-
-pub fn get_all_chapters() -> io::Result<Vec<String>> {
- let path = get_project_root()?;
- let output = read_dir(path.join("content"))?
- .map(|path| {
- path.expect("The values sholud be fine")
- .file_name()
- .to_str()
- .expect("all names should be valid utf-8")
- .to_owned()
- })
- .collect();
- Ok(output)
-}
diff --git a/src/new/project.rs b/src/new/project.rs
deleted file mode 100644
index 56edead..0000000
--- a/src/new/project.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-use std::{
- env,
- fs::{self, File},
- io::{self, Write},
- path::PathBuf,
- process::Command,
-};
-
-use convert_case::{Case, Casing};
-
-use crate::data::Data;
-
-use super::{CHAPTER, MAIN_FILE, TITLE_FILE};
-
-const NEEDED_DIRECTORYS: &'static [&'static str] =
- &["build", "content", "headers", "references", "resources"];
-
-pub fn generate_new_project(
- name: String,
- first_chapter: String,
- //first_section: String,
- preamble_path: PathBuf,
- resource_path: PathBuf,
-) -> io::Result<()> {
- fs::create_dir(&name).unwrap();
- env::set_current_dir(&name).unwrap();
- let project_root = env::current_dir().unwrap();
-
- for directory in NEEDED_DIRECTORYS {
- fs::create_dir(directory).unwrap();
- }
-
- // content
- env::set_current_dir(project_root.join("content")).unwrap();
- fs::create_dir(&first_chapter.to_case(Case::Snake)).unwrap();
- fs::create_dir("static").unwrap();
-
- env::set_current_dir("static").unwrap();
- let mut title_file = File::create("title.tex").unwrap();
- title_file.write_all(TITLE_FILE.as_bytes()).unwrap();
-
- env::set_current_dir(
- project_root
- .join("content")
- .join(&first_chapter.to_case(Case::Snake)),
- )
- .unwrap();
- fs::create_dir("sections").unwrap();
- let mut chapter_file = File::create("chapter_01.tex").unwrap();
- chapter_file
- .write_all(
- CHAPTER
- .replace("REPLACEMENT_CHAPTER", &first_chapter)
- .as_bytes(),
- )
- .unwrap();
-
- //env::set_current_dir("sections").unwrap();
- //let mut section_file = File::create(format!("{}.tex", &first_section)).unwrap();
- //section_file
- // .write_all(SECTION.as_bytes())
- // .unwrap();
-
- // headers
- env::set_current_dir(project_root.join("headers")).unwrap();
- File::create("preamble_local.tex").unwrap();
- fs::copy(fs::canonicalize(preamble_path).unwrap(), "preamble.tex").unwrap();
-
- // resources
- env::set_current_dir(project_root.join("resources")).unwrap();
- fs::canonicalize(resource_path)
- .unwrap()
- .read_dir()
- .unwrap()
- .map(|path| path.expect("The provided path should work"))
- .for_each(|path| {
- fs::copy(path.path(), path.file_name()).unwrap();
- });
-
- // root files
- env::set_current_dir(project_root).unwrap();
- let mut main_file = File::create("main.tex").unwrap();
- main_file
- .write_all(
- MAIN_FILE
- .replace("REPLACEMENT_CHAPTER", &first_chapter.to_case(Case::Snake))
- .as_bytes(),
- )
- .unwrap();
-
- let data_file = Data {
- last_chapter: crate::data::LastChapter {
- user_name: first_chapter.to_case(Case::Snake),
- number: 1,
- },
- };
- let mut lpm_file = File::create("lpm.toml").unwrap();
- lpm_file
- .write_all(toml::to_string(&data_file).unwrap().as_bytes())
- .unwrap();
-
- Command::new("git")
- .arg("init")
- .output()
- .expect("failed to execute process");
-
- let mut lpm_file = File::create(".gitignore").unwrap();
- lpm_file.write_all(b"/build").unwrap();
-
- Ok(())
-}
diff --git a/src/new/section.rs b/src/new/section.rs
index 31742c2..a359fb0 100644
--- a/src/new/section.rs
+++ b/src/new/section.rs
@@ -1,63 +1,63 @@
-use std::{
- env,
- fs::{self, read_dir},
- io::{self, ErrorKind},
- path::PathBuf,
- time::SystemTime,
-};
+use std::{fs, path::Path, time::SystemTime};
+use anyhow::Context;
use chrono::{DateTime, Local};
use convert_case::{Case, Casing};
+use log::debug;
-use super::SECTION;
+use crate::{
+ config_file::Config,
+ file_tree::{FileTree, GeneratedFile},
+};
-pub fn generate_new_section(name: String) -> io::Result<()> {
- let chapter_root = get_section_root()?;
- let chapter_main_file_path = read_dir(&chapter_root)?
- .into_iter()
- .map(|path| path.unwrap())
- .filter(|path| path.file_name().to_str().unwrap().contains("chapter_"))
- .last()
- .unwrap()
- .path();
- let mut main_file = fs::read_to_string(&chapter_main_file_path).unwrap();
+pub fn generate_new_section(
+ config: &Config,
+ name: String,
+ project_root: &Path,
+ chapter_name: &str,
+) -> anyhow::Result<FileTree> {
+ let chapter_root = project_root.join("content").join(chapter_name);
+ debug!("Chapter root is: {}", chapter_root.display());
- main_file.push_str(&format!(
- "\\input{{content/{}/sections/{}}}\n",
- chapter_root.file_name().unwrap().to_str().unwrap(),
- &name.to_case(Case::Snake)
- ));
- fs::write(chapter_main_file_path, main_file)?;
- fs::write(
- chapter_root.join(format!("sections/{}.tex", name.to_case(Case::Snake))),
- SECTION.replace("REPLACMENT_SECTION_TITLE", &name).replace(
+ let mut file_tree = FileTree::new();
+
+ let new_section_text = config
+ .templates
+ .section
+ .replace("REPLACMENT_SECTION_TITLE", &name)
+ .replace(
"DATE",
&format!(
"{}",
- DateTime::<Local>::from(SystemTime::now()).format("%Y-%m-%d")
+ // FIXME: The time is not really precise enough to display the time. <2024-03-31>
+ DateTime::<Local>::from(SystemTime::now()).format("%Y-%m-%d (%_H:%_S)")
),
- ),
- )?;
- Ok(())
-}
+ );
+
+ let new_section_file = GeneratedFile::new(
+ chapter_root
+ .join("sections")
+ .join(format!("{}.tex", name.to_case(Case::Snake))),
+ new_section_text,
+ );
+ file_tree.add_file(new_section_file);
+
+ let chapter_file_path = chapter_root.join("chapter.tex");
+ let mut chapter_file_text = fs::read_to_string(&chapter_file_path).with_context(|| {
+ format!(
+ "Failed to read the chapter main file ('{}') to string",
+ &chapter_file_path.display(),
+ )
+ })?;
+
+ chapter_file_text.push_str(&format!(
+ "\\input{{content/{}/sections/{}}}\n",
+ chapter_name,
+ &name.to_case(Case::Snake)
+ ));
-pub fn get_section_root() -> io::Result<PathBuf> {
- let path = env::current_dir()?;
- let mut path_ancestors = path.as_path().ancestors();
+ let chapter_file = GeneratedFile::new(chapter_file_path, chapter_file_text);
+ file_tree.add_file(chapter_file);
- while let Some(path_segment) = path_ancestors.next() {
- if read_dir(path_segment)?.into_iter().any(|path| {
- path.expect("The read_dir shouldn't error out here")
- .file_name()
- .to_str()
- .unwrap()
- .contains("chapter_")
- }) {
- return Ok(PathBuf::from(path_segment));
- }
- }
- Err(io::Error::new(
- ErrorKind::NotFound,
- "Ran out of places to find chapter_root",
- ))
+ Ok(file_tree)
}