Skip to content

Add index page argument #54543

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Nov 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@ impl<'a> Builder<'a> {
"build" => self.cargo_out(compiler, mode, target),

// This is the intended out directory for crate documentation.
"doc" => self.crate_doc_out(target),
"doc" | "rustdoc" => self.crate_doc_out(target),

_ => self.stage_out(compiler, mode),
};
Expand Down Expand Up @@ -743,7 +743,7 @@ impl<'a> Builder<'a> {
_ => compile::librustc_stamp(self, cmp, target),
};

if cmd == "doc" {
if cmd == "doc" || cmd == "rustdoc" {
if mode == Mode::Rustc || mode == Mode::ToolRustc || mode == Mode::Codegen {
// This is the intended out directory for compiler documentation.
my_out = self.compiler_doc_out(target);
Expand Down Expand Up @@ -883,7 +883,7 @@ impl<'a> Builder<'a> {
.env("RUSTDOC", self.out.join("bootstrap/debug/rustdoc"))
.env(
"RUSTDOC_REAL",
if cmd == "doc" || (cmd == "test" && want_rustdoc) {
if cmd == "doc" || cmd == "rustdoc" || (cmd == "test" && want_rustdoc) {
self.rustdoc(compiler.host)
} else {
PathBuf::from("/path/to/nowhere/rustdoc/not/required")
Expand Down
35 changes: 22 additions & 13 deletions src/bootstrap/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,14 +405,15 @@ impl Step for Standalone {
cmd.arg("--html-after-content").arg(&footer)
.arg("--html-before-content").arg(&version_info)
.arg("--html-in-header").arg(&favicon)
.arg("--markdown-no-toc")
.arg("--index-page").arg(&builder.src.join("src/doc/index.md"))
.arg("--markdown-playground-url")
.arg("https://play.rust-lang.org/")
.arg("-o").arg(&out)
.arg(&path);

if filename == "not_found.md" {
cmd.arg("--markdown-no-toc")
.arg("--markdown-css")
cmd.arg("--markdown-css")
.arg("https://doc.rust-lang.org/rust.css");
} else {
cmd.arg("--markdown-css").arg("rust.css");
Expand Down Expand Up @@ -480,23 +481,31 @@ impl Step for Std {
// will also directly handle merging.
let my_out = builder.crate_doc_out(target);
t!(symlink_dir_force(&builder.config, &my_out, &out_dir));
t!(fs::copy(builder.src.join("src/doc/rust.css"), out.join("rust.css")));

let mut cargo = builder.cargo(compiler, Mode::Std, target, "doc");
compile::std_cargo(builder, &compiler, target, &mut cargo);
let run_cargo_rustdoc_for = |package: &str| {
let mut cargo = builder.cargo(compiler, Mode::Std, target, "rustdoc");
compile::std_cargo(builder, &compiler, target, &mut cargo);

// Keep a whitelist so we do not build internal stdlib crates, these will be
// build by the rustc step later if enabled.
cargo.arg("--no-deps");
for krate in &["alloc", "core", "std"] {
cargo.arg("-p").arg(krate);
// Keep a whitelist so we do not build internal stdlib crates, these will be
// build by the rustc step later if enabled.
cargo.arg("-Z").arg("unstable-options")
.arg("-p").arg(package);
// Create all crate output directories first to make sure rustdoc uses
// relative links.
// FIXME: Cargo should probably do this itself.
t!(fs::create_dir_all(out_dir.join(krate)));
t!(fs::create_dir_all(out_dir.join(package)));
cargo.arg("--")
.arg("--markdown-css").arg("rust.css")
.arg("--markdown-no-toc")
.arg("--index-page").arg(&builder.src.join("src/doc/index.md"));

builder.run(&mut cargo);
builder.cp_r(&my_out, &out);
};
for krate in &["alloc", "core", "std"] {
run_cargo_rustdoc_for(krate);
}

builder.run(&mut cargo);
builder.cp_r(&my_out, &out);
}
}

Expand Down
35 changes: 24 additions & 11 deletions src/doc/rustdoc/src/unstable-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,22 @@ issue][issue-include].
[unstable-include]: ../unstable-book/language-features/external-doc.html
[issue-include]: https://github.com/rust-lang/rust/issues/44732

### Add aliases for an item in documentation search

This feature allows you to add alias(es) to an item when using the `rustdoc` search through the
`doc(alias)` attribute. Example:

```rust,no_run
#![feature(doc_alias)]

#[doc(alias = "x")]
#[doc(alias = "big")]
pub struct BigX;
```

Then, when looking for it through the `rustdoc` search, if you enter "x" or
"big", search will show the `BigX` struct first.

## Unstable command-line arguments

These features are enabled by passing a command-line flag to Rustdoc, but the flags in question are
Expand Down Expand Up @@ -374,18 +390,15 @@ This is an internal flag intended for the standard library and compiler that app
allows `rustdoc` to be able to generate documentation for the compiler crates and the standard
library, as an equivalent command-line argument is provided to `rustc` when building those crates.

### `doc_alias` feature
### `--index-page`: provide a top-level landing page for docs

This feature allows you to add alias(es) to an item when using the `rustdoc` search through the
`doc(alias)` attribute. Example:
This feature allows you to generate an index-page with a given markdown file. A good example of it
is the [rust documentation index](https://doc.rust-lang.org/index.html).

```rust,no_run
#![feature(doc_alias)]
With this, you'll have a page which you can custom as much as you want at the top of your crates.

#[doc(alias = "x")]
#[doc(alias = "big")]
pub struct BigX;
```
Using `index-page` option enables `enable-index-page` option as well.

Then, when looking for it through the `rustdoc` search, if you enter "x" or
"big", search will show the `BigX` struct first.
### `--enable-index-page`: generate a default index page for docs

This feature allows the generation of a default index-page which lists the generated crates.
86 changes: 74 additions & 12 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ use std::rc::Rc;

use externalfiles::ExternalHtml;

use errors;
use getopts;

use serialize::json::{ToJson, Json, as_json};
use syntax::ast;
use syntax::ext::base::MacroKind;
Expand Down Expand Up @@ -106,6 +109,8 @@ struct Context {
/// The map used to ensure all generated 'id=' attributes are unique.
id_map: Rc<RefCell<IdMap>>,
pub shared: Arc<SharedContext>,
pub enable_index_page: bool,
pub index_page: Option<PathBuf>,
}

struct SharedContext {
Expand Down Expand Up @@ -501,7 +506,12 @@ pub fn run(mut krate: clean::Crate,
sort_modules_alphabetically: bool,
themes: Vec<PathBuf>,
enable_minification: bool,
id_map: IdMap) -> Result<(), Error> {
id_map: IdMap,
enable_index_page: bool,
index_page: Option<PathBuf>,
matches: &getopts::Matches,
diag: &errors::Handler,
) -> Result<(), Error> {
let src_root = match krate.src {
FileName::Real(ref p) => match p.parent() {
Some(p) => p.to_path_buf(),
Expand Down Expand Up @@ -572,6 +582,8 @@ pub fn run(mut krate: clean::Crate,
codes: ErrorCodes::from(UnstableFeatures::from_environment().is_nightly_build()),
id_map: Rc::new(RefCell::new(id_map)),
shared: Arc::new(scx),
enable_index_page,
index_page,
};

// Crawl the crate to build various caches used for the output
Expand Down Expand Up @@ -666,7 +678,7 @@ pub fn run(mut krate: clean::Crate,
CACHE_KEY.with(|v| *v.borrow_mut() = cache.clone());
CURRENT_LOCATION_KEY.with(|s| s.borrow_mut().clear());

write_shared(&cx, &krate, &*cache, index, enable_minification)?;
write_shared(&cx, &krate, &*cache, index, enable_minification, matches, diag)?;

// And finally render the whole crate's documentation
cx.krate(krate)
Expand Down Expand Up @@ -742,11 +754,15 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
Json::Object(crate_data))
}

fn write_shared(cx: &Context,
krate: &clean::Crate,
cache: &Cache,
search_index: String,
enable_minification: bool) -> Result<(), Error> {
fn write_shared(
cx: &Context,
krate: &clean::Crate,
cache: &Cache,
search_index: String,
enable_minification: bool,
matches: &getopts::Matches,
diag: &errors::Handler,
) -> Result<(), Error> {
// Write out the shared files. Note that these are shared among all rustdoc
// docs placed in the output directory, so this needs to be a synchronized
// operation with respect to all other rustdocs running around.
Expand Down Expand Up @@ -902,8 +918,9 @@ themePicker.onblur = handleThemeButtonsBlur;
write(cx.dst.join("COPYRIGHT.txt"),
include_bytes!("static/COPYRIGHT.txt"))?;

fn collect(path: &Path, krate: &str, key: &str) -> io::Result<Vec<String>> {
fn collect(path: &Path, krate: &str, key: &str) -> io::Result<(Vec<String>, Vec<String>)> {
let mut ret = Vec::new();
let mut krates = Vec::new();
if path.exists() {
for line in BufReader::new(File::open(path)?).lines() {
let line = line?;
Expand All @@ -914,9 +931,13 @@ themePicker.onblur = handleThemeButtonsBlur;
continue;
}
ret.push(line.to_string());
krates.push(line[key.len() + 2..].split('"')
.next()
.map(|s| s.to_owned())
.unwrap_or_else(|| String::new()));
}
}
Ok(ret)
Ok((ret, krates))
}

fn show_item(item: &IndexItem, krate: &str) -> String {
Expand All @@ -931,7 +952,7 @@ themePicker.onblur = handleThemeButtonsBlur;

let dst = cx.dst.join("aliases.js");
{
let mut all_aliases = try_err!(collect(&dst, &krate.name, "ALIASES"), &dst);
let (mut all_aliases, _) = try_err!(collect(&dst, &krate.name, "ALIASES"), &dst);
let mut w = try_err!(File::create(&dst), &dst);
let mut output = String::with_capacity(100);
for (alias, items) in &cache.aliases {
Expand All @@ -955,7 +976,7 @@ themePicker.onblur = handleThemeButtonsBlur;

// Update the search index
let dst = cx.dst.join("search-index.js");
let mut all_indexes = try_err!(collect(&dst, &krate.name, "searchIndex"), &dst);
let (mut all_indexes, mut krates) = try_err!(collect(&dst, &krate.name, "searchIndex"), &dst);
all_indexes.push(search_index);
// Sort the indexes by crate so the file will be generated identically even
// with rustdoc running in parallel.
Expand All @@ -969,6 +990,46 @@ themePicker.onblur = handleThemeButtonsBlur;
}
try_err!(writeln!(&mut w, "initSearch(searchIndex);"), &dst);

if cx.enable_index_page == true {
if let Some(ref index_page) = cx.index_page {
::markdown::render(index_page,
cx.dst.clone(),
&matches, &(*cx.shared).layout.external_html,
!matches.opt_present("markdown-no-toc"),
diag);
} else {
let dst = cx.dst.join("index.html");
let mut w = BufWriter::new(try_err!(File::create(&dst), &dst));
let page = layout::Page {
title: "Index of crates",
css_class: "mod",
root_path: "./",
description: "List of crates",
keywords: BASIC_KEYWORDS,
resource_suffix: &cx.shared.resource_suffix,
};
krates.push(krate.name.clone());
krates.sort();
krates.dedup();

let content = format!(
"<h1 class='fqn'>\
<span class='in-band'>List of all crates</span>\
</h1><ul class='mod'>{}</ul>",
krates
.iter()
.map(|s| {
format!("<li><a href=\"{}/index.html\">{}</li>", s, s)
})
.collect::<String>());
try_err!(layout::render(&mut w, &cx.shared.layout,
&page, &(""), &content,
cx.shared.css_file_extension.is_some(),
&cx.shared.themes), &dst);
try_err!(w.flush(), &dst);
}
}

// Update the list of all implementors for traits
let dst = cx.dst.join("implementors");
for (&did, imps) in &cache.implementors {
Expand Down Expand Up @@ -1022,7 +1083,8 @@ themePicker.onblur = handleThemeButtonsBlur;
remote_item_type.css_class(),
remote_path[remote_path.len() - 1]));

let mut all_implementors = try_err!(collect(&mydst, &krate.name, "implementors"), &mydst);
let (mut all_implementors, _) = try_err!(collect(&mydst, &krate.name, "implementors"),
&mydst);
all_implementors.push(implementors);
// Sort the implementors by crate so the file will be generated
// identically even with rustdoc running in parallel.
Expand Down
Loading