Tholp's bespoke website generator
at v2025.11.14 2.7 kB view raw
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}