Skip to content

Commit f6e55e2

Browse files
committed
Add support for relative image source paths with no prefix
1 parent 884dfbe commit f6e55e2

File tree

4 files changed

+48
-11
lines changed

4 files changed

+48
-11
lines changed

Cargo.lock

+27
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ log = "0.4"
2626
notify = "4.0.17"
2727
pathbuftools = "0.1.2"
2828
pulldown-cmark = { version = "0.9.0", default-features = false, features = ["simd"] }
29+
regex = "1.5.4"
2930
serde = { version = "1.0", features = ["derive"] }
3031
serde_json = "1.0.74"
3132
serde_yaml = "0.8.23"

src/markdown.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use std::fs;
77
use std::io;
88
use std::path::{PathBuf, Path};
99
use std::collections::HashSet;
10+
use regex::Regex;
1011
use pulldown_cmark::{Parser, Options, Event, html};
1112

1213
/// Encapsulates a markdown file and provides an interface to turn its contents into HTML.
@@ -35,6 +36,9 @@ impl Renderer {
3536
let markdown = fs::read_to_string(&self.canonical_md_path)?;
3637
let root_dir = self.canonical_md_path.parent().unwrap_or_else(|| Path::new(""));
3738

39+
let re_absolute_url = Regex::new(r"^[a-z]+://").unwrap();
40+
let re_path_prefix = Regex::new(r"^(/|\./)?").unwrap();
41+
3842
let mut options = Options::empty();
3943
options.insert(Options::ENABLE_TABLES);
4044
options.insert(Options::ENABLE_FOOTNOTES);
@@ -52,8 +56,8 @@ impl Renderer {
5256
languages.insert(content.to_string());
5357
}
5458
},
55-
Event::Start(Tag::Image(_, url, _)) if url.starts_with("./") => {
56-
*url = format!("file://{}/{}", root_dir.display(), &url[2..]).into();
59+
Event::Start(Tag::Image(_, url, _)) if !re_absolute_url.is_match(url) => {
60+
*url = format!("file://{}/{}", root_dir.display(), re_path_prefix.replace(url, "")).into();
5761
},
5862
_ => (),
5963
}

tests/test_markdown.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,22 @@ fn test_renders_local_images() {
3434
let mut file = NamedTempFile::new().unwrap();
3535
let tempdir = file.path().parent().unwrap().to_path_buf();
3636

37-
writeln!(file, "![demo image](./local-image.png)").unwrap();
38-
writeln!(file, "![demo image](http://remote-image.png)").unwrap();
39-
writeln!(file, "![demo image](unprefixed_image.png)").unwrap();
37+
writeln!(file, "![demo image](local-image-01.png)").unwrap();
38+
writeln!(file, "![demo image](.local-image-02.png)").unwrap();
39+
writeln!(file, "![demo image](/local-image-03.png)").unwrap();
40+
writeln!(file, "![demo image](./local-image-04.png)").unwrap();
41+
writeln!(file, "![demo image](../local-image-05.png)").unwrap();
42+
writeln!(file, "![demo image](http://remote-image-01.png)").unwrap();
43+
writeln!(file, "![demo image](https://remote-image-02.png)").unwrap();
4044

4145
let renderer = Renderer::new(file.path().to_path_buf());
4246
let content = renderer.run().unwrap();
4347

44-
let local_src = format!("src=\"file://{}/local-image.png\"", tempdir.display());
45-
assert!(content.html.contains(&local_src));
46-
assert!(content.html.contains("src=\"http://remote-image.png\""));
47-
48-
// Without a ./ prefix, it's left alone
49-
assert!(content.html.contains("src=\"unprefixed_image.png\""));
48+
assert!(content.html.contains(&format!("src=\"file://{}/local-image-01.png\"", tempdir.display())));
49+
assert!(content.html.contains(&format!("src=\"file://{}/.local-image-02.png\"", tempdir.display())));
50+
assert!(content.html.contains(&format!("src=\"file://{}/local-image-03.png\"", tempdir.display())));
51+
assert!(content.html.contains(&format!("src=\"file://{}/local-image-04.png\"", tempdir.display())));
52+
assert!(content.html.contains(&format!("src=\"file://{}/../local-image-05.png\"", tempdir.display())));
53+
assert!(content.html.contains("src=\"http://remote-image-01.png\""));
54+
assert!(content.html.contains("src=\"https://remote-image-02.png\""));
5055
}

0 commit comments

Comments
 (0)