Skip to content

Commit 3a919db

Browse files
committed
fix: exclude fragments
cleanup fix: merge conflicts
1 parent 8937c83 commit 3a919db

File tree

4 files changed

+68
-45
lines changed

4 files changed

+68
-45
lines changed

lychee-bin/tests/cli.rs

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2940,7 +2940,8 @@ mod cli {
29402940
.assert()
29412941
.success()
29422942
.stdout(contains("https://example.org")); // Should extract the link as plaintext
2943-
2943+
}
2944+
#[test]
29442945
fn test_wikilink_fixture_obsidian_style() {
29452946
let input = fixtures_path().join("wiki/obsidian-style.md");
29462947

@@ -2959,52 +2960,39 @@ mod cli {
29592960
}
29602961

29612962
#[test]
2962-
fn test_wikilink_fixture_with_fragments_obsidian_style() {
2963+
fn test_wikilink_fixture_with_fragments_obsidian_style_fixtures_excluded() {
29632964
let input = fixtures_path().join("wiki/obsidian-style-plus-headers.md");
29642965

29652966
//fragments should resolve all headers
2966-
let dir_links_with_fragment = 2;
2967-
main_command()
2968-
.arg(&input)
2969-
.arg("--include-wikilinks")
2970-
.arg("--include-fragments")
2971-
.arg("--fallback-extensions")
2972-
.arg("md")
2973-
.assert()
2974-
.failure()
2975-
.stdout(contains("Cannot find fragment").count(dir_links_with_fragment))
2976-
.stdout(contains("#").count(dir_links_with_fragment));
2977-
}
2978-
2979-
#[test]
2980-
fn test_wikilink_fixture_wikilink_style() {
2981-
let input = fixtures_path().join("wiki/wikilink-style.md");
2982-
2983-
// testing without fragments should not yield failures
29842967
main_command()
29852968
.arg(&input)
29862969
.arg("--include-wikilinks")
29872970
.arg("--fallback-extensions")
29882971
.arg("md")
2972+
.arg("--base-url")
2973+
.arg(fixtures_path())
2974+
.arg("--root-dir")
2975+
.arg(fixtures_path())
29892976
.assert()
29902977
.success();
29912978
}
29922979

29932980
#[test]
2994-
fn test_wikilink_fixture_with_fragments_wikilink_style() {
2995-
let input = fixtures_path().join("wiki/wikilink-style.md");
2981+
fn test_wikilink_fixture_with_fragments_obsidian_style() {
2982+
let input = fixtures_path().join("wiki/obsidian-style-plus-headers.md");
29962983

29972984
//fragments should resolve all headers
2998-
let dir_links_with_fragment = 2;
29992985
main_command()
30002986
.arg(&input)
30012987
.arg("--include-wikilinks")
30022988
.arg("--include-fragments")
30032989
.arg("--fallback-extensions")
30042990
.arg("md")
2991+
.arg("--base-url")
2992+
.arg(fixtures_path())
2993+
.arg("--root-dir")
2994+
.arg(fixtures_path())
30052995
.assert()
3006-
.failure()
3007-
.stdout(contains("Cannot find fragment").count(dir_links_with_fragment))
3008-
.stdout(contains("#").count(dir_links_with_fragment));
2996+
.success();
30092997
}
30102998
}

lychee-lib/src/checker/file.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ impl FileChecker {
8383
pub(crate) async fn check(&self, uri: &Uri) -> Status {
8484
//only populate the wikilink filenames if it is enabled
8585
if self.include_wikilinks {
86-
self.setup_wikilinks().await;
86+
self.setup_wikilinks();
8787
}
8888
let Ok(path) = uri.url.to_file_path() else {
8989
return ErrorKind::InvalidFilePath(uri.clone()).into();
@@ -150,7 +150,7 @@ impl FileChecker {
150150
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
151151
match self.apply_fallback_extensions(path, uri).map(Cow::Owned) {
152152
Ok(val) => Ok(val),
153-
Err(_) => self.apply_wikilink_check(path, uri).await.map(Cow::Owned),
153+
Err(_) => self.apply_wikilink_check(path, uri).map(Cow::Owned),
154154
}
155155
}
156156

@@ -322,16 +322,16 @@ impl FileChecker {
322322
}
323323

324324
// Initializes the Index of the wikilink checker
325-
async fn setup_wikilinks(&self) {
326-
self.wikilink_checker.index_files().await;
325+
fn setup_wikilinks(&self) {
326+
self.wikilink_checker.index_files();
327327
}
328328
// Tries to resolve a link by looking up the filename in the wikilink index
329329
// The
330-
async fn apply_wikilink_check(&self, path: &Path, uri: &Uri) -> Result<PathBuf, ErrorKind> {
330+
fn apply_wikilink_check(&self, path: &Path, uri: &Uri) -> Result<PathBuf, ErrorKind> {
331331
let mut path_buf = path.to_path_buf();
332332
for ext in &self.fallback_extensions {
333333
path_buf.set_extension(ext);
334-
match self.wikilink_checker.check(&path_buf, uri).await {
334+
match self.wikilink_checker.check(&path_buf, uri) {
335335
Err(_) => {}
336336
Ok(resolved_path) => return Ok(resolved_path),
337337
}

lychee-lib/src/extract/markdown.rs

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,27 @@ pub(crate) fn extract_markdown(
9494
}
9595

9696
//Strip potholes (|) from wikilinks
97-
let stripped_dest_url = if has_pothole {
97+
let mut stripped_dest_url = if has_pothole {
9898
pulldown_cmark::CowStr::Borrowed(&dest_url[0..dest_url.find('|').unwrap_or(dest_url.len())])
9999
}else {
100100
dest_url.clone()
101101
};
102102

103-
Some(vec![RawUri {
104-
text: stripped_dest_url.to_string(),
105-
element: Some("a".to_string()),
106-
attribute: Some("wikilink".to_string()),
107-
}])
103+
//Strip fragments (#) from wikilinks, according to the obsidian spec
104+
//fragments come before potholes
105+
if stripped_dest_url.contains('#') {
106+
stripped_dest_url = pulldown_cmark::CowStr::Borrowed(&dest_url[0..dest_url.find('#').unwrap_or(dest_url.len())]);
107+
}
108+
109+
if stripped_dest_url.is_empty() {
110+
None
111+
} else {
112+
Some(vec![RawUri {
113+
text: stripped_dest_url.to_string(),
114+
element: Some("a".to_string()),
115+
attribute: Some("wikilink".to_string()),
116+
}])
117+
}
108118
}
109119
}
110120
}
@@ -580,7 +590,8 @@ Shortcut link: [link4]
580590
"Missing expected URI: {expected_uri:?}. Found: {uris:?}"
581591
);
582592
}
583-
593+
}
594+
#[test]
584595
fn test_remove_wikilink_pothole() {
585596
let markdown = r"[[foo|bar]]";
586597
let uris = extract_markdown(markdown, true, true);
@@ -591,4 +602,28 @@ Shortcut link: [link4]
591602
}];
592603
assert_eq!(uris, expected);
593604
}
605+
606+
#[test]
607+
fn test_remove_wikilink_fragment() {
608+
let markdown = r"[[foo#bar]]";
609+
let uris = extract_markdown(markdown, true, true);
610+
let expected = vec![RawUri {
611+
text: "foo".to_string(),
612+
element: Some("a".to_string()),
613+
attribute: Some("wikilink".to_string()),
614+
}];
615+
assert_eq!(uris, expected);
616+
}
617+
618+
#[test]
619+
fn test_remove_wikilink_potholes_and_fragments() {
620+
let markdown = r"[[foo#bar|baz]]";
621+
let uris = extract_markdown(markdown, true, true);
622+
let expected = vec![RawUri {
623+
text: "foo".to_string(),
624+
element: Some("a".to_string()),
625+
attribute: Some("wikilink".to_string()),
626+
}];
627+
assert_eq!(uris, expected);
628+
}
594629
}

lychee-lib/src/utils/wikilink_checker.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use log::info;
33
use std::collections::HashMap;
44
use std::ffi::OsString;
55
use std::path::Path;
6+
use std::sync::Mutex;
67
use std::{path::PathBuf, sync::Arc};
7-
use tokio::sync::Mutex;
88
use walkdir::WalkDir;
99

1010
#[derive(Clone, Debug, Default)]
@@ -22,9 +22,9 @@ impl WikilinkChecker {
2222
}
2323
}
2424

25-
pub(crate) async fn index_files(&self) {
25+
pub(crate) fn index_files(&self) {
2626
//Skip the indexing step in case the filenames are already populated
27-
if !self.filenames.lock().await.is_empty() {
27+
if !self.filenames.lock().unwrap().is_empty() {
2828
return;
2929
}
3030
match self.basedir {
@@ -39,7 +39,7 @@ impl WikilinkChecker {
3939
localbasename.display()
4040
);
4141

42-
let mut filenameslock = self.filenames.lock().await;
42+
let mut filenameslock = self.filenames.lock().unwrap();
4343
for entry in WalkDir::new::<PathBuf>(localbasename.into())
4444
//actively ignore symlinks
4545
.follow_links(false)
@@ -58,11 +58,11 @@ impl WikilinkChecker {
5858
}
5959
}
6060

61-
pub(crate) async fn check(&self, path: &Path, uri: &Uri) -> Result<PathBuf, ErrorKind> {
61+
pub(crate) fn check(&self, path: &Path, uri: &Uri) -> Result<PathBuf, ErrorKind> {
6262
match path.file_name() {
6363
None => Err(ErrorKind::InvalidFilePath(uri.clone())),
6464
Some(filename) => {
65-
let filenamelock = self.filenames.lock().await;
65+
let filenamelock = self.filenames.lock().unwrap();
6666
if filenamelock.contains_key(&filename.to_ascii_lowercase()) {
6767
Ok(filenamelock
6868
.get(&filename.to_ascii_lowercase())

0 commit comments

Comments
 (0)