Tholp's bespoke website generator

extend !insert

Tholp1 94b0f56f 3a16cd22

+107 -27
+1
src/macros/clear.rs
··· 6 6 7 7 pub fn macro_clear( 8 8 _file: &mut InputFile, 9 + _origin_index: usize, 9 10 _context: &mut ProjectContext, 10 11 _args: &Vec<String>, 11 12 _scope: &[Token],
+63 -6
src/macros/insert.rs
··· 1 - use std::{env::Args, fs, path::PathBuf}; 1 + use std::{ 2 + env::Args, 3 + fs, 4 + path::{Path, PathBuf}, 5 + process::exit, 6 + }; 2 7 3 8 use crate::{ 4 9 projectparse::{FileIndexing, ProjectContext}, ··· 8 13 9 14 pub fn macro_insert( 10 15 _file: &mut InputFile, 16 + _origin_index: usize, 11 17 _context: &mut ProjectContext, 12 18 args: &Vec<String>, 13 19 _scope: &[Token], 14 20 ) -> Vec<Token> { 15 - print!("\nargs: {:?}\n", args); 16 - let mut output = fs::read_to_string(args[0].clone()).expect("File unreadable or missing"); 17 - if output.ends_with("\n") { 21 + let mut origin_file = _context 22 + .file_for_index(_origin_index) 23 + .expect("Macro 'Insert' was given a bad origin index") 24 + .clone(); 25 + if args.len() != 1 { 26 + println!( 27 + "\"{:?}\":Insert only accepts 1 argument, got given {} ({:?})", 28 + origin_file.to_str(), 29 + args.len(), 30 + args 31 + ); 32 + exit(1); 33 + } 34 + 35 + let mut arg = args[0].clone(); 36 + let mut search_from_root = arg.starts_with("//"); 37 + let mut ok = false; 38 + 39 + if search_from_root 40 + { 41 + arg.drain(0..2); //remove "//" 42 + } 43 + 44 + let mut include_file = "".to_string(); 45 + if !search_from_root { 46 + let mut include_path = origin_file.clone(); 47 + include_path.pop(); 48 + include_path.push(&arg); 49 + 50 + if include_path.exists() && include_path.is_file() { 51 + ok = true; 52 + include_file = include_path.to_str().unwrap().to_string(); 53 + } else { 54 + search_from_root = true; 55 + } 56 + } 57 + 58 + if search_from_root { 59 + let mut include_path = _context.input_folder.clone(); 60 + include_path.push(&arg); 61 + 62 + if include_path.exists() && include_path.is_file() { 63 + ok = true; 64 + include_file = include_path.to_str().unwrap().to_string(); 65 + } 66 + } 67 + 68 + if !ok { 69 + println!("\"{:?}\": Insert was unable to find the file \"{}\" relative to its origin or in project root.", origin_file.to_str(), arg); 70 + exit(1); 71 + } 72 + 73 + let mut output = fs::read_to_string(&include_file).expect("File unreadable or missing"); 74 + while output.ends_with("\n") { 18 75 output.pop(); 19 - } //remove trailing newline 76 + } //remove trailing newlines 20 77 21 78 let split_output = split_keep_delimiters(output); 22 79 return strings_to_tokens( 23 80 split_output, 24 - _context.index_of_file(&PathBuf::from(&args[0])), 81 + _context.index_of_file(&PathBuf::from(&include_file)), 25 82 ); 26 83 }
+7 -2
src/macros/mod.rs
··· 5 5 6 6 use clear::macro_clear; 7 7 use insert::macro_insert; 8 - use simple_blocks::{macro_comment, macro_repeat}; 8 + use simple_blocks::{macro_comment, macro_null, macro_repeat}; 9 9 10 - pub static MACRO_LIST: [Macro<'_>; 4] = [ 10 + pub static MACRO_LIST: [Macro<'_>; 5] = [ 11 11 // Unscoped 12 12 Macro { 13 13 symbol: "insert", // Inserts another file ··· 28 28 Macro { 29 29 symbol: "repeat", // Outputs what its give x number of times 30 30 expand: macro_repeat, 31 + has_scope: true, 32 + }, 33 + Macro { 34 + symbol: "preformatted", 35 + expand: macro_null, 31 36 has_scope: true, 32 37 }, 33 38 ];
+3
src/macros/simple_blocks.rs
··· 5 5 6 6 pub fn macro_comment( 7 7 _file: &mut InputFile, 8 + _origin_index: usize, 8 9 _context: &mut ProjectContext, 9 10 _args: &Vec<String>, 10 11 _scope: &[Token], ··· 14 15 15 16 pub fn macro_null( 16 17 _file: &mut InputFile, 18 + _origin_index: usize, 17 19 _context: &mut ProjectContext, 18 20 _args: &Vec<String>, 19 21 scope: &[Token], ··· 27 29 28 30 pub fn macro_repeat( 29 31 _file: &mut InputFile, 32 + _origin_index: usize, 30 33 _context: &mut ProjectContext, 31 34 args: &Vec<String>, 32 35 scope: &[Token],
+15 -3
src/main.rs
··· 19 19 }; 20 20 use types::{InputFile, Macro, Token}; 21 21 22 - static DELIMITERS: [char; 10] = [' ', '\n', '\t', '(', ')', '{', '}', '\\', '\'', '\"']; 22 + static DELIMITERS: [char; 12] = [' ', '\n', '\t', '(', ')', '{', '}', '[', ']', '\\', '\'', '\"']; 23 23 24 24 fn main() { 25 25 let mut project_folder = PathBuf::from(env::current_dir().unwrap().as_path()); ··· 117 117 &file.tokens[(file.working_index + args_tokcount)..], 118 118 ); 119 119 println!("{}", block_tokcount); 120 - expansion = (m.expand)(file, context, &args, &block[..]); 120 + expansion = (m.expand)( 121 + file, 122 + file.tokens[file.working_index].origin_file, 123 + context, 124 + &args, 125 + &block[..], 126 + ); 121 127 } else { 122 128 block_tokcount = 0; 123 - expansion = (m.expand)(file, context, &args, &Vec::new()[..]); 129 + expansion = (m.expand)( 130 + file, 131 + file.tokens[file.working_index].origin_file, 132 + context, 133 + &args, 134 + &Vec::new()[..], 135 + ); 124 136 } 125 137 } 126 138
+15 -14
src/projectparse.rs
··· 11 11 12 12 pub struct Project { 13 13 pub filegroups: Vec<FileGroup>, 14 - pub settings: ProjectSettings, 14 + //pub settings: ProjectSettings, 15 15 pub context: ProjectContext, 16 16 } 17 17 ··· 23 23 pub process: bool, 24 24 } 25 25 26 - pub struct ProjectSettings { 26 + // pub struct ProjectSettings { 27 + 28 + // } 29 + 30 + pub struct ProjectContext { 27 31 pub input_folder: PathBuf, 28 32 pub output_folder: PathBuf, 29 33 pub global_pre_insert: PathBuf, 30 34 pub global_post_insert: PathBuf, 31 - } 32 35 33 - pub struct ProjectContext { 34 36 pub filemap: Vec<PathBuf>, // mapped to index 37 + 35 38 //variables later 36 39 } 37 40 ··· 65 68 66 69 let mut project: Project = Project { 67 70 filegroups: Vec::new(), 68 - settings: ProjectSettings { 71 + context: ProjectContext { 69 72 input_folder: PathBuf::new(), 70 73 output_folder: PathBuf::new(), 71 74 global_pre_insert: PathBuf::new(), 72 75 global_post_insert: PathBuf::new(), 73 - }, 74 - context: ProjectContext { 75 76 filemap: Vec::new(), 76 77 }, 77 78 }; ··· 89 90 .parent() 90 91 .expect("Project file unreadable or missing."); 91 92 92 - project.settings.input_folder = PathBuf::from(get_table_string_or_default!( 93 + project.context.input_folder = PathBuf::from(get_table_string_or_default!( 93 94 settings_section, 94 95 "inputFolder", 95 96 "skid" 96 97 )); 97 98 98 - project.settings.output_folder = PathBuf::from(get_table_string_or_default!( 99 + project.context.output_folder = PathBuf::from(get_table_string_or_default!( 99 100 settings_section, 100 101 "outputFolder", 101 102 "content" 102 103 )); 103 104 104 - project.settings.global_pre_insert = project_root.join(get_table_string_or_default!( 105 + project.context.global_pre_insert = project_root.join(get_table_string_or_default!( 105 106 settings_section, 106 107 "preInsertGlobal", 107 108 "" 108 109 )); 109 - project.settings.global_post_insert = project_root.join(get_table_string_or_default!( 110 + project.context.global_post_insert = project_root.join(get_table_string_or_default!( 110 111 settings_section, 111 112 "postInsertGlobal", 112 113 "" ··· 146 147 ) 147 148 }); 148 149 let mut new_file = crate::types::InputFile::new(); 149 - new_file.file_input = project.settings.input_folder.clone(); 150 + new_file.file_input = project.context.input_folder.clone(); 150 151 new_file.file_input.push(filename); 151 152 152 - new_file.file_htmlout = project.settings.output_folder.clone(); 153 + new_file.file_htmlout = project.context.output_folder.clone(); 153 154 new_file.file_htmlout.push(filename); 154 155 new_file.file_htmlout.set_extension("html"); 155 156 ··· 182 183 index = index + 1; 183 184 } 184 185 self.filemap.push(cannonical); 185 - self.filemap.len() 186 + return self.filemap.len() - 1; 186 187 } 187 188 188 189 fn file_for_index(&self, i: usize) -> Option<&PathBuf> {
+1 -1
src/stringtools.rs
··· 207 207 } 208 208 209 209 for tok in tokens.iter().rev() { 210 - end = end - 1; 211 210 if !tok.contents.is_only_whitespace() { 212 211 break; 213 212 } 213 + end = end - 1; 214 214 } 215 215 216 216 return &tokens[start..end];
+2 -1
src/types.rs
··· 16 16 pub working_index: usize, 17 17 } 18 18 19 - type MacroExpansion = fn(&mut InputFile, &mut ProjectContext, &Vec<String>, &[Token]) -> Vec<Token>; 19 + type MacroExpansion = 20 + fn(&mut InputFile, usize, &mut ProjectContext, &Vec<String>, &[Token]) -> Vec<Token>; 20 21 pub struct Macro<'a> { 21 22 pub symbol: &'a str, 22 23 pub expand: MacroExpansion,