Tholp's bespoke website generator

Small refactor

+3 -2
src/macros/insert.rs
···
use crate::{
console::error_skid,
+
macros::template::SkidTemplate,
project::{FileIndexing, ProjectContext},
stringtools::split_to_tokens,
-
types::{InputFile, Token},
+
types::Token,
};
pub fn macro_insert(
-
_file: &mut InputFile,
origin_index: usize,
origin_line: usize,
context: &mut ProjectContext,
+
_templates: &mut Vec<SkidTemplate>,
args: &Vec<String>,
_scope: &[Token],
) -> Vec<Token> {
+1 -8
src/macros/mod.rs
···
use insert::macro_insert;
use simple_blocks::{macro_comment, macro_for_each_arg, macro_repeat, macro_section};
-
use simple_macros::{macro_clear, macro_filename, macro_filename_canonical, macro_time};
+
use simple_macros::{macro_filename, macro_filename_canonical, macro_time};
use template::macro_template;
pub static MACRO_LIST: &'static [Macro] = &[
···
has_scope: false,
min_args: 1,
max_args: 1,
-
},
-
Macro {
-
symbol: "clear", // Clears text buffer
-
expansion: macro_clear,
-
has_scope: false,
-
min_args: 0,
-
max_args: 0,
},
Macro {
symbol: "time",
+6 -5
src/macros/simple_blocks.rs
···
use crate::{
console::{error_skid, warn_skid},
+
macros::template::SkidTemplate,
project::ProjectContext,
stringtools::{find_pattern, split_to_tokens, TokenTools},
-
types::{InputFile, Token},
+
types::Token,
};
pub fn macro_comment(
-
_file: &mut InputFile,
_origin_index: usize,
_origin_line: usize,
_context: &mut ProjectContext,
+
_templates: &mut Vec<SkidTemplate>,
_args: &Vec<String>,
_scope: &[Token],
) -> Vec<Token> {
···
}
pub fn macro_section(
-
_file: &mut InputFile,
_origin_index: usize,
_origin_line: usize,
_context: &mut ProjectContext,
+
_templates: &mut Vec<SkidTemplate>,
_args: &Vec<String>,
scope: &[Token],
) -> Vec<Token> {
···
}
pub fn macro_repeat(
-
_file: &mut InputFile,
_origin_index: usize,
_origin_line: usize,
_context: &mut ProjectContext,
+
_templates: &mut Vec<SkidTemplate>,
args: &Vec<String>,
scope: &[Token],
) -> Vec<Token> {
···
}
pub fn macro_for_each_arg(
-
_file: &mut InputFile,
origin_index: usize,
origin_line: usize,
context: &mut ProjectContext,
+
_templates: &mut Vec<SkidTemplate>,
args: &Vec<String>,
scope: &[Token],
) -> Vec<Token> {
+7 -19
src/macros/simple_macros.rs
···
use crate::{
console::{error_skid, reminder_skid},
+
macros::template::SkidTemplate,
project::{FileIndexing, ProjectContext},
stringtools::split_to_tokens,
-
types::{InputFile, Token},
+
types::Token,
};
-
pub fn macro_clear(
-
_file: &mut InputFile,
-
_origin_index: usize,
-
_origin_line: usize,
-
_context: &mut ProjectContext,
-
_args: &Vec<String>,
-
_scope: &[Token],
-
) -> Vec<Token> {
-
_file.tokens = _file.tokens.split_off(_file.working_index);
-
_file.working_index = 0;
-
return Vec::new();
-
}
-
pub fn macro_time(
-
file: &mut InputFile,
origin_index: usize,
origin_line: usize,
context: &mut ProjectContext,
+
_templates: &mut Vec<SkidTemplate>,
args: &Vec<String>,
_scope: &[Token],
) -> Vec<Token> {
···
}
pub fn macro_filename(
-
_file: &mut InputFile,
origin_index: usize,
-
_origin_line: usize,
+
origin_line: usize,
context: &mut ProjectContext,
+
_templates: &mut Vec<SkidTemplate>,
_args: &Vec<String>,
_scope: &[Token],
) -> Vec<Token> {
···
}
pub fn macro_filename_canonical(
-
_file: &mut InputFile,
origin_index: usize,
_origin_line: usize,
context: &mut ProjectContext,
+
_templates: &mut Vec<SkidTemplate>,
_args: &Vec<String>,
_scope: &[Token],
) -> Vec<Token> {
···
}
pub fn macro_reminder(
-
_file: &mut InputFile,
origin_index: usize,
origin_line: usize,
context: &mut ProjectContext,
+
_templates: &mut Vec<SkidTemplate>,
args: &Vec<String>,
_scope: &[Token],
) -> Vec<Token> {
+4 -4
src/macros/template.rs
···
project::ProjectContext,
reservednames::{RESERVED_NAMES_HTML, RESERVED_NAMES_MISC},
stringtools::{find_pattern, split_to_tokens, WhitespaceChecks},
-
types::{InputFile, Token},
+
types::Token,
};
use super::MACRO_LIST;
···
}
pub fn macro_template(
-
file: &mut InputFile,
origin_index: usize,
origin_line: usize,
context: &mut ProjectContext,
+
templates: &mut Vec<SkidTemplate>,
args: &Vec<String>,
scope: &[Token],
) -> Vec<Token> {
-
for t in &file.templates {
+
for t in templates.iter().as_ref() {
if t.symbol == args[0] {
error_skid(
context,
···
}
let template = SkidTemplate::new(args[0].clone(), &args[1..], scope);
-
file.templates.push(template);
+
templates.push(template);
return Vec::new();
}
+87 -67
src/main.rs
···
mod types;
use crate::{
-
args::ProgramArgs, project::FileGroup, reservednames::RESERVED_NAMES_MISC, types::Expand,
+
args::ProgramArgs, macros::template::SkidTemplate, project::FileGroup,
+
reservednames::RESERVED_NAMES_MISC, types::Expand,
};
use clap::Parser;
use console::*;
···
env,
fs::{self},
path::PathBuf,
+
task::Context,
};
use stringtools::{collect_arguments, collect_block, split_to_tokens, trim_whitespace_tokens};
use types::{InputFile, Token};
···
project_path = project_folder.clone();
project_path.push("skidmark.toml");
}
-
println!("Operatting with {:?}", &project_path.as_os_str());
+
println!("Operatting on {:?}", &project_path.as_os_str());
assert!(env::set_current_dir(&project_folder).is_ok());
let mut project = parse_project(&project_path);
···
}
println!("Proccesing {} files.", num);
+
// for group in &mut project.filegroups {
+
// for infile in &mut group.files {
+
// process_skid(infile, group.convert_html, &mut project.context);
+
// }
+
// }
+
for group in &mut project.filegroups {
for infile in &mut group.files {
-
process_file(infile, group.convert_html, &mut project.context);
+
let contents =
+
fs::read_to_string(&infile.file_input).expect("File unreadable or missing");
+
infile.tokens =
+
split_to_tokens(contents, project.context.index_of_file(&infile.file_input));
+
+
process_skid(
+
&mut infile.tokens,
+
project.context.index_of_file(&infile.file_input),
+
&mut project.context,
+
Vec::new(),
+
);
}
}
}
-
fn process_file(file: &mut InputFile, convert_html: bool, context: &mut ProjectContext) {
+
fn process_skid(
+
tokens_in: &mut [Token],
+
file_index: usize,
+
context: &mut ProjectContext,
+
templates_base: Vec<SkidTemplate>,
+
) -> Vec<Token> {
//}, context: &mut ProjectContext) {
-
let contents = fs::read_to_string(&file.file_input).expect("File unreadable or missing");
//println!("{}\n {}", f.filename_out, contents);
//file.tokens = strings_to_tokens(split_keep_delimiters(contents), file.filename_input.clone());
-
file.tokens = split_to_tokens(contents, context.index_of_file(&file.file_input));
+
//let mut escaped = false;
+
let mut tokens = tokens_in.to_vec();
+
let mut templates = templates_base;
-
while file.working_index < file.tokens.len() {
+
let mut working_index = 0;
+
+
while working_index < tokens.len() {
//look for macros or blocks
-
//println!(">\"{}\"<", file.tokens[file.working_index].contents);
+
//println!(">\"{}\"<", tokens[working_index].contents);
-
if file.tokens[file.working_index].contents.len() == 0 {
-
file.working_index += 1;
+
if tokens[working_index].contents.len() == 0 {
+
working_index += 1;
continue;
}
-
if file.tokens[file.working_index].contents == "\\" {
-
file.tokens[file.working_index].contents = "".into();
-
file.working_index += 2;
+
if tokens[working_index].contents == "\\" {
+
tokens[working_index].contents = "".into();
+
working_index += 2;
//println!("Hit backslash");
continue;
}
let mut matched_macro: bool = false;
-
if file.tokens[file.working_index]
-
.contents
-
.starts_with(['!', '&'])
-
{
+
if tokens[working_index].contents.starts_with(['!', '&']) {
let mut prefix_len = 1;
-
let mut symbol = file.tokens[file.working_index].contents.clone();
+
let mut symbol = tokens[working_index].contents.clone();
symbol = symbol.trim().to_string();
if symbol.len() > 2 {
let mut ephemeral = false;
-
let same_file = file.tokens[file.working_index].origin_file
-
!= context.index_of_file(&file.file_input);
+
let same_file = tokens[working_index].origin_file != file_index;
// Inversely Ephemeral
if symbol.starts_with("!&") {
···
matched_macro = true;
//println!("Found a macro ({})", m.symbol);
-
let (args, args_tokcount) =
-
collect_arguments(&file.tokens[file.working_index..]);
+
let (args, args_tokcount) = collect_arguments(&tokens[working_index..]);
let expansion: Vec<Token>;
let block_tokcount: usize;
if m.has_scope {
//println!("is scoped.");
let block_opt =
-
collect_block(&file.tokens[(file.working_index + args_tokcount)..]);
+
collect_block(&tokens[(working_index + args_tokcount)..]);
if block_opt.is_none() {
error_skid(
context,
-
file.tokens[file.working_index].template_origin,
-
file.tokens[file.working_index].line_number,
+
tokens[working_index].template_origin,
+
tokens[working_index].line_number,
&"Malformed Block".into(),
);
}
···
expansion = Vec::new();
} else {
expansion = m.expand(
-
file,
-
file.tokens[file.working_index].origin_file,
-
file.tokens[file.working_index].line_number,
+
tokens[working_index].origin_file,
+
tokens[working_index].line_number,
context,
+
&mut templates,
&args,
&block,
);
···
expansion = Vec::new();
} else {
expansion = m.expand(
-
file,
-
file.tokens[file.working_index].origin_file,
-
file.tokens[file.working_index].line_number,
+
tokens[working_index].origin_file,
+
tokens[working_index].line_number,
context,
+
&mut templates,
&args,
&Vec::new()[..],
);
···
let trimmed = trim_whitespace_tokens(&expansion);
-
file.tokens.remove(file.working_index);
-
file.tokens.splice(
-
file.working_index
-
..(file.working_index + args_tokcount + block_tokcount - 1),
+
tokens.remove(working_index);
+
tokens.splice(
+
working_index..(working_index + args_tokcount + block_tokcount - 1),
trimmed.iter().cloned(),
);
-
if expansion.len() == 0 && file.working_index > 0 {
-
file.working_index -= 1;
+
if expansion.len() == 0 && working_index > 0 {
+
working_index -= 1;
}
}
}
// check for templates
// todo maybe deduplicate this
-
for m in &mut file.templates {
-
if &symbol[prefix_len..] == m.symbol {
+
for t in &templates {
+
if &symbol[prefix_len..] == t.symbol {
matched_macro = true;
//println!("Found a macro ({})", m.symbol);
-
let (args, args_tokcount) =
-
collect_arguments(&file.tokens[file.working_index..]);
+
let (args, args_tokcount) = collect_arguments(&tokens[working_index..]);
let expansion: Vec<Token>;
let block_tokcount: usize;
-
if m.has_scope {
+
if t.has_scope {
//println!("is scoped.");
let block: Vec<Token>;
let block_opt =
-
collect_block(&file.tokens[(file.working_index + args_tokcount)..]);
+
collect_block(&tokens[(working_index + args_tokcount)..]);
if block_opt.is_none() {
error_skid(
context,
-
file.tokens[file.working_index].template_origin,
-
file.tokens[file.working_index].line_number,
+
tokens[working_index].template_origin,
+
tokens[working_index].line_number,
&"Malformed Block".into(),
);
}
···
if ephemeral {
expansion = Vec::new();
} else {
-
expansion = m.expand(
+
expansion = t.expand(
//file,
-
file.tokens[file.working_index].origin_file,
-
file.tokens[file.working_index].line_number,
+
tokens[working_index].origin_file,
+
tokens[working_index].line_number,
context,
&args,
&block,
···
if ephemeral {
expansion = Vec::new();
} else {
-
expansion = m.expand(
+
expansion = t.expand(
//file,
-
file.tokens[file.working_index].origin_file,
-
file.tokens[file.working_index].line_number,
+
tokens[working_index].origin_file,
+
tokens[working_index].line_number,
context,
&args,
&Vec::new()[..],
···
let trimmed = trim_whitespace_tokens(&expansion);
-
file.tokens.remove(file.working_index);
-
file.tokens.splice(
-
file.working_index
-
..(file.working_index + args_tokcount + block_tokcount - 1),
+
tokens.remove(working_index);
+
tokens.splice(
+
working_index..(working_index + args_tokcount + block_tokcount - 1),
trimmed.iter().cloned(),
);
-
if expansion.len() == 0 && file.working_index > 0 {
-
file.working_index -= 1;
+
if expansion.len() == 0 && working_index > 0 {
+
working_index -= 1;
}
}
}
}
if !matched_macro {
-
let name = file.tokens[file.working_index]
-
.contents
-
.trim()
-
.to_lowercase();
+
let name = tokens[working_index].contents.trim().to_lowercase();
let mut dont_error = name.len() <= 1;
{
-
if !dont_error && convert_html {
+
if !dont_error {
for reserved in RESERVED_NAMES_HTML {
if name[1..].starts_with(reserved) {
dont_error = true;
···
if !dont_error {
warn_skid(
context,
-
file.tokens[file.working_index].origin_file,
-
file.tokens[file.working_index].line_number,
+
tokens[working_index].origin_file,
+
tokens[working_index].line_number,
&format!(
"Token written as a function but no such function exists \"{}\"",
-
file.tokens[file.working_index].contents.trim()
+
tokens[working_index].contents.trim()
),
);
}
}
}
if !matched_macro {
-
file.working_index += 1;
+
working_index += 1;
}
}
-
//println!("{:?}", file.tokens);
+
+
return tokens;
+
}
+
+
fn write_file(file: InputFile, convert_html: bool) {
+
//println!("{:?}", tokens);
let mut skid_output: String = "".to_string();
for t in &file.tokens {
skid_output += &t.contents;
-6
src/project.rs
···
pub output_extention: String,
}
-
// pub struct ProjectSettings {
-
-
// }
-
pub struct ProjectContext {
pub input_folder: PathBuf,
pub output_folder: PathBuf,
···
pub global_post_insert: PathBuf,
pub filemap: Vec<PathBuf>, // mapped to index
-
-
//variables later
}
macro_rules! get_table_bool_or_default {
+14 -12
src/types.rs
···
pub file_skidout: PathBuf,
pub file_out: PathBuf,
pub tokens: Vec<Token>,
-
pub working_index: usize,
-
pub templates: Vec<SkidTemplate>,
}
-
type MacroExpansion =
-
fn(&mut InputFile, usize, usize, &mut ProjectContext, &Vec<String>, &[Token]) -> Vec<Token>;
+
type MacroExpansion = fn(
+
usize,
+
usize,
+
&mut ProjectContext,
+
&mut Vec<SkidTemplate>,
+
&Vec<String>,
+
&[Token],
+
) -> Vec<Token>;
// (
-
// _file: &mut InputFile,
// origin_index: usize,
// origin_line: usize,
// context: &mut ProjectContext,
+
// templates: &mut Vec<SkidTemplate>,
// args: &Vec<String>,
-
// _scope: &[Token],
+
// scope: &[Token],
// ) -> Vec<Token>
pub struct Macro {
pub symbol: &'static str,
pub expansion: MacroExpansion,
-
pub has_scope: bool, //takes blocks of text input as well as parameters using {{...}}
+
pub has_scope: bool, //takes blocks of text input as well as parameters using [[{}]]
pub min_args: usize,
pub max_args: usize,
}
···
pub trait Expand {
fn expand(
&self,
-
input_file: &mut InputFile,
origin_index: usize,
origin_line: usize,
context: &mut ProjectContext,
+
templates: &mut Vec<SkidTemplate>,
args: &Vec<String>,
scope: &[Token],
) -> Vec<Token>;
···
impl Expand for Macro {
fn expand(
&self,
-
input_file: &mut InputFile,
origin_index: usize,
origin_line: usize,
context: &mut ProjectContext,
+
templates: &mut Vec<SkidTemplate>,
args: &Vec<String>,
scope: &[Token],
) -> Vec<Token> {
···
self.symbol, args.len(), self.min_args, if self.max_args == usize::max_value() {"No Limit".to_string()} else {format!("{}", self.max_args)}));
Vec::new()
} else {
-
(self.expansion)(input_file, origin_index, origin_line, context, args, scope)
+
(self.expansion)(origin_index, origin_line, context, templates, args, scope)
}
}
···
file_skidout: "".into(),
file_out: "".into(),
tokens: Vec::new(),
-
working_index: 0,
-
templates: Vec::new(),
}
}
}