diff --git a/guide/src/format/configuration/renderers.md b/guide/src/format/configuration/renderers.md index 2552a5ae..814990da 100644 --- a/guide/src/format/configuration/renderers.md +++ b/guide/src/format/configuration/renderers.md @@ -109,6 +109,7 @@ edit-url-template = "https://github.com/rust-lang/mdBook/edit/master/guide/{path site-url = "/example-book/" cname = "myproject.rs" input-404 = "not-found.md" +use-site-url-as-root = false ``` The following configuration options are available: diff --git a/src/renderer/html_handlebars/hbs_renderer.rs b/src/renderer/html_handlebars/hbs_renderer.rs index f2b01063..1572e3a5 100644 --- a/src/renderer/html_handlebars/hbs_renderer.rs +++ b/src/renderer/html_handlebars/hbs_renderer.rs @@ -56,7 +56,7 @@ impl HtmlHandlebars { let content = ch.content.clone(); let content = if ctx.html_config.use_site_url_as_root { - utils::render_markdown_with_path( + utils::render_markdown_with_abs_path( &content, ctx.html_config.curly_quotes, None, @@ -66,12 +66,8 @@ impl HtmlHandlebars { utils::render_markdown(&content, ctx.html_config.curly_quotes) }; - let fixed_content = utils::render_markdown_with_path( - &ch.content, - ctx.html_config.curly_quotes, - Some(path), - None, - ); + let fixed_content = + utils::render_markdown_with_path(&ch.content, ctx.html_config.curly_quotes, Some(path)); if !ctx.is_index && ctx.html_config.print.page_break { // Add page break between chapters // See https://developer.mozilla.org/en-US/docs/Web/CSS/break-before and https://developer.mozilla.org/en-US/docs/Web/CSS/page-break-before diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 4a3da661..6636ed5f 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -126,20 +126,25 @@ fn adjust_links<'a>(event: Event<'a>, path: Option<&Path>, abs_url: Option<&Stri } if let Some(caps) = MD_LINK.captures(&dest) { - fixed_link.push_str(&caps["link"]); + fixed_link.push_str(&caps["link"].trim_start_matches('/')); fixed_link.push_str(".html"); if let Some(anchor) = caps.name("anchor") { fixed_link.push_str(anchor.as_str()); } + } else if !fixed_link.is_empty() { + // prevent links with double slashes + fixed_link.push_str(&dest.trim_start_matches('/')); } else { fixed_link.push_str(&dest); }; - if fixed_link.starts_with('/') { - fixed_link = match abs_url { - Some(abs_url) => format!("{}{}", abs_url.trim_end_matches('/'), &fixed_link), - None => fixed_link, + if dest.starts_with('/') || path.is_some() { + if let Some(abs_url) = abs_url { + fixed_link = format!( + "{}/{}", + abs_url.trim_end_matches('/'), + &fixed_link.trim_start_matches('/') + ); } - .into(); } return CowStr::from(format!("{}", fixed_link)); } @@ -181,7 +186,7 @@ fn adjust_links<'a>(event: Event<'a>, path: Option<&Path>, abs_url: Option<&Stri /// Wrapper around the pulldown-cmark parser for rendering markdown to HTML. pub fn render_markdown(text: &str, curly_quotes: bool) -> String { - render_markdown_with_path(text, curly_quotes, None, None) + render_markdown_with_path(text, curly_quotes, None) } pub fn new_cmark_parser(text: &str, curly_quotes: bool) -> Parser<'_, '_> { @@ -196,12 +201,18 @@ pub fn new_cmark_parser(text: &str, curly_quotes: bool) -> Parser<'_, '_> { Parser::new_ext(text, opts) } -pub fn render_markdown_with_path( +pub fn render_markdown_with_path(text: &str, curly_quotes: bool, path: Option<&Path>) -> String { + render_markdown_with_abs_path(text, curly_quotes, path, None) +} + +pub fn render_markdown_with_abs_path( text: &str, curly_quotes: bool, path: Option<&Path>, abs_url: Option<&String>, ) -> String { + // This function should be merged with `render_markdown_with_path` + // in the future. Currently, it is used not to break compatibility. let mut s = String::with_capacity(text.len() * 3 / 2); let p = new_cmark_parser(text, curly_quotes); let events = p