Skip to content

Commit a9f34c8

Browse files
committed
Auto merge of #32230 - GuillaumeGomez:extend_css, r=alexcrichton
Add --extend-css option to rustdoc Fixes #32223 r? @brson
2 parents bf5da36 + 669edfa commit a9f34c8

File tree

5 files changed

+196
-123
lines changed

5 files changed

+196
-123
lines changed

src/librustc/session/config.rs

+85-21
Original file line numberDiff line numberDiff line change
@@ -785,12 +785,12 @@ impl RustcOptGroup {
785785
self.stability == OptionStability::Stable
786786
}
787787

788-
fn stable(g: getopts::OptGroup) -> RustcOptGroup {
788+
pub fn stable(g: getopts::OptGroup) -> RustcOptGroup {
789789
RustcOptGroup { opt_group: g, stability: OptionStability::Stable }
790790
}
791791

792792
#[allow(dead_code)] // currently we have no "truly unstable" options
793-
fn unstable(g: getopts::OptGroup) -> RustcOptGroup {
793+
pub fn unstable(g: getopts::OptGroup) -> RustcOptGroup {
794794
RustcOptGroup { opt_group: g, stability: OptionStability::Unstable }
795795
}
796796

@@ -926,33 +926,32 @@ pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
926926
pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
927927
let mut opts = rustc_short_optgroups();
928928
opts.extend_from_slice(&[
929-
opt::multi_s("", "extern", "Specify where an external rust library is \
930-
located",
931-
"NAME=PATH"),
929+
opt::multi_s("", "extern", "Specify where an external rust library is located",
930+
"NAME=PATH"),
932931
opt::opt_s("", "sysroot", "Override the system root", "PATH"),
933932
opt::multi_ubnr("Z", "", "Set internal debugging options", "FLAG"),
934933
opt::opt_ubnr("", "error-format",
935934
"How errors and other messages are produced",
936935
"human|json"),
937936
opt::opt_s("", "color", "Configure coloring of output:
938-
auto = colorize, if output goes to a tty (default);
939-
always = always colorize output;
940-
never = never colorize output", "auto|always|never"),
937+
auto = colorize, if output goes to a tty (default);
938+
always = always colorize output;
939+
never = never colorize output", "auto|always|never"),
941940

942941
opt::flagopt_ubnr("", "pretty",
943-
"Pretty-print the input instead of compiling;
944-
valid types are: `normal` (un-annotated source),
945-
`expanded` (crates expanded), or
946-
`expanded,identified` (fully parenthesized, AST nodes with IDs).",
947-
"TYPE"),
942+
"Pretty-print the input instead of compiling;
943+
valid types are: `normal` (un-annotated source),
944+
`expanded` (crates expanded), or
945+
`expanded,identified` (fully parenthesized, AST nodes with IDs).",
946+
"TYPE"),
948947
opt::flagopt_ubnr("", "unpretty",
949-
"Present the input source, unstable (and less-pretty) variants;
950-
valid types are any of the types for `--pretty`, as well as:
951-
`flowgraph=<nodeid>` (graphviz formatted flowgraph for node),
952-
`everybody_loops` (all function bodies replaced with `loop {}`),
953-
`hir` (the HIR), `hir,identified`, or
954-
`hir,typed` (HIR with types for each node).",
955-
"TYPE"),
948+
"Present the input source, unstable (and less-pretty) variants;
949+
valid types are any of the types for `--pretty`, as well as:
950+
`flowgraph=<nodeid>` (graphviz formatted flowgraph for node),
951+
`everybody_loops` (all function bodies replaced with `loop {}`),
952+
`hir` (the HIR), `hir,identified`, or
953+
`hir,typed` (HIR with types for each node).",
954+
"TYPE"),
956955

957956
// new options here should **not** use the `_ubnr` functions, all new
958957
// unstable options should use the short variants to indicate that they
@@ -1263,7 +1262,6 @@ pub fn get_unstable_features_setting() -> UnstableFeatures {
12631262
}
12641263

12651264
pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
1266-
12671265
let mut crate_types: Vec<CrateType> = Vec::new();
12681266
for unparsed_crate_type in &list_list {
12691267
for part in unparsed_crate_type.split(',') {
@@ -1287,6 +1285,72 @@ pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateTy
12871285
return Ok(crate_types);
12881286
}
12891287

1288+
pub mod nightly_options {
1289+
use getopts;
1290+
use syntax::feature_gate::UnstableFeatures;
1291+
use super::{ErrorOutputType, OptionStability, RustcOptGroup, get_unstable_features_setting};
1292+
use session::{early_error, early_warn};
1293+
1294+
pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
1295+
is_nightly_build() && matches.opt_strs("Z").iter().any(|x| *x == "unstable-options")
1296+
}
1297+
1298+
fn is_nightly_build() -> bool {
1299+
match get_unstable_features_setting() {
1300+
UnstableFeatures::Allow | UnstableFeatures::Cheat => true,
1301+
_ => false,
1302+
}
1303+
}
1304+
1305+
pub fn check_nightly_options(matches: &getopts::Matches, flags: &[RustcOptGroup]) {
1306+
let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
1307+
let really_allows_unstable_options = match get_unstable_features_setting() {
1308+
UnstableFeatures::Disallow => false,
1309+
_ => true,
1310+
};
1311+
1312+
for opt in flags.iter() {
1313+
if opt.stability == OptionStability::Stable {
1314+
continue
1315+
}
1316+
let opt_name = if opt.opt_group.long_name.is_empty() {
1317+
&opt.opt_group.short_name
1318+
} else {
1319+
&opt.opt_group.long_name
1320+
};
1321+
if !matches.opt_present(opt_name) {
1322+
continue
1323+
}
1324+
if opt_name != "Z" && !has_z_unstable_option {
1325+
early_error(ErrorOutputType::default(),
1326+
&format!("the `-Z unstable-options` flag must also be passed to enable \
1327+
the flag `{}`",
1328+
opt_name));
1329+
}
1330+
if really_allows_unstable_options {
1331+
continue
1332+
}
1333+
match opt.stability {
1334+
OptionStability::Unstable => {
1335+
let msg = format!("the option `{}` is only accepted on the \
1336+
nightly compiler", opt_name);
1337+
early_error(ErrorOutputType::default(), &msg);
1338+
}
1339+
OptionStability::UnstableButNotReally => {
1340+
let msg = format!("the option `{}` is is unstable and should \
1341+
only be used on the nightly compiler, but \
1342+
it is currently accepted for backwards \
1343+
compatibility; this will soon change, \
1344+
see issue #31847 for more details",
1345+
opt_name);
1346+
early_warn(ErrorOutputType::default(), &msg);
1347+
}
1348+
OptionStability::Stable => {}
1349+
}
1350+
}
1351+
}
1352+
}
1353+
12901354
impl fmt::Display for CrateType {
12911355
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
12921356
match *self {

src/librustc_driver/lib.rs

+4-49
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ use rustc_save_analysis as save;
6767
use rustc_trans::back::link;
6868
use rustc::session::{config, Session, build_session, CompileResult};
6969
use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
70-
use rustc::session::config::{get_unstable_features_setting, OptionStability};
70+
use rustc::session::config::{get_unstable_features_setting, nightly_options};
7171
use rustc::middle::cstore::CrateStore;
7272
use rustc::lint::Lint;
7373
use rustc::lint;
@@ -88,7 +88,7 @@ use std::str;
8888
use std::sync::{Arc, Mutex};
8989
use std::thread;
9090

91-
use rustc::session::{early_error, early_warn};
91+
use rustc::session::early_error;
9292

9393
use syntax::ast;
9494
use syntax::parse::{self, PResult};
@@ -909,64 +909,19 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
909909
// (unstable option being used on stable)
910910
// * If we're a historically stable-but-should-be-unstable option then we
911911
// emit a warning that we're going to turn this into an error soon.
912-
let has_z_unstable_options = matches.opt_strs("Z")
913-
.iter()
914-
.any(|x| *x == "unstable-options");
915-
let really_allows_unstable_options = match get_unstable_features_setting() {
916-
UnstableFeatures::Disallow => false,
917-
_ => true,
918-
};
919-
for opt in config::rustc_optgroups() {
920-
if opt.stability == OptionStability::Stable {
921-
continue
922-
}
923-
let opt_name = if opt.opt_group.long_name.is_empty() {
924-
&opt.opt_group.short_name
925-
} else {
926-
&opt.opt_group.long_name
927-
};
928-
if !matches.opt_present(opt_name) {
929-
continue
930-
}
931-
if opt_name != "Z" && !has_z_unstable_options {
932-
let msg = format!("the `-Z unstable-options` flag must also be \
933-
passed to enable the flag `{}`", opt_name);
934-
early_error(ErrorOutputType::default(), &msg);
935-
}
936-
if really_allows_unstable_options {
937-
continue
938-
}
939-
match opt.stability {
940-
OptionStability::Unstable => {
941-
let msg = format!("the option `{}` is only accepted on the \
942-
nightly compiler", opt_name);
943-
early_error(ErrorOutputType::default(), &msg);
944-
}
945-
OptionStability::UnstableButNotReally => {
946-
let msg = format!("the option `{}` is is unstable and should \
947-
only be used on the nightly compiler, but \
948-
it is currently accepted for backwards \
949-
compatibility; this will soon change, \
950-
see issue #31847 for more details",
951-
opt_name);
952-
early_warn(ErrorOutputType::default(), &msg);
953-
}
954-
OptionStability::Stable => {}
955-
}
956-
}
912+
nightly_options::check_nightly_options(&matches, &config::rustc_optgroups());
957913

958914
if matches.opt_present("h") || matches.opt_present("help") {
959915
// Only show unstable options in --help if we *really* accept unstable
960916
// options, which catches the case where we got `-Z unstable-options` on
961917
// the stable channel of Rust which was accidentally allowed
962918
// historically.
963919
usage(matches.opt_present("verbose"),
964-
has_z_unstable_options && really_allows_unstable_options);
920+
nightly_options::is_unstable_enabled(&matches));
965921
return None;
966922
}
967923

968924
// Don't handle -W help here, because we might first load plugins.
969-
970925
let r = matches.opt_strs("Z");
971926
if r.iter().any(|x| *x == "help") {
972927
describe_debug_flags();

src/librustdoc/html/layout.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,12 @@ pub struct Page<'a> {
2828
pub ty: &'a str,
2929
pub root_path: &'a str,
3030
pub description: &'a str,
31-
pub keywords: &'a str
31+
pub keywords: &'a str,
3232
}
3333

3434
pub fn render<T: fmt::Display, S: fmt::Display>(
35-
dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T)
35+
dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T,
36+
css_file_extension: bool)
3637
-> io::Result<()>
3738
{
3839
write!(dst,
@@ -49,6 +50,7 @@ r##"<!DOCTYPE html>
4950
5051
<link rel="stylesheet" type="text/css" href="{root_path}rustdoc.css">
5152
<link rel="stylesheet" type="text/css" href="{root_path}main.css">
53+
{css_extension}
5254
5355
{favicon}
5456
{in_header}
@@ -141,6 +143,12 @@ r##"<!DOCTYPE html>
141143
<script defer src="{root_path}search-index.js"></script>
142144
</body>
143145
</html>"##,
146+
css_extension = if css_file_extension {
147+
format!("<link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}theme.css\">",
148+
root_path = page.root_path)
149+
} else {
150+
"".to_owned()
151+
},
144152
content = *t,
145153
root_path = page.root_path,
146154
ty = page.ty,

src/librustdoc/html/render.rs

+22-4
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,9 @@ pub struct SharedContext {
119119
/// The base-URL of the issue tracker for when an item has been tagged with
120120
/// an issue number.
121121
pub issue_tracker_base_url: Option<String>,
122+
/// The given user css file which allow to customize the generated
123+
/// documentation theme.
124+
pub css_file_extension: Option<PathBuf>,
122125
}
123126

124127
/// Indicates where an external crate can be found.
@@ -411,7 +414,8 @@ pub fn derive_id(candidate: String) -> String {
411414
pub fn run(mut krate: clean::Crate,
412415
external_html: &ExternalHtml,
413416
dst: PathBuf,
414-
passes: HashSet<String>) -> Result<(), Error> {
417+
passes: HashSet<String>,
418+
css_file_extension: Option<PathBuf>) -> Result<(), Error> {
415419
let src_root = match krate.src.parent() {
416420
Some(p) => p.to_path_buf(),
417421
None => PathBuf::new(),
@@ -429,6 +433,7 @@ pub fn run(mut krate: clean::Crate,
429433
krate: krate.name.clone(),
430434
playground_url: "".to_string(),
431435
},
436+
css_file_extension: css_file_extension.clone(),
432437
};
433438

434439
// Crawl the crate attributes looking for attributes which control how we're
@@ -637,6 +642,7 @@ fn write_shared(cx: &Context,
637642

638643
// Add all the static files. These may already exist, but we just
639644
// overwrite them anyway to make sure that they're fresh and up-to-date.
645+
640646
write(cx.dst.join("jquery.js"),
641647
include_bytes!("static/jquery-2.1.4.min.js"))?;
642648
write(cx.dst.join("main.js"),
@@ -647,6 +653,17 @@ fn write_shared(cx: &Context,
647653
include_bytes!("static/rustdoc.css"))?;
648654
write(cx.dst.join("main.css"),
649655
include_bytes!("static/styles/main.css"))?;
656+
if let Some(ref css) = cx.shared.css_file_extension {
657+
let mut content = String::new();
658+
let css = css.as_path();
659+
let mut f = try_err!(File::open(css), css);
660+
661+
try_err!(f.read_to_string(&mut content), css);
662+
let css = cx.dst.join("theme.css");
663+
let css = css.as_path();
664+
let mut f = try_err!(File::create(css), css);
665+
try_err!(write!(f, "{}", &content), css);
666+
}
650667
write(cx.dst.join("normalize.css"),
651668
include_bytes!("static/normalize.css"))?;
652669
write(cx.dst.join("FiraSans-Regular.woff"),
@@ -932,7 +949,8 @@ impl<'a> SourceCollector<'a> {
932949
keywords: BASIC_KEYWORDS,
933950
};
934951
layout::render(&mut w, &self.scx.layout,
935-
&page, &(""), &Source(contents))?;
952+
&page, &(""), &Source(contents),
953+
self.scx.css_file_extension.is_some())?;
936954
w.flush()?;
937955
self.scx.local_sources.insert(p, href);
938956
Ok(())
@@ -1294,8 +1312,8 @@ impl Context {
12941312
if !cx.render_redirect_pages {
12951313
layout::render(&mut writer, &cx.shared.layout, &page,
12961314
&Sidebar{ cx: cx, item: it },
1297-
&Item{ cx: cx, item: it })?;
1298-
1315+
&Item{ cx: cx, item: it },
1316+
cx.shared.css_file_extension.is_some())?;
12991317
} else {
13001318
let mut url = repeat("../").take(cx.current.len())
13011319
.collect::<String>();

0 commit comments

Comments
 (0)