summary refs log tree commit diff stats
path: root/src/new/chapter.rs
blob: 749202f7688bc423d4cb40659b4a560bf2e04c86 (plain) (blame)
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
use std::{fs, path::Path};

use convert_case::{Case, Casing};

use crate::{
    config_file::Config,
    file_tree::{FileTree, GeneratedFile},
};

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));

    Ok(file_tree)
}

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;

    GeneratedFile::new(
        project_root.join("lpm.toml"),
        toml::to_string(&config).expect("We changed it ourselfes, the conversion should work"),
    )
}

fn new_chapter_file(config: &Config, name: &str, project_root: &Path) -> GeneratedFile {
    let chapter_text = config
        .templates
        .chapter
        .replace("REPLACEMENT_CHAPTER", &name);

    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    ",
            &format!(
                "{:02}_{}",
                config.last_chapter.number + 1,
                &name.to_case(Case::Snake)
            ),
            "chapter.tex",
        ),
    );

    Ok(GeneratedFile::new(project_root.join("main.tex"), main_text))
}