diff --git a/mk/docs.mk b/mk/docs.mk
index a84977b382b..1104c3eb6db 100644
--- a/mk/docs.mk
+++ b/mk/docs.mk
@@ -275,9 +275,8 @@ endif
 docs: $(DOC_TARGETS)
 compiler-docs: $(COMPILER_DOC_TARGETS)
 
-trpl: tmp/trpl.ok
+trpl: doc/book/index.html
 
-tmp/trpl.ok: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/trpl/*.md)
+doc/book/index.html: $(RUSTBOOK_EXE) $(wildcard $(S)/src/doc/trpl/*.md)
 	$(Q)rm -rf doc/book
 	$(Q)$(RUSTBOOK) build $(S)src/doc/trpl doc/book
-	$(Q)touch $@
diff --git a/mk/tests.mk b/mk/tests.mk
index 97455e744d4..c8c4beb1153 100644
--- a/mk/tests.mk
+++ b/mk/tests.mk
@@ -156,8 +156,8 @@ endef
 
 $(foreach doc,$(DOCS), \
   $(eval $(call DOCTEST,md-$(doc),$(S)src/doc/$(doc).md)))
-$(foreach file,$(wildcard $(S)src/doc/trpl/src/*), \
-  $(eval $(call DOCTEST,$(file:$(S)src/doc/trpl/src/%.md=trpl-%),$(file))))
+$(foreach file,$(wildcard $(S)src/doc/trpl/*.md), \
+  $(eval $(call DOCTEST,$(file:$(S)src/doc/trpl/%.md=trpl-%),$(file))))
 
 ######################################################################
 # Main test targets
diff --git a/src/doc/trpl/SUMMARY.md b/src/doc/trpl/SUMMARY.md
index 0f1bce389df..1a61c6d216b 100644
--- a/src/doc/trpl/SUMMARY.md
+++ b/src/doc/trpl/SUMMARY.md
@@ -1,35 +1,36 @@
 # Summary
 
-* [I: The Basics](src/basic.md)
-    * [Installing Rust](src/installing-rust.md)
-    * [Hello, world!](src/hello-world.md)
-    * [Hello, Cargo!](src/hello-cargo.md)
-    * [Variable Bindings](src/variable-bindings.md)
-    * [If](src/if.md)
-    * [Functions](src/functions.md)
-    * [Comments](src/comments.md)
-    * [Compound Data Types](src/compound-data-types.md)
-    * [Match](src/match.md)
-    * [Looping](src/looping.md)
-    * [Strings](src/strings.md)
-    * [Arrays, Vectors, and Slices](src/arrays-vectors-and-slices.md)
-    * [Standard Input](src/standard-input.md)
-    * [Guessing Game](src/guessing-game.md)
-* [II: Intermedite Rust](src/intermediate.md)
-    * [Crates and Modules](src/crates-and-modules.md)
-    * [Testing](src/testing.md)
-    * [Pointers](src/pointers.md)
-    * [Patterns](src/patterns.md)
-    * [Method Syntax](src/method-syntax.md)
-    * [Closures](src/closures.md)
-    * [Iterators](src/iterators.md)
-    * [Generics](src/generics.md)
-    * [Traits](src/traits.md)
-    * [Tasks](src/tasks.md)
-    * [Error Handling](src/error-handling.md)
-* [III: Advanced Topics](src/advanced.md)
-    * [FFI](src/ffi.md)
-    * [Unsafe Code](src/unsafe.md)
-    * [Macros](src/macros.md)
-    * [Compiler Plugins](src/plugins.md)
-* [Conclusion](src/conclusion.md)
+* [I: The Basics](basic.md)
+    * [Installing Rust](installing-rust.md)
+    * [Hello, world!](hello-world.md)
+    * [Hello, Cargo!](hello-cargo.md)
+    * [Variable Bindings](variable-bindings.md)
+    * [If](if.md)
+    * [Functions](functions.md)
+    * [Comments](comments.md)
+    * [Compound Data Types](compound-data-types.md)
+    * [Match](match.md)
+    * [Looping](looping.md)
+    * [Strings](strings.md)
+    * [Arrays, Vectors, and Slices](arrays-vectors-and-slices.md)
+    * [Standard Input](standard-input.md)
+    * [Guessing Game](guessing-game.md)
+* [II: Intermediate Rust](intermediate.md)
+    * [Crates and Modules](crates-and-modules.md)
+    * [Testing](testing.md)
+    * [Pointers](pointers.md)
+    * [Ownership](ownership.md)
+    * [Patterns](patterns.md)
+    * [Method Syntax](method-syntax.md)
+    * [Closures](closures.md)
+    * [Iterators](iterators.md)
+    * [Generics](generics.md)
+    * [Traits](traits.md)
+    * [Tasks](tasks.md)
+    * [Error Handling](error-handling.md)
+* [III: Advanced Topics](advanced.md)
+    * [FFI](ffi.md)
+    * [Unsafe Code](unsafe.md)
+    * [Macros](macros.md)
+    * [Compiler Plugins](plugins.md)
+* [Conclusion](conclusion.md)
diff --git a/src/doc/trpl/src/advanced.md b/src/doc/trpl/advanced.md
similarity index 100%
rename from src/doc/trpl/src/advanced.md
rename to src/doc/trpl/advanced.md
diff --git a/src/doc/trpl/src/arrays-vectors-and-slices.md b/src/doc/trpl/arrays-vectors-and-slices.md
similarity index 96%
rename from src/doc/trpl/src/arrays-vectors-and-slices.md
rename to src/doc/trpl/arrays-vectors-and-slices.md
index 68fc73222fd..24d60dd2e4e 100644
--- a/src/doc/trpl/src/arrays-vectors-and-slices.md
+++ b/src/doc/trpl/arrays-vectors-and-slices.md
@@ -1,4 +1,4 @@
-# Arrays, Vectors, and Slices
+% Arrays, Vectors, and Slices
 
 Like many programming languages, Rust has list types to represent a sequence of
 things. The most basic is the **array**, a fixed-size list of elements of the
@@ -48,7 +48,7 @@ errant access is the source of many bugs in other systems programming
 languages.
 
 A **vector** is a dynamic or "growable" array, implemented as the standard
-library type [`Vec<T>`](std/vec/) (we'll talk about what the `<T>` means
+library type [`Vec<T>`](../std/vec/) (we'll talk about what the `<T>` means
 later). Vectors are to arrays what `String` is to `&str`. You can create them
 with the `vec!` macro:
 
diff --git a/src/doc/trpl/src/basic.md b/src/doc/trpl/basic.md
similarity index 100%
rename from src/doc/trpl/src/basic.md
rename to src/doc/trpl/basic.md
diff --git a/src/doc/trpl/src/closures.md b/src/doc/trpl/closures.md
similarity index 99%
rename from src/doc/trpl/src/closures.md
rename to src/doc/trpl/closures.md
index 79ae28e1b91..6413b90ee71 100644
--- a/src/doc/trpl/src/closures.md
+++ b/src/doc/trpl/closures.md
@@ -1,4 +1,4 @@
-# Closures
+% Closures
 
 So far, we've made lots of functions in Rust, but we've given them all names.
 Rust also allows us to create anonymous functions. Rust's anonymous
diff --git a/src/doc/trpl/src/comments.md b/src/doc/trpl/comments.md
similarity index 93%
rename from src/doc/trpl/src/comments.md
rename to src/doc/trpl/comments.md
index cce6eacea04..f02c1ad9a18 100644
--- a/src/doc/trpl/src/comments.md
+++ b/src/doc/trpl/comments.md
@@ -1,4 +1,4 @@
-# Comments
+% Comments
 
 Now that we have some functions, it's a good idea to learn about comments.
 Comments are notes that you leave to other programmers to help explain things
@@ -42,5 +42,5 @@ fn hello(name: &str) {
 When writing doc comments, adding sections for any arguments, return values,
 and providing some examples of usage is very, very helpful.
 
-You can use the [`rustdoc`](rustdoc.html) tool to generate HTML documentation
+You can use the [`rustdoc`](../rustdoc.html) tool to generate HTML documentation
 from these doc comments.
diff --git a/src/doc/trpl/src/compound-data-types.md b/src/doc/trpl/compound-data-types.md
similarity index 99%
rename from src/doc/trpl/src/compound-data-types.md
rename to src/doc/trpl/compound-data-types.md
index b9bb5097361..b80d248bc41 100644
--- a/src/doc/trpl/src/compound-data-types.md
+++ b/src/doc/trpl/compound-data-types.md
@@ -1,4 +1,4 @@
-# Compound Data Types
+% Compound Data Types
 
 Rust, like many programming languages, has a number of different data types
 that are built-in. You've already done some simple work with integers and
diff --git a/src/doc/trpl/src/conclusion.md b/src/doc/trpl/conclusion.md
similarity index 100%
rename from src/doc/trpl/src/conclusion.md
rename to src/doc/trpl/conclusion.md
diff --git a/src/doc/trpl/src/crates-and-modules.md b/src/doc/trpl/crates-and-modules.md
similarity index 100%
rename from src/doc/trpl/src/crates-and-modules.md
rename to src/doc/trpl/crates-and-modules.md
diff --git a/src/doc/trpl/src/error-handling.md b/src/doc/trpl/error-handling.md
similarity index 100%
rename from src/doc/trpl/src/error-handling.md
rename to src/doc/trpl/error-handling.md
diff --git a/src/doc/trpl/src/ffi.md b/src/doc/trpl/ffi.md
similarity index 100%
rename from src/doc/trpl/src/ffi.md
rename to src/doc/trpl/ffi.md
diff --git a/src/doc/trpl/src/functions.md b/src/doc/trpl/functions.md
similarity index 99%
rename from src/doc/trpl/src/functions.md
rename to src/doc/trpl/functions.md
index 0fa3c66af64..e3827d962c3 100644
--- a/src/doc/trpl/src/functions.md
+++ b/src/doc/trpl/functions.md
@@ -1,4 +1,4 @@
-# Functions
+% Functions
 
 You've already seen one function so far, the `main` function:
 
diff --git a/src/doc/trpl/src/generics.md b/src/doc/trpl/generics.md
similarity index 100%
rename from src/doc/trpl/src/generics.md
rename to src/doc/trpl/generics.md
diff --git a/src/doc/trpl/src/guessing-game.md b/src/doc/trpl/guessing-game.md
similarity index 98%
rename from src/doc/trpl/src/guessing-game.md
rename to src/doc/trpl/guessing-game.md
index 1efcd489760..2847964f15f 100644
--- a/src/doc/trpl/src/guessing-game.md
+++ b/src/doc/trpl/guessing-game.md
@@ -1,4 +1,4 @@
-# Guessing Game
+% Guessing Game
 
 Okay! We've got the basics of Rust down. Let's write a bigger program.
 
@@ -108,12 +108,12 @@ we do know that Rust has random number generation, but we don't know how to
 use it.
 
 Enter the docs. Rust has a page specifically to document the standard library.
-You can find that page [here](std/index.html). There's a lot of information on
+You can find that page [here](../std/index.html). There's a lot of information on
 that page, but the best part is the search bar. Right up at the top, there's
 a box that you can enter in a search term. The search is pretty primitive
 right now, but is getting better all the time. If you type 'random' in that
-box, the page will update to [this one](std/index.html?search=random). The very
-first result is a link to [`std::rand::random`](std/rand/fn.random.html). If we
+box, the page will update to [this one](../std/index.html?search=random). The very
+first result is a link to [`std::rand::random`](../std/rand/fn.random.html). If we
 click on that result, we'll be taken to its documentation page.
 
 This page shows us a few things: the type signature of the function, some
diff --git a/src/doc/trpl/src/hello-cargo.md b/src/doc/trpl/hello-cargo.md
similarity index 99%
rename from src/doc/trpl/src/hello-cargo.md
rename to src/doc/trpl/hello-cargo.md
index c81cdc465c8..d8acd95b59d 100644
--- a/src/doc/trpl/src/hello-cargo.md
+++ b/src/doc/trpl/hello-cargo.md
@@ -1,4 +1,4 @@
-# Hello, Cargo!
+% Hello, Cargo!
 
 [Cargo](http://crates.io) is a tool that Rustaceans use to help manage their
 Rust projects. Cargo is currently in an alpha state, just like Rust, and so it
diff --git a/src/doc/trpl/src/hello-world.md b/src/doc/trpl/hello-world.md
similarity index 99%
rename from src/doc/trpl/src/hello-world.md
rename to src/doc/trpl/hello-world.md
index 33cb752c364..f9cc1ebf0bf 100644
--- a/src/doc/trpl/src/hello-world.md
+++ b/src/doc/trpl/hello-world.md
@@ -1,4 +1,4 @@
-# Hello, world!
+% Hello, world!
 
 Now that you have Rust installed, let's write your first Rust program. It's
 traditional to make your first program in any new language one that prints the
diff --git a/src/doc/trpl/src/if.md b/src/doc/trpl/if.md
similarity index 99%
rename from src/doc/trpl/src/if.md
rename to src/doc/trpl/if.md
index bc3d548ce9f..6f81a27b2b7 100644
--- a/src/doc/trpl/src/if.md
+++ b/src/doc/trpl/if.md
@@ -1,4 +1,4 @@
-# `if`
+% `if`
 
 Rust's take on `if` is not particularly complex, but it's much more like the
 `if` you'll find in a dynamically typed language than in a more traditional
diff --git a/src/doc/trpl/src/installing-rust.md b/src/doc/trpl/installing-rust.md
similarity index 99%
rename from src/doc/trpl/src/installing-rust.md
rename to src/doc/trpl/installing-rust.md
index 1705893c397..5893b51a420 100644
--- a/src/doc/trpl/src/installing-rust.md
+++ b/src/doc/trpl/installing-rust.md
@@ -1,4 +1,4 @@
-# Installing Rust
+% Installing Rust
 
 The first step to using Rust is to install it! There are a number of ways to
 install Rust, but the easiest is to use the `rustup` script. If you're on
diff --git a/src/doc/trpl/src/intermediate.md b/src/doc/trpl/intermediate.md
similarity index 100%
rename from src/doc/trpl/src/intermediate.md
rename to src/doc/trpl/intermediate.md
diff --git a/src/doc/trpl/src/iterators.md b/src/doc/trpl/iterators.md
similarity index 99%
rename from src/doc/trpl/src/iterators.md
rename to src/doc/trpl/iterators.md
index 056e9a9720e..a773b7329db 100644
--- a/src/doc/trpl/src/iterators.md
+++ b/src/doc/trpl/iterators.md
@@ -336,4 +336,4 @@ can help you with. There are a number of really useful iterators, and you can
 write your own as well. Iterators provide a safe, efficient way to manipulate
 all kinds of lists. They're a little unusual at first, but if you play with
 them, you'll get hooked. For a full list of the different iterators and
-consumers, check out the [iterator module documentation](std/iter/index.html).
+consumers, check out the [iterator module documentation](../std/iter/index.html).
diff --git a/src/doc/trpl/src/looping.md b/src/doc/trpl/looping.md
similarity index 99%
rename from src/doc/trpl/src/looping.md
rename to src/doc/trpl/looping.md
index 03384b28703..80926c99e87 100644
--- a/src/doc/trpl/src/looping.md
+++ b/src/doc/trpl/looping.md
@@ -1,4 +1,4 @@
-# Looping
+% Looping
 
 Looping is the last basic construct that we haven't learned yet in Rust. Rust has
 two main looping constructs: `for` and `while`.
diff --git a/src/doc/trpl/src/macros.md b/src/doc/trpl/macros.md
similarity index 99%
rename from src/doc/trpl/src/macros.md
rename to src/doc/trpl/macros.md
index 95f5305775e..c694806b4ba 100644
--- a/src/doc/trpl/src/macros.md
+++ b/src/doc/trpl/macros.md
@@ -507,7 +507,7 @@ When this library is loaded with `#[use_macros] extern crate`, only `m2` will
 be imported.
 
 The Rust Reference has a [listing of macro-related
-attributes](reference.html#macro--and-plugin-related-attributes).
+attributes](../reference.html#macro--and-plugin-related-attributes).
 
 # The variable `$crate`
 
@@ -567,7 +567,7 @@ intermediate states out, and passing the flag `--pretty expanded` as a
 command-line argument to the compiler will show the result of expansion.
 
 If Rust's macro system can't do what you need, you may want to write a
-[compiler plugin](guide-plugin.html) instead. Compared to `macro_rules!`
+[compiler plugin](plugin.html) instead. Compared to `macro_rules!`
 macros, this is significantly more work, the interfaces are much less stable,
 and the warnings about debugging apply ten-fold. In exchange you get the
 flexibility of running arbitrary Rust code within the compiler. Syntax
diff --git a/src/doc/trpl/src/match.md b/src/doc/trpl/match.md
similarity index 99%
rename from src/doc/trpl/src/match.md
rename to src/doc/trpl/match.md
index 0170109def0..c120142cf5c 100644
--- a/src/doc/trpl/src/match.md
+++ b/src/doc/trpl/match.md
@@ -1,4 +1,4 @@
-# Match
+% Match
 
 Often, a simple `if`/`else` isn't enough, because you have more than two
 possible options. Also, `else` conditions can get incredibly complicated, so
diff --git a/src/doc/trpl/src/method-syntax.md b/src/doc/trpl/method-syntax.md
similarity index 100%
rename from src/doc/trpl/src/method-syntax.md
rename to src/doc/trpl/method-syntax.md
diff --git a/src/doc/trpl/src/ownership.md b/src/doc/trpl/ownership.md
similarity index 100%
rename from src/doc/trpl/src/ownership.md
rename to src/doc/trpl/ownership.md
diff --git a/src/doc/trpl/src/patterns.md b/src/doc/trpl/patterns.md
similarity index 100%
rename from src/doc/trpl/src/patterns.md
rename to src/doc/trpl/patterns.md
diff --git a/src/doc/trpl/src/plugins.md b/src/doc/trpl/plugins.md
similarity index 81%
rename from src/doc/trpl/src/plugins.md
rename to src/doc/trpl/plugins.md
index 025f0cced63..2a0710d018c 100644
--- a/src/doc/trpl/src/plugins.md
+++ b/src/doc/trpl/plugins.md
@@ -5,20 +5,20 @@
 <p>
 <b>Warning:</b> Plugins are an advanced, unstable feature! For many details,
 the only available documentation is the <a
-href="syntax/index.html"><code>libsyntax</code></a> and <a
-href="rustc/index.html"><code>librustc</code></a> API docs, or even the source
+href="../syntax/index.html"><code>libsyntax</code></a> and <a
+href="../rustc/index.html"><code>librustc</code></a> API docs, or even the source
 code itself. These internal compiler APIs are also subject to change at any
 time.
 </p>
 
 <p>
 For defining new syntax it is often much easier to use Rust's <a
-href="guide-macros.html">built-in macro system</a>.
+href="macros.html">built-in macro system</a>.
 </p>
 
 <p style="margin-bottom: 0">
 The code in this document uses language features not covered in the Rust
-Guide.  See the <a href="reference.html">Reference Manual</a> for more
+Guide.  See the <a href="../reference.html">Reference Manual</a> for more
 information.
 </p>
 
@@ -32,19 +32,19 @@ extend the compiler's behavior with new syntax extensions, lint checks, etc.
 A plugin is a dynamic library crate with a designated "registrar" function that
 registers extensions with `rustc`. Other crates can use these extensions by
 loading the plugin crate with `#[plugin] extern crate`. See the
-[`rustc::plugin`](rustc/plugin/index.html) documentation for more about the
+[`rustc::plugin`](../rustc/plugin/index.html) documentation for more about the
 mechanics of defining and loading a plugin.
 
 Arguments passed as `#[plugin=...]` or `#[plugin(...)]` are not interpreted by
 rustc itself.  They are provided to the plugin through the `Registry`'s [`args`
-method](rustc/plugin/registry/struct.Registry.html#method.args).
+method](../rustc/plugin/registry/struct.Registry.html#method.args).
 
 # Syntax extensions
 
 Plugins can extend Rust's syntax in various ways. One kind of syntax extension
 is the procedural macro. These are invoked the same way as [ordinary
-macros](guide-macros.html), but the expansion is performed by arbitrary Rust
-code that manipulates [syntax trees](syntax/ast/index.html) at
+macros](macros.html), but the expansion is performed by arbitrary Rust
+code that manipulates [syntax trees](../syntax/ast/index.html) at
 compile time.
 
 Let's write a plugin
@@ -126,14 +126,13 @@ The advantages over a simple `fn(&str) -> uint` are:
   a way to define new literal syntax for any data type.
 
 In addition to procedural macros, you can define new
-[`deriving`](reference.html#deriving)-like attributes and other kinds of
+[`deriving`](../reference.html#deriving)-like attributes and other kinds of
 extensions.  See
-[`Registry::register_syntax_extension`](rustc/plugin/registry/struct.Registry.html#method.register_syntax_extension)
+[`Registry::register_syntax_extension`](../rustc/plugin/registry/struct.Registry.html#method.register_syntax_extension)
 and the [`SyntaxExtension`
 enum](http://doc.rust-lang.org/syntax/ext/base/enum.SyntaxExtension.html).  For
 a more involved macro example, see
-[`src/libregex_macros/lib.rs`](https://github.com/rust-lang/rust/blob/master/src/libregex_macros/lib.rs)
-in the Rust distribution.
+[`regex_macros`](https://github.com/rust-lang/regex/blob/master/regex_macros/src/lib.rs).
 
 
 ## Tips and tricks
@@ -147,7 +146,7 @@ variables of the same name (but different syntax contexts) are in play
 in the same scope. In this case `--pretty expanded,hygiene` will tell
 you about the syntax contexts.
 
-You can use [`syntax::parse`](syntax/parse/index.html) to turn token trees into
+You can use [`syntax::parse`](../syntax/parse/index.html) to turn token trees into
 higher-level syntax elements like expressions:
 
 ```ignore
@@ -163,23 +162,23 @@ Looking through [`libsyntax` parser
 code](https://github.com/rust-lang/rust/blob/master/src/libsyntax/parse/parser.rs)
 will give you a feel for how the parsing infrastructure works.
 
-Keep the [`Span`s](syntax/codemap/struct.Span.html) of
+Keep the [`Span`s](../syntax/codemap/struct.Span.html) of
 everything you parse, for better error reporting. You can wrap
-[`Spanned`](syntax/codemap/struct.Spanned.html) around
+[`Spanned`](../syntax/codemap/struct.Spanned.html) around
 your custom data structures.
 
 Calling
-[`ExtCtxt::span_fatal`](syntax/ext/base/struct.ExtCtxt.html#method.span_fatal)
+[`ExtCtxt::span_fatal`](../syntax/ext/base/struct.ExtCtxt.html#method.span_fatal)
 will immediately abort compilation. It's better to instead call
-[`ExtCtxt::span_err`](syntax/ext/base/struct.ExtCtxt.html#method.span_err)
+[`ExtCtxt::span_err`](../syntax/ext/base/struct.ExtCtxt.html#method.span_err)
 and return
-[`DummyResult`](syntax/ext/base/struct.DummyResult.html),
+[`DummyResult`](../syntax/ext/base/struct.DummyResult.html),
 so that the compiler can continue and find further errors.
 
 The example above produced an integer literal using
-[`AstBuilder::expr_uint`](syntax/ext/build/trait.AstBuilder.html#tymethod.expr_uint).
+[`AstBuilder::expr_uint`](../syntax/ext/build/trait.AstBuilder.html#tymethod.expr_uint).
 As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of
-[quasiquote macros](syntax/ext/quote/index.html).  They are undocumented and
+[quasiquote macros](../syntax/ext/quote/index.html).  They are undocumented and
 very rough around the edges.  However, the implementation may be a good
 starting point for an improved quasiquote as an ordinary plugin library.
 
@@ -187,7 +186,7 @@ starting point for an improved quasiquote as an ordinary plugin library.
 # Lint plugins
 
 Plugins can extend [Rust's lint
-infrastructure](reference.html#lint-check-attributes) with additional checks for
+infrastructure](../reference.html#lint-check-attributes) with additional checks for
 code style, safety, etc. You can see
 [`src/test/auxiliary/lint_plugin_test.rs`](https://github.com/rust-lang/rust/blob/master/src/test/auxiliary/lint_plugin_test.rs)
 for a full example, the core of which is reproduced here:
@@ -236,11 +235,11 @@ foo.rs:4 fn lintme() { }
 The components of a lint plugin are:
 
 * one or more `declare_lint!` invocations, which define static
-  [`Lint`](rustc/lint/struct.Lint.html) structs;
+  [`Lint`](../rustc/lint/struct.Lint.html) structs;
 
 * a struct holding any state needed by the lint pass (here, none);
 
-* a [`LintPass`](rustc/lint/trait.LintPass.html)
+* a [`LintPass`](../rustc/lint/trait.LintPass.html)
   implementation defining how to check each syntax element. A single
   `LintPass` may call `span_lint` for several different `Lint`s, but should
   register them all through the `get_lints` method.
@@ -252,7 +251,7 @@ mostly use the same infrastructure as lint plugins, and provide examples of how
 to access type information.
 
 Lints defined by plugins are controlled by the usual [attributes and compiler
-flags](reference.html#lint-check-attributes), e.g. `#[allow(test_lint)]` or
+flags](../reference.html#lint-check-attributes), e.g. `#[allow(test_lint)]` or
 `-A test-lint`. These identifiers are derived from the first argument to
 `declare_lint!`, with appropriate case and punctuation conversion.
 
diff --git a/src/doc/trpl/src/pointers.md b/src/doc/trpl/pointers.md
similarity index 98%
rename from src/doc/trpl/src/pointers.md
rename to src/doc/trpl/pointers.md
index 4c35fae3ecc..ad80d2812d0 100644
--- a/src/doc/trpl/src/pointers.md
+++ b/src/doc/trpl/pointers.md
@@ -409,7 +409,7 @@ test.rs:4         let y = &x;
 
 As you might guess, this kind of analysis is complex for a human, and therefore
 hard for a computer, too! There is an entire [guide devoted to references, ownership,
-and lifetimes](guide-ownership.html) that goes into this topic in
+and lifetimes](ownership.html) that goes into this topic in
 great detail, so if you want the full details, check that out.
 
 ## Best practices
@@ -542,7 +542,7 @@ with some improvements:
 4. Rust enforces that no other writeable pointers alias to this heap memory,
    which means writing to an invalid pointer is not possible.
 
-See the section on references or the [ownership guide](guide-ownership.html)
+See the section on references or the [ownership guide](ownership.html)
 for more detail on how lifetimes work.
 
 Using boxes and references together is very common. For example:
@@ -780,6 +780,6 @@ Here's a quick rundown of Rust's pointer types:
 
 # Related resources
 
-* [API documentation for Box](std/boxed/index.html)
-* [Ownership guide](guide-ownership.html)
+* [API documentation for Box](../std/boxed/index.html)
+* [Ownership guide](ownership.html)
 * [Cyclone paper on regions](http://www.cs.umd.edu/projects/cyclone/papers/cyclone-regions.pdf), which inspired Rust's lifetime system
diff --git a/src/doc/trpl/src/guide-lifetimes.md b/src/doc/trpl/src/guide-lifetimes.md
deleted file mode 100644
index 7a5c535827c..00000000000
--- a/src/doc/trpl/src/guide-lifetimes.md
+++ /dev/null
@@ -1,565 +0,0 @@
-% The Rust References and Lifetimes Guide
-
-# Introduction
-
-References are one of the more flexible and powerful tools available in
-Rust. They can point anywhere: into the heap, stack, and even into the
-interior of another data structure. A reference is as flexible as a C pointer
-or C++ reference.
-
-Unlike C and C++ compilers, the Rust compiler includes special static
-checks that ensure that programs use references safely.
-
-Despite their complete safety, a reference's representation at runtime
-is the same as that of an ordinary pointer in a C program. They introduce zero
-overhead. The compiler does all safety checks at compile time.
-
-Although references have rather elaborate theoretical underpinnings
-(e.g. region pointers), the core concepts will be familiar to anyone
-who has worked with C or C++. The best way to explain how they are
-used—and their limitations—is probably just to work through several examples.
-
-# By example
-
-References, sometimes known as *borrowed pointers*, are only valid for
-a limited duration. References never claim any kind of ownership
-over the data that they point to. Instead, they are used for cases
-where you would like to use data for a short time.
-
-Consider a simple struct type `Point`:
-
-~~~
-struct Point {x: f64, y: f64}
-~~~
-
-We can use this simple definition to allocate points in many different ways. For
-example, in this code, each of these local variables contains a point,
-but allocated in a different place:
-
-~~~
-# struct Point {x: f64, y: f64}
-let on_the_stack : Point      =     Point {x: 3.0, y: 4.0};
-let on_the_heap  : Box<Point> = box Point {x: 7.0, y: 9.0};
-~~~
-
-Suppose we wanted to write a procedure that computed the distance between any
-two points, no matter where they were stored. One option is to define a function
-that takes two arguments of type `Point`—that is, it takes the points by value.
-But if we define it this way, calling the function will cause the points to be
-copied. For points, this is probably not so bad, but often copies are
-expensive. So we'd like to define a function that takes the points just as
-a reference.
-
-~~~
-# use std::num::Float;
-# struct Point {x: f64, y: f64}
-# fn sqrt(f: f64) -> f64 { 0.0 }
-fn compute_distance(p1: &Point, p2: &Point) -> f64 {
-    let x_d = p1.x - p2.x;
-    let y_d = p1.y - p2.y;
-    (x_d * x_d + y_d * y_d).sqrt()
-}
-~~~
-
-Now we can call `compute_distance()`:
-
-~~~
-# struct Point {x: f64, y: f64}
-# let on_the_stack :     Point  =     Point{x: 3.0, y: 4.0};
-# let on_the_heap  : Box<Point> = box Point{x: 7.0, y: 9.0};
-# fn compute_distance(p1: &Point, p2: &Point) -> f64 { 0.0 }
-compute_distance(&on_the_stack, &*on_the_heap);
-~~~
-
-Here, the `&` operator takes the address of the variable
-`on_the_stack`; this is because `on_the_stack` has the type `Point`
-(that is, a struct value) and we have to take its address to get a
-value. We also call this _borrowing_ the local variable
-`on_the_stack`, because we have created an alias: that is, another
-name for the same data.
-
-Likewise, in the case of `on_the_heap`,
-the `&` operator is used in conjunction with the `*` operator
-to take a reference to the contents of the box.
-
-Whenever a caller lends data to a callee, there are some limitations on what
-the caller can do with the original. For example, if the contents of a
-variable have been lent out, you cannot send that variable to another task. In
-addition, the compiler will reject any code that might cause the borrowed
-value to be freed or overwrite its component fields with values of different
-types (I'll get into what kinds of actions those are shortly). This rule
-should make intuitive sense: you must wait for a borrower to return the value
-that you lent it (that is, wait for the reference to go out of scope)
-before you can make full use of it again.
-
-# Other uses for the & operator
-
-In the previous example, the value `on_the_stack` was defined like so:
-
-~~~
-# struct Point {x: f64, y: f64}
-let on_the_stack: Point = Point {x: 3.0, y: 4.0};
-~~~
-
-This declaration means that code can only pass `Point` by value to other
-functions. As a consequence, we had to explicitly take the address of
-`on_the_stack` to get a reference. Sometimes however it is more
-convenient to move the & operator into the definition of `on_the_stack`:
-
-~~~
-# struct Point {x: f64, y: f64}
-let on_the_stack2: &Point = &Point {x: 3.0, y: 4.0};
-~~~
-
-Applying `&` to an rvalue (non-assignable location) is just a convenient
-shorthand for creating a temporary and taking its address. A more verbose
-way to write the same code is:
-
-~~~
-# struct Point {x: f64, y: f64}
-let tmp = Point {x: 3.0, y: 4.0};
-let on_the_stack2 : &Point = &tmp;
-~~~
-
-# Taking the address of fields
-
-The `&` operator is not limited to taking the address of
-local variables. It can also take the address of fields or
-individual array elements. For example, consider this type definition
-for `Rectangle`:
-
-~~~
-struct Point {x: f64, y: f64} // as before
-struct Size {w: f64, h: f64} // as before
-struct Rectangle {origin: Point, size: Size}
-~~~
-
-Now, as before, we can define rectangles in a few different ways:
-
-~~~
-# struct Point {x: f64, y: f64}
-# struct Size {w: f64, h: f64} // as before
-# struct Rectangle {origin: Point, size: Size}
-let rect_stack   =    &Rectangle {origin: Point {x: 1.0, y: 2.0},
-                                  size: Size {w: 3.0, h: 4.0}};
-let rect_heap    = box Rectangle {origin: Point {x: 5.0, y: 6.0},
-                                  size: Size {w: 3.0, h: 4.0}};
-~~~
-
-In each case, we can extract out individual subcomponents with the `&`
-operator. For example, I could write:
-
-~~~
-# struct Point {x: f64, y: f64} // as before
-# struct Size {w: f64, h: f64} // as before
-# struct Rectangle {origin: Point, size: Size}
-# let rect_stack  = &Rectangle {origin: Point {x: 1.0, y: 2.0}, size: Size {w: 3.0, h: 4.0}};
-# let rect_heap   = box Rectangle {origin: Point {x: 5.0, y: 6.0}, size: Size {w: 3.0, h: 4.0}};
-# fn compute_distance(p1: &Point, p2: &Point) -> f64 { 0.0 }
-compute_distance(&rect_stack.origin, &rect_heap.origin);
-~~~
-
-which would borrow the field `origin` from the rectangle on the stack
-as well as from the owned box, and then compute the distance between them.
-
-# Lifetimes
-
-We’ve seen a few examples of borrowing data. To this point, we’ve glossed
-over issues of safety. As stated in the introduction, at runtime a reference
-is simply a pointer, nothing more. Therefore, avoiding C's problems with
-dangling pointers requires a compile-time safety check.
-
-The basis for the check is the notion of _lifetimes_. A lifetime is a
-static approximation of the span of execution during which the pointer
-is valid: it always corresponds to some expression or block within the
-program.
-
-The compiler will only allow a borrow *if it can guarantee that the data will
-not be reassigned or moved for the lifetime of the pointer*. This does not
-necessarily mean that the data is stored in immutable memory. For example,
-the following function is legal:
-
-~~~
-# fn some_condition() -> bool { true }
-# struct Foo { f: int }
-fn example3() -> int {
-    let mut x = box Foo {f: 3};
-    if some_condition() {
-        let y = &x.f;      // -+ L
-        return *y;         //  |
-    }                      // -+
-    x = box Foo {f: 4};
-    // ...
-# return 0;
-}
-~~~
-
-Here, the interior of the variable `x` is being borrowed
-and `x` is declared as mutable. However, the compiler can prove that
-`x` is not assigned anywhere in the lifetime L of the variable
-`y`. Therefore, it accepts the function, even though `x` is mutable
-and in fact is mutated later in the function.
-
-It may not be clear why we are so concerned about mutating a borrowed
-variable. The reason is that the runtime system frees any box
-_as soon as its owning reference changes or goes out of
-scope_. Therefore, a program like this is illegal (and would be
-rejected by the compiler):
-
-~~~ {.ignore}
-fn example3() -> int {
-    let mut x = box X {f: 3};
-    let y = &x.f;
-    x = box X {f: 4};  // Error reported here.
-    *y
-}
-~~~
-
-To make this clearer, consider this diagram showing the state of
-memory immediately before the re-assignment of `x`:
-
-~~~ {.text}
-    Stack               Exchange Heap
-
-  x +-------------+
-    | box {f:int} | ----+
-  y +-------------+     |
-    | &int        | ----+
-    +-------------+     |    +---------+
-                        +--> |  f: 3   |
-                             +---------+
-~~~
-
-Once the reassignment occurs, the memory will look like this:
-
-~~~ {.text}
-    Stack               Exchange Heap
-
-  x +-------------+          +---------+
-    | box {f:int} | -------> |  f: 4   |
-  y +-------------+          +---------+
-    | &int        | ----+
-    +-------------+     |    +---------+
-                        +--> | (freed) |
-                             +---------+
-~~~
-
-Here you can see that the variable `y` still points at the old `f`
-property of Foo, which has been freed.
-
-In fact, the compiler can apply the same kind of reasoning to any
-memory that is (uniquely) owned by the stack frame. So we could
-modify the previous example to introduce additional owned pointers
-and structs, and the compiler will still be able to detect possible
-mutations. This time, we'll use an analogy to illustrate the concept.
-
-~~~ {.ignore}
-fn example3() -> int {
-    struct House { owner: Box<Person> }
-    struct Person { age: int }
-
-    let mut house = box House {
-        owner: box Person {age: 30}
-    };
-
-    let owner_age = &house.owner.age;
-    house = box House {owner: box Person {age: 40}};  // Error reported here.
-    house.owner = box Person {age: 50};               // Error reported here.
-    *owner_age
-}
-~~~
-
-In this case, two errors are reported, one when the variable `house` is
-modified and another when `house.owner` is modified. Either modification would
-invalidate the pointer `owner_age`.
-
-# Borrowing and enums
-
-The previous example showed that the type system forbids any mutations
-of owned boxed values while they are being borrowed. In general, the type
-system also forbids borrowing a value as mutable if it is already being
-borrowed - either as a mutable reference or an immutable one. This restriction
-prevents pointers from pointing into freed memory. There is one other
-case where the compiler must be very careful to ensure that pointers
-remain valid: pointers into the interior of an `enum`.
-
-Let’s look at the following `shape` type that can represent both rectangles
-and circles:
-
-~~~
-struct Point {x: f64, y: f64}; // as before
-struct Size {w: f64, h: f64}; // as before
-enum Shape {
-    Circle(Point, f64),   // origin, radius
-    Rectangle(Point, Size)  // upper-left, dimensions
-}
-~~~
-
-Now we might write a function to compute the area of a shape. This
-function takes a reference to a shape, to avoid the need for
-copying.
-
-~~~
-# struct Point {x: f64, y: f64}; // as before
-# struct Size {w: f64, h: f64}; // as before
-# enum Shape {
-#     Circle(Point, f64),   // origin, radius
-#     Rectangle(Point, Size)  // upper-left, dimensions
-# }
-fn compute_area(shape: &Shape) -> f64 {
-    match *shape {
-        Shape::Circle(_, radius) => std::f64::consts::PI * radius * radius,
-        Shape::Rectangle(_, ref size) => size.w * size.h
-    }
-}
-~~~
-
-The first case matches against circles. Here, the pattern extracts the
-radius from the shape variant and the action uses it to compute the
-area of the circle.
-
-The second match is more interesting. Here we match against a
-rectangle and extract its size: but rather than copy the `size`
-struct, we use a by-reference binding to create a pointer to it. In
-other words, a pattern binding like `ref size` binds the name `size`
-to a pointer of type `&size` into the _interior of the enum_.
-
-To make this more clear, let's look at a diagram of memory layout in
-the case where `shape` points at a rectangle:
-
-~~~ {.text}
-Stack             Memory
-
-+-------+         +---------------+
-| shape | ------> | rectangle(    |
-+-------+         |   {x: f64,    |
-| size  | -+      |    y: f64},   |
-+-------+  +----> |   {w: f64,    |
-                  |    h: f64})   |
-                  +---------------+
-~~~
-
-Here you can see that rectangular shapes are composed of five words of
-memory. The first is a tag indicating which variant this enum is
-(`rectangle`, in this case). The next two words are the `x` and `y`
-fields for the point and the remaining two are the `w` and `h` fields
-for the size. The binding `size` is then a pointer into the inside of
-the shape.
-
-Perhaps you can see where the danger lies: if the shape were somehow
-to be reassigned, perhaps to a circle, then although the memory used
-to store that shape value would still be valid, _it would have a
-different type_! The following diagram shows what memory would look
-like if code overwrote `shape` with a circle:
-
-~~~ {.text}
-Stack             Memory
-
-+-------+         +---------------+
-| shape | ------> | circle(       |
-+-------+         |   {x: f64,    |
-| size  | -+      |    y: f64},   |
-+-------+  +----> |   f64)        |
-                  |               |
-                  +---------------+
-~~~
-
-As you can see, the `size` pointer would be pointing at a `f64`
-instead of a struct. This is not good: dereferencing the second field
-of a `f64` as if it were a struct with two fields would be a memory
-safety violation.
-
-So, in fact, for every `ref` binding, the compiler will impose the
-same rules as the ones we saw for borrowing the interior of an owned
-box: it must be able to guarantee that the `enum` will not be
-overwritten for the duration of the borrow.  In fact, the compiler
-would accept the example we gave earlier. The example is safe because
-the shape pointer has type `&Shape`, which means "reference to
-immutable memory containing a `shape`". If, however, the type of that
-pointer were `&mut Shape`, then the ref binding would be ill-typed.
-Just as with owned boxes, the compiler will permit `ref` bindings
-into data owned by the stack frame even if the data are mutable,
-but otherwise it requires that the data reside in immutable memory.
-
-# Returning references
-
-So far, all of the examples we have looked at, use references in a
-“downward” direction. That is, a method or code block creates a
-reference, then uses it within the same scope. It is also
-possible to return references as the result of a function, but
-as we'll see, doing so requires some explicit annotation.
-
-We could write a subroutine like this:
-
-~~~
-struct Point {x: f64, y: f64}
-fn get_x<'r>(p: &'r Point) -> &'r f64 { &p.x }
-~~~
-
-Here, the function `get_x()` returns a pointer into the structure it
-was given. The type of the parameter (`&'r Point`) and return type
-(`&'r f64`) both use a new syntactic form that we have not seen so
-far.  Here the identifier `r` names the lifetime of the pointer
-explicitly. So in effect, this function declares that it takes a
-pointer with lifetime `r` and returns a pointer with that same
-lifetime.
-
-In general, it is only possible to return references if they
-are derived from a parameter to the procedure. In that case, the
-pointer result will always have the same lifetime as one of the
-parameters; named lifetimes indicate which parameter that
-is.
-
-In the previous code samples, function parameter types did not include a
-lifetime name. The compiler simply creates a fresh name for the lifetime
-automatically: that is, the lifetime name is guaranteed to refer to a distinct
-lifetime from the lifetimes of all other parameters.
-
-Named lifetimes that appear in function signatures are conceptually
-the same as the other lifetimes we have seen before, but they are a bit
-abstract: they don’t refer to a specific expression within `get_x()`,
-but rather to some expression within the *caller of `get_x()`*.  The
-lifetime `r` is actually a kind of *lifetime parameter*: it is defined
-by the caller to `get_x()`, just as the value for the parameter `p` is
-defined by that caller.
-
-In any case, whatever the lifetime of `r` is, the pointer produced by
-`&p.x` always has the same lifetime as `p` itself: a pointer to a
-field of a struct is valid as long as the struct is valid. Therefore,
-the compiler accepts the function `get_x()`.
-
-In general, if you borrow a struct or box to create a
-reference, it will only be valid within the function
-and cannot be returned. This is why the typical way to return references
-is to take references as input (the only other case in
-which it can be legal to return a reference is if it
-points at a static constant).
-
-# Named lifetimes
-
-Lifetimes can be named and referenced. For example, the special lifetime
-`'static`, which does not go out of scope, can be used to create global
-variables and communicate between tasks (see the manual for use cases).
-
-## Parameter Lifetimes
-
-Named lifetimes allow for grouping of parameters by lifetime.
-For example, consider this function:
-
-~~~
-# struct Point {x: f64, y: f64}; // as before
-# struct Size {w: f64, h: f64}; // as before
-# enum Shape {
-#     Circle(Point, f64),   // origin, radius
-#     Rectangle(Point, Size)  // upper-left, dimensions
-# }
-# fn compute_area(shape: &Shape) -> f64 { 0.0 }
-fn select<'r, T>(shape: &'r Shape, threshold: f64,
-                 a: &'r T, b: &'r T) -> &'r T {
-    if compute_area(shape) > threshold {a} else {b}
-}
-~~~
-
-This function takes three references and assigns each the same
-lifetime `r`.  In practice, this means that, in the caller, the
-lifetime `r` will be the *intersection of the lifetime of the three
-region parameters*. This may be overly conservative, as in this
-example:
-
-~~~
-# struct Point {x: f64, y: f64}; // as before
-# struct Size {w: f64, h: f64}; // as before
-# enum Shape {
-#     Circle(Point, f64),   // origin, radius
-#     Rectangle(Point, Size)  // upper-left, dimensions
-# }
-# fn compute_area(shape: &Shape) -> f64 { 0.0 }
-# fn select<'r, T>(shape: &Shape, threshold: f64,
-#                  a: &'r T, b: &'r T) -> &'r T {
-#     if compute_area(shape) > threshold {a} else {b}
-# }
-                                                            // -+ r
-fn select_based_on_unit_circle<'r, T>(                      //  |-+ B
-    threshold: f64, a: &'r T, b: &'r T) -> &'r T {          //  | |
-                                                            //  | |
-    let shape = Shape::Circle(Point {x: 0., y: 0.}, 1.);    //  | |
-    select(&shape, threshold, a, b)                         //  | |
-}                                                           //  |-+
-                                                            // -+
-~~~
-
-In this call to `select()`, the lifetime of the first parameter shape
-is B, the function body. Both of the second two parameters `a` and `b`
-share the same lifetime, `r`, which is a lifetime parameter of
-`select_based_on_unit_circle()`. The caller will infer the
-intersection of these two lifetimes as the lifetime of the returned
-value, and hence the return value of `select()` will be assigned a
-lifetime of B. This will in turn lead to a compilation error, because
-`select_based_on_unit_circle()` is supposed to return a value with the
-lifetime `r`.
-
-To address this, we can modify the definition of `select()` to
-distinguish the lifetime of the first parameter from the lifetime of
-the latter two. After all, the first parameter is not being
-returned. Here is how the new `select()` might look:
-
-~~~
-# struct Point {x: f64, y: f64}; // as before
-# struct Size {w: f64, h: f64}; // as before
-# enum Shape {
-#     Circle(Point, f64),   // origin, radius
-#     Rectangle(Point, Size)  // upper-left, dimensions
-# }
-# fn compute_area(shape: &Shape) -> f64 { 0.0 }
-fn select<'r, 'tmp, T>(shape: &'tmp Shape, threshold: f64,
-                       a: &'r T, b: &'r T) -> &'r T {
-    if compute_area(shape) > threshold {a} else {b}
-}
-~~~
-
-Here you can see that `shape`'s lifetime is now named `tmp`. The
-parameters `a`, `b`, and the return value all have the lifetime `r`.
-However, since the lifetime `tmp` is not returned, it would be more
-concise to just omit the named lifetime for `shape` altogether:
-
-~~~
-# struct Point {x: f64, y: f64}; // as before
-# struct Size {w: f64, h: f64}; // as before
-# enum Shape {
-#     Circle(Point, f64),   // origin, radius
-#     Rectangle(Point, Size)  // upper-left, dimensions
-# }
-# fn compute_area(shape: &Shape) -> f64 { 0.0 }
-fn select<'r, T>(shape: &Shape, threshold: f64,
-                 a: &'r T, b: &'r T) -> &'r T {
-    if compute_area(shape) > threshold {a} else {b}
-}
-~~~
-
-This is equivalent to the previous definition.
-
-## Labeled Control Structures
-
-Named lifetime notation can also be used to control the flow of execution:
-
-~~~
-'h: for i in range(0u, 10) {
-    'g: loop {
-        if i % 2 == 0 { continue 'h; }
-        if i == 9 { break 'h; }
-        break 'g;
-    }
-}
-~~~
-
-> *Note:* Labelled breaks are not currently supported within `while` loops.
-
-Named labels are hygienic and can be used safely within macros.
-See the macros guide section on hygiene for more details.
-
-# Conclusion
-
-So there you have it: a (relatively) brief tour of the lifetime
-system. For more details, we refer to the (yet to be written) reference
-document on references, which will explain the full notation
-and give more examples.
diff --git a/src/doc/trpl/src/standard-input.md b/src/doc/trpl/standard-input.md
similarity index 99%
rename from src/doc/trpl/src/standard-input.md
rename to src/doc/trpl/standard-input.md
index 5a150594f0c..2d31f06ebaa 100644
--- a/src/doc/trpl/src/standard-input.md
+++ b/src/doc/trpl/standard-input.md
@@ -1,4 +1,4 @@
-# Standard Input
+% Standard Input
 
 Getting input from the keyboard is pretty easy, but uses some things
 we haven't seen before. Here's a simple program that reads some input,
diff --git a/src/doc/trpl/src/strings.md b/src/doc/trpl/strings.md
similarity index 99%
rename from src/doc/trpl/src/strings.md
rename to src/doc/trpl/strings.md
index be1d09f6e95..a40e748dae7 100644
--- a/src/doc/trpl/src/strings.md
+++ b/src/doc/trpl/strings.md
@@ -1,4 +1,4 @@
-# Strings
+% Strings
 
 Strings are an important concept for any programmer to master. Rust's string
 handling system is a bit different from other languages, due to its systems
diff --git a/src/doc/trpl/src/tasks.md b/src/doc/trpl/tasks.md
similarity index 99%
rename from src/doc/trpl/src/tasks.md
rename to src/doc/trpl/tasks.md
index 8eb13187e58..8e9f40b0f4e 100644
--- a/src/doc/trpl/src/tasks.md
+++ b/src/doc/trpl/tasks.md
@@ -369,7 +369,7 @@ Unlike `spawn`, the function spawned using `try` may return a value, which
 child thread terminates successfully, `try` will return an `Ok` result; if the
 child thread panics, `try` will return an `Error` result.
 
-[`Result`]: std/result/index.html
+[`Result`]: ../std/result/index.html
 
 > *Note:* A panicked thread does not currently produce a useful error
 > value (`try` always returns `Err(())`). In the
diff --git a/src/doc/trpl/src/testing.md b/src/doc/trpl/testing.md
similarity index 100%
rename from src/doc/trpl/src/testing.md
rename to src/doc/trpl/testing.md
diff --git a/src/doc/trpl/src/traits.md b/src/doc/trpl/traits.md
similarity index 100%
rename from src/doc/trpl/src/traits.md
rename to src/doc/trpl/traits.md
diff --git a/src/doc/trpl/src/unsafe.md b/src/doc/trpl/unsafe.md
similarity index 98%
rename from src/doc/trpl/src/unsafe.md
rename to src/doc/trpl/unsafe.md
index 25ca07ad74f..3e0a1ef1345 100644
--- a/src/doc/trpl/src/unsafe.md
+++ b/src/doc/trpl/unsafe.md
@@ -12,7 +12,7 @@ block which allows the programmer to dodge some of the compiler's
 checks and do a wide range of operations, such as:
 
 - dereferencing [raw pointers](#raw-pointers)
-- calling a function via FFI ([covered by the FFI guide](guide-ffi.html))
+- calling a function via FFI ([covered by the FFI guide](ffi.html))
 - casting between types bitwise (`transmute`, aka "reinterpret cast")
 - [inline assembly](#inline-assembly)
 
@@ -37,7 +37,7 @@ build safe interfaces.
 ## References
 
 One of Rust's biggest features is memory safety.  This is achieved in
-part via [the ownership system](guide-ownership.html), which is how the
+part via [the ownership system](ownership.html), which is how the
 compiler can guarantee that every `&` reference is always valid, and,
 for example, never pointing to freed memory.
 
@@ -504,7 +504,7 @@ shouldn't get triggered.
 The second of these three functions, `eh_personality`, is used by the
 failure mechanisms of the compiler. This is often mapped to GCC's
 personality function (see the
-[libstd implementation](std/rt/unwind/index.html) for more
+[libstd implementation](../std/rt/unwind/index.html) for more
 information), but crates which do not trigger a panic can be assured
 that this function is never called. The final function, `panic_fmt`, is
 also used by the failure mechanisms of the compiler.
@@ -517,7 +517,7 @@ also used by the failure mechanisms of the compiler.
 With the above techniques, we've got a bare-metal executable running some Rust
 code. There is a good deal of functionality provided by the standard library,
 however, that is necessary to be productive in Rust. If the standard library is
-not sufficient, then [libcore](core/index.html) is designed to be used
+not sufficient, then [libcore](../core/index.html) is designed to be used
 instead.
 
 The core library has very few dependencies and is much more portable than the
diff --git a/src/doc/trpl/src/variable-bindings.md b/src/doc/trpl/variable-bindings.md
similarity index 98%
rename from src/doc/trpl/src/variable-bindings.md
rename to src/doc/trpl/variable-bindings.md
index 8cf2522b9af..4e2e7bd2fe2 100644
--- a/src/doc/trpl/src/variable-bindings.md
+++ b/src/doc/trpl/variable-bindings.md
@@ -1,4 +1,4 @@
-# Variable bindings
+% Variable bindings
 
 The first thing we'll learn about are 'variable bindings.' They look like this:
 
@@ -170,5 +170,5 @@ arguments we pass to functions and macros, if you're passing more than one.
 When you just use the curly braces, Rust will attempt to display the
 value in a meaningful way by checking out its type. If you want to specify the
 format in a more detailed manner, there are a [wide number of options
-available](std/fmt/index.html). For now, we'll just stick to the default:
+available](../std/fmt/index.html). For now, we'll just stick to the default:
 integers aren't very complicated to print.
diff --git a/src/rustbook/book.rs b/src/rustbook/book.rs
index 45a864e3378..1d16de2a2fe 100644
--- a/src/rustbook/book.rs
+++ b/src/rustbook/book.rs
@@ -29,8 +29,8 @@ pub struct Book {
 /// A depth-first iterator over a book.
 pub struct BookItems<'a> {
     cur_items: &'a [BookItem],
-    cur_idx: uint,
-    stack: Vec<(&'a [BookItem], uint)>,
+    cur_idx: usize,
+    stack: Vec<(&'a [BookItem], usize)>,
 }
 
 impl<'a> Iterator for BookItems<'a> {
@@ -80,7 +80,7 @@ impl Book {
 pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String>> {
     fn collapse(stack: &mut Vec<BookItem>,
                 top_items: &mut Vec<BookItem>,
-                to_level: uint) {
+                to_level: usize) {
         loop {
             if stack.len() < to_level { return }
             if stack.len() == 1 {
@@ -141,7 +141,7 @@ pub fn parse_summary<R: Reader>(input: R, src: &Path) -> Result<Book, Vec<String
             };
             let level = cap.name("indent").unwrap().chars().map(|c| {
                 match c {
-                    ' ' => 1u,
+                    ' ' => 1us,
                     '\t' => 4,
                     _ => unreachable!()
                 }
diff --git a/src/rustbook/build.rs b/src/rustbook/build.rs
old mode 100755
new mode 100644
index db79e0b45e0..1cb5e38e190
--- a/src/rustbook/build.rs
+++ b/src/rustbook/build.rs
@@ -130,8 +130,8 @@ fn render(book: &Book, tgt: &Path) -> CliResult<()> {
         ];
         let output_result = rustdoc::main_args(rustdoc_args);
         if output_result != 0 {
-
-            let message = format!("Could not execute `rustdoc`: {}", output_result);
+            let message = format!("Could not execute `rustdoc` with {:?}: {}",
+                                  rustdoc_args, output_result);
             return Err(box message as Box<Error>);
         }
     }
@@ -172,12 +172,13 @@ impl Subcommand for Build {
         match book::parse_summary(summary, &src) {
             Ok(book) => {
                 // execute rustdoc on the whole book
-                let _ = render(&book, &tgt).map_err(|err| {
+                try!(render(&book, &tgt).map_err(|err| {
                     term.err(&format!("error: {}", err.description())[]);
                     err.detail().map(|detail| {
                         term.err(&format!("detail: {}", detail)[]);
-                    })
-                });
+                    });
+                    err
+                }))
             }
             Err(errors) => {
                 for err in errors.into_iter() {
diff --git a/src/rustbook/error.rs b/src/rustbook/error.rs
index 1d3baef8c1c..a5915ed4d73 100644
--- a/src/rustbook/error.rs
+++ b/src/rustbook/error.rs
@@ -56,6 +56,12 @@ impl Error for String {
     }
 }
 
+impl<'a> Error for Box<Error + 'a> {
+    fn description(&self) -> &str { (**self).description() }
+    fn detail(&self) -> Option<&str> { (**self).detail() }
+    fn cause(&self) -> Option<&Error> { (**self).cause() }
+}
+
 impl FromError<()> for () {
     fn from_err(_: ()) -> () { () }
 }
diff --git a/src/rustbook/main.rs b/src/rustbook/main.rs
old mode 100755
new mode 100644
diff --git a/src/rustbook/term.rs b/src/rustbook/term.rs
index 18306d6ec20..471e22ce7c1 100644
--- a/src/rustbook/term.rs
+++ b/src/rustbook/term.rs
@@ -11,6 +11,7 @@
 //! An abstraction of the terminal. Eventually, provide color and
 //! verbosity support. For now, just a wrapper around stdout/stderr.
 
+use std::os;
 use std::io::stdio;
 
 pub struct Term {
@@ -27,5 +28,6 @@ impl Term {
     pub fn err(&mut self, msg: &str) {
         // swallow any errors
         let _ = self.err.write_line(msg);
+        os::set_exit_status(101);
     }
 }