rustyphoenixlecture 1.10.0

This project aims to provide a simple a powerfull lecture compilation to generate html web sites
/***************************************
	Auteur : Pierre Aubert
	Mail : pierre.aubert@lapp.in2p3.fr
	Licence : CeCILL-C
****************************************/

use crate::phighlighter::{
	pfileparser::PFileParserIter,
	lecture_str_to_html::lecture_str_to_html,
};

///Describe a highlighting action
#[derive(Debug,Default,Clone,PartialEq, Eq)]
pub enum PTypeHighLight{
	///No action to perform
	#[default]
	None,
	///The given match is a token and it is not followed by any token character
	Token,
	///The given match is a generic expression and can be followed by token characters
	Match,
	///Get a full sequence until the given String pattern
	GetUntil(String),
	///Replace the previous matched sequence by the given String
	Replace(String),
	///Get a full sequence until the given String pattern and replace the previous string by the first given String and the last by the second given String
	GetUntilReplace(String, String, String),
}

///Perform the highlight action
#[derive(Debug,Default,Clone)]
pub struct PActionHighLight{
	///Css style to be used when a String matches
	p_style: String,
	///Type of the highlighting
	p_type: PTypeHighLight,
}

impl PActionHighLight{
	///Constructor of a PActionHighLight
	/// # Parameters
	/// - `style` : CSS style to be applied on match
	/// - `highlight_type` : type of the highlight (None, Token, GetUntil, Replace)
	/// # Returns
	/// Initialised PActionHighLight
	pub fn new(style: &String, highlight_type: &PTypeHighLight) -> Self{
		PActionHighLight{
			p_style: style.clone(),
			p_type: highlight_type.clone()
		}
	}
	///Run the PActionHighLight
	/// # Parameters
	/// - `iter` : iterator on the file which is currently parsed
	/// - `prev_str` : previous sequence of characters to get to this particular action
	/// - `token_charset` : charset which contains all characters which composed a token
	/// - `is_prev_char_in_token_charset` : true if the previous char of the whole sequence was in the token charset
	/// # Returns
	/// String with corresponding style
	pub fn run(&self, iter: &mut PFileParserIter, prev_str: &String, token_charset: &String, is_prev_char_in_token_charset: bool) -> String{
		match &self.p_type {
			PTypeHighLight::None => prev_str.clone(),
			PTypeHighLight::GetUntil(pattern) => {
				// println!("PActionHighlight::run : get_until('{}'), prev_str = '{}'", pattern, prev_str);
				//We have to make sure the last value of the span is not a newline otherwise it breaks the line count of the PContentParser
				let mut final_pattern = pattern.clone();
				let mut after_final_pattern = String::from("");
				if *pattern == String::from("\n") {
					after_final_pattern = pattern.clone();
					final_pattern = String::from("");
				}
				format!("<span class=\"{}\">{}{}{}</span>{}",
				self.p_style, &lecture_str_to_html(&prev_str), &lecture_str_to_html(&iter.get_until(&pattern)), &lecture_str_to_html(&final_pattern), &after_final_pattern)
			},
			PTypeHighLight::Replace(replace_str) => {
				//Here, we have to test if there is not more characters which might be related to a token
				let extra_token_str: String = iter.get_str_of(token_charset);
				if extra_token_str.is_empty() {	// If there is not match, this is a token
					//We do not transform the replace str into html, because it is already html
					// format!("<span class=\"{}\">{}</span>", self.p_style, &replace_str)
					format!("{}", &replace_str)
				}else{	// If there is a match, this is not a token
					format!("{}{}", &lecture_str_to_html(&prev_str), &lecture_str_to_html(&extra_token_str))
				}
			},
			PTypeHighLight::Token => {
				//Here, we have to test if there is not more characters which might be related to a token
				let extra_token_str: String = iter.get_str_of(token_charset);
				if extra_token_str.is_empty() && !is_prev_char_in_token_charset {	// If there is not match, this is a token
					format!("<span class=\"{}\">{}</span>", self.p_style, &lecture_str_to_html(&prev_str))
				}else{	// If there is a match, this is not a token
					format!("{}{}", &lecture_str_to_html(&prev_str), &lecture_str_to_html(&extra_token_str))
				}
			},
			PTypeHighLight::Match => {
				format!("<span class=\"{}\">{}</span>", self.p_style, &lecture_str_to_html(&prev_str))
			},
			PTypeHighLight::GetUntilReplace(pattern, start_replace, end_replace) => format!("{}{}{}", start_replace, &lecture_str_to_html(&iter.get_until(&pattern)), end_replace),
		}
	}
}

#[cfg(test)]
mod tests{
	use super::*;
	use crate::phighlighter::pfileparser::PFileParser;
	
	///Test the action highlight none
	#[test]
	fn test_action_highlight_none(){
		let action = PActionHighLight::new(&String::from("string"), &PTypeHighLight::None);
		let parser = PFileParser::from_content(&String::from("just some text"));
		let mut iter = &mut parser.iter(false);
		assert_eq!(action.run(&mut iter, &String::from("just some text"), &String::from(""), false), String::from("just some text"));
	}
	///Test the action highlight getuntil
	#[test]
	fn test_action_highlight_getuntil(){
		let action = PActionHighLight::new(&String::from("string"), &PTypeHighLight::GetUntil(String::from("\"")));
		let parser = PFileParser::from_content(&String::from("end of a string\""));
		let mut iter = &mut parser.iter(false);
		assert_eq!(action.run(&mut iter, &String::from("\""), &String::from(""), false), String::from("<span class=\"string\">&quot;end of a string&quot;</span>"));
	}
	///Test the action highlight replace
	#[test]
	fn test_action_highlight_replace(){
		let action = PActionHighLight::new(&String::from("keyword"), &PTypeHighLight::Replace(String::from("%23")));
		let parser = PFileParser::from_content(&String::from("#"));
		let mut iter = &mut parser.iter(false);
		// assert_eq!(action.run(&mut iter, &String::from("#"), &String::from("")), String::from("<span class=\"keyword\">%23</span>"));
		assert_eq!(action.run(&mut iter, &String::from("#"), &String::from(""), false), String::from("%23"));
	}
	///Test the action highlight token
	#[test]
	fn test_action_highlight_token(){
		let action = PActionHighLight::new(&String::from("keyword"), &PTypeHighLight::Token);
		let parser = PFileParser::from_content(&String::from("return"));
		let mut iter = &mut parser.iter(false);
		assert_eq!(action.run(&mut iter, &String::from("return"), &String::from(""), false), String::from("<span class=\"keyword\">return</span>"));
	}
	///Test the action highlight getuntilreplace
	#[test]
	fn test_action_highlight_getuntilreplace(){
		//In this case we lose the style we previously passed
		let action = PActionHighLight::new(&String::from("title"), &PTypeHighLight::GetUntilReplace(String::from("\n"), String::from("<h1>"), String::from("</h1>")));
		let parser = PFileParser::from_content(&String::from("Some title\n"));
		let mut iter = &mut parser.iter(false);
		assert_eq!(action.run(&mut iter, &String::from("\""), &String::from(""), false), String::from("<h1>Some title</h1>"));
	}
}