aboutsummaryrefslogtreecommitdiffstats
path: root/src/new
diff options
context:
space:
mode:
authorBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-09-29 11:31:20 +0200
committerBenedikt Peetz <benedikt.peetz@b-peetz.de>2024-09-29 11:31:20 +0200
commit5630948b876445db6416437eb582a18e53498a5d (patch)
tree89f119293da22284d72bf72502033d5aaf34ff7b /src/new
parentfix(MangledName): Ensure that the mangled names are actually correct (diff)
downloadlpm-5630948b876445db6416437eb582a18e53498a5d.zip
feat(new/chapter): Improve `\include` and `\includeonly` generation
Diffstat (limited to 'src/new')
-rw-r--r--src/new/chapter.rs111
1 files changed, 85 insertions, 26 deletions
diff --git a/src/new/chapter.rs b/src/new/chapter.rs
index 7628db6..9fb5301 100644
--- a/src/new/chapter.rs
+++ b/src/new/chapter.rs
@@ -1,9 +1,11 @@
use std::{fmt::Display, fs, path::Path};
use anyhow::{Context, Result};
+use log::error;
use crate::{
config_file::Config,
+ constants::{NEXT_CHAPTER, NEXT_CHAPTER_INCLUDE_ONLY},
file_tree::{FileTree, GeneratedFile},
};
@@ -141,6 +143,30 @@ fn new_chapter_file(
)
}
+fn find(input: &str, marker: &str, source_path: &Path) -> anyhow::Result<usize> {
+ let find_index = input.find(marker).with_context(|| {
+ format!(
+ "Failed to find the '{}' in '{}'.",
+ marker,
+ source_path.display()
+ )
+ })?;
+ Ok(find_index)
+}
+
+fn find_and_append(
+ input: &mut String,
+ marker: &str,
+ source_path: &Path,
+ insertion: &str,
+) -> anyhow::Result<()> {
+ let find_index = find(input, marker, source_path)?;
+
+ input.insert_str(find_index, insertion);
+
+ Ok(())
+}
+
fn new_main_file(
project_root: &Path,
config: &Config,
@@ -151,38 +177,71 @@ fn new_main_file(
let main_path = project_root.join(&config.main_file);
let mut main_text = fs::read_to_string(&main_path)?;
- let chapter_includeonly: String = format!(
- "\\includeonly{{content/{}/{}}}",
+ let chapter_path = format!(
+ "content/{}/{}",
ChapterName::from_str(name, last_chapter_number).to_string(),
"chapter.tex",
);
- if &last_chapter_name.as_str() == &"static" && last_chapter_number == 0 {
- // This is the first added chapter; The `\includeonly` will be empty.
- main_text = main_text.replace("\\includeonly{}", &chapter_includeonly)
- } else {
- main_text = main_text.replace(
- &format!(
- "\\includeonly{{content/{}/{}}}",
- ChapterName::new(last_chapter_name, last_chapter_number - 1).to_string(),
- "chapter.tex",
- ),
- &chapter_includeonly,
- )
- };
+ // Check if this is the first added chapter; Then there should be no other path before this one.
+ if last_chapter_name.as_str() != "static" && last_chapter_number != 0 {
+ let old_path = format!(
+ "content/{}/{}",
+ ChapterName::new(last_chapter_name, last_chapter_number - 1).to_string(),
+ "chapter.tex",
+ );
+ let find_index = find(&main_text, NEXT_CHAPTER_INCLUDE_ONLY, &main_path)?;
- let find_index = main_text
- .find("% NEXT_CHAPTER")
- .expect("The % NEXT_CHAPTER maker must exist");
+ // The last element adds the indentation.
+ let previous_includeonly_white_space = main_text
+ .as_bytes()
+ .iter()
+ .take(find_index)
+ .rev()
+ .take_while(|byte| **byte == ' ' as u8 || **byte == '\n' as u8)
+ .count();
+ let previous_includeonly = find_index - (old_path.len() + previous_includeonly_white_space);
- main_text.insert_str(
- find_index,
- &format!(
- "\\include{{content/{}/{}}}\n ",
- ChapterName::from_str(name, last_chapter_number).to_string(),
- "chapter.tex",
- ),
- );
+ let old_include = {
+ let old_bytes = main_text
+ .as_bytes()
+ .into_iter()
+ .take(find_index)
+ .rev()
+ .take(find_index - previous_includeonly)
+ .rev()
+ .map(|b| *b)
+ .collect::<Vec<u8>>();
+
+ let string = String::from_utf8(old_bytes).expect("This should be valid utf8");
+
+ string.trim().to_owned()
+ };
+
+ if old_include != old_path.as_str() {
+ error!(
+ "Failed to determine the old includeonly path: Found '{}' but expected '{}'. \
+ Refusing to add a comment to it.",
+ old_include, old_path
+ )
+ } else {
+ main_text.insert_str(previous_includeonly, "% ");
+ }
+ }
+
+ find_and_append(
+ &mut main_text,
+ NEXT_CHAPTER_INCLUDE_ONLY,
+ &main_path,
+ &format!("{}\n ", chapter_path),
+ )?;
+
+ find_and_append(
+ &mut main_text,
+ NEXT_CHAPTER,
+ &main_path,
+ &format!("\\include{{{}}}\n", chapter_path),
+ )?;
Ok(GeneratedFile::new(main_path, main_text))
}