summary refs log tree commit diff stats
path: root/src/new
diff options
context:
space:
mode:
Diffstat (limited to 'src/new')
-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.rs102
4 files changed, 143 insertions, 308 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)
+    ));
+
+    let chapter_file = GeneratedFile::new(chapter_file_path, chapter_file_text);
+    file_tree.add_file(chapter_file);
 
-pub fn get_section_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| {
-            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)
 }