Skip to content

Commit 150ba49

Browse files
committed
Auto merge of #1852 - raftario:readme-svg, r=carols10cents
Fix GitHub relative SVGs not rendering properly Fixes #1851 where SVGs from GitHub aren't rendered in READMEs if they use relative links. First PR, so if I did something wrong point it out!
2 parents 0a6d3fb + b4d1464 commit 150ba49

File tree

1 file changed

+50
-6
lines changed

1 file changed

+50
-6
lines changed

src/render.rs

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,39 @@ impl SanitizeUrl {
103103
}
104104
}
105105

106+
/// Groups media-related URL info
107+
struct MediaUrl {
108+
is_media: bool,
109+
add_sanitize_query: bool,
110+
}
111+
106112
/// Determine whether the given URL has a media file externsion.
107-
fn is_media_url(url: &str) -> bool {
113+
/// Also check if `sanitize=true` must be added to the query string,
114+
/// which is required to load SVGs properly from GitHub.
115+
fn is_media_url(url: &str) -> MediaUrl {
108116
Path::new(url)
109117
.extension()
110118
.and_then(std::ffi::OsStr::to_str)
111-
.map_or(false, |e| match e {
112-
"png" | "svg" | "jpg" | "jpeg" | "gif" | "mp4" | "webm" | "ogg" => true,
113-
_ => false,
114-
})
119+
.map_or(
120+
MediaUrl {
121+
is_media: false,
122+
add_sanitize_query: false,
123+
},
124+
|e| match e {
125+
"svg" => MediaUrl {
126+
is_media: true,
127+
add_sanitize_query: true,
128+
},
129+
"png" | "jpg" | "jpeg" | "gif" | "mp4" | "webm" | "ogg" => MediaUrl {
130+
is_media: true,
131+
add_sanitize_query: false,
132+
},
133+
_ => MediaUrl {
134+
is_media: false,
135+
add_sanitize_query: false,
136+
},
137+
},
138+
)
115139
}
116140

117141
impl UrlRelativeEvaluate for SanitizeUrl {
@@ -124,7 +148,11 @@ impl UrlRelativeEvaluate for SanitizeUrl {
124148
let mut new_url = base_url.clone();
125149
// Assumes GitHub’s URL scheme. GitHub renders text and markdown
126150
// better in the "blob" view, but images need to be served raw.
127-
new_url += if is_media_url(url) {
151+
let MediaUrl {
152+
is_media,
153+
add_sanitize_query,
154+
} = is_media_url(url);
155+
new_url += if is_media {
128156
"raw/master"
129157
} else {
130158
"blob/master"
@@ -133,6 +161,12 @@ impl UrlRelativeEvaluate for SanitizeUrl {
133161
new_url.push('/');
134162
}
135163
new_url += url;
164+
if add_sanitize_query {
165+
if let Ok(mut parsed_url) = Url::parse(&new_url) {
166+
parsed_url.query_pairs_mut().append_pair("sanitize", "true");
167+
new_url = parsed_url.into_string();
168+
}
169+
}
136170
Cow::Owned(new_url)
137171
})
138172
}
@@ -310,6 +344,7 @@ mod tests {
310344
let absolute = "[hi](/hi)";
311345
let relative = "[there](there)";
312346
let image = "![alt](img.png)";
347+
let svg = "![alt](sanitize.svg)";
313348

314349
for host in &["github.com", "gitlab.com", "bitbucket.org"] {
315350
for (&extra_slash, &dot_git) in [true, false].iter().zip(&[true, false]) {
@@ -346,6 +381,15 @@ mod tests {
346381
host
347382
)
348383
);
384+
385+
let result = markdown_to_html(svg, Some(&url));
386+
assert_eq!(
387+
result,
388+
format!(
389+
"<p><img src=\"https://{}/rust-lang/test/raw/master/sanitize.svg?sanitize=true\" alt=\"alt\"></p>\n",
390+
host
391+
)
392+
);
349393
}
350394
}
351395

0 commit comments

Comments
 (0)