Skip to content

Commit d321ce8

Browse files
Add --extend-css option to rustdoc
1 parent db6dd8e commit d321ce8

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

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

+21-3
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ pub struct Context {
115115
/// The base-URL of the issue tracker for when an item has been tagged with
116116
/// an issue number.
117117
pub issue_tracker_base_url: Option<String>,
118+
/// The given user css file which allow to customize the generated
119+
/// documentation theme.
120+
pub css_file_extension: Option<PathBuf>,
118121
}
119122

120123
/// Indicates where an external crate can be found.
@@ -404,7 +407,8 @@ pub fn derive_id(candidate: String) -> String {
404407
pub fn run(mut krate: clean::Crate,
405408
external_html: &ExternalHtml,
406409
dst: PathBuf,
407-
passes: HashSet<String>) -> Result<(), Error> {
410+
passes: HashSet<String>,
411+
css_file_extension: Option<PathBuf>) -> Result<(), Error> {
408412
let src_root = match krate.src.parent() {
409413
Some(p) => p.to_path_buf(),
410414
None => PathBuf::new(),
@@ -426,6 +430,7 @@ pub fn run(mut krate: clean::Crate,
426430
local_sources: HashMap::new(),
427431
render_redirect_pages: false,
428432
issue_tracker_base_url: None,
433+
css_file_extension: css_file_extension,
429434
};
430435

431436
try_err!(mkdir(&cx.dst), &cx.dst);
@@ -639,6 +644,17 @@ fn write_shared(cx: &Context,
639644
include_bytes!("static/rustdoc.css")));
640645
try!(write(cx.dst.join("main.css"),
641646
include_bytes!("static/styles/main.css")));
647+
if let Some(ref css) = cx.css_file_extension {
648+
let mut content = String::new();
649+
let css = css.as_path();
650+
let mut f = try_err!(File::open(css), css);
651+
652+
try_err!(f.read_to_string(&mut content), css);
653+
let css = cx.dst.join("theme.css");
654+
let css = css.as_path();
655+
let mut f = try_err!(File::create(css), css);
656+
try_err!(write!(f, "{}", &content), css);
657+
}
642658
try!(write(cx.dst.join("normalize.css"),
643659
include_bytes!("static/normalize.css")));
644660
try!(write(cx.dst.join("FiraSans-Regular.woff"),
@@ -925,7 +941,8 @@ impl<'a> SourceCollector<'a> {
925941
keywords: BASIC_KEYWORDS,
926942
};
927943
try!(layout::render(&mut w, &self.cx.layout,
928-
&page, &(""), &Source(contents)));
944+
&page, &(""), &Source(contents),
945+
self.cx.css_file_extension.is_some()));
929946
try!(w.flush());
930947
self.cx.local_sources.insert(p, href);
931948
Ok(())
@@ -1291,7 +1308,8 @@ impl Context {
12911308
if !cx.render_redirect_pages {
12921309
try!(layout::render(&mut writer, &cx.layout, &page,
12931310
&Sidebar{ cx: cx, item: it },
1294-
&Item{ cx: cx, item: it }));
1311+
&Item{ cx: cx, item: it },
1312+
cx.css_file_extension.is_some()));
12951313
} else {
12961314
let mut url = repeat("../").take(cx.current.len())
12971315
.collect::<String>();

src/librustdoc/lib.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,10 @@ pub fn opts() -> Vec<getopts::OptGroup> {
183183
"FILES"),
184184
optopt("", "markdown-playground-url",
185185
"URL to send code snippets to", "URL"),
186-
optflag("", "markdown-no-toc", "don't include table of contents")
186+
optflag("", "markdown-no-toc", "don't include table of contents"),
187+
optopt("e", "extend-css",
188+
"to redefine some css rules with a given file to generate doc with your \
189+
own theme", "PATH"),
187190
)
188191
}
189192

@@ -252,8 +255,16 @@ pub fn main_args(args: &[String]) -> isize {
252255
let markdown_input = input.ends_with(".md") || input.ends_with(".markdown");
253256

254257
let output = matches.opt_str("o").map(|s| PathBuf::from(&s));
258+
let css_file_extension = matches.opt_str("e").map(|s| PathBuf::from(&s));
255259
let cfgs = matches.opt_strs("cfg");
256260

261+
if let Some(ref p) = css_file_extension {
262+
if !p.is_file() {
263+
println!("{}", "--extend-css option must take a css file as input");
264+
return 1;
265+
}
266+
}
267+
257268
let external_html = match ExternalHtml::load(
258269
&matches.opt_strs("html-in-header"),
259270
&matches.opt_strs("html-before-content"),
@@ -289,7 +300,8 @@ pub fn main_args(args: &[String]) -> isize {
289300
Some("html") | None => {
290301
html::render::run(krate, &external_html,
291302
output.unwrap_or(PathBuf::from("doc")),
292-
passes.into_iter().collect())
303+
passes.into_iter().collect(),
304+
css_file_extension)
293305
.expect("failed to generate documentation")
294306
}
295307
Some("json") => {

0 commit comments

Comments
 (0)