Tholp's bespoke website generator

extend !insert

Tholp1 94b0f56f 3a16cd22

+1
src/macros/clear.rs
···
pub fn macro_clear(
_file: &mut InputFile,
+
_origin_index: usize,
_context: &mut ProjectContext,
_args: &Vec<String>,
_scope: &[Token],
+63 -6
src/macros/insert.rs
···
-
use std::{env::Args, fs, path::PathBuf};
+
use std::{
+
env::Args,
+
fs,
+
path::{Path, PathBuf},
+
process::exit,
+
};
use crate::{
projectparse::{FileIndexing, ProjectContext},
···
pub fn macro_insert(
_file: &mut InputFile,
+
_origin_index: usize,
_context: &mut ProjectContext,
args: &Vec<String>,
_scope: &[Token],
) -> Vec<Token> {
-
print!("\nargs: {:?}\n", args);
-
let mut output = fs::read_to_string(args[0].clone()).expect("File unreadable or missing");
-
if output.ends_with("\n") {
+
let mut origin_file = _context
+
.file_for_index(_origin_index)
+
.expect("Macro 'Insert' was given a bad origin index")
+
.clone();
+
if args.len() != 1 {
+
println!(
+
"\"{:?}\":Insert only accepts 1 argument, got given {} ({:?})",
+
origin_file.to_str(),
+
args.len(),
+
args
+
);
+
exit(1);
+
}
+
+
let mut arg = args[0].clone();
+
let mut search_from_root = arg.starts_with("//");
+
let mut ok = false;
+
+
if search_from_root
+
{
+
arg.drain(0..2); //remove "//"
+
}
+
+
let mut include_file = "".to_string();
+
if !search_from_root {
+
let mut include_path = origin_file.clone();
+
include_path.pop();
+
include_path.push(&arg);
+
+
if include_path.exists() && include_path.is_file() {
+
ok = true;
+
include_file = include_path.to_str().unwrap().to_string();
+
} else {
+
search_from_root = true;
+
}
+
}
+
+
if search_from_root {
+
let mut include_path = _context.input_folder.clone();
+
include_path.push(&arg);
+
+
if include_path.exists() && include_path.is_file() {
+
ok = true;
+
include_file = include_path.to_str().unwrap().to_string();
+
}
+
}
+
+
if !ok {
+
println!("\"{:?}\": Insert was unable to find the file \"{}\" relative to its origin or in project root.", origin_file.to_str(), arg);
+
exit(1);
+
}
+
+
let mut output = fs::read_to_string(&include_file).expect("File unreadable or missing");
+
while output.ends_with("\n") {
output.pop();
-
} //remove trailing newline
+
} //remove trailing newlines
let split_output = split_keep_delimiters(output);
return strings_to_tokens(
split_output,
-
_context.index_of_file(&PathBuf::from(&args[0])),
+
_context.index_of_file(&PathBuf::from(&include_file)),
);
}
+7 -2
src/macros/mod.rs
···
use clear::macro_clear;
use insert::macro_insert;
-
use simple_blocks::{macro_comment, macro_repeat};
+
use simple_blocks::{macro_comment, macro_null, macro_repeat};
-
pub static MACRO_LIST: [Macro<'_>; 4] = [
+
pub static MACRO_LIST: [Macro<'_>; 5] = [
// Unscoped
Macro {
symbol: "insert", // Inserts another file
···
Macro {
symbol: "repeat", // Outputs what its give x number of times
expand: macro_repeat,
+
has_scope: true,
+
},
+
Macro {
+
symbol: "preformatted",
+
expand: macro_null,
has_scope: true,
},
];
+3
src/macros/simple_blocks.rs
···
pub fn macro_comment(
_file: &mut InputFile,
+
_origin_index: usize,
_context: &mut ProjectContext,
_args: &Vec<String>,
_scope: &[Token],
···
pub fn macro_null(
_file: &mut InputFile,
+
_origin_index: usize,
_context: &mut ProjectContext,
_args: &Vec<String>,
scope: &[Token],
···
pub fn macro_repeat(
_file: &mut InputFile,
+
_origin_index: usize,
_context: &mut ProjectContext,
args: &Vec<String>,
scope: &[Token],
+15 -3
src/main.rs
···
};
use types::{InputFile, Macro, Token};
-
static DELIMITERS: [char; 10] = [' ', '\n', '\t', '(', ')', '{', '}', '\\', '\'', '\"'];
+
static DELIMITERS: [char; 12] = [' ', '\n', '\t', '(', ')', '{', '}', '[', ']', '\\', '\'', '\"'];
fn main() {
let mut project_folder = PathBuf::from(env::current_dir().unwrap().as_path());
···
&file.tokens[(file.working_index + args_tokcount)..],
);
println!("{}", block_tokcount);
-
expansion = (m.expand)(file, context, &args, &block[..]);
+
expansion = (m.expand)(
+
file,
+
file.tokens[file.working_index].origin_file,
+
context,
+
&args,
+
&block[..],
+
);
} else {
block_tokcount = 0;
-
expansion = (m.expand)(file, context, &args, &Vec::new()[..]);
+
expansion = (m.expand)(
+
file,
+
file.tokens[file.working_index].origin_file,
+
context,
+
&args,
+
&Vec::new()[..],
+
);
}
}
+15 -14
src/projectparse.rs
···
pub struct Project {
pub filegroups: Vec<FileGroup>,
-
pub settings: ProjectSettings,
+
//pub settings: ProjectSettings,
pub context: ProjectContext,
}
···
pub process: bool,
}
-
pub struct ProjectSettings {
+
// pub struct ProjectSettings {
+
+
// }
+
+
pub struct ProjectContext {
pub input_folder: PathBuf,
pub output_folder: PathBuf,
pub global_pre_insert: PathBuf,
pub global_post_insert: PathBuf,
-
}
-
pub struct ProjectContext {
pub filemap: Vec<PathBuf>, // mapped to index
+
//variables later
}
···
let mut project: Project = Project {
filegroups: Vec::new(),
-
settings: ProjectSettings {
+
context: ProjectContext {
input_folder: PathBuf::new(),
output_folder: PathBuf::new(),
global_pre_insert: PathBuf::new(),
global_post_insert: PathBuf::new(),
-
},
-
context: ProjectContext {
filemap: Vec::new(),
},
};
···
.parent()
.expect("Project file unreadable or missing.");
-
project.settings.input_folder = PathBuf::from(get_table_string_or_default!(
+
project.context.input_folder = PathBuf::from(get_table_string_or_default!(
settings_section,
"inputFolder",
"skid"
));
-
project.settings.output_folder = PathBuf::from(get_table_string_or_default!(
+
project.context.output_folder = PathBuf::from(get_table_string_or_default!(
settings_section,
"outputFolder",
"content"
));
-
project.settings.global_pre_insert = project_root.join(get_table_string_or_default!(
+
project.context.global_pre_insert = project_root.join(get_table_string_or_default!(
settings_section,
"preInsertGlobal",
""
));
-
project.settings.global_post_insert = project_root.join(get_table_string_or_default!(
+
project.context.global_post_insert = project_root.join(get_table_string_or_default!(
settings_section,
"postInsertGlobal",
""
···
)
});
let mut new_file = crate::types::InputFile::new();
-
new_file.file_input = project.settings.input_folder.clone();
+
new_file.file_input = project.context.input_folder.clone();
new_file.file_input.push(filename);
-
new_file.file_htmlout = project.settings.output_folder.clone();
+
new_file.file_htmlout = project.context.output_folder.clone();
new_file.file_htmlout.push(filename);
new_file.file_htmlout.set_extension("html");
···
index = index + 1;
}
self.filemap.push(cannonical);
-
self.filemap.len()
+
return self.filemap.len() - 1;
}
fn file_for_index(&self, i: usize) -> Option<&PathBuf> {
+1 -1
src/stringtools.rs
···
}
for tok in tokens.iter().rev() {
-
end = end - 1;
if !tok.contents.is_only_whitespace() {
break;
}
+
end = end - 1;
}
return &tokens[start..end];
+2 -1
src/types.rs
···
pub working_index: usize,
}
-
type MacroExpansion = fn(&mut InputFile, &mut ProjectContext, &Vec<String>, &[Token]) -> Vec<Token>;
+
type MacroExpansion =
+
fn(&mut InputFile, usize, &mut ProjectContext, &Vec<String>, &[Token]) -> Vec<Token>;
pub struct Macro<'a> {
pub symbol: &'a str,
pub expand: MacroExpansion,