Tholp's bespoke website generator
1use std::path::PathBuf;
2
3use crate::{
4 console::error_skid,
5 macros::{simple_blocks::macro_comment, template::SkidTemplate},
6 project::Project,
7};
8
9pub struct Token {
10 //pub contents: String,
11 pub contents: char,
12 pub origin_index: usize,
13 pub template_origin: usize,
14 pub origin_line: usize,
15 pub section_index: usize,
16 pub pre_proccessed: bool,
17}
18
19impl PartialEq<char> for Token {
20 fn eq(&self, other: &char) -> bool {
21 self.contents == *other
22 }
23}
24
25pub struct InputFile {
26 pub file_input: PathBuf,
27 pub file_skidout: PathBuf,
28 pub file_out: PathBuf,
29}
30
31pub struct SkidContext {
32 pub templates: Vec<SkidTemplate>,
33 pub file_index: usize,
34}
35
36impl SkidContext {
37 pub fn new(file_index: usize) -> SkidContext {
38 SkidContext {
39 templates: Vec::new(),
40 file_index,
41 }
42 }
43}
44
45type MacroExpansion =
46 fn(usize, usize, &mut Project, &mut SkidContext, &Vec<String>, &[Token]) -> Vec<Token>;
47// (
48// origin_index: usize,
49// origin_line: usize,
50// context: &mut ProjectContext,
51// templates: &mut Vec<SkidTemplate>,
52// args: &Vec<String>,
53// scope: &[Token],
54// ) -> Vec<Token>
55
56pub struct Macro {
57 pub symbol: &'static str,
58 pub expansion: MacroExpansion,
59 pub takes_block: bool, //takes blocks of text input as well as parameters using [[{}]]
60 pub min_args: usize,
61 pub max_args: usize,
62}
63
64pub trait MacroExpand {
65 fn expand(
66 &self,
67 origin_index: usize,
68 origin_line: usize,
69 context: &mut Project,
70 skid_context: &mut SkidContext,
71 args: &Vec<String>,
72 scope: &[Token],
73 ) -> Vec<Token>;
74}
75
76pub trait IsScoped {
77 fn is_scoped(&self) -> bool;
78}
79
80impl Macro {
81 fn default() -> Macro {
82 Macro {
83 symbol: "default_symbol",
84 expansion: macro_comment,
85 takes_block: true,
86 min_args: 0,
87 max_args: usize::max_value(),
88 }
89 }
90}
91
92impl MacroExpand for Macro {
93 fn expand(
94 &self,
95 origin_index: usize,
96 origin_line: usize,
97 proj_context: &mut Project,
98 skid_context: &mut SkidContext,
99 args: &Vec<String>,
100 block: &[Token],
101 ) -> Vec<Token> {
102 if (args.len() > self.max_args) || (args.len() < self.min_args) {
103 error_skid(proj_context, origin_index, origin_line, &format!("Macro \'{}\' was given a number of arguments ({}) not in its acceptable range ({}-{})",
104 self.symbol, args.len(), self.min_args, if self.max_args == usize::max_value() {"No Limit".to_string()} else {format!("{}", self.max_args)}));
105 Vec::new()
106 } else {
107 (self.expansion)(
108 origin_index,
109 origin_line,
110 proj_context,
111 skid_context,
112 args,
113 block,
114 )
115 }
116 }
117}
118
119impl IsScoped for Macro {
120 fn is_scoped(&self) -> bool {
121 self.takes_block
122 }
123}
124
125impl InputFile {
126 pub fn new() -> InputFile {
127 InputFile {
128 file_input: "".into(),
129 file_skidout: "".into(),
130 file_out: "".into(),
131 }
132 }
133}
134
135impl Token {
136 pub fn new(contents: char, origin_file: usize, line_number: usize) -> Token {
137 Token {
138 contents,
139 origin_index: origin_file,
140 template_origin: origin_file,
141 origin_line: line_number,
142 section_index: 0,
143 pre_proccessed: false,
144 }
145 }
146}
147
148impl Clone for Token {
149 fn clone(&self) -> Self {
150 let mut t = Token::new(
151 self.contents.clone(),
152 self.origin_index.clone(),
153 self.origin_line,
154 );
155 t.section_index = self.section_index;
156 t.template_origin = self.template_origin;
157 t.pre_proccessed = self.pre_proccessed;
158 return t;
159 }
160}