diff --git a/Cargo.lock b/Cargo.lock
index 3e70410..83b20be 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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)",
diff --git a/Cargo.toml b/Cargo.toml
index 89ce4f2..83463c3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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"
diff --git a/src/main.rs b/src/main.rs
index c3e1c8f..8a4431c 100644
--- a/src/main.rs
+++ b/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", "
");
contents = contents.replace(" ", " ");
@@ -182,6 +187,7 @@ fn rst_page(page: PathBuf) -> Template {
}
+
/// Catches 404 errors and displays an error message
///
/// #Arguments
diff --git a/src/rst_parser.rs b/src/rst_parser.rs
new file mode 100644
index 0000000..93ef3f9
--- /dev/null
+++ b/src/rst_parser.rs
@@ -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:: = 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!("{}",
+ link, &cap[1]).as_str());
+ }
+
+ output
+}
diff --git a/src/tests/mod.rs b/src/tests/mod.rs
new file mode 100644
index 0000000..617fca8
--- /dev/null
+++ b/src/tests/mod.rs
@@ -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 link.")
+}
diff --git a/static/raw_rst/projects/website.rst b/static/raw_rst/projects/website.rst
index e596ff9..5ba61cb 100644
--- a/static/raw_rst/projects/website.rst
+++ b/static/raw_rst/projects/website.rst
@@ -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.
\ No newline at end of file
+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.