~exprez135/castor

11097f940d0f0182609cc63dbd681593bafe4c42 — Julien Blanchard 1 year, 5 months ago 0578df0
[gopher] fix links parsing in text files
3 files changed, 47 insertions(+), 10 deletions(-)

M src/draw.rs
M src/gopher/link.rs
M src/gopher/parser.rs
M src/draw.rs => src/draw.rs +20 -0
@@ 310,6 310,26 @@ pub fn gopher_link(gui: &Arc<Gui>, link_item: String) {
            let new_url = Gopher { source: url }.to_absolute_url().unwrap();
            insert_button(&gui, new_url, label);
        }
        Ok(GopherLink::Ftp(url, label)) => {
            let button_label = if label.is_empty() {
                url.clone().to_string()
            } else {
                label
            };
            let ftp_label = format!("{} [FTP]", button_label);

            insert_external_button(&gui, url, &ftp_label);
        }
        Ok(GopherLink::Finger(url, label)) => {
            let button_label = if label.is_empty() {
                url.clone().to_string()
            } else {
                label
            };
            let finger_label = format!("{} [Finger]", button_label);

            insert_external_button(&gui, url, &finger_label);
        }
        Ok(GopherLink::Unknown(_, _)) => (),
        Err(_) => (),
    }

M src/gopher/link.rs => src/gopher/link.rs +21 -2
@@ 1,9 1,14 @@
extern crate regex;
use regex::Regex;

use std::str::FromStr;
use url::Url;

#[derive(Debug)]
pub enum Link {
    File(Url, String),
    Ftp(Url, String),
    Finger(Url, String),
    Gemini(Url, String),
    Gopher(Url, String),
    Http(Url, String),


@@ 167,10 172,10 @@ impl FromStr for Link {
                Err(ParseError)
            }
        } else if line.contains("://") {
            let url = String::from(line);
            let url = extract_url(line);
            let label = String::from(line);

            match make_link(url, label) {
            match make_link(String::from(url), label) {
                Some(link) => Ok(link),
                None => Err(ParseError),
            }


@@ 183,6 188,8 @@ impl FromStr for Link {
pub fn make_link(url: String, label: String) -> Option<Link> {
    match Url::parse(&url) {
        Ok(url) => match url.scheme() {
            "finger" => Some(Link::Finger(url, label)),
            "ftp" => Some(Link::Ftp(url, label)),
            "gemini" => Some(Link::Gemini(url, label)),
            "gopher" => Some(Link::Gopher(url, label)),
            "http" => Some(Link::Http(url, label)),


@@ 193,3 200,15 @@ pub fn make_link(url: String, label: String) -> Option<Link> {
        _ => None,
    }
}

const URL_REGEX: &str = r"((ftp|gopher|gemini|finger|http|https)://[a-zA-Z0-9-+&@#/%=~_|$?!:,.]*)";

fn extract_url(line: &str) -> &str {
    let url_regexp = Regex::new(URL_REGEX).unwrap();
    if url_regexp.is_match(&line) {
        let caps = url_regexp.captures(line).unwrap();
        caps.get(1).map_or("", |m| m.as_str())
    } else {
        line
    }
}

M src/gopher/parser.rs => src/gopher/parser.rs +6 -8
@@ 35,14 35,6 @@ impl FromStr for TextElement {
                Ok(TextElement::Image(colors::cleanup(line)))
            } else if line.starts_with('9') {
                Ok(TextElement::Binary(String::from(line)))
            } else if line.contains("://") {
                if line.contains("gopher://") {
                    Ok(TextElement::LinkItem(String::from(line)))
                } else if line.contains("http://") || line.contains("https://") {
                    Ok(TextElement::ExternalLinkItem(String::from(line)))
                } else {
                    Ok(TextElement::Text(colors::colorize(line)))
                }
            } else {
                Ok(TextElement::Text(colors::colorize(line)))
            }


@@ 52,6 44,12 @@ impl FromStr for TextElement {
                Ok(TextElement::LinkItem(String::from(line)))
            } else if line.contains("http://") || line.contains("https://") {
                Ok(TextElement::ExternalLinkItem(String::from(line)))
            } else if line.contains("gemini://") {
                Ok(TextElement::ExternalLinkItem(String::from(line)))
            } else if line.contains("ftp://") {
                Ok(TextElement::ExternalLinkItem(String::from(line)))
            } else if line.contains("finger://") {
                Ok(TextElement::ExternalLinkItem(String::from(line)))
            } else {
                Ok(TextElement::Text(colors::colorize(line)))
            }