Skip to content

Commit e25adf6

Browse files
committed
Convert std links to be relative.
1 parent 994073f commit e25adf6

File tree

1 file changed

+24
-0
lines changed

1 file changed

+24
-0
lines changed

mdbook-spec/src/std_links.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ pub fn std_links(chapter: &Chapter) -> String {
8787
// Append the link definitions to the bottom of the chapter.
8888
write!(output, "\n").unwrap();
8989
for ((link, dest), url) in links.iter().zip(urls) {
90+
// Convert links to be relative so that links work offline and
91+
// with the linkchecker.
92+
let url = relative_url(url, chapter);
9093
if let Some(dest) = dest {
9194
write!(output, "[{dest}]: {url}\n").unwrap();
9295
} else {
@@ -188,3 +191,24 @@ fn run_rustdoc(tmp: &TempDir, links: &[(&str, Option<&str>)], chapter: &Chapter)
188191
process::exit(1);
189192
}
190193
}
194+
195+
static DOC_URL: Lazy<Regex> = Lazy::new(|| {
196+
Regex::new(r"^https://doc.rust-lang.org/(?:nightly|beta|stable|dev|1\.[0-9]+\.[0-9]+)").unwrap()
197+
});
198+
199+
/// Converts a URL to doc.rust-lang.org to be relative.
200+
fn relative_url(url: &str, chapter: &Chapter) -> String {
201+
// Set SPEC_RELATIVE=0 to disable this, which can be useful for working locally.
202+
if std::env::var("SPEC_RELATIVE").as_deref() != Ok("0") {
203+
let Some(url_start) = DOC_URL.shortest_match(url) else {
204+
eprintln!("expected rustdoc URL to start with {DOC_URL:?}, got {url}");
205+
std::process::exit(1);
206+
};
207+
let url_path = &url[url_start..];
208+
let num_dots = chapter.path.as_ref().unwrap().components().count();
209+
let dots = vec![".."; num_dots].join("/");
210+
format!("{dots}{url_path}")
211+
} else {
212+
url.to_string()
213+
}
214+
}

0 commit comments

Comments
 (0)