markly/parser/span/
link.rs

1use parser::Span;
2use parser::Span::Link;
3use regex::Regex;
4
5pub fn parse_link(text: &str) -> Option<(Span, usize)> {
6    lazy_static! {
7        static ref LINK: Regex =
8            Regex::new("^\\[(?P<text>.*?)\\]\\((?P<url>.*?)(?:\\s\"(?P<title>.*?)\")?\\)").unwrap();
9    }
10
11    if LINK.is_match(text) {
12        let caps = LINK.captures(text).unwrap();
13        let text = if let Some(mat) = caps.name("text") {
14            mat.as_str().to_owned()
15        } else {
16            "".to_owned()
17        };
18        let url = if let Some(mat) = caps.name("url") {
19            mat.as_str().to_owned()
20        } else {
21            "".to_owned()
22        };
23        let title = if let Some(mat) = caps.name("title") {
24            Some(mat.as_str().to_owned())
25        } else {
26            None
27        };
28        // let title = caps.name("title").map(|t| t.to_owned());
29        // TODO correctly get whitespace length between url and title
30        let len = text.len() + url.len() + 4 + title.clone().map_or(0, |t| t.len() + 3);
31        return Some((Link(text, url, title), len));
32    }
33    None
34}
35
36#[test]
37fn finds_link() {
38    assert_eq!(
39        parse_link("[an example](example.com) test"),
40        Some((
41            Link("an example".to_owned(), "example.com".to_owned(), None),
42            25
43        ))
44    );
45
46    assert_eq!(
47        parse_link("[](example.com) test"),
48        Some((Link("".to_owned(), "example.com".to_owned(), None), 15))
49    );
50
51    assert_eq!(
52        parse_link("[an example]() test"),
53        Some((Link("an example".to_owned(), "".to_owned(), None), 14))
54    );
55
56    assert_eq!(
57        parse_link("[]() test"),
58        Some((Link("".to_owned(), "".to_owned(), None), 4))
59    );
60
61    assert_eq!(
62        parse_link("[an example](example.com \"Title\") test"),
63        Some((
64            Link(
65                "an example".to_owned(),
66                "example.com".to_owned(),
67                Some("Title".to_owned())
68            ),
69            33
70        ))
71    );
72
73    assert_eq!(
74        parse_link("[an example](example.com) test [a link](example.com)"),
75        Some((
76            Link("an example".to_owned(), "example.com".to_owned(), None),
77            25
78        ))
79    );
80}
81
82#[test]
83fn no_false_positives() {
84    assert_eq!(parse_link("[()] testing things test"), None);
85    assert_eq!(parse_link("()[] testing things test"), None);
86}
87
88#[test]
89fn no_early_matching() {
90    assert_eq!(parse_link("were [an example](example.com) test"), None);
91}