html_preprocessor/
lib.rs

1use std::{fs, path::{PathBuf, Path}, io::Write};
2
3#[allow(dead_code)]
4pub fn process_files(base_dir: &str, template_dir: &str, out_dir: &str) {
5    
6    // Redefine all input strings to be path buffers
7    let base_dir = PathBuf::from(base_dir);
8    let template_dir = PathBuf::from(template_dir);
9    let out_dir = PathBuf::from(out_dir);
10
11    fs::create_dir_all(&out_dir).expect("Failed to create output directory");
12    println!("Created output directory: {:?}", out_dir);
13
14    // Recursively copy all files from base_dir to out_dir
15    copy_dir_recursively(&base_dir, &out_dir).expect("Failed to copy files");
16    println!("Copied files from {:?} to {:?}", base_dir, out_dir);
17
18    for entry in fs::read_dir(&base_dir).expect("Failed to read base directory") {
19        let entry = entry.expect("Failed to read base entry");
20        let path = entry.path();
21
22        if path.extension().unwrap_or_default() == "html" {
23            let mut base_html = fs::read_to_string(&path).expect("Failed to read base HTML file");
24            println!("Read base HTML file: {:?}", path);
25
26            let extends_tag_start = "{% extends ";
27            let extends_tag_end = " %}";
28
29            if let Some(start) = base_html.find(extends_tag_start) {
30                if let Some(end) = base_html.find(extends_tag_end) {
31                    let template_file = base_html[start + extends_tag_start.len()..end].trim().to_string();
32                    base_html = base_html.replace(&format!("{}{}{}", extends_tag_start, template_file, extends_tag_end), "");
33
34                    let template_path = template_dir.join(&template_file);
35                    let template_html = fs::read_to_string(&template_path).expect("Failed to read template HTML file");
36                    println!("Read template HTML file: {:?}", template_path);
37
38                    let new_html = process_html(base_html, template_html);
39
40                    let out_path = out_dir.join(path.file_name().unwrap());
41                    let mut file = fs::File::create(out_path.clone()).expect("Failed to create output file");
42                    file.write_all(new_html.as_bytes()).expect("Failed to write to output file");
43                    println!("Created output file: {:?}", out_path);
44                }
45            }
46        }
47    }
48}
49
50pub fn copy_dir_recursively<U: AsRef<Path>, V: AsRef<Path>>(from: U, to: V) -> std::io::Result<()> {
51  let from = from.as_ref();
52  let to = to.as_ref();
53  println!("Copying directory recursively from {:?} to {:?}", from, to);
54
55  if !from.is_dir() {
56      return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput, "Expected a directory"));
57  }
58
59  if let Some(parent) = to.parent() {
60      fs::create_dir_all(parent)?;
61      println!("Created parent directory: {:?}", parent);
62  }
63  if !to.exists() {
64      fs::create_dir(to)?;
65      println!("Created directory: {:?}", to);
66  }
67
68  for entry_result in fs::read_dir(from)? {
69      let entry = entry_result?;
70      let path = entry.path();
71      let name = entry.file_name();
72      let new_path = to.join(name);
73      if path.is_dir() {
74          println!("Copying directory recursively: {:?}", path);
75          copy_dir_recursively(&path, new_path)?;
76      } else {
77          println!("Copying file: {:?} -> {:?}", path, new_path);
78          fs::copy(&path, new_path)?;
79      }
80  }
81
82  Ok(())
83}
84
85
86pub fn process_html(mut base_html: String, index_html: String) -> String {
87    let blocks = ["header", "content"];
88
89    for block in &blocks {
90        let block_start_tag = format!("{{% block {} %}}", block);
91        let block_end_tag = format!("{{% endblock {} %}}", block);
92
93        let index_start = index_html.find(&block_start_tag).expect(&format!("Failed to find '{}' in index file", block_start_tag)) + block_start_tag.len();
94        let index_end = index_html.find(&block_end_tag).expect(&format!("Failed to find '{}' in index file", block_end_tag));
95        let index_block_content = &index_html[index_start..index_end].trim();
96
97        let base_start = base_html.find(&block_start_tag).expect(&format!("Failed to find '{}' in base file", block_start_tag));
98        let base_end = base_html.find(&block_end_tag).expect(&format!("Failed to find '{}' in base file", block_end_tag)) + block_end_tag.len();
99
100        base_html.replace_range(base_start..base_end, index_block_content);
101    }
102
103    base_html
104}