mirror of
https://github.com/Hopiu/lychee.git
synced 2026-04-04 05:30:26 +00:00
Add support for reletive links in Markdown files (#150)
This commit is contained in:
parent
a6ebba6b69
commit
cefe38ee25
3 changed files with 69 additions and 4 deletions
15
.gitignore
vendored
15
.gitignore
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
15
src/uri.rs
15
src/uri.rs
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue