Skip to content

Commit

Permalink
Auto merge of #54733 - GuillaumeGomez:stabilize-rustdoc-theme, r=olli…
Browse files Browse the repository at this point in the history
…e27,Dylan-DPC

Stabilize rustdoc theme options

Closes #54730

This PR stabilizes the `--themes` (now `--theme`) and `--theme-checker` (now `--check-theme`) options, for allowing users to add custom themes to their documentation.

Rustdoc includes two themes by default: `light` and `dark`. Using the `--theme` option, you can give rustdoc a CSS file to include as an extra theme for that render. Themes are named after the CSS file used, so using `--theme /path/to/your/custom-theme.css` will add a theme called `custom-theme` to the documentation.

Even though the CLI flag to add a theme is getting stabilized, there's no guarantee that a theme file will always have the same effect on documentation generated with future versions of rustdoc. To aid in ensuring that a theme will work, the flag `--check-theme` is also available, which compares the CSS rules defined by a custom theme against the ones used in the `light` theme. If the `light` theme defines a CSS rule that the custom theme does not, rustdoc will report an error. (Rustdoc also performs this check for themes given to `--theme`, but only reports a warning when a difference is found.)
  • Loading branch information
bors committed Nov 18, 2019
2 parents a0d40f8 + 45b83c9 commit 3e525e3
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 52 deletions.
33 changes: 32 additions & 1 deletion src/doc/rustdoc/src/command-line-arguments.md
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,38 @@ $ rustdoc src/lib.rs --edition 2018
$ rustdoc --test src/lib.rs --edition 2018
```

This flag allows rustdoc to treat your rust code as the given edition. It will compile doctests with
This flag allows `rustdoc` to treat your rust code as the given edition. It will compile doctests with
the given edition as well. As with `rustc`, the default edition that `rustdoc` will use is `2015`
(the first edition).

## `--theme`: add a theme to the documentation output

Using this flag looks like this:

```bash
$ rustdoc src/lib.rs --theme /path/to/your/custom-theme.css
```

`rustdoc`'s default output includes two themes: `light` (the default) and
`dark`. This flag allows you to add custom themes to the output. Giving a CSS
file to this flag adds it to your documentation as an additional theme choice.
The theme's name is determined by its filename; a theme file named
`custom-theme.css` will add a theme named `custom-theme` to the documentation.

## `--check-theme`: verify custom themes against the default theme

Using this flag looks like this:

```bash
$ rustdoc --check-theme /path/to/your/custom-theme.css
```

While `rustdoc`'s HTML output is more-or-less consistent between versions, there
is no guarantee that a theme file will have the same effect. The `--theme` flag
will still allow you to add the theme to your documentation, but to ensure that
your theme works as expected, you can use this flag to verify that it implements
the same CSS rules as the official `light` theme.

`--check-theme` is a separate mode in `rustdoc`. When `rustdoc` sees the
`--check-theme` flag, it discards all other flags and only performs the CSS rule
comparison operation.
24 changes: 0 additions & 24 deletions src/doc/rustdoc/src/unstable-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,30 +294,6 @@ some consideration for their stability, and names that end in a number). Giving
`rustdoc` will disable this sorting and instead make it print the items in the order they appear in
the source.

### `--themes`: provide additional themes

Using this flag looks like this:

```bash
$ rustdoc src/lib.rs -Z unstable-options --themes theme.css
```

Giving this flag to `rustdoc` will make it copy your theme into the generated crate docs and enable
it in the theme selector. Note that `rustdoc` will reject your theme file if it doesn't style
everything the "light" theme does. See `--theme-checker` below for details.

### `--theme-checker`: verify theme CSS for validity

Using this flag looks like this:

```bash
$ rustdoc -Z unstable-options --theme-checker theme.css
```

Before including your theme in crate docs, `rustdoc` will compare all the CSS rules it contains
against the "light" theme included by default. Using this flag will allow you to see which rules are
missing if `rustdoc` rejects your theme.

### `--resource-suffix`: modifying the name of CSS/JavaScript in crate docs

Using this flag looks like this:
Expand Down
31 changes: 22 additions & 9 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::BTreeMap;
use std::ffi::OsStr;
use std::fmt;
use std::path::PathBuf;

Expand Down Expand Up @@ -281,12 +282,12 @@ impl Options {
// check for deprecated options
check_deprecated_options(&matches, &diag);

let to_check = matches.opt_strs("theme-checker");
let to_check = matches.opt_strs("check-theme");
if !to_check.is_empty() {
let paths = theme::load_css_paths(static_files::themes::LIGHT.as_bytes());
let mut errors = 0;

println!("rustdoc: [theme-checker] Starting tests!");
println!("rustdoc: [check-theme] Starting tests! (Ignoring all other arguments)");
for theme_file in to_check.iter() {
print!(" - Checking \"{}\"...", theme_file);
let (success, differences) = theme::test_theme_against(theme_file, &paths, &diag);
Expand Down Expand Up @@ -357,23 +358,35 @@ impl Options {
}

let mut themes = Vec::new();
if matches.opt_present("themes") {
if matches.opt_present("theme") {
let paths = theme::load_css_paths(static_files::themes::LIGHT.as_bytes());

for (theme_file, theme_s) in matches.opt_strs("themes")
for (theme_file, theme_s) in matches.opt_strs("theme")
.iter()
.map(|s| (PathBuf::from(&s), s.to_owned())) {
if !theme_file.is_file() {
diag.struct_err("option --themes arguments must all be files").emit();
diag.struct_err(&format!("invalid argument: \"{}\"", theme_s))
.help("arguments to --theme must be files")
.emit();
return Err(1);
}
let (success, ret) = theme::test_theme_against(&theme_file, &paths, &diag);
if !success || !ret.is_empty() {
diag.struct_err(&format!("invalid theme: \"{}\"", theme_s))
.help("check what's wrong with the --theme-checker option")
if theme_file.extension() != Some(OsStr::new("css")) {
diag.struct_err(&format!("invalid argument: \"{}\"", theme_s))
.emit();
return Err(1);
}
let (success, ret) = theme::test_theme_against(&theme_file, &paths, &diag);
if !success {
diag.struct_err(&format!("error loading theme file: \"{}\"", theme_s)).emit();
return Err(1);
} else if !ret.is_empty() {
diag.struct_warn(&format!("theme file \"{}\" is missing CSS rules from the \
default theme", theme_s))
.warn("the theme may appear incorrect when loaded")
.help(&format!("to see what rules are missing, call `rustdoc \
--check-theme \"{}\"`", theme_s))
.emit();
}
themes.push(theme_file);
}
}
Expand Down
10 changes: 6 additions & 4 deletions src/librustdoc/html/layout.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::path::PathBuf;

use crate::externalfiles::ExternalHtml;
use crate::html::escape::Escape;
use crate::html::render::ensure_trailing_slash;
use crate::html::format::{Buffer, Print};

Expand Down Expand Up @@ -166,10 +167,11 @@ pub fn render<T: Print, S: Print>(
themes = themes.iter()
.filter_map(|t| t.file_stem())
.filter_map(|t| t.to_str())
.map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}{}{}.css">"#,
static_root_path,
t,
page.resource_suffix))
.map(|t| format!(r#"<link rel="stylesheet" type="text/css" href="{}.css">"#,
Escape(&format!("{}{}{}",
static_root_path,
t,
page.resource_suffix))))
.collect::<String>(),
suffix=page.resource_suffix,
static_extra_scripts=page.static_extra_scripts.iter().map(|e| {
Expand Down
9 changes: 3 additions & 6 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -633,19 +633,16 @@ function handleThemeButtonsBlur(e) {{
themePicker.onclick = switchThemeButtonState;
themePicker.onblur = handleThemeButtonsBlur;
[{}].forEach(function(item) {{
{}.forEach(function(item) {{
var but = document.createElement('button');
but.innerHTML = item;
but.textContent = item;
but.onclick = function(el) {{
switchTheme(currentTheme, mainTheme, item, true);
}};
but.onblur = handleThemeButtonsBlur;
themes.appendChild(but);
}});"#,
themes.iter()
.map(|s| format!("\"{}\"", s))
.collect::<Vec<String>>()
.join(","));
as_json(&themes));
write(cx.dst.join(&format!("theme{}.js", cx.shared.resource_suffix)),
theme_js.as_bytes()
)?;
Expand Down
2 changes: 1 addition & 1 deletion src/librustdoc/html/static_files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub static RUST_FAVICON: &'static [u8] = include_bytes!("static/favicon.ico");
/// The built-in themes given to every documentation site.
pub mod themes {
/// The "light" theme, selected by default when no setting is available. Used as the basis for
/// the `--theme-checker` functionality.
/// the `--check-theme` functionality.
pub static LIGHT: &'static str = include_str!("static/themes/light.css");

/// The "dark" theme.
Expand Down
8 changes: 4 additions & 4 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,13 @@ fn opts() -> Vec<RustcOptGroup> {
o.optflag("", "sort-modules-by-appearance", "sort modules by where they appear in the \
program, rather than alphabetically")
}),
unstable("themes", |o| {
o.optmulti("", "themes",
stable("theme", |o| {
o.optmulti("", "theme",
"additional themes which will be added to the generated docs",
"FILES")
}),
unstable("theme-checker", |o| {
o.optmulti("", "theme-checker",
stable("check-theme", |o| {
o.optmulti("", "check-theme",
"check if given theme is valid",
"FILES")
}),
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ pub fn test_theme_against<P: AsRef<Path>>(
diag: &Handler,
) -> (bool, Vec<String>) {
let data = try_something!(fs::read(f), diag, (false, vec![]));

let paths = load_css_paths(&data);
let mut ret = vec![];
get_differences(against, &paths, &mut ret);
Expand Down
10 changes: 10 additions & 0 deletions src/test/run-make-fulldeps/rustdoc-themes/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-include ../tools.mk

# Test that rustdoc will properly load in a theme file and display it in the theme selector.

OUTPUT_DIR := "$(TMPDIR)/rustdoc-themes"

all:
cp $(S)/src/librustdoc/html/static/themes/light.css $(TMPDIR)/test.css
$(RUSTDOC) -o $(OUTPUT_DIR) foo.rs --theme $(TMPDIR)/test.css
$(HTMLDOCCK) $(OUTPUT_DIR) foo.rs
4 changes: 4 additions & 0 deletions src/test/run-make-fulldeps/rustdoc-themes/foo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// @has test.css
// @has foo/struct.Foo.html
// @has - '//link[@rel="stylesheet"]/@href' '../test.css'
pub struct Foo;
2 changes: 1 addition & 1 deletion src/test/run-make-fulldeps/tools.mk
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ RUSTC := $(RUSTC) -Clinker=$(RUSTC_LINKER)
RUSTDOC := $(RUSTDOC) -Clinker=$(RUSTC_LINKER)
endif
#CC := $(CC) -L $(TMPDIR)
HTMLDOCCK := $(PYTHON) $(S)/src/etc/htmldocck.py
HTMLDOCCK := '$(PYTHON)' '$(S)/src/etc/htmldocck.py'
CGREP := "$(S)/src/etc/cat-and-grep.sh"

# This is the name of the binary we will generate and run; use this
Expand Down
6 changes: 4 additions & 2 deletions src/tools/rustdoc-themes/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@ fn main() {
eprintln!("No theme found in \"{}\"...", themes_folder);
exit(1);
}
let arg_name = "--check-theme".to_owned();
let status = Command::new(rustdoc_bin)
.args(&["-Z", "unstable-options", "--theme-checker"])
.args(&themes)
.args(&themes.iter()
.flat_map(|t| vec![&arg_name, t].into_iter())
.collect::<Vec<_>>())
.status()
.expect("failed to execute child");
if !status.success() {
Expand Down

0 comments on commit 3e525e3

Please sign in to comment.