diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/macro_processor/macro_processor.rs | 39 | ||||
| -rw-r--r-- | src/skaldpress/error.rs | 3 | ||||
| -rw-r--r-- | src/skaldpress/main.rs | 66 | 
3 files changed, 75 insertions, 33 deletions
diff --git a/src/macro_processor/macro_processor.rs b/src/macro_processor/macro_processor.rs index f26780e..82a94ef 100644 --- a/src/macro_processor/macro_processor.rs +++ b/src/macro_processor/macro_processor.rs @@ -51,9 +51,9 @@ fn smp_builtin_define(      let arg0 = smp.process_input(&args[0])?;      if args.len() > 1 {          let arg1 = smp.process_input(&args[1])?; -        smp.define_macro(arg0, arg1); +        smp.define_macro(arg0, MacroType::String(arg1));      } else { -        smp.define_macro(arg0, String::new()); +        smp.define_macro(arg0, MacroType::String(String::new()));      }      Ok(String::new())  } @@ -212,6 +212,7 @@ enum ParserState {      Normal,      InMacro,      InMacroArgs, +    DNL,  }  /// Defines a MacroProcessor object, with it's associated state @@ -233,32 +234,32 @@ impl MacroProcessor {      /// Bootstrapping-function for defining all builtins,      /// the same way all other macros might be defined      fn define_builtins(&mut self) { -        self.define_macro_fn( +        self.define_macro(              String::from("define"),              MacroType::Function(smp_builtin_define),          ); -        self.define_macro_fn( +        self.define_macro(              String::from("ifdef"),              MacroType::Function(smp_builtin_ifdef),          ); -        self.define_macro_fn( +        self.define_macro(              String::from("ifndef"),              MacroType::Function(smp_builtin_ifndef),          ); -        self.define_macro_fn(String::from("ifeq"), MacroType::Function(smp_builtin_ifeq)); -        self.define_macro_fn( +        self.define_macro(String::from("ifeq"), MacroType::Function(smp_builtin_ifeq)); +        self.define_macro(              String::from("ifneq"),              MacroType::Function(smp_builtin_ifneq),          ); -        self.define_macro_fn( +        self.define_macro(              String::from("include"),              MacroType::Function(smp_builtin_include),          ); -        self.define_macro_fn( +        self.define_macro(              String::from("shell"),              MacroType::Function(smp_builtin_shell),          ); -        self.define_macro_fn(String::from("expr"), MacroType::Function(smp_builtin_expr)); +        self.define_macro(String::from("expr"), MacroType::Function(smp_builtin_expr));          // format('Result id %d', 3282)      } @@ -268,7 +269,7 @@ impl MacroProcessor {      ///      /// * `name` - The name of the new macro      /// * `body` - The body of the new macro, this will be expanded when macro is executed -    pub fn define_macro(&mut self, name: String, body: String) { +    pub fn define_macro_string(&mut self, name: String, body: String) {          self.macros.insert(name, MacroType::String(body));      } @@ -278,7 +279,7 @@ impl MacroProcessor {      ///      /// * `name` - The name of the new macro      /// * `macro_expansion` - The MacroType struct to use. -    pub fn define_macro_fn(&mut self, name: String, macro_expansion: MacroType) { +    pub fn define_macro(&mut self, name: String, macro_expansion: MacroType) {          self.macros.insert(name, macro_expansion);      } @@ -303,11 +304,12 @@ impl MacroProcessor {                      let placeholder = format!("${}", i + 1);                      expanded = expanded.replace(&placeholder, arg);                  } -                return Ok(expanded); +                self.process_input(&expanded)              }              MacroType::Function(func) => {                  return func(self, macro_name, args);              } +            MacroType::Array(vec) => return Ok(format!("Array[{}]", vec.len())),          }      } @@ -339,6 +341,11 @@ impl MacroProcessor {              highlight_debug!(input, macro_name_start, i);              match state { +                ParserState::DNL => { +                    if c == '\n' { +                        state = ParserState::Normal; +                    } +                }                  ParserState::Normal => {                      macro_name_start = i; @@ -365,6 +372,12 @@ impl MacroProcessor {                          }                          if macro_name == "SNNL" {                              skip_next_line_ending = c != '\n'; +                        } else if macro_name == "DNL" { +                            if c != '\n' { +                                state = ParserState::DNL; +                            } +                            macro_name.clear(); +                            continue;                          } else {                              let expanded = self.expand_macro(¯o_name, &mut [])?;                              output.push_str(&expanded); diff --git a/src/skaldpress/error.rs b/src/skaldpress/error.rs index 65a89ab..ae769a5 100644 --- a/src/skaldpress/error.rs +++ b/src/skaldpress/error.rs @@ -6,7 +6,8 @@ pub const SP_COMPILE_FILE_TEMPLATE_READ_ERROR: u8 = 2;  pub const SP_COMPILE_FILE_EXTENSION_ERROR_2: u8 = 3;  pub const SP_GEN_DEST_STRIP_PREFIX_ERROR: u8 = 4;  pub const SP_COMPILE_FILE_EXTENSION_ERROR: u8 = 7; -pub const SP_COMPILE_FILE_MACRO_PROCESS_ERROR: u8 = 9; +pub const SP_COMPILE_TEMPLATE_MACRO_PROCESS_ERROR: u8 = 9; +pub const SP_COMPILE_FILE_MACRO_PROCESS_ERROR: u8 = 10;  #[derive(Debug)]  pub enum SkaldpressError { diff --git a/src/skaldpress/main.rs b/src/skaldpress/main.rs index 3563bf7..c1b2006 100644 --- a/src/skaldpress/main.rs +++ b/src/skaldpress/main.rs @@ -1,3 +1,4 @@ +use std::collections::HashMap;  use std::fs;  use std::path::Path; @@ -6,15 +7,22 @@ use skaldpress::skaldpress::error::SkaldpressError;  use skaldpress::skaldpress::error::{      SP_COMPILE_FILE_EXTENSION_ERROR, SP_COMPILE_FILE_EXTENSION_ERROR_2,      SP_COMPILE_FILE_MACRO_PROCESS_ERROR, SP_COMPILE_FILE_TEMPLATE_READ_ERROR, -    SP_GEN_DEST_STRIP_PREFIX_ERROR, +    SP_COMPILE_TEMPLATE_MACRO_PROCESS_ERROR, SP_GEN_DEST_STRIP_PREFIX_ERROR,  };  use skaldpress::skaldpress::metadata_parser::extract_parse_yaml_metadata; +use skaldpress::skaldpress::metadata_parser::YamlValue;  const TEMPLATES_DIR: &str = "templates/";  const CONTENT_DIR: &str = "content/";  const BUILD_DIR: &str = "build/"; -fn compile_file(file_path: &Path) -> Result<String, SkaldpressError> { +struct CompiledFile { +    content: String, +    metadata: HashMap<String, YamlValue>, +} + +/// Will attempt to compile a specific file, potentially storing some state about the file +fn compile_file(file_path: &Path) -> Result<CompiledFile, SkaldpressError> {      let extension = file_path          .extension()          .ok_or(SkaldpressError::PathOperationError( @@ -40,33 +48,54 @@ fn compile_file(file_path: &Path) -> Result<String, SkaldpressError> {          _ => file_content.to_string(),      }; -    let Some(template) = map.get("template") else { -        return Ok(file_content); +    let mut macro_processor = MacroProcessor::new(); +    for (key, value) in &map { +        macro_processor.define_macro_string(format!("METADATA_{}", key), value.to_string()); +    } + +    let Some(template) = &map.get("template") else { +        let file_content = macro_processor +            .process_input(&file_content) +            .map_err(|e| SkaldpressError::SMPError(SP_COMPILE_FILE_MACRO_PROCESS_ERROR, e))?; +        return Ok(CompiledFile { +            content: file_content, +            metadata: map, +        });      }; -    let template_file = format!("{}{}.html", TEMPLATES_DIR, template); +    let template_file = format!("{}{}", TEMPLATES_DIR, template);      let template = fs::read_to_string(&template_file).map_err(|e| {          SkaldpressError::TemplateReadError(SP_COMPILE_FILE_TEMPLATE_READ_ERROR, e, template_file)      })?; -    let mut macro_processor = MacroProcessor::new(); -    for (key, value) in map { -        macro_processor.define_macro(format!("METADATA_{}", key), value.to_string()); -    } -    macro_processor.define_macro(String::from("CONTENT"), file_content); -    macro_processor +    macro_processor.define_macro_string(String::from("CONTENT"), file_content); +    let content = macro_processor          .process_input(&template) -        .map_err(|e| SkaldpressError::SMPError(SP_COMPILE_FILE_MACRO_PROCESS_ERROR, e)) +        .map_err(|e| SkaldpressError::SMPError(SP_COMPILE_TEMPLATE_MACRO_PROCESS_ERROR, e))?; +    Ok(CompiledFile { +        content, +        metadata: map, +    })  }  fn compile_file_and_write(source_file_path: &Path) -> Result<(), Box<dyn std::error::Error>> { +    let cfile = compile_file(&source_file_path)?; + +    if let Some(skip_build) = cfile.metadata.get("skip_build") { +        if let YamlValue::Scalar(skip_build) = skip_build { +            if skip_build.to_lowercase() == "true" { +                return Ok(()); +            } +        } +    } +      let dest_file_path = Path::new(BUILD_DIR) -        .join( -            source_file_path -                .strip_prefix(CONTENT_DIR) -                .map_err(|e| SkaldpressError::PathOperationError(SP_GEN_DEST_STRIP_PREFIX_ERROR, Some(Box::new(e))))?, -        ) +        .join(source_file_path.strip_prefix(CONTENT_DIR).map_err(|e| { +            SkaldpressError::PathOperationError(SP_GEN_DEST_STRIP_PREFIX_ERROR, Some(Box::new(e))) +        })?)          .with_extension("html"); +    // Here we need to do something about the extension, read it from the metadata of the template, +    // or the main file      let dest_dir = &dest_file_path          .parent() @@ -79,8 +108,7 @@ fn compile_file_and_write(source_file_path: &Path) -> Result<(), Box<dyn std::er          )      })?; -    let file_content = compile_file(&source_file_path)?; -    fs::write(&dest_file_path, file_content)?; +    fs::write(&dest_file_path, cfile.content)?;      Ok(())  }  | 
