Added support for links in RST files
+ Added rst_parser.rs for future RST parsing operations + Added tests for RST parsing
This commit is contained in:
		
							parent
							
								
									fafad80e47
								
							
						
					
					
						commit
						e88d9d3179
					
				
							
								
								
									
										1
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -330,6 +330,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| name = "jsite" | ||||
| version = "0.1.0" | ||||
| dependencies = [ | ||||
|  "regex 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "rocket_contrib 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)", | ||||
|  | ||||
| @ -11,6 +11,7 @@ rocket = "0.4.2" | ||||
| serde = "1.0" | ||||
| serde_derive = "1.0" | ||||
| serde_json = "1.0" | ||||
| regex = "1.3.4" | ||||
| 
 | ||||
| [dependencies.rocket_contrib] | ||||
| version = "0.4.2" | ||||
|  | ||||
							
								
								
									
										12
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/main.rs
									
									
									
									
									
								
							| @ -3,8 +3,11 @@ | ||||
| #[macro_use] extern crate rocket; | ||||
| #[macro_use] extern crate serde_derive; | ||||
| 
 | ||||
| use std::collections::HashMap; | ||||
| mod tests; | ||||
| mod rst_parser; | ||||
| 
 | ||||
| use rst_parser::parse_links; | ||||
| use std::collections::HashMap; | ||||
| use rocket::Request; | ||||
| use rocket_contrib::templates::Template; | ||||
| use rocket_contrib::serve::StaticFiles; | ||||
| @ -30,7 +33,6 @@ impl error::Error for PageNotFoundError { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| #[derive(Serialize)] | ||||
| struct SiteFile { | ||||
|     file_name: String, | ||||
| @ -162,7 +164,7 @@ fn rst_page(page: PathBuf) -> Template { | ||||
|     else { | ||||
|         // Else, render the RST page
 | ||||
|         let mut map = HashMap::new(); | ||||
|         let mut contents = match fs::read_to_string(site_page.path) { | ||||
|         let contents = match fs::read_to_string(site_page.path) { | ||||
|             Ok(contents) => contents, | ||||
|             Err(_) => { | ||||
|                 let mut map = HashMap::new(); | ||||
| @ -171,6 +173,9 @@ fn rst_page(page: PathBuf) -> Template { | ||||
|             }, | ||||
|         }; | ||||
| 
 | ||||
|         // Render links
 | ||||
|         let mut contents = parse_links(&contents); | ||||
| 
 | ||||
|         // Ensure render will look good
 | ||||
|         contents = contents.replace("\n", "<br>"); | ||||
|         contents = contents.replace("  ", "  "); | ||||
| @ -182,6 +187,7 @@ fn rst_page(page: PathBuf) -> Template { | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /// Catches 404 errors and displays an error message
 | ||||
| ///
 | ||||
| /// #Arguments
 | ||||
|  | ||||
							
								
								
									
										33
									
								
								src/rst_parser.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/rst_parser.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| use regex::Regex; | ||||
| use std::collections::HashMap; | ||||
| 
 | ||||
| /// Renders RST links as HTML links
 | ||||
| ///
 | ||||
| /// # Arguments
 | ||||
| ///
 | ||||
| /// * `string` - input RST string
 | ||||
| ///
 | ||||
| pub fn parse_links(string: & String) -> String { | ||||
|     let re_link_ref = Regex::new(r"\n?.. _(.*): (.*)\n").unwrap(); | ||||
|     let mut link_map: HashMap::<String, String> = HashMap::new(); | ||||
| 
 | ||||
|     for cap in re_link_ref.captures_iter(string.as_str()) { | ||||
|         link_map.insert(String::from(&cap[1]), String::from(&cap[2])); | ||||
|     } | ||||
| 
 | ||||
|     let mut output: String = re_link_ref.replace_all(string, "").to_string(); | ||||
| 
 | ||||
|     let re_link = Regex::new(r"`(.*)`_").unwrap(); | ||||
|     for cap in re_link.captures_iter(output.clone().as_ref()) { | ||||
|         let link = match link_map.get(&cap[1]) { | ||||
|             None => String::from(""), | ||||
|             Some(link) => link.to_owned() | ||||
|         }; | ||||
| 
 | ||||
|         output = output.replace(&cap[0], | ||||
|                                 format!("<a class=\"link\" href=\"{}\">{}</a>", | ||||
|                                         link, &cap[1]).as_str()); | ||||
|     } | ||||
| 
 | ||||
|     output | ||||
| } | ||||
							
								
								
									
										13
									
								
								src/tests/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/tests/mod.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| #[cfg(test)] | ||||
| use super::*; | ||||
| 
 | ||||
| #[test] | ||||
| fn test_link_parser() { | ||||
|     let mut input = String::from("This is a paragraph that contains `a link`_.
 | ||||
| 
 | ||||
|     .. _a link: https://domain.invalida\n");
 | ||||
| 
 | ||||
|     let output = parse_links(&mut input); | ||||
| 
 | ||||
|     assert_eq!(output.trim_end(), "This is a paragraph that contains <a class=\"link\" href=\"https://domain.invalida\">a link</a>.") | ||||
| } | ||||
| @ -15,10 +15,12 @@ Picking Rust and Rocket | ||||
| As I am not much of a UI person, the website update was put on the back burner for sometime. The old site was "good  | ||||
| enough." I originally considered doing it in Python and using Django. But that fails the criteria of being easily | ||||
| deployable. In early 2020, I began learning Rust out of curiosity and the need to use it for research.  | ||||
| I decided to tackle the website backend in Rust as a learning exercise. I went with the Rocket framework. It | ||||
| I decided to tackle the website backend in Rust as a learning exercise. I went with the `Rocket`_ framework. It | ||||
| seemed to suit my needs and supported Tera templates. Tera templates are very similar to Django's templates that I | ||||
| had already had experience in. | ||||
| 
 | ||||
| .. _Rocket: https://rocket.rs/ | ||||
| 
 | ||||
| Easily Editable | ||||
| --------------- | ||||
| As the style of the site is a simplistic linux terminal, I decided it would be nice to have the longer pages be in | ||||
| @ -40,5 +42,5 @@ improving how the site looked on mobile. | ||||
| 
 | ||||
| Future Improvements | ||||
| ------------------- | ||||
| As I continue to learn Rust, I plan to implement more features of RST into the raw file displays. Having clickable | ||||
| links or embedding images. I want to strike a balance between the aesthetic of a terminal and ease of use of a website. | ||||
| As I continue to learn Rust, I plan to implement more features of RST into the raw file displays. For example, | ||||
| embedding images. I want to strike a balance between the aesthetic of a terminal and ease of use of a website. | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user