go.talks/present: use present and socket packages from go.tools

R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/13263054
diff --git a/pkg/present/args.go b/pkg/present/args.go
deleted file mode 100644
index 49ee1a9..0000000
--- a/pkg/present/args.go
+++ /dev/null
@@ -1,229 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package present
-
-import (
-	"errors"
-	"regexp"
-	"strconv"
-	"unicode/utf8"
-)
-
-// This file is stolen from go/src/cmd/godoc/codewalk.go.
-// It's an evaluator for the file address syntax implemented by acme and sam,
-// but using Go-native regular expressions.
-// To keep things reasonably close, this version uses (?m:re) for all user-provided
-// regular expressions. That is the only change to the code from codewalk.go.
-// See http://plan9.bell-labs.com/sys/doc/sam/sam.html Table II
-// for details on the syntax.
-
-// addrToByte evaluates the given address starting at offset start in data.
-// It returns the lo and hi byte offset of the matched region within data.
-func addrToByteRange(addr string, start int, data []byte) (lo, hi int, err error) {
-	if addr == "" {
-		lo, hi = start, len(data)
-		return
-	}
-	var (
-		dir        byte
-		prevc      byte
-		charOffset bool
-	)
-	lo = start
-	hi = start
-	for addr != "" && err == nil {
-		c := addr[0]
-		switch c {
-		default:
-			err = errors.New("invalid address syntax near " + string(c))
-		case ',':
-			if len(addr) == 1 {
-				hi = len(data)
-			} else {
-				_, hi, err = addrToByteRange(addr[1:], hi, data)
-			}
-			return
-
-		case '+', '-':
-			if prevc == '+' || prevc == '-' {
-				lo, hi, err = addrNumber(data, lo, hi, prevc, 1, charOffset)
-			}
-			dir = c
-
-		case '$':
-			lo = len(data)
-			hi = len(data)
-			if len(addr) > 1 {
-				dir = '+'
-			}
-
-		case '#':
-			charOffset = true
-
-		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
-			var i int
-			for i = 1; i < len(addr); i++ {
-				if addr[i] < '0' || addr[i] > '9' {
-					break
-				}
-			}
-			var n int
-			n, err = strconv.Atoi(addr[0:i])
-			if err != nil {
-				break
-			}
-			lo, hi, err = addrNumber(data, lo, hi, dir, n, charOffset)
-			dir = 0
-			charOffset = false
-			prevc = c
-			addr = addr[i:]
-			continue
-
-		case '/':
-			var i, j int
-		Regexp:
-			for i = 1; i < len(addr); i++ {
-				switch addr[i] {
-				case '\\':
-					i++
-				case '/':
-					j = i + 1
-					break Regexp
-				}
-			}
-			if j == 0 {
-				j = i
-			}
-			pattern := addr[1:i]
-			lo, hi, err = addrRegexp(data, lo, hi, dir, pattern)
-			prevc = c
-			addr = addr[j:]
-			continue
-		}
-		prevc = c
-		addr = addr[1:]
-	}
-
-	if err == nil && dir != 0 {
-		lo, hi, err = addrNumber(data, lo, hi, dir, 1, charOffset)
-	}
-	if err != nil {
-		return 0, 0, err
-	}
-	return lo, hi, nil
-}
-
-// addrNumber applies the given dir, n, and charOffset to the address lo, hi.
-// dir is '+' or '-', n is the count, and charOffset is true if the syntax
-// used was #n.  Applying +n (or +#n) means to advance n lines
-// (or characters) after hi.  Applying -n (or -#n) means to back up n lines
-// (or characters) before lo.
-// The return value is the new lo, hi.
-func addrNumber(data []byte, lo, hi int, dir byte, n int, charOffset bool) (int, int, error) {
-	switch dir {
-	case 0:
-		lo = 0
-		hi = 0
-		fallthrough
-
-	case '+':
-		if charOffset {
-			pos := hi
-			for ; n > 0 && pos < len(data); n-- {
-				_, size := utf8.DecodeRune(data[pos:])
-				pos += size
-			}
-			if n == 0 {
-				return pos, pos, nil
-			}
-			break
-		}
-		// find next beginning of line
-		if hi > 0 {
-			for hi < len(data) && data[hi-1] != '\n' {
-				hi++
-			}
-		}
-		lo = hi
-		if n == 0 {
-			return lo, hi, nil
-		}
-		for ; hi < len(data); hi++ {
-			if data[hi] != '\n' {
-				continue
-			}
-			switch n--; n {
-			case 1:
-				lo = hi + 1
-			case 0:
-				return lo, hi + 1, nil
-			}
-		}
-
-	case '-':
-		if charOffset {
-			// Scan backward for bytes that are not UTF-8 continuation bytes.
-			pos := lo
-			for ; pos > 0 && n > 0; pos-- {
-				if data[pos]&0xc0 != 0x80 {
-					n--
-				}
-			}
-			if n == 0 {
-				return pos, pos, nil
-			}
-			break
-		}
-		// find earlier beginning of line
-		for lo > 0 && data[lo-1] != '\n' {
-			lo--
-		}
-		hi = lo
-		if n == 0 {
-			return lo, hi, nil
-		}
-		for ; lo >= 0; lo-- {
-			if lo > 0 && data[lo-1] != '\n' {
-				continue
-			}
-			switch n--; n {
-			case 1:
-				hi = lo
-			case 0:
-				return lo, hi, nil
-			}
-		}
-	}
-
-	return 0, 0, errors.New("address out of range")
-}
-
-// addrRegexp searches for pattern in the given direction starting at lo, hi.
-// The direction dir is '+' (search forward from hi) or '-' (search backward from lo).
-// Backward searches are unimplemented.
-func addrRegexp(data []byte, lo, hi int, dir byte, pattern string) (int, int, error) {
-	// We want ^ and $ to work as in sam/acme, so use ?m.
-	re, err := regexp.Compile("(?m:" + pattern + ")")
-	if err != nil {
-		return 0, 0, err
-	}
-	if dir == '-' {
-		// Could implement reverse search using binary search
-		// through file, but that seems like overkill.
-		return 0, 0, errors.New("reverse search not implemented")
-	}
-	m := re.FindIndex(data[hi:])
-	if len(m) > 0 {
-		m[0] += hi
-		m[1] += hi
-	} else if hi > 0 {
-		// No match.  Wrap to beginning of data.
-		m = re.FindIndex(data)
-	}
-	if len(m) == 0 {
-		return 0, 0, errors.New("no match for " + pattern)
-	}
-	return m[0], m[1], nil
-}
diff --git a/pkg/present/code.go b/pkg/present/code.go
deleted file mode 100644
index 4d82d9a..0000000
--- a/pkg/present/code.go
+++ /dev/null
@@ -1,252 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package present
-
-import (
-	"bufio"
-	"bytes"
-	"fmt"
-	"html/template"
-	"path/filepath"
-	"regexp"
-	"strconv"
-	"strings"
-)
-
-// Is the playground available?
-var PlayEnabled = false
-
-// TOOD(adg): replace the PlayEnabled flag with something less spaghetti-like.
-// Instead this will probably be determined by a template execution Context
-// value that contains various global metadata required when rendering
-// templates.
-
-func init() {
-	Register("code", parseCode)
-	Register("play", parseCode)
-}
-
-type Code struct {
-	Text template.HTML
-	Play bool // runnable code
-}
-
-func (c Code) TemplateName() string { return "code" }
-
-// The input line is a .code or .play entry with a file name and an optional HLfoo marker on the end.
-// Anything between the file and HL (if any) is an address expression, which we treat as a string here.
-// We pick off the HL first, for easy parsing.
-var (
-	highlightRE = regexp.MustCompile(`\s+HL([a-zA-Z0-9_]+)?$`)
-	hlCommentRE = regexp.MustCompile(`(.+) // HL(.*)$`)
-	codeRE      = regexp.MustCompile(`\.(code|play)\s+([^\s]+)(\s+)?(.*)?$`)
-)
-
-func parseCode(ctx *Context, sourceFile string, sourceLine int, cmd string) (Elem, error) {
-	cmd = strings.TrimSpace(cmd)
-
-	// Pull off the HL, if any, from the end of the input line.
-	highlight := ""
-	if hl := highlightRE.FindStringSubmatchIndex(cmd); len(hl) == 4 {
-		highlight = cmd[hl[2]:hl[3]]
-		cmd = cmd[:hl[2]-2]
-	}
-
-	// Parse the remaining command line.
-	// Arguments:
-	// args[0]: whole match
-	// args[1]:  .code/.play
-	// args[2]: file name
-	// args[3]: space, if any, before optional address
-	// args[4]: optional address
-	args := codeRE.FindStringSubmatch(cmd)
-	if len(args) != 5 {
-		return nil, fmt.Errorf("%s:%d: syntax error for .code/.play invocation", sourceFile, sourceLine)
-	}
-	command, file, addr := args[1], args[2], strings.TrimSpace(args[4])
-	play := command == "play" && PlayEnabled
-
-	// Read in code file and (optionally) match address.
-	filename := filepath.Join(filepath.Dir(sourceFile), file)
-	textBytes, err := ctx.ReadFile(filename)
-	if err != nil {
-		return nil, fmt.Errorf("%s:%d: %v", sourceFile, sourceLine, err)
-	}
-	lo, hi, err := addrToByteRange(addr, 0, textBytes)
-	if err != nil {
-		return nil, fmt.Errorf("%s:%d: %v", sourceFile, sourceLine, err)
-	}
-
-	// Acme pattern matches can stop mid-line,
-	// so run to end of line in both directions if not at line start/end.
-	for lo > 0 && textBytes[lo-1] != '\n' {
-		lo--
-	}
-	if hi > 0 {
-		for hi < len(textBytes) && textBytes[hi-1] != '\n' {
-			hi++
-		}
-	}
-
-	lines := codeLines(textBytes, lo, hi)
-
-	for i, line := range lines {
-		// Replace tabs by spaces, which work better in HTML.
-		line.L = strings.Replace(line.L, "\t", "    ", -1)
-
-		// Highlight lines that end with "// HL[highlight]"
-		// and strip the magic comment.
-		if m := hlCommentRE.FindStringSubmatch(line.L); m != nil {
-			line.L = m[1]
-			line.HL = m[2] == highlight
-		}
-
-		lines[i] = line
-	}
-
-	data := &codeTemplateData{Lines: lines}
-
-	// Include before and after in a hidden span for playground code.
-	if play {
-		data.Prefix = textBytes[:lo]
-		data.Suffix = textBytes[hi:]
-	}
-
-	var buf bytes.Buffer
-	if err := codeTemplate.Execute(&buf, data); err != nil {
-		return nil, err
-	}
-	return Code{Text: template.HTML(buf.String()), Play: play}, nil
-}
-
-type codeTemplateData struct {
-	Lines          []codeLine
-	Prefix, Suffix []byte
-}
-
-var leadingSpaceRE = regexp.MustCompile(`^[ \t]*`)
-
-var codeTemplate = template.Must(template.New("code").Funcs(template.FuncMap{
-	"trimSpace":    strings.TrimSpace,
-	"leadingSpace": leadingSpaceRE.FindString,
-}).Parse(codeTemplateHTML))
-
-const codeTemplateHTML = `
-{{with .Prefix}}<pre style="display: none"><span>{{printf "%s" .}}</span></pre>{{end}}
-
-<pre>{{range .Lines}}<span num="{{.N}}">{{/*
-	*/}}{{if .HL}}{{leadingSpace .L}}<b>{{trimSpace .L}}</b>{{/*
-	*/}}{{else}}{{.L}}{{end}}{{/*
-*/}}</span>
-{{end}}</pre>
-
-{{with .Suffix}}<pre style="display: none"><span>{{printf "%s" .}}</span></pre>{{end}}
-`
-
-// codeLine represents a line of code extracted from a source file.
-type codeLine struct {
-	L  string // The line of code.
-	N  int    // The line number from the source file.
-	HL bool   // Whether the line should be highlighted.
-}
-
-// codeLines takes a source file and returns the lines that
-// span the byte range specified by start and end.
-// It discards lines that end in "OMIT".
-func codeLines(src []byte, start, end int) (lines []codeLine) {
-	startLine := 1
-	for i, b := range src {
-		if i == start {
-			break
-		}
-		if b == '\n' {
-			startLine++
-		}
-	}
-	s := bufio.NewScanner(bytes.NewReader(src[start:end]))
-	for n := startLine; s.Scan(); n++ {
-		l := s.Text()
-		if strings.HasSuffix(l, "OMIT") {
-			continue
-		}
-		lines = append(lines, codeLine{L: l, N: n})
-	}
-	// Trim leading and trailing blank lines.
-	for len(lines) > 0 && len(lines[0].L) == 0 {
-		lines = lines[1:]
-	}
-	for len(lines) > 0 && len(lines[len(lines)-1].L) == 0 {
-		lines = lines[:len(lines)-1]
-	}
-	return
-}
-
-func parseArgs(name string, line int, args []string) (res []interface{}, err error) {
-	res = make([]interface{}, len(args))
-	for i, v := range args {
-		if len(v) == 0 {
-			return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v)
-		}
-		switch v[0] {
-		case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
-			n, err := strconv.Atoi(v)
-			if err != nil {
-				return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v)
-			}
-			res[i] = n
-		case '/':
-			if len(v) < 2 || v[len(v)-1] != '/' {
-				return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v)
-			}
-			res[i] = v
-		case '$':
-			res[i] = "$"
-		default:
-			return nil, fmt.Errorf("%s:%d bad code argument %q", name, line, v)
-		}
-	}
-	return
-}
-
-// parseArg returns the integer or string value of the argument and tells which it is.
-func parseArg(arg interface{}, max int) (ival int, sval string, isInt bool, err error) {
-	switch n := arg.(type) {
-	case int:
-		if n <= 0 || n > max {
-			return 0, "", false, fmt.Errorf("%d is out of range", n)
-		}
-		return n, "", true, nil
-	case string:
-		return 0, n, false, nil
-	}
-	return 0, "", false, fmt.Errorf("unrecognized argument %v type %T", arg, arg)
-}
-
-// match identifies the input line that matches the pattern in a code invocation.
-// If start>0, match lines starting there rather than at the beginning.
-// The return value is 1-indexed.
-func match(file string, start int, lines []string, pattern string) (int, error) {
-	// $ matches the end of the file.
-	if pattern == "$" {
-		if len(lines) == 0 {
-			return 0, fmt.Errorf("%q: empty file", file)
-		}
-		return len(lines), nil
-	}
-	// /regexp/ matches the line that matches the regexp.
-	if len(pattern) > 2 && pattern[0] == '/' && pattern[len(pattern)-1] == '/' {
-		re, err := regexp.Compile(pattern[1 : len(pattern)-1])
-		if err != nil {
-			return 0, err
-		}
-		for i := start; i < len(lines); i++ {
-			if re.MatchString(lines[i]) {
-				return i + 1, nil
-			}
-		}
-		return 0, fmt.Errorf("%s: no match for %#q", file, pattern)
-	}
-	return 0, fmt.Errorf("unrecognized pattern: %q", pattern)
-}
diff --git a/pkg/present/doc.go b/pkg/present/doc.go
deleted file mode 100644
index 32be150..0000000
--- a/pkg/present/doc.go
+++ /dev/null
@@ -1,184 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-/*
-The present file format
-
-Present files have the following format.  The first non-blank non-comment
-line is the title, so the header looks like
-
-	Title of document
-	Subtitle of document
-	15:04 2 Jan 2006
-	Tags: foo, bar, baz
-	<blank line>
-	Author Name
-	Job title, Company
-	joe@example.com
-	http://url/
-	@twitter_name
-
-The subtitle, date, and tags lines are optional.
-
-The date line may be written without a time:
-	2 Jan 2006
-In this case, the time will be interpreted as 10am UTC on that date.
-
-The tags line is a comma-separated list of tags that may be used to categorize
-the document.
-
-The author section may contain a mixture of text, twitter names, and links.
-For slide presentations, only the plain text lines will be displayed on the
-first slide.
-
-Multiple presenters may be specified, separated by a blank line.
-
-After that come slides/sections, each after a blank line:
-
-	* Title of slide or section (must have asterisk)
-
-	Some Text
-
-	** Subsection
-
-	- bullets
-	- more bullets
-	- a bullet with
-
-	*** Sub-subsection
-
-	Some More text
-
-	  Preformatted text
-	  is indented (however you like)
-
-	Further Text, including invocations like:
-
-	.code x.go /^func main/,/^}/
-	.play y.go
-	.image image.jpg
-	.iframe http://foo
-	.link http://foo label
-	.html file.html
-
-	Again, more text
-
-Blank lines are OK (not mandatory) after the title and after the
-text.  Text, bullets, and .code etc. are all optional; title is
-not.
-
-Lines starting with # in column 1 are commentary.
-
-Fonts:
-
-Within the input for plain text or lists, text bracketed by font
-markers will be presented in italic, bold, or program font.
-Marker characters are _ (italic), * (bold) and ` (program font).
-Unmatched markers appear as plain text.
-Within marked text, a single marker character becomes a space
-and a doubled single marker quotes the marker character.
-
-	_italic_
-	*bold*
-	`program`
-	_this_is_all_italic_
-	_Why_use_scoped__ptr_? Use plain ***ptr* instead.
-
-Inline links:
-
-Links can be included in any text with the form [[url][label]], or
-[[url]] to use the URL itself as the label.
-
-Functions:
-
-A number of template functions are available through invocations
-in the input text. Each such invocation contains a period as the
-first character on the line, followed immediately by the name of
-the function, followed by any arguments. A typical invocation might
-be
-	.play demo.go /^func show/,/^}/
-(except that the ".play" must be at the beginning of the line and
-not be indented like this.)
-
-Here follows a description of the functions:
-
-code:
-
-Injects program source into the output by extracting code from files
-and injecting them as HTML-escaped <pre> blocks.  The argument is
-a file name followed by an optional address that specifies what
-section of the file to display. The address syntax is similar in
-its simplest form to that of ed, but comes from sam and is more
-general. See
-	http://plan9.bell-labs.com/sys/doc/sam/sam.html Table II
-for full details. The displayed block is always rounded out to a
-full line at both ends.
-
-If no pattern is present, the entire file is displayed.
-
-Any line in the program that ends with the four characters
-	OMIT
-is deleted from the source before inclusion, making it easy
-to write things like
-	.code test.go /START OMIT/,/END OMIT/
-to find snippets like this
-	tedious_code = boring_function()
-	// START OMIT
-	interesting_code = fascinating_function()
-	// END OMIT
-and see only this:
-	interesting_code = fascinating_function()
-
-Also, inside the displayed text a line that ends
-	// HL
-will be highlighted in the display; the 'h' key in the browser will
-toggle extra emphasis of any highlighted lines. A highlighting mark
-may have a suffix word, such as
-	// HLxxx
-Such highlights are enabled only if the code invocation ends with
-"HL" followed by the word:
-	.code test.go /^type Foo/,/^}/ HLxxx
-
-play:
-
-The function "play" is the same as "code" but puts a button
-on the displayed source so the program can be run from the browser.
-Although only the selected text is shown, all the source is included
-in the HTML output so it can be presented to the compiler.
-
-link:
-
-Create a hyperlink. The syntax is 1 or 2 space-separated arguments.
-The first argument is always the HTTP URL.  If there is a second
-argument, it is the text label to display for this link.
-
-	.link http://golang.org golang.org
-
-image:
-
-The template uses the function "image" to inject picture files.
-
-The syntax is simple: 1 or 3 space-separated arguments.
-The first argument is always the file name.
-If there are more arguments, they are the height and width;
-both must be present.
-
-	.image images/betsy.jpg 100 200
-
-iframe:
-
-The function "iframe" injects iframes (pages inside pages).
-Its syntax is the same as that of image.
-
-html:
-
-The function html includes the contents of the specified file as
-unescaped HTML. This is useful for including custom HTML elements
-that cannot be created using only the slide format.
-It is your responsibilty to make sure the included HTML is valid and safe.
-
-	.html file.html
-
-*/
-package present
diff --git a/pkg/present/gone.go b/pkg/present/gone.go
new file mode 100644
index 0000000..9cd5027
--- /dev/null
+++ b/pkg/present/gone.go
@@ -0,0 +1,4 @@
+/*
+Package present has moved to code.google.com/p/go.tools/present.
+*/
+package present
diff --git a/pkg/present/html.go b/pkg/present/html.go
deleted file mode 100644
index cca90ef..0000000
--- a/pkg/present/html.go
+++ /dev/null
@@ -1,31 +0,0 @@
-package present
-
-import (
-	"errors"
-	"html/template"
-	"path/filepath"
-	"strings"
-)
-
-func init() {
-	Register("html", parseHTML)
-}
-
-func parseHTML(ctx *Context, fileName string, lineno int, text string) (Elem, error) {
-	p := strings.Fields(text)
-	if len(p) != 2 {
-		return nil, errors.New("invalid .html args")
-	}
-	name := filepath.Join(filepath.Dir(fileName), p[1])
-	b, err := ctx.ReadFile(name)
-	if err != nil {
-		return nil, err
-	}
-	return HTML{template.HTML(b)}, nil
-}
-
-type HTML struct {
-	template.HTML
-}
-
-func (s HTML) TemplateName() string { return "html" }
diff --git a/pkg/present/iframe.go b/pkg/present/iframe.go
deleted file mode 100644
index 2f3c5e5..0000000
--- a/pkg/present/iframe.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2013 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package present
-
-import (
-	"fmt"
-	"strings"
-)
-
-func init() {
-	Register("iframe", parseIframe)
-}
-
-type Iframe struct {
-	URL    string
-	Width  int
-	Height int
-}
-
-func (i Iframe) TemplateName() string { return "iframe" }
-
-func parseIframe(ctx *Context, fileName string, lineno int, text string) (Elem, error) {
-	args := strings.Fields(text)
-	i := Iframe{URL: args[1]}
-	a, err := parseArgs(fileName, lineno, args[2:])
-	if err != nil {
-		return nil, err
-	}
-	switch len(a) {
-	case 0:
-		// no size parameters
-	case 2:
-		if v, ok := a[0].(int); ok {
-			i.Height = v
-		}
-		if v, ok := a[1].(int); ok {
-			i.Width = v
-		}
-	default:
-		return nil, fmt.Errorf("incorrect image invocation: %q", text)
-	}
-	return i, nil
-}
diff --git a/pkg/present/image.go b/pkg/present/image.go
deleted file mode 100644
index 2bab429..0000000
--- a/pkg/present/image.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package present
-
-import (
-	"fmt"
-	"strings"
-)
-
-func init() {
-	Register("image", parseImage)
-}
-
-type Image struct {
-	URL    string
-	Width  int
-	Height int
-}
-
-func (i Image) TemplateName() string { return "image" }
-
-func parseImage(ctx *Context, fileName string, lineno int, text string) (Elem, error) {
-	args := strings.Fields(text)
-	img := Image{URL: args[1]}
-	a, err := parseArgs(fileName, lineno, args[2:])
-	if err != nil {
-		return nil, err
-	}
-	switch len(a) {
-	case 0:
-		// no size parameters
-	case 2:
-		if v, ok := a[0].(int); ok {
-			img.Height = v
-		}
-		if v, ok := a[1].(int); ok {
-			img.Width = v
-		}
-	default:
-		return nil, fmt.Errorf("incorrect image invocation: %q", text)
-	}
-	return img, nil
-}
diff --git a/pkg/present/link.go b/pkg/present/link.go
deleted file mode 100644
index a840b23..0000000
--- a/pkg/present/link.go
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package present
-
-import (
-	"fmt"
-	"net/url"
-	"strings"
-)
-
-func init() {
-	Register("link", parseLink)
-}
-
-type Link struct {
-	URL   *url.URL
-	Label string
-}
-
-func (l Link) TemplateName() string { return "link" }
-
-func parseLink(ctx *Context, fileName string, lineno int, text string) (Elem, error) {
-	args := strings.Fields(text)
-	url, err := url.Parse(args[1])
-	if err != nil {
-		return nil, err
-	}
-	label := ""
-	if len(args) > 2 {
-		label = strings.Join(args[2:], " ")
-	} else {
-		scheme := url.Scheme + "://"
-		if url.Scheme == "mailto" {
-			scheme = "mailto:"
-		}
-		label = strings.Replace(url.String(), scheme, "", 1)
-	}
-	return Link{url, label}, nil
-}
-
-func renderLink(url, text string) string {
-	text = font(text)
-	if text == "" {
-		text = url
-	}
-	return fmt.Sprintf(`<a href="%s" target="_blank">%s</a>`, url, text)
-}
-
-// parseInlineLink parses an inline link at the start of s, and returns
-// a rendered HTML link and the total length of the raw inline link.
-// If no inline link is present, it returns all zeroes.
-func parseInlineLink(s string) (link string, length int) {
-	if !strings.HasPrefix(s, "[[") {
-		return
-	}
-	end := strings.Index(s, "]]")
-	if end == -1 {
-		return
-	}
-	urlEnd := strings.Index(s, "]")
-	rawURL := s[2:urlEnd]
-	const badURLChars = `<>"{}|\^[] ` + "`" // per RFC2396 section 2.4.3
-	if strings.ContainsAny(rawURL, badURLChars) {
-		return
-	}
-	if urlEnd == end {
-		simpleUrl := ""
-		url, err := url.Parse(rawURL)
-		if err == nil {
-			// If the URL is http://foo.com, drop the http://
-			// In other words, render [[http://golang.org]] as:
-			//   <a href="http://golang.org">golang.org</a>
-			if strings.HasPrefix(rawURL, url.Scheme+"://") {
-				simpleUrl = strings.TrimPrefix(rawURL, url.Scheme+"://")
-			} else if strings.HasPrefix(rawURL, url.Scheme+":") {
-				simpleUrl = strings.TrimPrefix(rawURL, url.Scheme+":")
-			}
-		}
-		return renderLink(rawURL, simpleUrl), end + 2
-	}
-	if s[urlEnd:urlEnd+2] != "][" {
-		return
-	}
-	text := s[urlEnd+2 : end]
-	return renderLink(rawURL, text), end + 2
-}
diff --git a/pkg/present/link_test.go b/pkg/present/link_test.go
deleted file mode 100644
index 334e72b..0000000
--- a/pkg/present/link_test.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package present
-
-import "testing"
-
-func TestInlineParsing(t *testing.T) {
-	var tests = []struct {
-		in     string
-		link   string
-		text   string
-		length int
-	}{
-		{"[[http://golang.org]]", "http://golang.org", "golang.org", 21},
-		{"[[http://golang.org][]]", "http://golang.org", "http://golang.org", 23},
-		{"[[http://golang.org]] this is ignored", "http://golang.org", "golang.org", 21},
-		{"[[http://golang.org][link]]", "http://golang.org", "link", 27},
-		{"[[http://golang.org][two words]]", "http://golang.org", "two words", 32},
-		{"[[http://golang.org][*link*]]", "http://golang.org", "<b>link</b>", 29},
-		{"[[http://bad[url]]", "", "", 0},
-		{"[[http://golang.org][a [[link]] ]]", "http://golang.org", "a [[link", 31},
-		{"[[http:// *spaces* .com]]", "", "", 0},
-		{"[[http://bad`char.com]]", "", "", 0},
-		{" [[http://google.com]]", "", "", 0},
-		{"[[mailto:gopher@golang.org][Gopher]]", "mailto:gopher@golang.org", "Gopher", 36},
-		{"[[mailto:gopher@golang.org]]", "mailto:gopher@golang.org", "gopher@golang.org", 28},
-	}
-
-	for i, test := range tests {
-		link, length := parseInlineLink(test.in)
-		if length == 0 && test.length == 0 {
-			continue
-		}
-		if a := renderLink(test.link, test.text); length != test.length || link != a {
-			t.Errorf("#%d: parseInlineLink(%q):\ngot\t%q, %d\nwant\t%q, %d", i, test.in, link, length, a, test.length)
-		}
-	}
-}
diff --git a/pkg/present/parse.go b/pkg/present/parse.go
deleted file mode 100644
index a78a85b..0000000
--- a/pkg/present/parse.go
+++ /dev/null
@@ -1,495 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package present
-
-import (
-	"bufio"
-	"bytes"
-	"errors"
-	"fmt"
-	"html/template"
-	"io"
-	"io/ioutil"
-	"log"
-	"net/url"
-	"regexp"
-	"strings"
-	"time"
-	"unicode"
-	"unicode/utf8"
-)
-
-var (
-	parsers = make(map[string]ParseFunc)
-	funcs   = template.FuncMap{}
-)
-
-// Template returns an empty template with the action functions in its FuncMap.
-func Template() *template.Template {
-	return template.New("").Funcs(funcs)
-}
-
-// Render renders the doc to the given writer using the provided template.
-func (d *Doc) Render(w io.Writer, t *template.Template) error {
-	data := struct {
-		*Doc
-		Template    *template.Template
-		PlayEnabled bool
-	}{d, t, PlayEnabled}
-	return t.ExecuteTemplate(w, "root", data)
-}
-
-type ParseFunc func(ctx *Context, fileName string, lineNumber int, inputLine string) (Elem, error)
-
-// Register binds the named action, which does not begin with a period, to the
-// specified parser to be invoked when the name, with a period, appears in the
-// present input text.
-func Register(name string, parser ParseFunc) {
-	if len(name) == 0 || name[0] == ';' {
-		panic("bad name in Register: " + name)
-	}
-	parsers["."+name] = parser
-}
-
-// Doc represents an entire document.
-type Doc struct {
-	Title    string
-	Subtitle string
-	Time     time.Time
-	Authors  []Author
-	Sections []Section
-	Tags     []string
-}
-
-// Author represents the person who wrote and/or is presenting the document.
-type Author struct {
-	Elem []Elem
-}
-
-// TextElem returns the first text elements of the author details.
-// This is used to display the author' name, job title, and company
-// without the contact details.
-func (p *Author) TextElem() (elems []Elem) {
-	for _, el := range p.Elem {
-		if _, ok := el.(Text); !ok {
-			break
-		}
-		elems = append(elems, el)
-	}
-	return
-}
-
-// Section represents a section of a document (such as a presentation slide)
-// comprising a title and a list of elements.
-type Section struct {
-	Number []int
-	Title  string
-	Elem   []Elem
-}
-
-func (s Section) Sections() (sections []Section) {
-	for _, e := range s.Elem {
-		if section, ok := e.(Section); ok {
-			sections = append(sections, section)
-		}
-	}
-	return
-}
-
-// Level returns the level of the given section.
-// The document title is level 1, main section 2, etc.
-func (s Section) Level() int {
-	return len(s.Number) + 1
-}
-
-// FormattedNumber returns a string containing the concatenation of the
-// numbers identifying a Section.
-func (s Section) FormattedNumber() string {
-	b := &bytes.Buffer{}
-	for _, n := range s.Number {
-		fmt.Fprintf(b, "%v.", n)
-	}
-	return b.String()
-}
-
-func (s Section) TemplateName() string { return "section" }
-
-// Elem defines the interface for a present element. That is, something that
-// can provide the name of the template used to render the element.
-type Elem interface {
-	TemplateName() string
-}
-
-// renderElem implements the elem template function, used to render
-// sub-templates.
-func renderElem(t *template.Template, e Elem) (template.HTML, error) {
-	var data interface{} = e
-	if s, ok := e.(Section); ok {
-		data = struct {
-			Section
-			Template *template.Template
-		}{s, t}
-	}
-	return execTemplate(t, e.TemplateName(), data)
-}
-
-func init() {
-	funcs["elem"] = renderElem
-}
-
-// execTemplate is a helper to execute a template and return the output as a
-// template.HTML value.
-func execTemplate(t *template.Template, name string, data interface{}) (template.HTML, error) {
-	b := new(bytes.Buffer)
-	err := t.ExecuteTemplate(b, name, data)
-	if err != nil {
-		return "", err
-	}
-	return template.HTML(b.String()), nil
-}
-
-// Text represents an optionally preformatted paragraph.
-type Text struct {
-	Lines []string
-	Pre   bool
-}
-
-func (t Text) TemplateName() string { return "text" }
-
-// List represents a bulleted list.
-type List struct {
-	Bullet []string
-}
-
-func (l List) TemplateName() string { return "list" }
-
-// Lines is a helper for parsing line-based input.
-type Lines struct {
-	line int // 0 indexed, so has 1-indexed number of last line returned
-	text []string
-}
-
-func readLines(r io.Reader) (*Lines, error) {
-	var lines []string
-	s := bufio.NewScanner(r)
-	for s.Scan() {
-		lines = append(lines, s.Text())
-	}
-	if err := s.Err(); err != nil {
-		return nil, err
-	}
-	return &Lines{0, lines}, nil
-}
-
-func (l *Lines) next() (text string, ok bool) {
-	for {
-		current := l.line
-		l.line++
-		if current >= len(l.text) {
-			return "", false
-		}
-		text = l.text[current]
-		// Lines starting with # are comments.
-		if len(text) == 0 || text[0] != '#' {
-			ok = true
-			break
-		}
-	}
-	return
-}
-
-func (l *Lines) back() {
-	l.line--
-}
-
-func (l *Lines) nextNonEmpty() (text string, ok bool) {
-	for {
-		text, ok = l.next()
-		if !ok {
-			return
-		}
-		if len(text) > 0 {
-			break
-		}
-	}
-	return
-}
-
-// A Context specifies the supporting context for parsing a presentation.
-type Context struct {
-	// ReadFile reads the file named by filename and returns the contents.
-	ReadFile func(filename string) ([]byte, error)
-}
-
-// ParseMode represents flags for the Parse function.
-type ParseMode int
-
-const (
-	// If set, parse only the title and subtitle.
-	TitlesOnly ParseMode = 1
-)
-
-// Parse parses a document from r.
-func (ctx *Context) Parse(r io.Reader, name string, mode ParseMode) (*Doc, error) {
-	doc := new(Doc)
-	lines, err := readLines(r)
-	if err != nil {
-		return nil, err
-	}
-	err = parseHeader(doc, lines)
-	if err != nil {
-		return nil, err
-	}
-	if mode&TitlesOnly != 0 {
-		return doc, nil
-	}
-	// Authors
-	if doc.Authors, err = parseAuthors(lines); err != nil {
-		return nil, err
-	}
-	// Sections
-	if doc.Sections, err = parseSections(ctx, name, lines, []int{}, doc); err != nil {
-		return nil, err
-	}
-	return doc, nil
-}
-
-// Parse parses a document from r. Parse reads assets used by the presentation
-// from the file system using ioutil.ReadFile.
-func Parse(r io.Reader, name string, mode ParseMode) (*Doc, error) {
-	ctx := Context{ReadFile: ioutil.ReadFile}
-	return ctx.Parse(r, name, mode)
-}
-
-// isHeading matches any section heading.
-var isHeading = regexp.MustCompile(`^\*+ `)
-
-// lesserHeading returns true if text is a heading of a lesser or equal level
-// than that denoted by prefix.
-func lesserHeading(text, prefix string) bool {
-	return isHeading.MatchString(text) && !strings.HasPrefix(text, prefix+"*")
-}
-
-// parseSections parses Sections from lines for the section level indicated by
-// number (a nil number indicates the top level).
-func parseSections(ctx *Context, name string, lines *Lines, number []int, doc *Doc) ([]Section, error) {
-	var sections []Section
-	for i := 1; ; i++ {
-		// Next non-empty line is title.
-		text, ok := lines.nextNonEmpty()
-		for ok && text == "" {
-			text, ok = lines.next()
-		}
-		if !ok {
-			break
-		}
-		prefix := strings.Repeat("*", len(number)+1)
-		if !strings.HasPrefix(text, prefix+" ") {
-			lines.back()
-			break
-		}
-		section := Section{
-			Number: append(append([]int{}, number...), i),
-			Title:  text[len(prefix)+1:],
-		}
-		text, ok = lines.nextNonEmpty()
-		for ok && !lesserHeading(text, prefix) {
-			var e Elem
-			r, _ := utf8.DecodeRuneInString(text)
-			switch {
-			case unicode.IsSpace(r):
-				i := strings.IndexFunc(text, func(r rune) bool {
-					return !unicode.IsSpace(r)
-				})
-				if i < 0 {
-					break
-				}
-				indent := text[:i]
-				var s []string
-				for ok && (strings.HasPrefix(text, indent) || text == "") {
-					if text != "" {
-						text = text[i:]
-					}
-					s = append(s, text)
-					text, ok = lines.next()
-				}
-				lines.back()
-				pre := strings.Join(s, "\n")
-				pre = strings.Replace(pre, "\t", "    ", -1) // browsers treat tabs badly
-				pre = strings.TrimRightFunc(pre, unicode.IsSpace)
-				e = Text{Lines: []string{pre}, Pre: true}
-			case strings.HasPrefix(text, "- "):
-				var b []string
-				for ok && strings.HasPrefix(text, "- ") {
-					b = append(b, text[2:])
-					text, ok = lines.next()
-				}
-				lines.back()
-				e = List{Bullet: b}
-			case strings.HasPrefix(text, prefix+"* "):
-				lines.back()
-				subsecs, err := parseSections(ctx, name, lines, section.Number, doc)
-				if err != nil {
-					return nil, err
-				}
-				for _, ss := range subsecs {
-					section.Elem = append(section.Elem, ss)
-				}
-			case strings.HasPrefix(text, "."):
-				args := strings.Fields(text)
-				parser := parsers[args[0]]
-				if parser == nil {
-					return nil, fmt.Errorf("%s:%d: unknown command %q\n", name, lines.line, text)
-				}
-				t, err := parser(ctx, name, lines.line, text)
-				if err != nil {
-					return nil, err
-				}
-				e = t
-			default:
-				var l []string
-				for ok && strings.TrimSpace(text) != "" {
-					if text[0] == '.' { // Command breaks text block.
-						break
-					}
-					if strings.HasPrefix(text, `\.`) { // Backslash escapes initial period.
-						text = text[1:]
-					}
-					l = append(l, text)
-					text, ok = lines.next()
-				}
-				if len(l) > 0 {
-					e = Text{Lines: l}
-				}
-			}
-			if e != nil {
-				section.Elem = append(section.Elem, e)
-			}
-			text, ok = lines.nextNonEmpty()
-		}
-		if isHeading.MatchString(text) {
-			lines.back()
-		}
-		sections = append(sections, section)
-	}
-	return sections, nil
-}
-
-func parseHeader(doc *Doc, lines *Lines) error {
-	var ok bool
-	// First non-empty line starts header.
-	doc.Title, ok = lines.nextNonEmpty()
-	if !ok {
-		return errors.New("unexpected EOF; expected title")
-	}
-	for {
-		text, ok := lines.next()
-		if !ok {
-			return errors.New("unexpected EOF")
-		}
-		if text == "" {
-			break
-		}
-		const tagPrefix = "Tags:"
-		if strings.HasPrefix(text, tagPrefix) {
-			tags := strings.Split(text[len(tagPrefix):], ",")
-			for i := range tags {
-				tags[i] = strings.TrimSpace(tags[i])
-			}
-			doc.Tags = append(doc.Tags, tags...)
-		} else if t, ok := parseTime(text); ok {
-			doc.Time = t
-		} else if doc.Subtitle == "" {
-			doc.Subtitle = text
-		} else {
-			return fmt.Errorf("unexpected header line: %q", text)
-		}
-	}
-	return nil
-}
-
-func parseAuthors(lines *Lines) (authors []Author, err error) {
-	// This grammar demarcates authors with blanks.
-
-	// Skip blank lines.
-	if _, ok := lines.nextNonEmpty(); !ok {
-		return nil, errors.New("unexpected EOF")
-	}
-	lines.back()
-
-	var a *Author
-	for {
-		text, ok := lines.next()
-		if !ok {
-			return nil, errors.New("unexpected EOF")
-		}
-
-		// If we find a section heading, we're done.
-		if strings.HasPrefix(text, "* ") {
-			lines.back()
-			break
-		}
-
-		// If we encounter a blank we're done with this author.
-		if a != nil && len(text) == 0 {
-			authors = append(authors, *a)
-			a = nil
-			continue
-		}
-		if a == nil {
-			a = new(Author)
-		}
-
-		// Parse the line. Those that
-		// - begin with @ are twitter names,
-		// - contain slashes are links, or
-		// - contain an @ symbol are an email address.
-		// The rest is just text.
-		var el Elem
-		switch {
-		case strings.HasPrefix(text, "@"):
-			el = parseURL("http://twitter.com/" + text[1:])
-		case strings.Contains(text, ":"):
-			el = parseURL(text)
-		case strings.Contains(text, "@"):
-			el = parseURL("mailto:" + text)
-		}
-		if l, ok := el.(Link); ok {
-			l.Label = text
-			el = l
-		}
-		if el == nil {
-			el = Text{Lines: []string{text}}
-		}
-		a.Elem = append(a.Elem, el)
-	}
-	if a != nil {
-		authors = append(authors, *a)
-	}
-	return authors, nil
-}
-
-func parseURL(text string) Elem {
-	u, err := url.Parse(text)
-	if err != nil {
-		log.Printf("Parse(%q): %v", text, err)
-		return nil
-	}
-	return Link{URL: u}
-}
-
-func parseTime(text string) (t time.Time, ok bool) {
-	t, err := time.Parse("15:04 2 Jan 2006", text)
-	if err == nil {
-		return t, true
-	}
-	t, err = time.Parse("2 Jan 2006", text)
-	if err == nil {
-		// at 11am UTC it is the same date everywhere
-		t = t.Add(time.Hour * 11)
-		return t, true
-	}
-	return time.Time{}, false
-}
diff --git a/pkg/present/style.go b/pkg/present/style.go
deleted file mode 100644
index 1cd240d..0000000
--- a/pkg/present/style.go
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package present
-
-import (
-	"bytes"
-	"html"
-	"html/template"
-	"strings"
-	"unicode"
-	"unicode/utf8"
-)
-
-/*
-	Fonts are demarcated by an initial and final char bracketing a
-	space-delimited word, plus possibly some terminal punctuation.
-	The chars are
-		_ for italic
-		* for bold
-		` (back quote) for fixed width.
-	Inner appearances of the char become spaces. For instance,
-		_this_is_italic_!
-	becomes
-		<i>this is italic</i>!
-*/
-
-func init() {
-	funcs["style"] = Style
-}
-
-// Style returns s with HTML entities escaped and font indicators turned into
-// HTML font tags.
-func Style(s string) template.HTML {
-	return template.HTML(font(html.EscapeString(s)))
-}
-
-// font returns s with font indicators turned into HTML font tags.
-func font(s string) string {
-	if strings.IndexAny(s, "[`_*") == -1 {
-		return s
-	}
-	words := split(s)
-	var b bytes.Buffer
-Word:
-	for w, word := range words {
-		if len(word) < 2 {
-			continue Word
-		}
-		if link, _ := parseInlineLink(word); link != "" {
-			words[w] = link
-			continue Word
-		}
-		const punctuation = `.,;:()!?—–'"`
-		const marker = "_*`"
-		// Initial punctuation is OK but must be peeled off.
-		first := strings.IndexAny(word, marker)
-		if first == -1 {
-			continue Word
-		}
-		// Is the marker prefixed only by punctuation?
-		for _, r := range word[:first] {
-			if !strings.ContainsRune(punctuation, r) {
-				continue Word
-			}
-		}
-		open, word := word[:first], word[first:]
-		char := word[0] // ASCII is OK.
-		close := ""
-		switch char {
-		default:
-			continue Word
-		case '_':
-			open += "<i>"
-			close = "</i>"
-		case '*':
-			open += "<b>"
-			close = "</b>"
-		case '`':
-			open += "<code>"
-			close = "</code>"
-		}
-		// Terminal punctuation is OK but must be peeled off.
-		last := strings.LastIndex(word, word[:1])
-		if last == 0 {
-			continue Word
-		}
-		head, tail := word[:last+1], word[last+1:]
-		for _, r := range tail {
-			if !strings.ContainsRune(punctuation, r) {
-				continue Word
-			}
-		}
-		b.Reset()
-		b.WriteString(open)
-		var wid int
-		for i := 1; i < len(head)-1; i += wid {
-			var r rune
-			r, wid = utf8.DecodeRuneInString(head[i:])
-			if r != rune(char) {
-				// Ordinary character.
-				b.WriteRune(r)
-				continue
-			}
-			if head[i+1] != char {
-				// Inner char becomes space.
-				b.WriteRune(' ')
-				continue
-			}
-			// Doubled char becomes real char.
-			// Not worth worrying about "_x__".
-			b.WriteByte(char)
-			wid++ // Consumed two chars, both ASCII.
-		}
-		b.WriteString(close) // Write closing tag.
-		b.WriteString(tail)  // Restore trailing punctuation.
-		words[w] = b.String()
-	}
-	return strings.Join(words, "")
-}
-
-// split is like strings.Fields but also returns the runs of spaces
-// and treats inline links as distinct words.
-func split(s string) []string {
-	var (
-		words = make([]string, 0, 10)
-		start = 0
-	)
-
-	// appendWord appends the string s[start:end] to the words slice.
-	// If the word contains the beginning of a link, the non-link portion
-	// of the word and the entire link are appended as separate words,
-	// and the start index is advanced to the end of the link.
-	appendWord := func(end int) {
-		if j := strings.Index(s[start:end], "[["); j > -1 {
-			if _, l := parseInlineLink(s[start+j:]); l > 0 {
-				// Append portion before link, if any.
-				if j > 0 {
-					words = append(words, s[start:start+j])
-				}
-				// Append link itself.
-				words = append(words, s[start+j:start+j+l])
-				// Advance start index to end of link.
-				start = start + j + l
-				return
-			}
-		}
-		// No link; just add the word.
-		words = append(words, s[start:end])
-		start = end
-	}
-
-	wasSpace := false
-	for i, r := range s {
-		isSpace := unicode.IsSpace(r)
-		if i > start && isSpace != wasSpace {
-			appendWord(i)
-		}
-		wasSpace = isSpace
-	}
-	for start < len(s) {
-		appendWord(len(s))
-	}
-	return words
-}
diff --git a/pkg/present/style_test.go b/pkg/present/style_test.go
deleted file mode 100644
index d04db72..0000000
--- a/pkg/present/style_test.go
+++ /dev/null
@@ -1,116 +0,0 @@
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package present
-
-import (
-	"fmt"
-	"reflect"
-	"testing"
-)
-
-func TestSplit(t *testing.T) {
-	var tests = []struct {
-		in  string
-		out []string
-	}{
-		{"", []string{}},
-		{" ", []string{" "}},
-		{"abc", []string{"abc"}},
-		{"abc def", []string{"abc", " ", "def"}},
-		{"abc def ", []string{"abc", " ", "def", " "}},
-		{"hey [[http://golang.org][Gophers]] around",
-			[]string{"hey", " ", "[[http://golang.org][Gophers]]", " ", "around"}},
-		{"A [[http://golang.org/doc][two words]] link",
-			[]string{"A", " ", "[[http://golang.org/doc][two words]]", " ", "link"}},
-		{"Visit [[http://golang.org/doc]] now",
-			[]string{"Visit", " ", "[[http://golang.org/doc]]", " ", "now"}},
-		{"not [[http://golang.org/doc][a [[link]] ]] around",
-			[]string{"not", " ", "[[http://golang.org/doc][a [[link]]", " ", "]]", " ", "around"}},
-		{"[[http://golang.org][foo bar]]",
-			[]string{"[[http://golang.org][foo bar]]"}},
-		{"ends with [[http://golang.org][link]]",
-			[]string{"ends", " ", "with", " ", "[[http://golang.org][link]]"}},
-		{"my talk ([[http://talks.golang.org/][slides here]])",
-			[]string{"my", " ", "talk", " ", "(", "[[http://talks.golang.org/][slides here]]", ")"}},
-	}
-	for _, test := range tests {
-		out := split(test.in)
-		if !reflect.DeepEqual(out, test.out) {
-			t.Errorf("split(%q):\ngot\t%q\nwant\t%q", test.in, out, test.out)
-		}
-	}
-}
-
-func TestFont(t *testing.T) {
-	var tests = []struct {
-		in  string
-		out string
-	}{
-		{"", ""},
-		{" ", " "},
-		{"\tx", "\tx"},
-		{"_a_", "<i>a</i>"},
-		{"*a*", "<b>a</b>"},
-		{"`a`", "<code>a</code>"},
-		{"_a_b_", "<i>a b</i>"},
-		{"_a__b_", "<i>a_b</i>"},
-		{"_a___b_", "<i>a_ b</i>"},
-		{"*a**b*?", "<b>a*b</b>?"},
-		{"_a_<>_b_.", "<i>a <> b</i>."},
-		{"(_a_)", "(<i>a</i>)"},
-		{"((_a_), _b_, _c_).", "((<i>a</i>), <i>b</i>, <i>c</i>)."},
-		{"(_a)", "(_a)"},
-		{"(_a)", "(_a)"},
-		{"_Why_use_scoped__ptr_? Use plain ***ptr* instead.", "<i>Why use scoped_ptr</i>? Use plain <b>*ptr</b> instead."},
-		{"_hey_ [[http://golang.org][*Gophers*]] *around*",
-			`<i>hey</i> <a href="http://golang.org" target="_blank"><b>Gophers</b></a> <b>around</b>`},
-		{"_hey_ [[http://golang.org][so _many_ *Gophers*]] *around*",
-			`<i>hey</i> <a href="http://golang.org" target="_blank">so <i>many</i> <b>Gophers</b></a> <b>around</b>`},
-		{"Visit [[http://golang.org]] now",
-			`Visit <a href="http://golang.org" target="_blank">golang.org</a> now`},
-		{"my talk ([[http://talks.golang.org/][slides here]])",
-			`my talk (<a href="http://talks.golang.org/" target="_blank">slides here</a>)`},
-	}
-	for _, test := range tests {
-		out := font(test.in)
-		if out != test.out {
-			t.Errorf("font(%q):\ngot\t%q\nwant\t%q", test.in, out, test.out)
-		}
-	}
-}
-
-func TestStyle(t *testing.T) {
-	var tests = []struct {
-		in  string
-		out string
-	}{
-		{"", ""},
-		{" ", " "},
-		{"\tx", "\tx"},
-		{"_a_", "<i>a</i>"},
-		{"*a*", "<b>a</b>"},
-		{"`a`", "<code>a</code>"},
-		{"_a_b_", "<i>a b</i>"},
-		{"_a__b_", "<i>a_b</i>"},
-		{"_a___b_", "<i>a_ b</i>"},
-		{"*a**b*?", "<b>a*b</b>?"},
-		{"_a_<>_b_.", "<i>a &lt;&gt; b</i>."},
-		{"(_a_<>_b_)", "(<i>a &lt;&gt; b</i>)"},
-		{"((_a_), _b_, _c_).", "((<i>a</i>), <i>b</i>, <i>c</i>)."},
-		{"(_a)", "(_a)"},
-	}
-	for _, test := range tests {
-		out := string(Style(test.in))
-		if out != test.out {
-			t.Errorf("style(%q):\ngot\t%q\nwant\t%q", test.in, out, test.out)
-		}
-	}
-}
-
-func ExampleStyle() {
-	const s = "*Gophers* are _clearly_ > *cats*!"
-	fmt.Println(Style(s))
-	// Output: <b>Gophers</b> are <i>clearly</i> &gt; <b>cats</b>!
-}
diff --git a/pkg/socket/socket.go b/pkg/socket/socket.go
deleted file mode 100644
index e24d21c..0000000
--- a/pkg/socket/socket.go
+++ /dev/null
@@ -1,345 +0,0 @@
-// Copyright 2012 The Go Authors.  All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build !appengine
-
-// Package socket implements an WebSocket-based playground backend.
-// Clients connect to a websocket handler and send run/kill commands, and
-// the server sends the output and exit status of the running processes.
-// Multiple clients running multiple processes may be served concurrently.
-// The wire format is JSON and is described by the Message type.
-//
-// This will not run on App Engine as WebSockets are not supported there.
-package socket
-
-import (
-	"bytes"
-	"encoding/json"
-	"errors"
-	"go/parser"
-	"go/token"
-	"io"
-	"io/ioutil"
-	"log"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"runtime"
-	"strconv"
-	"strings"
-	"sync"
-	"time"
-	"unicode/utf8"
-
-	"code.google.com/p/go.net/websocket"
-)
-
-// Handler implements a WebSocket handler for a client connection.
-var Handler = websocket.Handler(socketHandler)
-
-// Environ provides an environment when a binary, such as the go tool, is
-// invoked.
-var Environ func() []string = os.Environ
-
-const (
-	// The maximum number of messages to send per session (avoid flooding).
-	msgLimit = 1000
-
-	// Batch messages sent in this interval and send as a single message.
-	msgDelay = 10 * time.Millisecond
-)
-
-// Message is the wire format for the websocket connection to the browser.
-// It is used for both sending output messages and receiving commands, as
-// distinguished by the Kind field.
-type Message struct {
-	Id      string // client-provided unique id for the process
-	Kind    string // in: "run", "kill" out: "stdout", "stderr", "end"
-	Body    string
-	Options *Options `json:",omitempty"`
-}
-
-// Options specify additional message options.
-type Options struct {
-	Race bool // use -race flag when building code (for "run" only)
-}
-
-// socketHandler handles the websocket connection for a given present session.
-// It handles transcoding Messages to and from JSON format, and starting
-// and killing processes.
-func socketHandler(c *websocket.Conn) {
-	in, out := make(chan *Message), make(chan *Message)
-	errc := make(chan error, 1)
-
-	// Decode messages from client and send to the in channel.
-	go func() {
-		dec := json.NewDecoder(c)
-		for {
-			var m Message
-			if err := dec.Decode(&m); err != nil {
-				errc <- err
-				return
-			}
-			in <- &m
-		}
-	}()
-
-	// Receive messages from the out channel and encode to the client.
-	go func() {
-		enc := json.NewEncoder(c)
-		for m := range out {
-			if err := enc.Encode(m); err != nil {
-				errc <- err
-				return
-			}
-		}
-	}()
-
-	// Start and kill processes and handle errors.
-	proc := make(map[string]*process)
-	for {
-		select {
-		case m := <-in:
-			switch m.Kind {
-			case "run":
-				proc[m.Id].Kill()
-				lOut := limiter(in, out)
-				proc[m.Id] = startProcess(m.Id, m.Body, lOut, m.Options)
-			case "kill":
-				proc[m.Id].Kill()
-			}
-		case err := <-errc:
-			if err != io.EOF {
-				// A encode or decode has failed; bail.
-				log.Println(err)
-			}
-			// Shut down any running processes.
-			for _, p := range proc {
-				p.Kill()
-			}
-			return
-		}
-	}
-}
-
-// process represents a running process.
-type process struct {
-	id   string
-	out  chan<- *Message
-	done chan struct{} // closed when wait completes
-	run  *exec.Cmd
-	bin  string
-}
-
-// startProcess builds and runs the given program, sending its output
-// and end event as Messages on the provided channel.
-func startProcess(id, body string, out chan<- *Message, opt *Options) *process {
-	p := &process{
-		id:   id,
-		out:  out,
-		done: make(chan struct{}),
-	}
-	if err := p.start(body, opt); err != nil {
-		p.end(err)
-		return nil
-	}
-	go p.wait()
-	return p
-}
-
-// Kill stops the process if it is running and waits for it to exit.
-func (p *process) Kill() {
-	if p == nil {
-		return
-	}
-	p.run.Process.Kill()
-	<-p.done // block until process exits
-}
-
-// start builds and starts the given program, sending its output to p.out,
-// and stores the running *exec.Cmd in the run field.
-func (p *process) start(body string, opt *Options) error {
-	// We "go build" and then exec the binary so that the
-	// resultant *exec.Cmd is a handle to the user's program
-	// (rather than the go tool process).
-	// This makes Kill work.
-
-	bin := filepath.Join(tmpdir, "compile"+strconv.Itoa(<-uniq))
-	src := bin + ".go"
-	if runtime.GOOS == "windows" {
-		bin += ".exe"
-	}
-
-	// write body to x.go
-	defer os.Remove(src)
-	err := ioutil.WriteFile(src, []byte(body), 0666)
-	if err != nil {
-		return err
-	}
-
-	// build x.go, creating x
-	p.bin = bin // to be removed by p.end
-	dir, file := filepath.Split(src)
-	args := []string{"go", "build", "-tags", "OMIT"}
-	if opt != nil && opt.Race {
-		p.out <- &Message{
-			Id: p.id, Kind: "stderr",
-			Body: "Running with race detector.\n",
-		}
-		args = append(args, "-race")
-	}
-	args = append(args, "-o", bin, file)
-	cmd := p.cmd(dir, args...)
-	cmd.Stdout = cmd.Stderr // send compiler output to stderr
-	if err := cmd.Run(); err != nil {
-		return err
-	}
-
-	// run x
-	cmd = p.cmd("", bin)
-	if opt != nil && opt.Race {
-		cmd.Env = append(cmd.Env, "GOMAXPROCS=2")
-	}
-	if err := cmd.Start(); err != nil {
-		// If we failed to exec, that might be because they built
-		// a non-main package instead of an executable.
-		// Check and report that.
-		if name, err := packageName(body); err == nil && name != "main" {
-			return errors.New(`executable programs must use "package main"`)
-		}
-		return err
-	}
-	p.run = cmd
-	return nil
-}
-
-// wait waits for the running process to complete
-// and sends its error state to the client.
-func (p *process) wait() {
-	p.end(p.run.Wait())
-	close(p.done) // unblock waiting Kill calls
-}
-
-// end sends an "end" message to the client, containing the process id and the
-// given error value. It also removes the binary.
-func (p *process) end(err error) {
-	if p.bin != "" {
-		defer os.Remove(p.bin)
-	}
-	m := &Message{Id: p.id, Kind: "end"}
-	if err != nil {
-		m.Body = err.Error()
-	}
-	// Wait for any outstanding reads to finish (potential race here).
-	time.AfterFunc(msgDelay, func() { p.out <- m })
-}
-
-// cmd builds an *exec.Cmd that writes its standard output and error to the
-// process' output channel.
-func (p *process) cmd(dir string, args ...string) *exec.Cmd {
-	cmd := exec.Command(args[0], args[1:]...)
-	cmd.Dir = dir
-	cmd.Env = Environ()
-	cmd.Stdout = &messageWriter{id: p.id, kind: "stdout", out: p.out}
-	cmd.Stderr = &messageWriter{id: p.id, kind: "stderr", out: p.out}
-	return cmd
-}
-
-func packageName(body string) (string, error) {
-	f, err := parser.ParseFile(token.NewFileSet(), "prog.go",
-		strings.NewReader(body), parser.PackageClauseOnly)
-	if err != nil {
-		return "", err
-	}
-	return f.Name.String(), nil
-}
-
-// messageWriter is an io.Writer that converts all writes to Message sends on
-// the out channel with the specified id and kind.
-type messageWriter struct {
-	id, kind string
-	out      chan<- *Message
-
-	mu   sync.Mutex
-	buf  []byte
-	send *time.Timer
-}
-
-func (w *messageWriter) Write(b []byte) (n int, err error) {
-	// Buffer writes that occur in a short period to send as one Message.
-	w.mu.Lock()
-	w.buf = append(w.buf, b...)
-	if w.send == nil {
-		w.send = time.AfterFunc(msgDelay, w.sendNow)
-	}
-	w.mu.Unlock()
-	return len(b), nil
-}
-
-func (w *messageWriter) sendNow() {
-	w.mu.Lock()
-	body := safeString(w.buf)
-	w.buf, w.send = nil, nil
-	w.mu.Unlock()
-	w.out <- &Message{Id: w.id, Kind: w.kind, Body: body}
-}
-
-// safeString returns b as a valid UTF-8 string.
-func safeString(b []byte) string {
-	if utf8.Valid(b) {
-		return string(b)
-	}
-	var buf bytes.Buffer
-	for len(b) > 0 {
-		r, size := utf8.DecodeRune(b)
-		b = b[size:]
-		buf.WriteRune(r)
-	}
-	return buf.String()
-}
-
-// limiter returns a channel that wraps dest. Messages sent to the channel are
-// sent to dest. After msgLimit Messages have been passed on, a "kill" Message
-// is sent to the kill channel, and only "end" messages are passed.
-func limiter(kill chan<- *Message, dest chan<- *Message) chan<- *Message {
-	ch := make(chan *Message)
-	go func() {
-		n := 0
-		for m := range ch {
-			switch {
-			case n < msgLimit || m.Kind == "end":
-				dest <- m
-				if m.Kind == "end" {
-					return
-				}
-			case n == msgLimit:
-				// process produced too much output. Kill it.
-				kill <- &Message{Id: m.Id, Kind: "kill"}
-			}
-			n++
-		}
-	}()
-	return ch
-}
-
-var tmpdir string
-
-func init() {
-	// find real path to temporary directory
-	var err error
-	tmpdir, err = filepath.EvalSymlinks(os.TempDir())
-	if err != nil {
-		log.Fatal(err)
-	}
-}
-
-var uniq = make(chan int) // a source of numbers for naming temporary files
-
-func init() {
-	go func() {
-		for i := 0; ; i++ {
-			uniq <- i
-		}
-	}()
-}
diff --git a/present/appengine.go b/present/appengine.go
index 1fb2d44..affcf50 100644
--- a/present/appengine.go
+++ b/present/appengine.go
@@ -7,9 +7,9 @@
 package main
 
 import (
-	"code.google.com/p/go.talks/pkg/present"
+	"code.google.com/p/go.tools/present"
 
-	_ "code.google.com/p/go.tools/godoc/playground"
+	_ "code.google.com/p/go.tools/playground"
 )
 
 var basePath = "./present/"
diff --git a/present/dir.go b/present/dir.go
index c8c8304..4cc225b 100644
--- a/present/dir.go
+++ b/present/dir.go
@@ -14,7 +14,7 @@
 	"path/filepath"
 	"sort"
 
-	"code.google.com/p/go.talks/pkg/present"
+	"code.google.com/p/go.tools/present"
 )
 
 func init() {
diff --git a/present/doc.go b/present/doc.go
index 39e2f5b..254de64 100644
--- a/present/doc.go
+++ b/present/doc.go
@@ -24,6 +24,6 @@
 	.article      // article format, such as a blog post
 
 The present file format is documented by the present package:
-http://godoc.org/code.google.com/p/go.talks/pkg/present
+http://godoc.org/code.google.com/p/go.tools/godoc/present
 */
 package main
diff --git a/present/local.go b/present/local.go
index 5478ef0..7bd067c 100644
--- a/present/local.go
+++ b/present/local.go
@@ -15,8 +15,8 @@
 	"os"
 	"strings"
 
-	"code.google.com/p/go.talks/pkg/present"
-	"code.google.com/p/go.talks/pkg/socket"
+	"code.google.com/p/go.tools/playground/socket"
+	"code.google.com/p/go.tools/present"
 )
 
 const basePkg = "code.google.com/p/go.talks/present"