Add support for reletive links in Markdown files (#150)

This commit is contained in:
Joesan 2021-02-22 01:11:15 +01:00 committed by GitHub
parent a6ebba6b69
commit cefe38ee25
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 4 deletions

15
.gitignore vendored
View file

@ -1 +1,14 @@
/target
# Generated by Cargo
# will have compiled files and executables
debug/
target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk
# IntelliJ generated files
*.idea

View file

@ -286,6 +286,49 @@ mod test {
assert_eq!(links, HashSet::new())
}
#[test]
fn test_markdown_internal_url() {
let base_url = "https://localhost.com/";
let input = "This is [an internal url](@/internal.md) \
This is [an internal url](@/internal.markdown) \
This is [an internal url](@/internal.markdown#example) \
This is [an internal url](@/internal.md#example)";
let links: HashSet<Uri> = extract_links(
&InputContent::from_string(input, FileType::Markdown),
Some(Url::parse(base_url).unwrap()),
)
.into_iter()
.map(|r| r.uri)
.collect();
let expected = [
website("https://localhost.com/@/internal.md"),
website("https://localhost.com/@/internal.markdown"),
website("https://localhost.com/@/internal.md#example"),
website("https://localhost.com/@/internal.markdown#example"),
]
.iter()
.cloned()
.collect();
assert_eq!(links, expected)
}
#[test]
fn test_skip_markdown_email() {
let input = "Get in touch - [Contact Us](mailto:test@test.com)";
let links: HashSet<Uri> =
extract_links(&InputContent::from_string(input, FileType::Markdown), None)
.into_iter()
.map(|r| r.uri)
.collect();
let expected: HashSet<Uri> = [Uri::Mail("test@test.com".to_string())]
.iter()
.cloned()
.collect();
assert_eq!(links, expected)
}
#[test]
fn test_non_markdown_links() {
let input =

View file

@ -40,19 +40,28 @@ impl Uri {
}
}
fn is_internal_link(link: &str) -> bool {
// The first element should contain the Markdown file link
// @see https://www.markdownguide.org/basic-syntax/#links
let anchor_links = link.split('#').next().unwrap_or("");
anchor_links.ends_with(".md") | anchor_links.ends_with(".markdown")
}
impl TryFrom<&str> for Uri {
type Error = anyhow::Error;
fn try_from(s: &str) -> Result<Self> {
// Check for internal Markdown links
let is_link_internal = is_internal_link(s);
// Remove the `mailto` scheme if it exists
// to avoid parsing it as a website URL.
let s = s.trim_start_matches("mailto:");
if s.contains('@') & !is_link_internal {
return Ok(Uri::Mail(s.to_string()));
}
if let Ok(uri) = Url::parse(s) {
return Ok(Uri::Website(uri));
};
if s.contains('@') {
return Ok(Uri::Mail(s.to_string()));
};
bail!("Cannot convert to Uri")
}
}