Skip to content

Commit 2059400

Browse files
Add root-path
1 parent 27a046e commit 2059400

File tree

2 files changed

+65
-34
lines changed

2 files changed

+65
-34
lines changed

src/librustdoc/html/render.rs

+47-31
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ pub struct Context {
9292
/// The current destination folder of where HTML artifacts should be placed.
9393
/// This changes as the context descends into the module hierarchy.
9494
pub dst: PathBuf,
95+
/// The configurable destination folder for static resources (css, js, etc...).
96+
pub resources_dst: PathBuf,
9597
/// A flag, which when `true`, will render pages which redirect to the
9698
/// real location of an item. This is used to allow external links to
9799
/// publicly reused items to redirect to the right location.
@@ -128,6 +130,8 @@ pub struct SharedContext {
128130
pub sort_modules_alphabetically: bool,
129131
/// Additional themes to be added to the generated docs.
130132
pub themes: Vec<PathBuf>,
133+
/// The path where all non-HTML resources will be stored.
134+
pub root_path: String,
131135
}
132136

133137
impl SharedContext {
@@ -476,12 +480,14 @@ pub fn derive_id(candidate: String) -> String {
476480
pub fn run(mut krate: clean::Crate,
477481
external_html: &ExternalHtml,
478482
playground_url: Option<String>,
483+
html_dst: PathBuf,
479484
dst: PathBuf,
480485
passes: FxHashSet<String>,
481486
css_file_extension: Option<PathBuf>,
482487
renderinfo: RenderInfo,
483488
sort_modules_alphabetically: bool,
484-
themes: Vec<PathBuf>) -> Result<(), Error> {
489+
themes: Vec<PathBuf>,
490+
root_path: String) -> Result<(), Error> {
485491
let src_root = match krate.src {
486492
FileName::Real(ref p) => match p.parent() {
487493
Some(p) => p.to_path_buf(),
@@ -505,6 +511,7 @@ pub fn run(mut krate: clean::Crate,
505511
created_dirs: RefCell::new(FxHashSet()),
506512
sort_modules_alphabetically,
507513
themes,
514+
root_path,
508515
};
509516

510517
// If user passed in `--playground-url` arg, we fill in crate name here
@@ -543,10 +550,12 @@ pub fn run(mut krate: clean::Crate,
543550
}
544551
}
545552
try_err!(fs::create_dir_all(&dst), &dst);
546-
krate = render_sources(&dst, &mut scx, krate)?;
553+
try_err!(fs::create_dir_all(&html_dst), &html_dst);
554+
krate = render_sources(&html_dst, &mut scx, krate)?;
547555
let cx = Context {
548556
current: Vec::new(),
549-
dst,
557+
dst: html_dst,
558+
resources_dst: dst,
550559
render_redirect_pages: false,
551560
shared: Arc::new(scx),
552561
};
@@ -717,7 +726,7 @@ fn write_shared(cx: &Context,
717726
// Add all the static files. These may already exist, but we just
718727
// overwrite them anyway to make sure that they're fresh and up-to-date.
719728

720-
write(cx.dst.join("rustdoc.css"),
729+
write(cx.resources_dst.join("rustdoc.css"),
721730
include_bytes!("static/rustdoc.css"))?;
722731

723732
// To avoid "main.css" to be overwritten, we'll first run over the received themes and only
@@ -729,24 +738,24 @@ fn write_shared(cx: &Context,
729738

730739
let mut f = try_err!(File::open(&entry), &entry);
731740
try_err!(f.read_to_end(&mut content), &entry);
732-
write(cx.dst.join(try_none!(entry.file_name(), &entry)), content.as_slice())?;
741+
write(cx.resources_dst.join(try_none!(entry.file_name(), &entry)), content.as_slice())?;
733742
themes.insert(try_none!(try_none!(entry.file_stem(), &entry).to_str(), &entry).to_owned());
734743
}
735744

736-
write(cx.dst.join("brush.svg"),
745+
write(cx.resources_dst.join("brush.svg"),
737746
include_bytes!("static/brush.svg"))?;
738-
write(cx.dst.join("main.css"),
747+
write(cx.resources_dst.join("main.css"),
739748
include_bytes!("static/themes/main.css"))?;
740749
themes.insert("main".to_owned());
741-
write(cx.dst.join("dark.css"),
750+
write(cx.resources_dst.join("dark.css"),
742751
include_bytes!("static/themes/dark.css"))?;
743752
themes.insert("dark".to_owned());
744753

745754
let mut themes: Vec<&String> = themes.iter().collect();
746755
themes.sort();
747756
// To avoid theme switch latencies as much as possible, we put everything theme related
748757
// at the beginning of the html files into another js file.
749-
write(cx.dst.join("theme.js"), format!(
758+
write(cx.resources_dst.join("theme.js"), format!(
750759
r#"var themes = document.getElementById("theme-choices");
751760
var themePicker = document.getElementById("theme-picker");
752761
themePicker.onclick = function() {{
@@ -773,42 +782,42 @@ themePicker.onclick = function() {{
773782
.collect::<Vec<String>>()
774783
.join(",")).as_bytes())?;
775784

776-
write(cx.dst.join("main.js"), include_bytes!("static/main.js"))?;
777-
write(cx.dst.join("storage.js"), include_bytes!("static/storage.js"))?;
785+
write(cx.resources_dst.join("main.js"), include_bytes!("static/main.js"))?;
786+
write(cx.resources_dst.join("storage.js"), include_bytes!("static/storage.js"))?;
778787

779788
if let Some(ref css) = cx.shared.css_file_extension {
780-
let out = cx.dst.join("theme.css");
789+
let out = cx.resources_dst.join("theme.css");
781790
try_err!(fs::copy(css, out), css);
782791
}
783-
write(cx.dst.join("normalize.css"),
792+
write(cx.resources_dst.join("normalize.css"),
784793
include_bytes!("static/normalize.css"))?;
785-
write(cx.dst.join("FiraSans-Regular.woff"),
794+
write(cx.resources_dst.join("FiraSans-Regular.woff"),
786795
include_bytes!("static/FiraSans-Regular.woff"))?;
787-
write(cx.dst.join("FiraSans-Medium.woff"),
796+
write(cx.resources_dst.join("FiraSans-Medium.woff"),
788797
include_bytes!("static/FiraSans-Medium.woff"))?;
789-
write(cx.dst.join("FiraSans-LICENSE.txt"),
798+
write(cx.resources_dst.join("FiraSans-LICENSE.txt"),
790799
include_bytes!("static/FiraSans-LICENSE.txt"))?;
791-
write(cx.dst.join("Heuristica-Italic.woff"),
800+
write(cx.resources_dst.join("Heuristica-Italic.woff"),
792801
include_bytes!("static/Heuristica-Italic.woff"))?;
793-
write(cx.dst.join("Heuristica-LICENSE.txt"),
802+
write(cx.resources_dst.join("Heuristica-LICENSE.txt"),
794803
include_bytes!("static/Heuristica-LICENSE.txt"))?;
795-
write(cx.dst.join("SourceSerifPro-Regular.woff"),
804+
write(cx.resources_dst.join("SourceSerifPro-Regular.woff"),
796805
include_bytes!("static/SourceSerifPro-Regular.woff"))?;
797-
write(cx.dst.join("SourceSerifPro-Bold.woff"),
806+
write(cx.resources_dst.join("SourceSerifPro-Bold.woff"),
798807
include_bytes!("static/SourceSerifPro-Bold.woff"))?;
799-
write(cx.dst.join("SourceSerifPro-LICENSE.txt"),
808+
write(cx.resources_dst.join("SourceSerifPro-LICENSE.txt"),
800809
include_bytes!("static/SourceSerifPro-LICENSE.txt"))?;
801-
write(cx.dst.join("SourceCodePro-Regular.woff"),
810+
write(cx.resources_dst.join("SourceCodePro-Regular.woff"),
802811
include_bytes!("static/SourceCodePro-Regular.woff"))?;
803-
write(cx.dst.join("SourceCodePro-Semibold.woff"),
812+
write(cx.resources_dst.join("SourceCodePro-Semibold.woff"),
804813
include_bytes!("static/SourceCodePro-Semibold.woff"))?;
805-
write(cx.dst.join("SourceCodePro-LICENSE.txt"),
814+
write(cx.resources_dst.join("SourceCodePro-LICENSE.txt"),
806815
include_bytes!("static/SourceCodePro-LICENSE.txt"))?;
807-
write(cx.dst.join("LICENSE-MIT.txt"),
816+
write(cx.resources_dst.join("LICENSE-MIT.txt"),
808817
include_bytes!("static/LICENSE-MIT.txt"))?;
809-
write(cx.dst.join("LICENSE-APACHE.txt"),
818+
write(cx.resources_dst.join("LICENSE-APACHE.txt"),
810819
include_bytes!("static/LICENSE-APACHE.txt"))?;
811-
write(cx.dst.join("COPYRIGHT.txt"),
820+
write(cx.resources_dst.join("COPYRIGHT.txt"),
812821
include_bytes!("static/COPYRIGHT.txt"))?;
813822

814823
fn collect(path: &Path, krate: &str,
@@ -830,7 +839,7 @@ themePicker.onclick = function() {{
830839
}
831840

832841
// Update the search index
833-
let dst = cx.dst.join("search-index.js");
842+
let dst = cx.resources_dst.join("search-index.js");
834843
let mut all_indexes = try_err!(collect(&dst, &krate.name, "searchIndex"), &dst);
835844
all_indexes.push(search_index);
836845
// Sort the indexes by crate so the file will be generated identically even
@@ -1039,12 +1048,11 @@ impl<'a> SourceCollector<'a> {
10391048

10401049
// Create the intermediate directories
10411050
let mut cur = self.dst.clone();
1042-
let mut root_path = String::from("../../");
1051+
let root_path = self.scx.root_path.clone();
10431052
let mut href = String::new();
10441053
clean_srcpath(&self.scx.src_root, &p, false, |component| {
10451054
cur.push(component);
10461055
fs::create_dir_all(&cur).unwrap();
1047-
root_path.push_str("../");
10481056
href.push_str(component);
10491057
href.push('/');
10501058
});
@@ -1340,6 +1348,14 @@ impl Context {
13401348
repeat("../").take(self.current.len()).collect::<String>()
13411349
}
13421350

1351+
/// String representation of how to get back to the root path of the
1352+
/// resources folder in terms of a relative URL.
1353+
fn resources_root_path(&self) -> String {
1354+
let mut s = repeat("../").take(self.current.len()).collect::<String>();
1355+
s.push_str(&self.shared.root_path.replace("../../", ""));
1356+
s
1357+
}
1358+
13431359
/// Recurse in the directory structure and change the "root path" to make
13441360
/// sure it always points to the top (relatively).
13451361
fn recurse<T, F>(&mut self, s: String, f: F) -> T where
@@ -1422,7 +1438,7 @@ impl Context {
14221438
let keywords = make_item_keywords(it);
14231439
let page = layout::Page {
14241440
css_class: tyname,
1425-
root_path: &self.root_path(),
1441+
root_path: &self.resources_root_path(),
14261442
title: &title,
14271443
description: &desc,
14281444
keywords: &keywords,

src/librustdoc/lib.rs

+18-3
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ pub fn opts() -> Vec<RustcOptGroup> {
260260
"check if given theme is valid",
261261
"FILES")
262262
}),
263+
unstable("root-path", |o| {
264+
o.optopt("", "root-path", "Change default folder to store non-HTML resources",
265+
"PATH")
266+
}),
263267
]
264268
}
265269

@@ -366,7 +370,7 @@ pub fn main_args(args: &[String]) -> isize {
366370
let markdown_input = Path::new(input).extension()
367371
.map_or(false, |e| e == "md" || e == "markdown");
368372

369-
let output = matches.opt_str("o").map(|s| PathBuf::from(&s));
373+
let mut output = matches.opt_str("o").map(|s| PathBuf::from(&s));
370374
let css_file_extension = matches.opt_str("e").map(|s| PathBuf::from(&s));
371375
let cfgs = matches.opt_strs("cfg");
372376

@@ -434,18 +438,29 @@ pub fn main_args(args: &[String]) -> isize {
434438
}
435439

436440
let output_format = matches.opt_str("w");
441+
let option_root_path = matches.opt_str("root-path").unwrap_or(String::new());
442+
let mut root_path = format!("../../{}", option_root_path);
443+
if !root_path.ends_with("/") {
444+
root_path.push('/');
445+
}
437446
let res = acquire_input(PathBuf::from(input), externs, &matches, move |out| {
438447
let Output { krate, passes, renderinfo } = out;
439448
info!("going to format");
440449
match output_format.as_ref().map(|s| &**s) {
441450
Some("html") | None => {
451+
if let Some(ref mut output) = output {
452+
output.push(&option_root_path);
453+
}
442454
html::render::run(krate, &external_html, playground_url,
443-
output.unwrap_or(PathBuf::from("doc")),
455+
output.clone().unwrap_or(PathBuf::from("doc")),
456+
output.unwrap_or(PathBuf::from(&format!("doc/{}",
457+
&option_root_path))),
444458
passes.into_iter().collect(),
445459
css_file_extension,
446460
renderinfo,
447461
sort_modules_alphabetically,
448-
themes)
462+
themes,
463+
root_path)
449464
.expect("failed to generate documentation");
450465
0
451466
}

0 commit comments

Comments
 (0)