aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFuwn <[email protected]>2022-06-01 01:37:06 +0000
committerFuwn <[email protected]>2022-06-01 01:37:06 +0000
commit8a5f82855bfd4bdcd73e83b3a73c763668ae4541 (patch)
tree3489eba88242425139b857f5d4c290a7126b893b
parentci(docker): build with fleet (diff)
downloadseptember-8a5f82855bfd4bdcd73e83b3a73c763668ae4541.tar.xz
september-8a5f82855bfd4bdcd73e83b3a73c763668ae4541.zip
feat(main.rs): replace gemini_to_html with germ!!!
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs158
2 files changed, 51 insertions, 108 deletions
diff --git a/Cargo.toml b/Cargo.toml
index b8d4dfa..b23b162 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -22,6 +22,7 @@ opt-level = 3
[dependencies]
# Gemini
gmi = "0.2.1"
+germ = { version = "0.2.2", features = ["ast"] }
# HTTP
actix-web = "4.0.1"
diff --git a/src/main.rs b/src/main.rs
index 327117d..02a8b9d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -34,6 +34,7 @@ extern crate log;
use std::{env::var, time::Instant};
use actix_web::{web, Error, HttpResponse};
+use germ::ast::Node;
use gmi::{protocol::Response, url::Url};
fn link_from_host_href(url: &Url, href: &str) -> String {
@@ -51,25 +52,23 @@ fn link_from_host_href(url: &Url, href: &str) -> String {
)
}
-#[allow(clippy::too_many_lines)]
fn gemini_to_html(
response: &Response,
url: &Url,
is_proxy: bool,
) -> (String, String) {
- let mut response_string = String::new();
- let mut in_block = false;
- let mut in_list = false;
- let mut title = String::new();
-
- for line in String::from_utf8_lossy(&response.data).to_string().lines() {
- match line.get(0..1).unwrap_or("") {
- // Convert links
- "=" => {
- let line = line.replace("=>", "").trim_start().to_owned();
- let mut split = line.split_whitespace().collect::<Vec<_>>();
- let mut href = split.remove(0).to_string();
- let text = split.join(" ");
+ let ast = germ::ast::build(&String::from_utf8_lossy(&response.data));
+ let mut html = String::new();
+ let mut title = "".to_string();
+
+ for node in ast {
+ match node {
+ Node::Text(text) => html.push_str(&format!("<p>{}</p>", text)),
+ Node::Link {
+ to,
+ text,
+ } => {
+ let mut href = to.clone();
if href.starts_with('/') || !href.contains("://") {
href = link_from_host_href(url, &href);
@@ -77,7 +76,7 @@ fn gemini_to_html(
if var("PROXY_BY_DEFAULT").unwrap_or_else(|_| "true".to_string())
== "true"
- && href.contains("gemini://")
+ && to.contains("gemini://")
{
if is_proxy
|| href
@@ -118,109 +117,52 @@ fn gemini_to_html(
}
}
- response_string
- .push_str(&format!("<p><a href=\"{}\">{}</a></p>\n", href, text));
- }
- // Add whitespace
- "" => {
- if in_list {
- in_list = false;
- response_string.push_str("</ul>\n");
- }
-
- response_string.push('\n');
- }
- // Convert lists
- "*" => {
- if !in_list {
- in_list = true;
- response_string.push_str("<ul>\n");
- }
-
- response_string.push_str(&format!(
- "<li>{}</li>\n",
- line.replace('*', "").trim_start()
+ html.push_str(&format!(
+ "<p><a href=\"{}\">{}</a></p>\n",
+ href,
+ text.unwrap_or(to)
));
}
- // Convert headings
- "#" => {
- if in_list {
- in_list = false;
- response_string.push_str("</ul>\n");
+ Node::Heading {
+ level,
+ text,
+ } => {
+ if title.is_empty() && level == 1 {
+ title = text.clone();
}
- match line.get(0..3) {
- Some(heading) =>
- match heading {
- "###" => {
- response_string.push_str(&format!(
- "<h3>{}</h3>",
- line.replace("###", "").trim_start()
- ));
- }
- _ =>
- if heading.starts_with("##") {
- response_string.push_str(&format!(
- "<h2>{}</h2>",
- line.replace("##", "").trim_start()
- ));
- } else {
- let fixed_line =
- line.replace('#', "").trim_start().to_owned();
-
- response_string.push_str(&format!("<h1>{}</h1>", fixed_line));
-
- if title.is_empty() {
- title = fixed_line;
- }
- },
- },
- None => {}
- }
- }
- // Convert blockquotes
- ">" => {
- if in_list {
- in_list = false;
- response_string.push_str("</ul>\n");
- }
-
- response_string.push_str(&format!(
- "<blockquote>{}</blockquote>\n",
- line.replace('>', "").trim_start()
+ html.push_str(&format!(
+ "<{}>{}</{0}>",
+ match level {
+ 1 => "h1",
+ 2 => "h2",
+ 3 => "h3",
+ _ => "p",
+ },
+ text
));
}
- // Convert preformatted blocks
- "`" => {
- if in_list {
- in_list = false;
- response_string.push_str("</ul>\n");
- }
-
- in_block = !in_block;
- if in_block {
- response_string.push_str("<pre>\n");
- } else {
- response_string.push_str("</pre>\n");
- }
- }
- // Add text lines
- _ => {
- if in_list {
- in_list = false;
- response_string.push_str("</ul>\n");
- }
-
- if in_block {
- response_string.push_str(&format!("{}\n", line));
- } else {
- response_string.push_str(&format!("<p>{}</p>", line));
- }
+ Node::List(items) =>
+ html.push_str(&format!(
+ "<ul>{}</ul>",
+ items
+ .into_iter()
+ .map(|i| format!("<li>{}</li>", i))
+ .collect::<Vec<String>>()
+ .join("\n")
+ )),
+ Node::Blockquote(text) =>
+ html.push_str(&format!("<blockquote>{}</blockquote>", text)),
+ Node::PreformattedText {
+ text, ..
+ } => {
+ html.push_str(&format!("<pre>{}</pre>", text));
}
+ Node::Whitespace => {}
}
}
- (title, response_string)
+ (title, html)
}
fn make_url(