Skip to content

Commit

Permalink
Allow external html in rustdoc for crates.
Browse files Browse the repository at this point in the history
Updated documentation to reflect md->html.
Modularized external file loading.
  • Loading branch information
zzmp committed Jun 30, 2014
1 parent 0ddf6f4 commit 63afc08
Show file tree
Hide file tree
Showing 8 changed files with 143 additions and 69 deletions.
9 changes: 9 additions & 0 deletions man/rustdoc.1
Expand Up @@ -38,6 +38,15 @@ directory to load plugins from (default: /tmp/rustdoc_ng/plugins)
-L --library-path <val>
directory to add to crate search path
.TP
--html-in-header <val>
file to add to <head>
.TP
--html-before-content <val>
file to add in <body>, before content
.TP
--html-after-content <val>
file to add in <body>, after content
.TP
-h, --help
Print help

Expand Down
8 changes: 4 additions & 4 deletions mk/docs.mk
Expand Up @@ -35,16 +35,16 @@ DOCS := index intro tutorial guide guide-ffi guide-macros guide-lifetimes \
PDF_DOCS := tutorial rust

RUSTDOC_DEPS_rust := doc/full-toc.inc
RUSTDOC_FLAGS_rust := --markdown-in-header=doc/full-toc.inc
RUSTDOC_FLAGS_rust := --html-in-header=doc/full-toc.inc

L10N_LANGS := ja

# Generally no need to edit below here.

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

RUSTDOC_HTML_OPTS = $(RUSTDOC_HTML_OPTS_NO_CSS) --markdown-css rust.css
Expand Down
19 changes: 15 additions & 4 deletions src/doc/rustdoc.md
Expand Up @@ -103,6 +103,17 @@ rustdoc can also generate JSON, for consumption by other tools, with
`rustdoc --output-format json`, and also consume already-generated JSON with
`rustdoc --input-format json`.

rustdoc also supports personalizing the output from crates' documentation,
similar to markdown options.

- `--html-in-header FILE`: includes the contents of `FILE` at the
end of the `<head>...</head>` section.
- `--html-before-content FILE`: includes the contents of `FILE`
directly after `<body>`, before the rendered content (including the
search bar).
- `--html-after-content FILE`: includes the contents of `FILE`
after all the rendered content.

# Using the Documentation

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

- `--markdown-css PATH`: adds a `<link rel="stylesheet">` tag pointing to `PATH`.
- `--markdown-in-header FILE`: includes the contents of `FILE` at the
- `--html-in-header FILE`: includes the contents of `FILE` at the
end of the `<head>...</head>` section.
- `--markdown-before-content FILE`: includes the contents of `FILE`
- `--html-before-content FILE`: includes the contents of `FILE`
directly after `<body>`, before the rendered content (including the
title).
- `--markdown-after-content FILE`: includes the contents of `FILE`
- `--html-after-content FILE`: includes the contents of `FILE`
directly before `</body>`, after all the rendered content.

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

Expand Down
70 changes: 70 additions & 0 deletions src/librustdoc/externalfiles.rs
@@ -0,0 +1,70 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::{io, str};

#[deriving(Clone)]
pub struct ExternalHtml{
pub in_header: String,
pub before_content: String,
pub after_content: String
}

impl ExternalHtml {
pub fn load(in_header: &[String], before_content: &[String], after_content: &[String])
-> Option<ExternalHtml> {
match (load_external_files(in_header),
load_external_files(before_content),
load_external_files(after_content)) {
(Some(ih), Some(bc), Some(ac)) => Some(ExternalHtml {
in_header: ih,
before_content: bc,
after_content: ac
}),
_ => None
}
}
}

pub fn load_string(input: &Path) -> io::IoResult<Option<String>> {
let mut f = try!(io::File::open(input));
let d = try!(f.read_to_end());
Ok(str::from_utf8(d.as_slice()).map(|s| s.to_string()))
}

macro_rules! load_or_return {
($input: expr, $cant_read: expr, $not_utf8: expr) => {
{
let input = Path::new($input);
match ::externalfiles::load_string(&input) {
Err(e) => {
let _ = writeln!(&mut io::stderr(),
"error reading `{}`: {}", input.display(), e);
return $cant_read;
}
Ok(None) => {
let _ = writeln!(&mut io::stderr(),
"error reading `{}`: not UTF-8", input.display());
return $not_utf8;
}
Ok(Some(s)) => s
}
}
}
}

pub fn load_external_files(names: &[String]) -> Option<String> {
let mut out = String::new();
for name in names.iter() {
out.push_str(load_or_return!(name.as_slice(), None, None).as_slice());
out.push_char('\n');
}
Some(out)
}
11 changes: 11 additions & 0 deletions src/librustdoc/html/layout.rs
Expand Up @@ -11,10 +11,13 @@
use std::fmt;
use std::io;

use externalfiles::ExternalHtml;

#[deriving(Clone)]
pub struct Layout {
pub logo: String,
pub favicon: String,
pub external_html: ExternalHtml,
pub krate: String,
pub playground_url: String,
}
Expand Down Expand Up @@ -44,6 +47,7 @@ r##"<!DOCTYPE html>
<link rel="stylesheet" type="text/css" href="{root_path}main.css">
{favicon}
{in_header}
</head>
<body>
<!--[if lte IE 8]>
Expand All @@ -53,6 +57,8 @@ r##"<!DOCTYPE html>
</div>
<![endif]-->
{before_content}
<section class="sidebar">
{logo}
{sidebar}
Expand Down Expand Up @@ -105,6 +111,8 @@ r##"<!DOCTYPE html>
</div>
</div>
{after_content}
<script>
window.rootPath = "{root_path}";
window.currentCrate = "{krate}";
Expand Down Expand Up @@ -133,6 +141,9 @@ r##"<!DOCTYPE html>
} else {
format!(r#"<link rel="shortcut icon" href="{}">"#, layout.favicon)
},
in_header = layout.external_html.in_header,
before_content = layout.external_html.before_content,
after_content = layout.external_html.after_content,
sidebar = *sidebar,
krate = layout.krate,
play_url = layout.playground_url,
Expand Down
8 changes: 6 additions & 2 deletions src/librustdoc/html/render.rs
Expand Up @@ -41,6 +41,8 @@ use std::str;
use std::string::String;
use std::sync::Arc;

use externalfiles::ExternalHtml;

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

/// Generates the documentation for `crate` into the directory `dst`
pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
pub fn run(mut krate: clean::Crate, external_html: &ExternalHtml, dst: Path) -> io::IoResult<()> {
let mut cx = Context {
dst: dst,
current: Vec::new(),
Expand All @@ -229,12 +231,14 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
layout: layout::Layout {
logo: "".to_string(),
favicon: "".to_string(),
external_html: external_html.clone(),
krate: krate.name.clone(),
playground_url: "".to_string(),
},
include_sources: true,
render_redirect_pages: false,
};

try!(mkdir(&cx.dst));

// Crawl the crate attributes looking for attributes which control how we're
Expand Down
28 changes: 20 additions & 8 deletions src/librustdoc/lib.rs
Expand Up @@ -32,13 +32,16 @@ use std::io::{File, MemWriter};
use std::str;
use std::gc::Gc;
use serialize::{json, Decodable, Encodable};
use externalfiles::ExternalHtml;

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

pub mod clean;
pub mod core;
pub mod doctree;
#[macro_escape]
pub mod externalfiles;
pub mod fold;
pub mod html {
pub mod highlight;
Expand Down Expand Up @@ -113,16 +116,17 @@ pub fn opts() -> Vec<getopts::OptGroup> {
"ARGS"),
optmulti("", "markdown-css", "CSS files to include via <link> in a rendered Markdown file",
"FILES"),
optmulti("", "markdown-in-header",
"files to include inline in the <head> section of a rendered Markdown file",
optmulti("", "html-in-header",
"files to include inline in the <head> section of a rendered Markdown file \
or generated documentation",
"FILES"),
optmulti("", "markdown-before-content",
optmulti("", "html-before-content",
"files to include inline between <body> and the content of a rendered \
Markdown file",
Markdown file or generated documentation",
"FILES"),
optmulti("", "markdown-after-content",
optmulti("", "html-after-content",
"files to include inline between the content and </body> of a rendered \
Markdown file",
Markdown file or generated documentation",
"FILES"),
optopt("", "markdown-playground-url",
"URL to send code snippets to", "URL")
Expand Down Expand Up @@ -179,6 +183,14 @@ pub fn main_args(args: &[String]) -> int {
let output = matches.opt_str("o").map(|s| Path::new(s));
let cfgs = matches.opt_strs("cfg");

let external_html = match ExternalHtml::load(
matches.opt_strs("html-in-header").as_slice(),
matches.opt_strs("html-before-content").as_slice(),
matches.opt_strs("html-after-content").as_slice()) {
Some(eh) => eh,
None => return 3
};

match (should_test, markdown_input) {
(true, true) => {
return markdown::test(input, libs, test_args)
Expand All @@ -187,7 +199,7 @@ pub fn main_args(args: &[String]) -> int {
return test::run(input, cfgs, libs, test_args)
}
(false, true) => return markdown::render(input, output.unwrap_or(Path::new("doc")),
&matches),
&matches, &external_html),
(false, false) => {}
}

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

5 comments on commit 63afc08

@bors
Copy link
Contributor

@bors bors commented on 63afc08 Jun 30, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from huonw
at zzmp@63afc08

@bors
Copy link
Contributor

@bors bors commented on 63afc08 Jun 30, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging zzmp/rust/feat/markdown-in-crate-documentation = 63afc08 into auto

@bors
Copy link
Contributor

@bors bors commented on 63afc08 Jun 30, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zzmp/rust/feat/markdown-in-crate-documentation = 63afc08 merged ok, testing candidate = 2735c7b

@bors
Copy link
Contributor

@bors bors commented on 63afc08 Jun 30, 2014

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 2735c7b

Please sign in to comment.