@@ -2,6 +2,7 @@ use ammonia::{Builder, UrlRelative};
2
2
use comrak;
3
3
use htmlescape:: encode_minimal;
4
4
use std:: borrow:: Cow ;
5
+ use std:: path:: Path ;
5
6
use url:: Url ;
6
7
7
8
use util:: CargoResult ;
@@ -119,6 +120,16 @@ impl<'a> MarkdownRenderer<'a> {
119
120
None
120
121
} ) ;
121
122
123
+ fn is_media_url ( url : & str ) -> bool {
124
+ Path :: new ( url)
125
+ . extension ( )
126
+ . and_then ( |e| e. to_str ( ) )
127
+ . map_or ( false , |e| match e {
128
+ "png" | "svg" | "jpg" | "jpeg" | "gif" | "mp4" | "webm" | "ogg" => true ,
129
+ _ => false ,
130
+ } )
131
+ }
132
+
122
133
let relative_url_sanitizer = constrain_closure ( move |url| {
123
134
// sanitizer_base_url is Some(String); use it to fix the relative URL.
124
135
if url. starts_with ( '#' ) {
@@ -133,7 +144,13 @@ impl<'a> MarkdownRenderer<'a> {
133
144
let offset = new_url. len ( ) - 5 ;
134
145
new_url. drain ( offset..offset + 4 ) ;
135
146
}
136
- new_url += "blob/master" ;
147
+ // Assumes GitHub's URL scheme. GitHub renders text and markdown
148
+ // better in the "blob" view, but images need to be served raw.
149
+ new_url += if is_media_url ( url) {
150
+ "raw/master"
151
+ } else {
152
+ "blob/master"
153
+ } ;
137
154
if !url. starts_with ( '/' ) {
138
155
new_url. push ( '/' ) ;
139
156
}
@@ -310,6 +327,7 @@ mod tests {
310
327
fn relative_links ( ) {
311
328
let absolute = "[hi](/hi)" ;
312
329
let relative = "[there](there)" ;
330
+ let image = "" ;
313
331
314
332
for host in & [ "github.com" , "gitlab.com" , "bitbucket.org" ] {
315
333
for ( & extra_slash, & dot_git) in [ true , false ] . iter ( ) . zip ( & [ true , false ] ) {
@@ -337,6 +355,15 @@ mod tests {
337
355
host
338
356
)
339
357
) ;
358
+
359
+ let result = markdown_to_html ( image, Some ( & url) ) . unwrap ( ) ;
360
+ assert_eq ! (
361
+ result,
362
+ format!(
363
+ "<p><img src=\" https://{}/rust-lang/test/raw/master/img.png\" alt=\" alt\" ></p>\n " ,
364
+ host
365
+ )
366
+ ) ;
340
367
}
341
368
}
342
369
0 commit comments