@@ -95,13 +95,13 @@ pub fn unique_id_from_content(content: &str, id_counter: &mut HashMap<String, us
95
95
/// page go to the original location. Normal page rendering sets `path` to
96
96
/// None. Ideally, print page links would link to anchors on the print page,
97
97
/// but that is very difficult.
98
- fn adjust_links < ' a > ( event : Event < ' a > , path : Option < & Path > ) -> Event < ' a > {
98
+ fn adjust_links < ' a > ( event : Event < ' a > , path : Option < & Path > , abs_url : Option < & String > ) -> Event < ' a > {
99
99
lazy_static ! {
100
100
static ref SCHEME_LINK : Regex = Regex :: new( r"^[a-z][a-z0-9+.-]*:" ) . unwrap( ) ;
101
101
static ref MD_LINK : Regex = Regex :: new( r"(?P<link>.*)\.md(?P<anchor>#.*)?" ) . unwrap( ) ;
102
102
}
103
103
104
- fn fix < ' a > ( dest : CowStr < ' a > , path : Option < & Path > ) -> CowStr < ' a > {
104
+ fn fix < ' a > ( dest : CowStr < ' a > , path : Option < & Path > , abs_url : Option < & String > ) -> CowStr < ' a > {
105
105
if dest. starts_with ( '#' ) {
106
106
// Fragment-only link.
107
107
if let Some ( path) = path {
@@ -138,12 +138,19 @@ fn adjust_links<'a>(event: Event<'a>, path: Option<&Path>) -> Event<'a> {
138
138
} else {
139
139
fixed_link. push_str ( & dest) ;
140
140
} ;
141
- return CowStr :: from ( fixed_link) ;
141
+ if fixed_link. starts_with ( '/' ) {
142
+ fixed_link = match abs_url {
143
+ Some ( abs_url) => format ! ( "{}{}" , abs_url. trim_end_matches( '/' ) , & fixed_link) ,
144
+ None => fixed_link,
145
+ }
146
+ . into ( ) ;
147
+ }
148
+ return CowStr :: from ( format ! ( "{}" , fixed_link) ) ;
142
149
}
143
150
dest
144
151
}
145
152
146
- fn fix_html < ' a > ( html : CowStr < ' a > , path : Option < & Path > ) -> CowStr < ' a > {
153
+ fn fix_html < ' a > ( html : CowStr < ' a > , path : Option < & Path > , abs_url : Option < & String > ) -> CowStr < ' a > {
147
154
// This is a terrible hack, but should be reasonably reliable. Nobody
148
155
// should ever parse a tag with a regex. However, there isn't anything
149
156
// in Rust that I know of that is suitable for handling partial html
@@ -159,7 +166,7 @@ fn adjust_links<'a>(event: Event<'a>, path: Option<&Path>) -> Event<'a> {
159
166
160
167
HTML_LINK
161
168
. replace_all ( & html, |caps : & regex:: Captures < ' _ > | {
162
- let fixed = fix ( caps[ 2 ] . into ( ) , path) ;
169
+ let fixed = fix ( caps[ 2 ] . into ( ) , path, abs_url ) ;
163
170
format ! ( "{}{}\" " , & caps[ 1 ] , fixed)
164
171
} )
165
172
. into_owned ( )
@@ -168,19 +175,19 @@ fn adjust_links<'a>(event: Event<'a>, path: Option<&Path>) -> Event<'a> {
168
175
169
176
match event {
170
177
Event :: Start ( Tag :: Link ( link_type, dest, title) ) => {
171
- Event :: Start ( Tag :: Link ( link_type, fix ( dest, path) , title) )
178
+ Event :: Start ( Tag :: Link ( link_type, fix ( dest, path, abs_url ) , title) )
172
179
}
173
180
Event :: Start ( Tag :: Image ( link_type, dest, title) ) => {
174
- Event :: Start ( Tag :: Image ( link_type, fix ( dest, path) , title) )
181
+ Event :: Start ( Tag :: Image ( link_type, fix ( dest, path, abs_url ) , title) )
175
182
}
176
- Event :: Html ( html) => Event :: Html ( fix_html ( html, path) ) ,
183
+ Event :: Html ( html) => Event :: Html ( fix_html ( html, path, abs_url ) ) ,
177
184
_ => event,
178
185
}
179
186
}
180
187
181
188
/// Wrapper around the pulldown-cmark parser for rendering markdown to HTML.
182
189
pub fn render_markdown ( text : & str , curly_quotes : bool ) -> String {
183
- render_markdown_with_path ( text, curly_quotes, None )
190
+ render_markdown_with_path ( text, curly_quotes, None , None )
184
191
}
185
192
186
193
pub fn new_cmark_parser ( text : & str , curly_quotes : bool ) -> Parser < ' _ , ' _ > {
@@ -195,12 +202,17 @@ pub fn new_cmark_parser(text: &str, curly_quotes: bool) -> Parser<'_, '_> {
195
202
Parser :: new_ext ( text, opts)
196
203
}
197
204
198
- pub fn render_markdown_with_path ( text : & str , curly_quotes : bool , path : Option < & Path > ) -> String {
205
+ pub fn render_markdown_with_path (
206
+ text : & str ,
207
+ curly_quotes : bool ,
208
+ path : Option < & Path > ,
209
+ abs_url : Option < & String > ,
210
+ ) -> String {
199
211
let mut s = String :: with_capacity ( text. len ( ) * 3 / 2 ) ;
200
212
let p = new_cmark_parser ( text, curly_quotes) ;
201
213
let events = p
202
214
. map ( clean_codeblock_headers)
203
- . map ( |event| adjust_links ( event, path) ) ;
215
+ . map ( |event| adjust_links ( event, path, abs_url ) ) ;
204
216
205
217
html:: push_html ( & mut s, events) ;
206
218
s
0 commit comments