diff --git a/src/librustdoc/externalfiles.rs b/src/librustdoc/externalfiles.rs
index f8320330ad265..420e0b2e80706 100644
--- a/src/librustdoc/externalfiles.rs
+++ b/src/librustdoc/externalfiles.rs
@@ -14,7 +14,7 @@ use std::str;
use html::markdown::{Markdown, RenderType};
#[derive(Clone)]
-pub struct ExternalHtml{
+pub struct ExternalHtml {
/// Content that will be included inline in the
section of a
/// rendered Markdown file or generated documentation
pub in_header: String,
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 007d663cf949c..95db6a8679e5d 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -132,6 +132,8 @@ pub struct SharedContext {
/// This flag indicates whether listings of modules (in the side bar and documentation itself)
/// should be ordered alphabetically or in order of appearance (in the source code).
pub sort_modules_alphabetically: bool,
+ /// Additional themes to be added to the generated docs.
+ pub themes: Vec,
}
impl SharedContext {
@@ -500,7 +502,8 @@ pub fn run(mut krate: clean::Crate,
renderinfo: RenderInfo,
render_type: RenderType,
sort_modules_alphabetically: bool,
- deny_render_differences: bool) -> Result<(), Error> {
+ deny_render_differences: bool,
+ themes: Vec) -> Result<(), Error> {
let src_root = match krate.src {
FileName::Real(ref p) => match p.parent() {
Some(p) => p.to_path_buf(),
@@ -524,6 +527,7 @@ pub fn run(mut krate: clean::Crate,
markdown_warnings: RefCell::new(vec![]),
created_dirs: RefCell::new(FxHashSet()),
sort_modules_alphabetically,
+ themes,
};
// If user passed in `--playground-url` arg, we fill in crate name here
@@ -872,19 +876,28 @@ fn write_shared(cx: &Context,
write(cx.dst.join("rustdoc.css"),
include_bytes!("static/rustdoc.css"))?;
- let path = cx.shared.src_root.join("../librustdoc/html/static/themes");
- let mut themes: Vec = Vec::new();
- for entry in try_err!(fs::read_dir(path.clone()), &path) {
- let entry = try_err!(entry, &path);
+
+ // To avoid "main.css" to be overwritten, we'll first run over the received themes and only
+ // then we'll run over the "official" styles.
+ let mut themes: HashSet = HashSet::new();
+
+ for entry in &cx.shared.themes {
let mut content = Vec::with_capacity(100000);
- let mut f = try_err!(File::open(entry.path()), &entry.path());
- try_err!(f.read_to_end(&mut content), &entry.path());
- write(cx.dst.join(entry.file_name()), content.as_slice())?;
- themes.push(try_none!(
- try_none!(entry.path().file_stem(), &entry.path()).to_str(),
- &entry.path()).to_owned());
+ let mut f = try_err!(File::open(&entry), &entry);
+ try_err!(f.read_to_end(&mut content), &entry);
+ write(cx.dst.join(try_none!(entry.file_name(), &entry)), content.as_slice())?;
+ themes.insert(try_none!(try_none!(entry.file_stem(), &entry).to_str(), &entry).to_owned());
}
+
+ write(cx.dst.join("main.css"),
+ include_bytes!("static/themes/main.css"))?;
+ themes.insert("main".to_owned());
+ write(cx.dst.join("dark.css"),
+ include_bytes!("static/themes/dark.css"))?;
+ themes.insert("dark".to_owned());
+
+ let mut themes: Vec<&String> = themes.iter().collect();
themes.sort();
// To avoid theme switch latencies as much as possible, we put everything theme related
// at the beginning of the html files into another js file.
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 2e2dba7681cc3..bf624c31d3d95 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -264,6 +264,11 @@ pub fn opts() -> Vec {
o.optflag("", "deny-render-differences", "abort doc runs when markdown rendering \
differences are found")
}),
+ unstable("themes", |o| {
+ o.optmulti("", "themes",
+ "additional themes which will be added to the generated docs",
+ "FILES")
+ }),
]
}
@@ -365,6 +370,15 @@ pub fn main_args(args: &[String]) -> isize {
}
}
+ let mut themes = Vec::new();
+ for theme in matches.opt_strs("themes").iter().map(|s| PathBuf::from(&s)) {
+ if !theme.is_file() {
+ eprintln!("rustdoc: option --themes arguments must all be files");
+ return 1;
+ }
+ themes.push(theme);
+ }
+
let external_html = match ExternalHtml::load(
&matches.opt_strs("html-in-header"),
&matches.opt_strs("html-before-content"),
@@ -413,7 +427,8 @@ pub fn main_args(args: &[String]) -> isize {
renderinfo,
render_type,
sort_modules_alphabetically,
- deny_render_differences)
+ deny_render_differences,
+ themes)
.expect("failed to generate documentation");
0
}