Tholp's bespoke website generator
1use std::{fs, path::PathBuf};
2
3use crate::{
4 console::error_skid,
5 process_skid,
6 project::{Indexing, Project},
7 stringtools::split_to_tokens,
8 types::{SkidContext, Token},
9};
10
11pub fn macro_insert(
12 origin_index: usize,
13 origin_line: usize,
14 proj_context: &mut Project,
15 skid_context: &mut SkidContext,
16 args: &Vec<String>,
17 _scope: &[Token],
18) -> Vec<Token> {
19 let origin_file = proj_context
20 .file_for_index_canonical(origin_index)
21 .expect("Macro 'Insert' was given a bad origin index")
22 .clone();
23
24 let mut sections_ids_to_keep = Vec::new();
25
26 if args.len() > 1 {
27 for a in &args[1..] {
28 let id = proj_context.index_of_section_name(a);
29 sections_ids_to_keep.push(id);
30 }
31 }
32
33 let mut arg = args[0].clone();
34 let mut search_from_root = arg.starts_with("//");
35 let mut ok = false;
36
37 if search_from_root {
38 arg.drain(0..2); //remove "//"
39 }
40
41 let mut include_file = "".to_string();
42 if !search_from_root {
43 let mut include_path = origin_file.clone();
44 include_path.pop();
45 include_path.push(&arg);
46
47 if include_path.exists() && include_path.is_file() {
48 ok = true;
49 include_file = include_path.to_str().unwrap().to_string();
50 } else {
51 search_from_root = true;
52 }
53 }
54
55 if search_from_root {
56 let mut include_path = proj_context.input_folder.clone();
57 include_path.push(&arg);
58
59 if include_path.exists() && include_path.is_file() {
60 ok = true;
61 include_file = include_path.to_str().unwrap().to_string();
62 }
63 }
64
65 if !ok {
66 error_skid(proj_context, origin_index, origin_line, &format!("Insert was unable to find the file \"{}\" relative to its origin or in project root.", arg));
67 }
68
69 let mut output = fs::read_to_string(&include_file).expect("File unreadable or missing");
70 while output.ends_with("\n") {
71 output.pop();
72 } //remove trailing newlines
73
74 if sections_ids_to_keep.len() > 0 {
75 let mut processed = process_skid(
76 &split_to_tokens(
77 output,
78 proj_context.index_of_file(&PathBuf::from(&include_file)),
79 ),
80 proj_context,
81 skid_context,
82 );
83 processed.retain(|t| sections_ids_to_keep.contains(&t.section_index));
84 for t in &mut processed {
85 t.pre_proccessed = true;
86 }
87 return processed;
88 } else {
89 return split_to_tokens(
90 output,
91 proj_context.index_of_file(&PathBuf::from(&include_file)),
92 );
93 }
94}