about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--mk/docs.mk4
-rw-r--r--src/doc/footer.inc2
-rw-r--r--src/doc/rust.css13
-rw-r--r--src/libcollections/lib.rs3
-rw-r--r--src/libcore/lib.rs3
-rw-r--r--src/libgetopts/lib.rs3
-rw-r--r--src/libglob/lib.rs4
-rw-r--r--src/libgreen/lib.rs3
-rw-r--r--src/liblog/lib.rs3
-rw-r--r--src/libnum/lib.rs3
-rw-r--r--src/librand/lib.rs3
-rw-r--r--src/libregex/lib.rs3
-rw-r--r--src/librustdoc/html/highlight.rs13
-rw-r--r--src/librustdoc/html/layout.rs13
-rw-r--r--src/librustdoc/html/markdown.rs35
-rw-r--r--src/librustdoc/html/render.rs15
-rw-r--r--src/librustdoc/html/static/main.css13
-rw-r--r--src/librustdoc/html/static/main.js2
-rw-r--r--src/librustdoc/html/static/playpen.js29
-rw-r--r--src/librustdoc/lib.rs4
-rw-r--r--src/librustdoc/markdown.rs13
-rw-r--r--src/librustdoc/test.rs24
-rw-r--r--src/libserialize/lib.rs3
-rw-r--r--src/libstd/lib.rs3
-rw-r--r--src/libsync/lib.rs3
-rw-r--r--src/libterm/lib.rs3
-rw-r--r--src/libtime/lib.rs3
-rw-r--r--src/liburl/lib.rs3
-rw-r--r--src/libuuid/lib.rs3
29 files changed, 186 insertions, 43 deletions
diff --git a/mk/docs.mk b/mk/docs.mk
index 90f85079464..dab40cb1654 100644
--- a/mk/docs.mk
+++ b/mk/docs.mk
@@ -43,7 +43,9 @@ L10N_LANGS := ja
 
 # 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
+	--markdown-in-header=doc/favicon.inc \
+	--markdown-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
 
diff --git a/src/doc/footer.inc b/src/doc/footer.inc
index a103a4908f6..4e7d60586f2 100644
--- a/src/doc/footer.inc
+++ b/src/doc/footer.inc
@@ -5,3 +5,5 @@ or the <a href="http://opensource.org/licenses/MIT">MIT license</a>, at your opt
 </p><p>
 This file may not be copied, modified, or distributed except according to those terms.
 </p></footer>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="playpen.js"></script>
diff --git a/src/doc/rust.css b/src/doc/rust.css
index d60dd54a67d..3957231a195 100644
--- a/src/doc/rust.css
+++ b/src/doc/rust.css
@@ -313,6 +313,19 @@ table th {
     padding: 5px;
 }
 
+/* Code snippets */
+
+.rusttest { display: none; }
+pre.rust { position: relative; }
+pre.rust a { transform: scaleX(-1); }
+.test-arrow {
+    display: inline-block;
+    position: absolute;
+    top: 0;
+    right: 10px;
+    font-size: 150%;
+}
+
 @media (min-width: 1170px) {
     pre {
         font-size: 15px;
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index 2004285ecb9..a65c06107ce 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -17,7 +17,8 @@
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules, managed_boxes, default_type_params, phase, globs)]
 #![no_std]
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 6aa07415e9c..2ccf431fc22 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -50,7 +50,8 @@
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 
 #![no_std]
 #![feature(globs, macro_rules, managed_boxes, phase, simd)]
diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs
index ddfe8380e09..10584223486 100644
--- a/src/libgetopts/lib.rs
+++ b/src/libgetopts/lib.rs
@@ -84,7 +84,8 @@
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 #![feature(globs, phase)]
 #![deny(missing_doc)]
 #![deny(deprecated_owned_vector)]
diff --git a/src/libglob/lib.rs b/src/libglob/lib.rs
index 86753fbb811..f3e1da77ce5 100644
--- a/src/libglob/lib.rs
+++ b/src/libglob/lib.rs
@@ -29,8 +29,8 @@
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
-
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 #![deny(deprecated_owned_vector)]
 
 use std::cell::Cell;
diff --git a/src/libgreen/lib.rs b/src/libgreen/lib.rs
index 31fd8950c80..c75d69480ce 100644
--- a/src/libgreen/lib.rs
+++ b/src/libgreen/lib.rs
@@ -203,7 +203,8 @@
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 
 // NB this does *not* include globs, please keep it that way.
 #![feature(macro_rules, phase)]
diff --git a/src/liblog/lib.rs b/src/liblog/lib.rs
index ff580559969..daacf8b3c47 100644
--- a/src/liblog/lib.rs
+++ b/src/liblog/lib.rs
@@ -111,7 +111,8 @@ if logging is disabled, none of the components of the log will be executed.
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules)]
 #![deny(missing_doc, deprecated_owned_vector)]
diff --git a/src/libnum/lib.rs b/src/libnum/lib.rs
index 29cf769ffc9..fae21e80f30 100644
--- a/src/libnum/lib.rs
+++ b/src/libnum/lib.rs
@@ -50,7 +50,8 @@
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 
 #![deny(deprecated_owned_vector)]
 
diff --git a/src/librand/lib.rs b/src/librand/lib.rs
index 3ed086e9b13..7a12dcf9f7f 100644
--- a/src/librand/lib.rs
+++ b/src/librand/lib.rs
@@ -21,7 +21,8 @@
 #![crate_type = "rlib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules, phase, globs)]
 #![no_std]
diff --git a/src/libregex/lib.rs b/src/libregex/lib.rs
index a48760913c1..44c206162ab 100644
--- a/src/libregex/lib.rs
+++ b/src/libregex/lib.rs
@@ -360,7 +360,8 @@
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules, phase)]
 #![deny(missing_doc, deprecated_owned_vector)]
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index f544e1e0973..3c9358b03a9 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -25,7 +25,7 @@ use html::escape::Escape;
 use t = syntax::parse::token;
 
 /// Highlights some source code, returning the HTML output.
-pub fn highlight(src: &str, class: Option<&str>) -> String {
+pub fn highlight(src: &str, class: Option<&str>, id: Option<&str>) -> String {
     debug!("highlighting: ================\n{}\n==============", src);
     let sess = parse::new_parse_sess();
     let fm = parse::string_to_filemap(&sess,
@@ -36,6 +36,7 @@ pub fn highlight(src: &str, class: Option<&str>) -> String {
     doit(&sess,
          lexer::StringReader::new(&sess.span_diagnostic, fm),
          class,
+         id,
          &mut out).unwrap();
     str::from_utf8_lossy(out.unwrap().as_slice()).to_string()
 }
@@ -47,11 +48,17 @@ pub fn highlight(src: &str, class: Option<&str>) -> String {
 /// it's used. All source code emission is done as slices from the source map,
 /// not from the tokens themselves, in order to stay true to the original
 /// source.
-fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader, class: Option<&str>,
+fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
+        class: Option<&str>, id: Option<&str>,
         out: &mut Writer) -> io::IoResult<()> {
     use syntax::parse::lexer::Reader;
 
-    try!(write!(out, "<pre class='rust {}'>\n", class.unwrap_or("")));
+    try!(write!(out, "<pre "));
+    match id {
+        Some(id) => try!(write!(out, "id='{}' ", id)),
+        None => {}
+    }
+    try!(write!(out, "class='rust {}'>\n", class.unwrap_or("")));
     let mut last = BytePos(0);
     let mut is_attribute = false;
     let mut is_macro = false;
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 80653878247..e2fa57148c2 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -16,6 +16,7 @@ pub struct Layout {
     pub logo: String,
     pub favicon: String,
     pub krate: String,
+    pub playground_url: String,
 }
 
 pub struct Page<'a> {
@@ -108,11 +109,13 @@ r##"<!DOCTYPE html>
     </div>
 
     <script>
-        var rootPath = "{root_path}";
-        var currentCrate = "{krate}";
+        window.rootPath = "{root_path}";
+        window.currentCrate = "{krate}";
+        window.playgroundUrl = "{play_url}";
     </script>
     <script src="{root_path}jquery.js"></script>
     <script src="{root_path}main.js"></script>
+    {play_js}
     <script async src="{root_path}search-index.js"></script>
 </body>
 </html>"##,
@@ -124,6 +127,12 @@ r##"<!DOCTYPE html>
     favicon   = nonestr(layout.favicon.as_slice()),
     sidebar   = *sidebar,
     krate     = layout.krate,
+    play_url  = layout.playground_url,
+    play_js   = if layout.playground_url.len() == 0 {
+        "".to_string()
+    } else {
+        format!(r#"<script src="{}playpen.js"></script>"#, page.root_path)
+    },
     )
 }
 
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index d1e2b5dffdd..260d26c5437 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -27,7 +27,7 @@
 #![allow(non_camel_case_types)]
 
 use libc;
-use std::cell::RefCell;
+use std::cell::{RefCell, Cell};
 use std::fmt;
 use std::slice;
 use std::str;
@@ -35,6 +35,8 @@ use std::collections::HashMap;
 
 use html::toc::TocBuilder;
 use html::highlight;
+use html::escape::Escape;
+use test;
 
 /// A unit struct which has the `fmt::Show` trait implemented. When
 /// formatted, this struct will emit the HTML corresponding to the rendered
@@ -139,6 +141,9 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> {
 }
 
 local_data_key!(used_header_map: RefCell<HashMap<String, uint>>)
+local_data_key!(test_idx: Cell<uint>)
+// None == render an example, but there's no crate name
+local_data_key!(pub playground_krate: Option<String>)
 
 pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
     extern fn block(ob: *mut hoedown_buffer, text: *hoedown_buffer,
@@ -149,9 +154,9 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
             let opaque = opaque as *mut hoedown_html_renderer_state;
             let my_opaque: &MyOpaque = &*((*opaque).opaque as *MyOpaque);
             slice::raw::buf_as_slice((*text).data, (*text).size as uint, |text| {
-                let text = str::from_utf8(text).unwrap();
+                let origtext = str::from_utf8(text).unwrap();
                 debug!("docblock: ==============\n{}\n=======", text);
-                let mut lines = text.lines().filter(|l| {
+                let mut lines = origtext.lines().filter(|l| {
                     stripped_filtered_line(*l).is_none()
                 });
                 let text = lines.collect::<Vec<&str>>().connect("\n");
@@ -180,9 +185,26 @@ pub fn render(w: &mut fmt::Formatter, s: &str, print_toc: bool) -> fmt::Result {
                 };
 
                 if !rendered {
-                    let output = highlight::highlight(text.as_slice(),
-                                                      None).as_slice()
-                                                           .to_c_str();
+                    let mut s = String::new();
+                    let id = playground_krate.get().map(|krate| {
+                        let idx = test_idx.get().unwrap();
+                        let i = idx.get();
+                        idx.set(i + 1);
+
+                        let test = origtext.lines().map(|l| {
+                            stripped_filtered_line(l).unwrap_or(l)
+                        }).collect::<Vec<&str>>().connect("\n");
+                        let krate = krate.as_ref().map(|s| s.as_slice());
+                        let test = test::maketest(test.as_slice(), krate, false);
+                        s.push_str(format!("<span id='rust-example-raw-{}' \
+                                             class='rusttest'>{}</span>",
+                                           i, Escape(test.as_slice())).as_slice());
+                        format!("rust-example-rendered-{}", i)
+                    });
+                    let id = id.as_ref().map(|a| a.as_slice());
+                    s.push_str(highlight::highlight(text.as_slice(), None, id)
+                                         .as_slice());
+                    let output = s.to_c_str();
                     output.with_ref(|r| {
                         hoedown_buffer_puts(ob, r)
                     })
@@ -377,6 +399,7 @@ fn parse_lang_string(string: &str) -> (bool,bool,bool,bool) {
 /// previous state (if any).
 pub fn reset_headers() {
     used_header_map.replace(Some(RefCell::new(HashMap::new())));
+    test_idx.replace(Some(Cell::new(0)));
 }
 
 impl<'a> fmt::Show for Markdown<'a> {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 20d4d677bc0..eab4a2c137a 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -230,6 +230,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
             logo: "".to_string(),
             favicon: "".to_string(),
             krate: krate.name.clone(),
+            playground_url: "".to_string(),
         },
         include_sources: true,
         render_redirect_pages: false,
@@ -250,6 +251,14 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
                             if "html_logo_url" == x.as_slice() => {
                         cx.layout.logo = s.to_string();
                     }
+                    clean::NameValue(ref x, ref s)
+                            if "html_playground_url" == x.as_slice() => {
+                        cx.layout.playground_url = s.to_string();
+                        let name = krate.name.clone();
+                        if markdown::playground_krate.get().is_none() {
+                            markdown::playground_krate.replace(Some(Some(name)));
+                        }
+                    }
                     clean::Word(ref x)
                             if "html_no_source" == x.as_slice() => {
                         cx.include_sources = false;
@@ -450,6 +459,7 @@ fn write_shared(cx: &Context,
     try!(write(cx.dst.join("jquery.js"),
                include_bin!("static/jquery-2.1.0.min.js")));
     try!(write(cx.dst.join("main.js"), include_bin!("static/main.js")));
+    try!(write(cx.dst.join("playpen.js"), include_bin!("static/playpen.js")));
     try!(write(cx.dst.join("main.css"), include_bin!("static/main.css")));
     try!(write(cx.dst.join("normalize.css"),
                include_bin!("static/normalize.css")));
@@ -2055,14 +2065,15 @@ impl<'a> fmt::Show for Source<'a> {
             try!(write!(fmt, "<span id='{0:u}'>{0:1$u}</span>\n", i, cols));
         }
         try!(write!(fmt, "</pre>"));
-        try!(write!(fmt, "{}", highlight::highlight(s.as_slice(), None)));
+        try!(write!(fmt, "{}", highlight::highlight(s.as_slice(), None, None)));
         Ok(())
     }
 }
 
 fn item_macro(w: &mut fmt::Formatter, it: &clean::Item,
               t: &clean::Macro) -> fmt::Result {
-    try!(w.write(highlight::highlight(t.source.as_slice(), Some("macro")).as_bytes()));
+    try!(w.write(highlight::highlight(t.source.as_slice(), Some("macro"),
+                                      None).as_bytes()));
     document(w, it)
 }
 
diff --git a/src/librustdoc/html/static/main.css b/src/librustdoc/html/static/main.css
index 7831f10ab91..07dd1a6c173 100644
--- a/src/librustdoc/html/static/main.css
+++ b/src/librustdoc/html/static/main.css
@@ -156,7 +156,7 @@ nav.sub {
     padding: 0 10px;
     margin-bottom: 10px;
 }
-.block h2 { 
+.block h2 {
     margin-top: 0;
     text-align: center;
 }
@@ -396,6 +396,17 @@ pre.rust .doccomment { color: #4D4D4C; }
 pre.rust .macro, pre.rust .macro-nonterminal { color: #3E999F; }
 pre.rust .lifetime { color: #B76514; }
 
+.rusttest { display: none; }
+pre.rust { position: relative; }
+pre.rust a { transform: scaleX(-1); }
+.test-arrow {
+    display: inline-block;
+    position: absolute;
+    top: 0;
+    right: 10px;
+    font-size: 150%;
+}
+
 .methods .section-header {
     /* Override parent class attributes. */
     border-bottom: none !important;
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 440b829c80c..195028c85bf 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -678,7 +678,7 @@
         window.register_implementors(window.pending_implementors);
     }
 
-    // See documentaiton in html/render.rs for what this is doing.
+    // See documentation in html/render.rs for what this is doing.
     var query = getQueryStringParams();
     if (query['gotosrc']) {
         window.location = $('#src-' + query['gotosrc']).attr('href');
diff --git a/src/librustdoc/html/static/playpen.js b/src/librustdoc/html/static/playpen.js
new file mode 100644
index 00000000000..5d2fe9c2166
--- /dev/null
+++ b/src/librustdoc/html/static/playpen.js
@@ -0,0 +1,29 @@
+// 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.
+
+/*jslint browser: true, es5: true */
+/*globals $: true, rootPath: true */
+
+(function() {
+    if (window.playgroundUrl) {
+        $('pre.rust').hover(function() {
+            var id = '#' + $(this).attr('id').replace('rendered', 'raw');
+            var a = $('<a>').text('⇱').attr('class', 'test-arrow');
+            var code = $(id).text();
+            a.attr('href', window.playgroundUrl + '?code=' +
+                           encodeURIComponent(code));
+            a.attr('target', '_blank');
+            $(this).append(a);
+        }, function() {
+            $(this).find('a').remove();
+        });
+    }
+}());
+
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 28443fc453f..e623d54675c 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -126,7 +126,9 @@ pub fn opts() -> Vec<getopts::OptGroup> {
         optmulti("", "markdown-after-content",
                  "files to include inline between the content and </body> of a rendered \
                  Markdown file",
-                 "FILES")
+                 "FILES"),
+        optopt("", "markdown-playground-url",
+               "URL to send code snippets to", "URL")
     )
 }
 
diff --git a/src/librustdoc/markdown.rs b/src/librustdoc/markdown.rs
index 500d17c9f9a..3b6203ef668 100644
--- a/src/librustdoc/markdown.rs
+++ b/src/librustdoc/markdown.rs
@@ -16,6 +16,7 @@ use getopts;
 use testing;
 
 use html::escape::Escape;
+use html::markdown;
 use html::markdown::{MarkdownWithToc, find_testable_code, reset_headers};
 use test::Collector;
 
@@ -84,6 +85,11 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches) -> int
     }
 
     let input_str = load_or_return!(input, 1, 2);
+    let playground = matches.opt_str("markdown-playground-url");
+    if playground.is_some() {
+        markdown::playground_krate.replace(Some(None));
+    }
+    let playground = playground.unwrap_or("".to_string());
 
     let (in_header, before_content, after_content) =
         match (load_external_files(matches.opt_strs("markdown-in-header")
@@ -148,6 +154,9 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches) -> int
     {before_content}
     <h1 class="title">{title}</h1>
     {text}
+    <script type="text/javascript">
+        window.playgroundUrl = "{playground}";
+    </script>
     {after_content}
 </body>
 </html>"#,
@@ -156,7 +165,9 @@ pub fn render(input: &str, mut output: Path, matches: &getopts::Matches) -> int
         in_header = in_header,
         before_content = before_content,
         text = MarkdownWithToc(text),
-        after_content = after_content);
+        after_content = after_content,
+        playground = playground,
+        );
 
     match err {
         Err(e) => {
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 1434c3eb07d..bc1da5b629e 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -103,7 +103,7 @@ pub fn run(input: &str,
 
 fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool,
            no_run: bool) {
-    let test = maketest(test, cratename);
+    let test = maketest(test, Some(cratename), true);
     let input = driver::StrInput(test.to_string());
 
     let sessopts = config::Options {
@@ -200,23 +200,31 @@ fn runtest(test: &str, cratename: &str, libs: HashSet<Path>, should_fail: bool,
     }
 }
 
-pub fn maketest(s: &str, cratename: &str) -> String {
-    let mut prog = String::from_str(r"
+pub fn maketest(s: &str, cratename: Option<&str>, lints: bool) -> String {
+    let mut prog = String::new();
+    if lints {
+        prog.push_str(r"
 #![deny(warnings)]
 #![allow(unused_variable, dead_assignment, unused_mut, attribute_usage, dead_code)]
 ");
+    }
 
     if !s.contains("extern crate") {
-        if s.contains(cratename) {
-            prog.push_str(format!("extern crate {};\n",
-                                  cratename).as_slice());
+        match cratename {
+            Some(cratename) => {
+                if s.contains(cratename) {
+                    prog.push_str(format!("extern crate {};\n",
+                                          cratename).as_slice());
+                }
+            }
+            None => {}
         }
     }
     if s.contains("fn main") {
         prog.push_str(s);
     } else {
-        prog.push_str("fn main() {\n");
-        prog.push_str(s);
+        prog.push_str("fn main() {\n    ");
+        prog.push_str(s.replace("\n", "\n    ").as_slice());
         prog.push_str("\n}");
     }
 
diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs
index 904c7da4da2..08348c96333 100644
--- a/src/libserialize/lib.rs
+++ b/src/libserialize/lib.rs
@@ -20,7 +20,8 @@ Core encoding and decoding interfaces.
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 #![feature(macro_rules, managed_boxes, default_type_params, phase)]
 
 // test harness access
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 90d6677d612..109832b7c47 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -101,7 +101,8 @@
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 #![feature(macro_rules, globs, asm, managed_boxes, thread_local, link_args,
            linkage, default_type_params, phase, concat_idents, quad_precision_float)]
 
diff --git a/src/libsync/lib.rs b/src/libsync/lib.rs
index e0cc57a4967..fc4d5fec5f5 100644
--- a/src/libsync/lib.rs
+++ b/src/libsync/lib.rs
@@ -18,7 +18,8 @@
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 #![feature(phase)]
 #![deny(deprecated_owned_vector)]
 
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index f2ae0c15860..cc813262576 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -45,7 +45,8 @@
 #![crate_type = "dylib"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(macro_rules, phase)]
 
diff --git a/src/libtime/lib.rs b/src/libtime/lib.rs
index 90af1da78a4..f087b9289c3 100644
--- a/src/libtime/lib.rs
+++ b/src/libtime/lib.rs
@@ -17,7 +17,8 @@
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 #![feature(phase)]
 #![deny(deprecated_owned_vector)]
 
diff --git a/src/liburl/lib.rs b/src/liburl/lib.rs
index 65b5a8428bd..30054ea4c92 100644
--- a/src/liburl/lib.rs
+++ b/src/liburl/lib.rs
@@ -16,7 +16,8 @@
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 #![feature(default_type_params)]
 
 use std::collections::HashMap;
diff --git a/src/libuuid/lib.rs b/src/libuuid/lib.rs
index 68c545802ad..2459a7fc273 100644
--- a/src/libuuid/lib.rs
+++ b/src/libuuid/lib.rs
@@ -60,7 +60,8 @@ Examples of string representations:
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
-       html_root_url = "http://doc.rust-lang.org/")]
+       html_root_url = "http://doc.rust-lang.org/",
+       html_playground_url = "http://play.rust-lang.org/")]
 
 #![feature(default_type_params)]