works ish
This commit is contained in:
parent
a7468d3f40
commit
1321e0dcaf
112
src/main.rs
112
src/main.rs
@ -1,88 +1,22 @@
|
|||||||
use std::process::{Command};
|
use std::process::{Command};
|
||||||
use std::io::{stdin,stdout,Write};
|
use std::io::{stdin,stdout,Write};
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use regex::Regex;
|
|
||||||
use url::{Url, ParseError};
|
use url::{Url, ParseError};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
|
const DEBUG_MODE: bool = false;
|
||||||
|
|
||||||
|
// Import other files
|
||||||
|
mod parse_gemtext;
|
||||||
|
|
||||||
fn clear_screen() {
|
fn clear_screen() {
|
||||||
println!("clearing");
|
if DEBUG_MODE == false
|
||||||
Command::new("clear")
|
{
|
||||||
.status()
|
println!("clearing");
|
||||||
.expect("Failed to clear screen");
|
Command::new("clear")
|
||||||
}
|
.status()
|
||||||
|
.expect("Failed to clear screen");
|
||||||
fn parse_gemtext(page_content: String) -> (String, Vec<String>) {
|
}
|
||||||
let mut parsed_page_content: String = "".to_string();
|
|
||||||
let mut hyperlink_number_counter: u64 = 0;
|
|
||||||
let mut links: Vec<String> = Vec::new();
|
|
||||||
let mut preformatted_code_toggle = false;
|
|
||||||
|
|
||||||
for line in page_content.lines() {
|
|
||||||
let mut parsed_line: String = line.to_string();
|
|
||||||
let mut remove_line = false;
|
|
||||||
|
|
||||||
// preformatted text
|
|
||||||
let preformatted_text_regex = Regex::new(r"^```(.*)").unwrap();
|
|
||||||
parsed_line = preformatted_text_regex.replace_all(&parsed_line, |caps: ®ex::Captures| {
|
|
||||||
// Flip the toggle
|
|
||||||
preformatted_code_toggle = ! preformatted_code_toggle;
|
|
||||||
|
|
||||||
if caps[1] == *""
|
|
||||||
{
|
|
||||||
remove_line = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove the ```
|
|
||||||
format!("{}", &caps[1].magenta())
|
|
||||||
}).to_string();
|
|
||||||
|
|
||||||
if preformatted_code_toggle == false
|
|
||||||
{
|
|
||||||
// Block quotes
|
|
||||||
let block_quotes_regex = Regex::new(r"^>(.*)").unwrap();
|
|
||||||
parsed_line = block_quotes_regex.replace_all(&parsed_line, |caps: ®ex::Captures| {
|
|
||||||
format!(" | {}", &caps[1].red())
|
|
||||||
}).to_string();
|
|
||||||
|
|
||||||
// Unordered list ([ ]+|^)- (.*)
|
|
||||||
let unordered_list_regex = Regex::new(r"^([ \t]+|^)(-|\+|\*).(.*)").unwrap();
|
|
||||||
parsed_line = unordered_list_regex.replace_all(&parsed_line, |caps: ®ex::Captures| {
|
|
||||||
format!("{} • {}", &caps[1], &caps[3])
|
|
||||||
}).to_string();
|
|
||||||
|
|
||||||
// HyperLink
|
|
||||||
let hyperlink_regex = Regex::new(r"=>\s(\S*)\s(.*)").unwrap();
|
|
||||||
parsed_line = hyperlink_regex.replace_all(&parsed_line, |caps: ®ex::Captures| {
|
|
||||||
// Check if the character before the link is not '!'
|
|
||||||
let result = format!("[{}] {}", hyperlink_number_counter, &caps[2].blue().underline());
|
|
||||||
let url = caps[1].to_string();
|
|
||||||
links.push(url);
|
|
||||||
hyperlink_number_counter += 1;
|
|
||||||
result
|
|
||||||
}).to_string();
|
|
||||||
|
|
||||||
let quick_hyperlink_regex = Regex::new(r"=>\s(.*)").unwrap();
|
|
||||||
parsed_line = quick_hyperlink_regex.replace_all(&parsed_line, |caps: ®ex::Captures| {
|
|
||||||
hyperlink_number_counter += 1;
|
|
||||||
let url = caps[1].to_string();
|
|
||||||
links.push(url);
|
|
||||||
format!("[{}] {}", hyperlink_number_counter, &caps[1].blue().underline())
|
|
||||||
}).to_string();
|
|
||||||
}
|
|
||||||
else if preformatted_code_toggle == true
|
|
||||||
{
|
|
||||||
parsed_line = parsed_line.magenta().to_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
if remove_line == false
|
|
||||||
{
|
|
||||||
parsed_page_content+=&(parsed_line + "\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return (parsed_page_content, links);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_page(url: &Url) {
|
fn fetch_page(url: &Url) {
|
||||||
@ -114,7 +48,7 @@ fn render_page(url: Url, source: bool) -> Vec<String> {
|
|||||||
content += &format!("{}", &"Viewing source code".yellow());
|
content += &format!("{}", &"Viewing source code".yellow());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
(content, links) = parse_gemtext(content);
|
(content, links) = parse_gemtext::parse_gemtext(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
for _i in 0..screen_width {
|
for _i in 0..screen_width {
|
||||||
@ -155,12 +89,8 @@ fn parse_url(user_input: String, previous_url: &Url) -> Result<Url, ParseError>
|
|||||||
println!("Contains different scheme or is a path");
|
println!("Contains different scheme or is a path");
|
||||||
user_input
|
user_input
|
||||||
}
|
}
|
||||||
else if user_input[..1] == *"/" {
|
|
||||||
format!("gemini://{}/{}",Url::host_str(previous_url).expect("ivalid").to_string(), user_input)
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
println!("prepending scheme to user input");
|
format!("gemini://{}/{}",Url::host_str(previous_url).expect("ivalid").to_string(), user_input)
|
||||||
format!("gemini://{}", user_input) // Prepend 'mttp://' if no scheme is found
|
|
||||||
};
|
};
|
||||||
|
|
||||||
println!("Parsing: {}", to_parse);
|
println!("Parsing: {}", to_parse);
|
||||||
@ -192,19 +122,30 @@ fn main() {
|
|||||||
let mut historical_position: usize = 0;
|
let mut historical_position: usize = 0;
|
||||||
let mut links: Vec<String> = Vec::new();
|
let mut links: Vec<String> = Vec::new();
|
||||||
let mut source: bool = false; // Wether to view source of markdown page or rendered version
|
let mut source: bool = false; // Wether to view source of markdown page or rendered version
|
||||||
if let Ok(mut url) = parse_url(user_input, &Url::parse(&"http://deadvey.com").unwrap()) { // Change this and make internal pages ;)
|
if let Ok(mut url) = parse_url(user_input, &Url::parse(&"gemini://geminiprotocol.net").unwrap()) { // Change this and make internal pages ;)
|
||||||
history.push(url.clone());
|
history.push(url.clone());
|
||||||
'mainloop: loop {
|
'mainloop: loop {
|
||||||
if load_page {
|
if load_page {
|
||||||
links = render_page(history[historical_position].clone(), source);
|
links = render_page(history[historical_position].clone(), source);
|
||||||
println!("Enter reference number to follow, h for help, or q to quit");
|
println!("Enter reference number to follow, h for help, or q to quit");
|
||||||
}
|
}
|
||||||
|
url = history[historical_position].clone();
|
||||||
load_page = false;
|
load_page = false;
|
||||||
|
|
||||||
let user_input = input();
|
let user_input = input();
|
||||||
if user_input == "q" {
|
if user_input == "q" {
|
||||||
break 'mainloop;
|
break 'mainloop;
|
||||||
}
|
}
|
||||||
|
else if user_input == "d" {
|
||||||
|
println!(
|
||||||
|
"load_page: {}\nhistory: {:?}\nhistorical_postition: {}\nlinks: {:?}\nsource: {}",
|
||||||
|
load_page,
|
||||||
|
history,
|
||||||
|
historical_position,
|
||||||
|
links,
|
||||||
|
source
|
||||||
|
);
|
||||||
|
}
|
||||||
else if user_input == "r" {
|
else if user_input == "r" {
|
||||||
load_page = true;
|
load_page = true;
|
||||||
continue;
|
continue;
|
||||||
@ -243,6 +184,7 @@ fn main() {
|
|||||||
else if user_input == "h" {
|
else if user_input == "h" {
|
||||||
println!("Source code: https://git.javalsai.dynv6.net/deadvey/markdown-webbrowser
|
println!("Source code: https://git.javalsai.dynv6.net/deadvey/markdown-webbrowser
|
||||||
q: quit
|
q: quit
|
||||||
|
d: debug info
|
||||||
h: help
|
h: help
|
||||||
r: reload
|
r: reload
|
||||||
s: view source code of page
|
s: view source code of page
|
||||||
|
91
src/parse_gemtext.rs
Normal file
91
src/parse_gemtext.rs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
use colored::Colorize;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
pub fn parse_gemtext(page_content: String) -> (String, Vec<String>) {
|
||||||
|
let mut parsed_page_content: String = "".to_string();
|
||||||
|
let mut hyperlink_number_counter: u64 = 0;
|
||||||
|
let mut links: Vec<String> = Vec::new();
|
||||||
|
let mut preformatted_code_toggle = false;
|
||||||
|
|
||||||
|
// Regex patterns
|
||||||
|
let preformatted_text_regex = Regex::new(r"^```(.*)").unwrap();
|
||||||
|
let header1_regex = Regex::new(r"^# (.*)").unwrap();
|
||||||
|
let header2_regex = Regex::new(r"^## (.*)").unwrap();
|
||||||
|
let header3_regex = Regex::new(r"^### (.*)").unwrap();
|
||||||
|
let block_quotes_regex = Regex::new(r"^>(.*)").unwrap();
|
||||||
|
let unordered_list_regex = Regex::new(r"^([ \t]+|^)(\*).(.*)").unwrap();
|
||||||
|
let hyperlink_regex = Regex::new(r"=>\s(\S*)\s(.*)").unwrap();
|
||||||
|
let quick_hyperlink_regex = Regex::new(r"=>\s(.*)").unwrap();
|
||||||
|
|
||||||
|
for line in page_content.lines() {
|
||||||
|
let mut parsed_line: String = line.to_string();
|
||||||
|
let mut remove_line = false;
|
||||||
|
|
||||||
|
// preformatted text
|
||||||
|
parsed_line = preformatted_text_regex.replace_all(&parsed_line, |caps: ®ex::Captures| {
|
||||||
|
// Flip the toggle
|
||||||
|
preformatted_code_toggle = ! preformatted_code_toggle;
|
||||||
|
|
||||||
|
if caps[1] == *""
|
||||||
|
{
|
||||||
|
remove_line = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the ```
|
||||||
|
format!("{}", &caps[1].magenta())
|
||||||
|
}).to_string();
|
||||||
|
|
||||||
|
if preformatted_code_toggle == false
|
||||||
|
{
|
||||||
|
// Headers
|
||||||
|
parsed_line = header1_regex.replace_all(&parsed_line, |caps: ®ex::Captures| {
|
||||||
|
format!("{}", &caps[1].blue().bold().underline())
|
||||||
|
}).to_string();
|
||||||
|
parsed_line = header2_regex.replace_all(&parsed_line, |caps: ®ex::Captures| {
|
||||||
|
format!("{}", &caps[1].blue().bold())
|
||||||
|
}).to_string();
|
||||||
|
parsed_line = header3_regex.replace_all(&parsed_line, |caps: ®ex::Captures| {
|
||||||
|
format!("{}", &caps[1].bold())
|
||||||
|
}).to_string();
|
||||||
|
|
||||||
|
// Block quotes
|
||||||
|
parsed_line = block_quotes_regex.replace_all(&parsed_line, |caps: ®ex::Captures| {
|
||||||
|
format!(" | {}", &caps[1].red())
|
||||||
|
}).to_string();
|
||||||
|
|
||||||
|
// Unordered list ([ ]+|^)- (.*)
|
||||||
|
parsed_line = unordered_list_regex.replace_all(&parsed_line, |caps: ®ex::Captures| {
|
||||||
|
format!("{} • {}", &caps[1], &caps[3])
|
||||||
|
}).to_string();
|
||||||
|
|
||||||
|
// HyperLink
|
||||||
|
parsed_line = hyperlink_regex.replace_all(&parsed_line, |caps: ®ex::Captures| {
|
||||||
|
// Check if the character before the link is not '!'
|
||||||
|
let result = format!("[{}] {}", hyperlink_number_counter, &caps[2].blue().underline());
|
||||||
|
let url = caps[1].to_string();
|
||||||
|
links.push(url);
|
||||||
|
hyperlink_number_counter += 1;
|
||||||
|
result
|
||||||
|
}).to_string();
|
||||||
|
|
||||||
|
parsed_line = quick_hyperlink_regex.replace_all(&parsed_line, |caps: ®ex::Captures| {
|
||||||
|
hyperlink_number_counter += 1;
|
||||||
|
let url = caps[1].to_string();
|
||||||
|
links.push(url);
|
||||||
|
format!("[{}] {}", hyperlink_number_counter, &caps[1].blue().underline())
|
||||||
|
}).to_string();
|
||||||
|
}
|
||||||
|
else if preformatted_code_toggle == true
|
||||||
|
{
|
||||||
|
parsed_line = parsed_line.magenta().to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
if remove_line == false
|
||||||
|
{
|
||||||
|
parsed_page_content+=&(parsed_line + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return (parsed_page_content, links);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user