Skip to content

Commit 63afc08

Browse files
committed
Allow external html in rustdoc for crates.
Updated documentation to reflect md->html. Modularized external file loading.
1 parent 0ddf6f4 commit 63afc08

File tree

8 files changed

+143
-69
lines changed

8 files changed

+143
-69
lines changed

man/rustdoc.1

+9
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,15 @@ directory to load plugins from (default: /tmp/rustdoc_ng/plugins)
3838
-L --library-path <val>
3939
directory to add to crate search path
4040
.TP
41+
--html-in-header <val>
42+
file to add to <head>
43+
.TP
44+
--html-before-content <val>
45+
file to add in <body>, before content
46+
.TP
47+
--html-after-content <val>
48+
file to add in <body>, after content
49+
.TP
4150
-h, --help
4251
Print help
4352

mk/docs.mk

+4-4
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@ DOCS := index intro tutorial guide guide-ffi guide-macros guide-lifetimes \
3535
PDF_DOCS := tutorial rust
3636

3737
RUSTDOC_DEPS_rust := doc/full-toc.inc
38-
RUSTDOC_FLAGS_rust := --markdown-in-header=doc/full-toc.inc
38+
RUSTDOC_FLAGS_rust := --html-in-header=doc/full-toc.inc
3939

4040
L10N_LANGS := ja
4141

4242
# Generally no need to edit below here.
4343

4444
# The options are passed to the documentation generators.
45-
RUSTDOC_HTML_OPTS_NO_CSS = --markdown-before-content=doc/version_info.html \
46-
--markdown-in-header=doc/favicon.inc \
47-
--markdown-after-content=doc/footer.inc \
45+
RUSTDOC_HTML_OPTS_NO_CSS = --html-before-content=doc/version_info.html \
46+
--html-in-header=doc/favicon.inc \
47+
--html-after-content=doc/footer.inc \
4848
--markdown-playground-url='http://play.rust-lang.org/'
4949

5050
RUSTDOC_HTML_OPTS = $(RUSTDOC_HTML_OPTS_NO_CSS) --markdown-css rust.css

src/doc/rustdoc.md

+15-4
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,17 @@ rustdoc can also generate JSON, for consumption by other tools, with
103103
`rustdoc --output-format json`, and also consume already-generated JSON with
104104
`rustdoc --input-format json`.
105105

106+
rustdoc also supports personalizing the output from crates' documentation,
107+
similar to markdown options.
108+
109+
- `--html-in-header FILE`: includes the contents of `FILE` at the
110+
end of the `<head>...</head>` section.
111+
- `--html-before-content FILE`: includes the contents of `FILE`
112+
directly after `<body>`, before the rendered content (including the
113+
search bar).
114+
- `--html-after-content FILE`: includes the contents of `FILE`
115+
after all the rendered content.
116+
106117
# Using the Documentation
107118

108119
The web pages generated by rustdoc present the same logical hierarchy that one
@@ -238,16 +249,16 @@ detected by a `.md` or `.markdown` extension.
238249
There are 4 options to modify the output that Rustdoc creates.
239250

240251
- `--markdown-css PATH`: adds a `<link rel="stylesheet">` tag pointing to `PATH`.
241-
- `--markdown-in-header FILE`: includes the contents of `FILE` at the
252+
- `--html-in-header FILE`: includes the contents of `FILE` at the
242253
end of the `<head>...</head>` section.
243-
- `--markdown-before-content FILE`: includes the contents of `FILE`
254+
- `--html-before-content FILE`: includes the contents of `FILE`
244255
directly after `<body>`, before the rendered content (including the
245256
title).
246-
- `--markdown-after-content FILE`: includes the contents of `FILE`
257+
- `--html-after-content FILE`: includes the contents of `FILE`
247258
directly before `</body>`, after all the rendered content.
248259

249260
All of these can be specified multiple times, and they are output in
250-
the order in which they are specified. The first line of the file must
261+
the order in which they are specified. The first line of the file being rendered must
251262
be the title, prefixed with `%` (e.g. this page has `% Rust
252263
Documentation` on the first line).
253264

src/librustdoc/externalfiles.rs

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::{io, str};
12+
13+
#[deriving(Clone)]
14+
pub struct ExternalHtml{
15+
pub in_header: String,
16+
pub before_content: String,
17+
pub after_content: String
18+
}
19+
20+
impl ExternalHtml {
21+
pub fn load(in_header: &[String], before_content: &[String], after_content: &[String])
22+
-> Option<ExternalHtml> {
23+
match (load_external_files(in_header),
24+
load_external_files(before_content),
25+
load_external_files(after_content)) {
26+
(Some(ih), Some(bc), Some(ac)) => Some(ExternalHtml {
27+
in_header: ih,
28+
before_content: bc,
29+
after_content: ac
30+
}),
31+
_ => None
32+
}
33+
}
34+
}
35+
36+
pub fn load_string(input: &Path) -> io::IoResult<Option<String>> {
37+
let mut f = try!(io::File::open(input));
38+
let d = try!(f.read_to_end());
39+
Ok(str::from_utf8(d.as_slice()).map(|s| s.to_string()))
40+
}
41+
42+
macro_rules! load_or_return {
43+
($input: expr, $cant_read: expr, $not_utf8: expr) => {
44+
{
45+
let input = Path::new($input);
46+
match ::externalfiles::load_string(&input) {
47+
Err(e) => {
48+
let _ = writeln!(&mut io::stderr(),
49+
"error reading `{}`: {}", input.display(), e);
50+
return $cant_read;
51+
}
52+
Ok(None) => {
53+
let _ = writeln!(&mut io::stderr(),
54+
"error reading `{}`: not UTF-8", input.display());
55+
return $not_utf8;
56+
}
57+
Ok(Some(s)) => s
58+
}
59+
}
60+
}
61+
}
62+
63+
pub fn load_external_files(names: &[String]) -> Option<String> {
64+
let mut out = String::new();
65+
for name in names.iter() {
66+
out.push_str(load_or_return!(name.as_slice(), None, None).as_slice());
67+
out.push_char('\n');
68+
}
69+
Some(out)
70+
}

src/librustdoc/html/layout.rs

+11
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,13 @@
1111
use std::fmt;
1212
use std::io;
1313

14+
use externalfiles::ExternalHtml;
15+
1416
#[deriving(Clone)]
1517
pub struct Layout {
1618
pub logo: String,
1719
pub favicon: String,
20+
pub external_html: ExternalHtml,
1821
pub krate: String,
1922
pub playground_url: String,
2023
}
@@ -44,6 +47,7 @@ r##"<!DOCTYPE html>
4447
<link rel="stylesheet" type="text/css" href="{root_path}main.css">
4548
4649
{favicon}
50+
{in_header}
4751
</head>
4852
<body>
4953
<!--[if lte IE 8]>
@@ -53,6 +57,8 @@ r##"<!DOCTYPE html>
5357
</div>
5458
<![endif]-->
5559
60+
{before_content}
61+
5662
<section class="sidebar">
5763
{logo}
5864
{sidebar}
@@ -105,6 +111,8 @@ r##"<!DOCTYPE html>
105111
</div>
106112
</div>
107113
114+
{after_content}
115+
108116
<script>
109117
window.rootPath = "{root_path}";
110118
window.currentCrate = "{krate}";
@@ -133,6 +141,9 @@ r##"<!DOCTYPE html>
133141
} else {
134142
format!(r#"<link rel="shortcut icon" href="{}">"#, layout.favicon)
135143
},
144+
in_header = layout.external_html.in_header,
145+
before_content = layout.external_html.before_content,
146+
after_content = layout.external_html.after_content,
136147
sidebar = *sidebar,
137148
krate = layout.krate,
138149
play_url = layout.playground_url,

src/librustdoc/html/render.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ use std::str;
4141
use std::string::String;
4242
use std::sync::Arc;
4343

44+
use externalfiles::ExternalHtml;
45+
4446
use serialize::json::ToJson;
4547
use syntax::ast;
4648
use syntax::ast_util;
@@ -78,7 +80,7 @@ pub struct Context {
7880
/// This changes as the context descends into the module hierarchy.
7981
pub dst: Path,
8082
/// This describes the layout of each page, and is not modified after
81-
/// creation of the context (contains info like the favicon)
83+
/// creation of the context (contains info like the favicon and added html).
8284
pub layout: layout::Layout,
8385
/// This map is a list of what should be displayed on the sidebar of the
8486
/// current page. The key is the section header (traits, modules,
@@ -220,7 +222,7 @@ local_data_key!(pub cache_key: Arc<Cache>)
220222
local_data_key!(pub current_location_key: Vec<String> )
221223

222224
/// Generates the documentation for `crate` into the directory `dst`
223-
pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
225+
pub fn run(mut krate: clean::Crate, external_html: &ExternalHtml, dst: Path) -> io::IoResult<()> {
224226
let mut cx = Context {
225227
dst: dst,
226228
current: Vec::new(),
@@ -229,12 +231,14 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
229231
layout: layout::Layout {
230232
logo: "".to_string(),
231233
favicon: "".to_string(),
234+
external_html: external_html.clone(),
232235
krate: krate.name.clone(),
233236
playground_url: "".to_string(),
234237
},
235238
include_sources: true,
236239
render_redirect_pages: false,
237240
};
241+
238242
try!(mkdir(&cx.dst));
239243

240244
// Crawl the crate attributes looking for attributes which control how we're

src/librustdoc/lib.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,16 @@ use std::io::{File, MemWriter};
3232
use std::str;
3333
use std::gc::Gc;
3434
use serialize::{json, Decodable, Encodable};
35+
use externalfiles::ExternalHtml;
3536

3637
// reexported from `clean` so it can be easily updated with the mod itself
3738
pub use clean::SCHEMA_VERSION;
3839

3940
pub mod clean;
4041
pub mod core;
4142
pub mod doctree;
43+
#[macro_escape]
44+
pub mod externalfiles;
4245
pub mod fold;
4346
pub mod html {
4447
pub mod highlight;
@@ -113,16 +116,17 @@ pub fn opts() -> Vec<getopts::OptGroup> {
113116
"ARGS"),
114117
optmulti("", "markdown-css", "CSS files to include via <link> in a rendered Markdown file",
115118
"FILES"),
116-
optmulti("", "markdown-in-header",
117-
"files to include inline in the <head> section of a rendered Markdown file",
119+
optmulti("", "html-in-header",
120+
"files to include inline in the <head> section of a rendered Markdown file \
121+
or generated documentation",
118122
"FILES"),
119-
optmulti("", "markdown-before-content",
123+
optmulti("", "html-before-content",
120124
"files to include inline between <body> and the content of a rendered \
121-
Markdown file",
125+
Markdown file or generated documentation",
122126
"FILES"),
123-
optmulti("", "markdown-after-content",
127+
optmulti("", "html-after-content",
124128
"files to include inline between the content and </body> of a rendered \
125-
Markdown file",
129+
Markdown file or generated documentation",
126130
"FILES"),
127131
optopt("", "markdown-playground-url",
128132
"URL to send code snippets to", "URL")
@@ -179,6 +183,14 @@ pub fn main_args(args: &[String]) -> int {
179183
let output = matches.opt_str("o").map(|s| Path::new(s));
180184
let cfgs = matches.opt_strs("cfg");
181185

186+
let external_html = match ExternalHtml::load(
187+
matches.opt_strs("html-in-header").as_slice(),
188+
matches.opt_strs("html-before-content").as_slice(),
189+
matches.opt_strs("html-after-content").as_slice()) {
190+
Some(eh) => eh,
191+
None => return 3
192+
};
193+
182194
match (should_test, markdown_input) {
183195
(true, true) => {
184196
return markdown::test(input, libs, test_args)
@@ -187,7 +199,7 @@ pub fn main_args(args: &[String]) -> int {
187199
return test::run(input, cfgs, libs, test_args)
188200
}
189201
(false, true) => return markdown::render(input, output.unwrap_or(Path::new("doc")),
190-
&matches),
202+
&matches, &external_html),
191203
(false, false) => {}
192204
}
193205

@@ -215,7 +227,7 @@ pub fn main_args(args: &[String]) -> int {
215227
let started = time::precise_time_ns();
216228
match matches.opt_str("w").as_ref().map(|s| s.as_slice()) {
217229
Some("html") | None => {
218-
match html::render::run(krate, output.unwrap_or(Path::new("doc"))) {
230+
match html::render::run(krate, &external_html, output.unwrap_or(Path::new("doc"))) {
219231
Ok(()) => {}
220232
Err(e) => fail!("failed to generate documentation: {}", e),
221233
}

0 commit comments

Comments
 (0)