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"
|
name = "jsite"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
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 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)",
|
"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)",
|
"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 = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
regex = "1.3.4"
|
||||||
|
|
||||||
[dependencies.rocket_contrib]
|
[dependencies.rocket_contrib]
|
||||||
version = "0.4.2"
|
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 rocket;
|
||||||
#[macro_use] extern crate serde_derive;
|
#[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::Request;
|
||||||
use rocket_contrib::templates::Template;
|
use rocket_contrib::templates::Template;
|
||||||
use rocket_contrib::serve::StaticFiles;
|
use rocket_contrib::serve::StaticFiles;
|
||||||
@ -30,7 +33,6 @@ impl error::Error for PageNotFoundError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct SiteFile {
|
struct SiteFile {
|
||||||
file_name: String,
|
file_name: String,
|
||||||
@ -162,7 +164,7 @@ fn rst_page(page: PathBuf) -> Template {
|
|||||||
else {
|
else {
|
||||||
// Else, render the RST page
|
// Else, render the RST page
|
||||||
let mut map = HashMap::new();
|
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,
|
Ok(contents) => contents,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let mut map = HashMap::new();
|
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
|
// Ensure render will look good
|
||||||
contents = contents.replace("\n", "<br>");
|
contents = contents.replace("\n", "<br>");
|
||||||
contents = contents.replace(" ", " ");
|
contents = contents.replace(" ", " ");
|
||||||
@ -182,6 +187,7 @@ fn rst_page(page: PathBuf) -> Template {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Catches 404 errors and displays an error message
|
/// Catches 404 errors and displays an error message
|
||||||
///
|
///
|
||||||
/// #Arguments
|
/// #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
|
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
|
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.
|
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
|
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.
|
had already had experience in.
|
||||||
|
|
||||||
|
.. _Rocket: https://rocket.rs/
|
||||||
|
|
||||||
Easily Editable
|
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
|
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
|
Future Improvements
|
||||||
-------------------
|
-------------------
|
||||||
As I continue to learn Rust, I plan to implement more features of RST into the raw file displays. Having clickable
|
As I continue to learn Rust, I plan to implement more features of RST into the raw file displays. For example,
|
||||||
links or embedding images. I want to strike a balance between the aesthetic of a terminal and ease of use of a website.
|
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