Skip to content

Commit 9a0dc06

Browse files
committed
Add --crate-root-link, displays links on crate root
1 parent 2186722 commit 9a0dc06

File tree

5 files changed

+71
-19
lines changed

5 files changed

+71
-19
lines changed

src/librustdoc/config.rs

+42-18
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ pub struct RenderOptions {
218218
pub extern_html_root_urls: BTreeMap<String, String>,
219219
/// If present, suffix added to CSS/JavaScript files when referencing them in generated pages.
220220
pub resource_suffix: String,
221+
/// Links displayed on the crate root page.
222+
pub crate_root_links: BTreeMap<String, String>,
221223
/// Whether to run the static CSS/JavaScript through a minifier when outputting them. `true` by
222224
/// default.
223225
//
@@ -270,6 +272,36 @@ impl Options {
270272
/// Parses the given command-line for options. If an error message or other early-return has
271273
/// been printed, returns `Err` with the exit code.
272274
pub fn from_matches(matches: &getopts::Matches) -> Result<Options, i32> {
275+
fn parse_keyval_opt_internal(
276+
matches: &getopts::Matches,
277+
opt_name: &'static str,
278+
empty_err: &'static str,
279+
invalid_form_err: &'static str,
280+
) -> Result<BTreeMap<String, String>, &'static str> {
281+
let mut externs = BTreeMap::new();
282+
for arg in &(matches).opt_strs(opt_name) {
283+
let mut parts = arg.splitn(2, '=');
284+
let name = parts.next().ok_or(empty_err)?;
285+
let url = parts.next().ok_or(invalid_form_err)?;
286+
externs.insert(name.to_string(), url.to_string());
287+
}
288+
289+
Ok(externs)
290+
}
291+
/// Extracts key-value arguments (such as for `--extern-html-root-url`) from `matches` and returns
292+
/// a map of crate names to the given URLs. If an argument was ill-formed, returns an error
293+
/// describing the issue.
294+
macro_rules! parse_keyval_opt {
295+
($matches:expr, $opt_name:literal) => {
296+
parse_keyval_opt_internal(
297+
$matches,
298+
$opt_name,
299+
concat!("--", $opt_name, "must not be empty"),
300+
concat!("--", $opt_name, "must be of the form name=url"),
301+
)
302+
};
303+
}
304+
273305
// Check for unstable options.
274306
nightly_options::check_nightly_options(&matches, &opts());
275307

@@ -366,7 +398,15 @@ impl Options {
366398
.map(|s| SearchPath::from_cli_opt(s, error_format))
367399
.collect();
368400
let externs = parse_externs(&matches, &debugging_options, error_format);
369-
let extern_html_root_urls = match parse_extern_html_roots(&matches) {
401+
let extern_html_root_urls = match parse_keyval_opt!(&matches, "extern-html-root-url") {
402+
Ok(ex) => ex,
403+
Err(err) => {
404+
diag.struct_err(err).emit();
405+
return Err(1);
406+
}
407+
};
408+
409+
let crate_root_links = match parse_keyval_opt!(&matches, "crate-root-link") {
370410
Ok(ex) => ex,
371411
Err(err) => {
372412
diag.struct_err(err).emit();
@@ -609,6 +649,7 @@ impl Options {
609649
generate_search_filter,
610650
document_private,
611651
document_hidden,
652+
crate_root_links,
612653
},
613654
output_format,
614655
})
@@ -654,20 +695,3 @@ fn check_deprecated_options(matches: &getopts::Matches, diag: &rustc_errors::Han
654695
}
655696
}
656697
}
657-
658-
/// Extracts `--extern-html-root-url` arguments from `matches` and returns a map of crate names to
659-
/// the given URLs. If an `--extern-html-root-url` argument was ill-formed, returns an error
660-
/// describing the issue.
661-
fn parse_extern_html_roots(
662-
matches: &getopts::Matches,
663-
) -> Result<BTreeMap<String, String>, &'static str> {
664-
let mut externs = BTreeMap::new();
665-
for arg in &matches.opt_strs("extern-html-root-url") {
666-
let mut parts = arg.splitn(2, '=');
667-
let name = parts.next().ok_or("--extern-html-root-url must not be empty")?;
668-
let url = parts.next().ok_or("--extern-html-root-url must be of the form name=url")?;
669-
externs.insert(name.to_string(), url.to_string());
670-
}
671-
672-
Ok(externs)
673-
}

src/librustdoc/html/render/mod.rs

+24
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,8 @@ crate struct SharedContext {
157157
pub edition: Edition,
158158
pub codes: ErrorCodes,
159159
playground: Option<markdown::Playground>,
160+
/// Links displayed on the crate root page.
161+
pub crate_root_links: BTreeMap<String, String>,
160162
}
161163

162164
impl Context {
@@ -396,6 +398,7 @@ impl FormatRenderer for Context {
396398
resource_suffix,
397399
static_root_path,
398400
generate_search_filter,
401+
crate_root_links,
399402
..
400403
} = options;
401404

@@ -466,6 +469,7 @@ impl FormatRenderer for Context {
466469
edition,
467470
codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()),
468471
playground,
472+
crate_root_links,
469473
};
470474

471475
// Add the default themes to the `Vec` of stylepaths
@@ -3894,6 +3898,26 @@ fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer, cache: &Ca
38943898
}
38953899
}
38963900

3901+
if it.is_crate() && !cx.shared.crate_root_links.is_empty() {
3902+
let mut links_html = String::new();
3903+
for (name, url) in &cx.shared.crate_root_links {
3904+
links_html.push_str(&format!(
3905+
"<li><a href='{}'>{}</a></li>",
3906+
Escape(url),
3907+
Escape(name),
3908+
));
3909+
}
3910+
write!(
3911+
buffer,
3912+
"<div class='block items'>\
3913+
<ul>\
3914+
{}\
3915+
</ul>\
3916+
</div>",
3917+
links_html
3918+
);
3919+
};
3920+
38973921
write!(buffer, "<div class=\"sidebar-elems\">");
38983922
if it.is_crate() {
38993923
write!(

src/librustdoc/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,9 @@ fn opts() -> Vec<RustcOptGroup> {
406406
"specified the rustc-like binary to use as the test builder",
407407
)
408408
}),
409+
unstable("crate-root-link", |o| {
410+
o.optmulti("", "crate-root-link", "", "Specifies links to display on the crate root")
411+
}),
409412
]
410413
}
411414

src/stdarch

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit 45340c0e2fdadf2f131ef43cb683b5cafab0ff15

x.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python
1+
#!/usr/bin/env python3
22

33
# This file is only a "symlink" to bootstrap.py, all logic should go there.
44

0 commit comments

Comments
 (0)