diff --git a/internal/godoc/astfuncs.go b/internal/godoc/astfuncs.go
new file mode 100644
index 0000000..48ab123
--- /dev/null
+++ b/internal/godoc/astfuncs.go
@@ -0,0 +1,190 @@
+// 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.
+
+//go:build go1.16
+// +build go1.16
+
+package godoc
+
+import (
+	"bufio"
+	"bytes"
+	"go/ast"
+	"go/doc"
+	"go/printer"
+	"go/token"
+	"io"
+	"log"
+	"unicode"
+
+	"golang.org/x/website/internal/texthtml"
+)
+
+var slashSlash = []byte("//")
+
+func (p *Presentation) nodeFunc(info *PageInfo, node interface{}) string {
+	var buf bytes.Buffer
+	p.writeNode(&buf, info, info.FSet, node)
+	return buf.String()
+}
+
+func (p *Presentation) node_htmlFunc(info *PageInfo, node interface{}, linkify bool) string {
+	var buf1 bytes.Buffer
+	p.writeNode(&buf1, info, info.FSet, node)
+
+	var buf2 bytes.Buffer
+	var n ast.Node
+	if linkify && p.DeclLinks {
+		n, _ = node.(ast.Node)
+	}
+	buf2.Write(texthtml.Format(buf1.Bytes(), texthtml.Config{
+		AST:        n,
+		GoComments: true,
+	}))
+	return buf2.String()
+}
+
+// writeNode writes the AST node x to w.
+//
+// The provided fset must be non-nil. The pageInfo is optional. If
+// present, the pageInfo is used to add comments to struct fields to
+// say which version of Go introduced them.
+func (p *Presentation) writeNode(w io.Writer, pageInfo *PageInfo, fset *token.FileSet, x interface{}) {
+	// convert trailing tabs into spaces using a tconv filter
+	// to ensure a good outcome in most browsers (there may still
+	// be tabs in comments and strings, but converting those into
+	// the right number of spaces is much harder)
+	//
+	// TODO(gri) rethink printer flags - perhaps tconv can be eliminated
+	//           with an another printer mode (which is more efficiently
+	//           implemented in the printer than here with another layer)
+
+	var pkgName, structName string
+	var apiInfo pkgAPIVersions
+	if gd, ok := x.(*ast.GenDecl); ok && pageInfo != nil && pageInfo.PDoc != nil &&
+		p.Corpus != nil &&
+		gd.Tok == token.TYPE && len(gd.Specs) != 0 {
+		pkgName = pageInfo.PDoc.ImportPath
+		if ts, ok := gd.Specs[0].(*ast.TypeSpec); ok {
+			if _, ok := ts.Type.(*ast.StructType); ok {
+				structName = ts.Name.Name
+			}
+		}
+		apiInfo = p.Corpus.pkgAPIInfo[pkgName]
+	}
+
+	var out = w
+	var buf bytes.Buffer
+	if structName != "" {
+		out = &buf
+	}
+
+	mode := printer.TabIndent | printer.UseSpaces
+	err := (&printer.Config{Mode: mode, Tabwidth: p.TabWidth}).Fprint(TabSpacer(out, p.TabWidth), fset, x)
+	if err != nil {
+		log.Print(err)
+	}
+
+	// Add comments to struct fields saying which Go version introduced them.
+	if structName != "" {
+		fieldSince := apiInfo.fieldSince[structName]
+		typeSince := apiInfo.typeSince[structName]
+		// Add/rewrite comments on struct fields to note which Go version added them.
+		var buf2 bytes.Buffer
+		buf2.Grow(buf.Len() + len(" // Added in Go 1.n")*10)
+		bs := bufio.NewScanner(&buf)
+		for bs.Scan() {
+			line := bs.Bytes()
+			field := firstIdent(line)
+			var since string
+			if field != "" {
+				since = fieldSince[field]
+				if since != "" && since == typeSince {
+					// Don't highlight field versions if they were the
+					// same as the struct itself.
+					since = ""
+				}
+			}
+			if since == "" {
+				buf2.Write(line)
+			} else {
+				if bytes.Contains(line, slashSlash) {
+					line = bytes.TrimRight(line, " \t.")
+					buf2.Write(line)
+					buf2.WriteString("; added in Go ")
+				} else {
+					buf2.Write(line)
+					buf2.WriteString(" // Go ")
+				}
+				buf2.WriteString(since)
+			}
+			buf2.WriteByte('\n')
+		}
+		w.Write(buf2.Bytes())
+	}
+}
+
+// firstIdent returns the first identifier in x.
+// This actually parses "identifiers" that begin with numbers too, but we
+// never feed it such input, so it's fine.
+func firstIdent(x []byte) string {
+	x = bytes.TrimSpace(x)
+	i := bytes.IndexFunc(x, func(r rune) bool { return !unicode.IsLetter(r) && !unicode.IsNumber(r) })
+	if i == -1 {
+		return string(x)
+	}
+	return string(x[:i])
+}
+
+func comment_htmlFunc(comment string) string {
+	var buf bytes.Buffer
+	// TODO(gri) Provide list of words (e.g. function parameters)
+	//           to be emphasized by ToHTML.
+	doc.ToHTML(&buf, comment, nil) // does html-escaping
+	return buf.String()
+}
+
+// sanitizeFunc sanitizes the argument src by replacing newlines with
+// blanks, removing extra blanks, and by removing trailing whitespace
+// and commas before closing parentheses.
+func sanitizeFunc(src string) string {
+	buf := make([]byte, len(src))
+	j := 0      // buf index
+	comma := -1 // comma index if >= 0
+	for i := 0; i < len(src); i++ {
+		ch := src[i]
+		switch ch {
+		case '\t', '\n', ' ':
+			// ignore whitespace at the beginning, after a blank, or after opening parentheses
+			if j == 0 {
+				continue
+			}
+			if p := buf[j-1]; p == ' ' || p == '(' || p == '{' || p == '[' {
+				continue
+			}
+			// replace all whitespace with blanks
+			ch = ' '
+		case ',':
+			comma = j
+		case ')', '}', ']':
+			// remove any trailing comma
+			if comma >= 0 {
+				j = comma
+			}
+			// remove any trailing whitespace
+			if j > 0 && buf[j-1] == ' ' {
+				j--
+			}
+		default:
+			comma = -1
+		}
+		buf[j] = ch
+		j++
+	}
+	// remove trailing blank, if any
+	if j > 0 && buf[j-1] == ' ' {
+		j--
+	}
+	return string(buf[:j])
+}
diff --git a/internal/godoc/examplefuncs.go b/internal/godoc/examplefuncs.go
new file mode 100644
index 0000000..a1048bb
--- /dev/null
+++ b/internal/godoc/examplefuncs.go
@@ -0,0 +1,235 @@
+// 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.
+
+//go:build go1.16
+// +build go1.16
+
+package godoc
+
+import (
+	"bytes"
+	"go/ast"
+	"go/format"
+	"go/printer"
+	"log"
+	"regexp"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+)
+
+func (p *Presentation) example_htmlFunc(info *PageInfo, funcName string) string {
+	var buf bytes.Buffer
+	for _, eg := range info.Examples {
+		name := stripExampleSuffix(eg.Name)
+
+		if name != funcName {
+			continue
+		}
+
+		// print code
+		cnode := &printer.CommentedNode{Node: eg.Code, Comments: eg.Comments}
+		code := p.node_htmlFunc(info, cnode, true)
+		out := eg.Output
+		wholeFile := true
+
+		// Additional formatting if this is a function body.
+		if n := len(code); n >= 2 && code[0] == '{' && code[n-1] == '}' {
+			wholeFile = false
+			// remove surrounding braces
+			code = code[1 : n-1]
+			// unindent
+			code = replaceLeadingIndentation(code, strings.Repeat(" ", p.TabWidth), "")
+			// remove output comment
+			if loc := exampleOutputRx.FindStringIndex(code); loc != nil {
+				code = strings.TrimSpace(code[:loc[0]])
+			}
+		}
+
+		// Write out the playground code in standard Go style
+		// (use tabs, no comment highlight, etc).
+		play := ""
+		if eg.Play != nil && p.ShowPlayground {
+			var buf bytes.Buffer
+			eg.Play.Comments = filterOutBuildAnnotations(eg.Play.Comments)
+			if err := format.Node(&buf, info.FSet, eg.Play); err != nil {
+				log.Print(err)
+			} else {
+				play = buf.String()
+			}
+		}
+
+		// Drop output, as the output comment will appear in the code.
+		if wholeFile && play == "" {
+			out = ""
+		}
+
+		if p.ExampleHTML == nil {
+			out = ""
+			return ""
+		}
+
+		err := p.ExampleHTML.Execute(&buf, struct {
+			Name, Doc, Code, Play, Output string
+			GoogleCN                      bool
+		}{eg.Name, eg.Doc, code, play, out, info.GoogleCN})
+		if err != nil {
+			log.Print(err)
+		}
+	}
+	return buf.String()
+}
+
+// replaceLeadingIndentation replaces oldIndent at the beginning of each line
+// with newIndent. This is used for formatting examples. Raw strings that
+// span multiple lines are handled specially: oldIndent is not removed (since
+// go/printer will not add any indentation there), but newIndent is added
+// (since we may still want leading indentation).
+func replaceLeadingIndentation(body, oldIndent, newIndent string) string {
+	// Handle indent at the beginning of the first line. After this, we handle
+	// indentation only after a newline.
+	var buf bytes.Buffer
+	if strings.HasPrefix(body, oldIndent) {
+		buf.WriteString(newIndent)
+		body = body[len(oldIndent):]
+	}
+
+	// Use a state machine to keep track of whether we're in a string or
+	// rune literal while we process the rest of the code.
+	const (
+		codeState = iota
+		runeState
+		interpretedStringState
+		rawStringState
+	)
+	searchChars := []string{
+		"'\"`\n", // codeState
+		`\'`,     // runeState
+		`\"`,     // interpretedStringState
+		"`\n",    // rawStringState
+		// newlineState does not need to search
+	}
+	state := codeState
+	for {
+		i := strings.IndexAny(body, searchChars[state])
+		if i < 0 {
+			buf.WriteString(body)
+			break
+		}
+		c := body[i]
+		buf.WriteString(body[:i+1])
+		body = body[i+1:]
+		switch state {
+		case codeState:
+			switch c {
+			case '\'':
+				state = runeState
+			case '"':
+				state = interpretedStringState
+			case '`':
+				state = rawStringState
+			case '\n':
+				if strings.HasPrefix(body, oldIndent) {
+					buf.WriteString(newIndent)
+					body = body[len(oldIndent):]
+				}
+			}
+
+		case runeState:
+			switch c {
+			case '\\':
+				r, size := utf8.DecodeRuneInString(body)
+				buf.WriteRune(r)
+				body = body[size:]
+			case '\'':
+				state = codeState
+			}
+
+		case interpretedStringState:
+			switch c {
+			case '\\':
+				r, size := utf8.DecodeRuneInString(body)
+				buf.WriteRune(r)
+				body = body[size:]
+			case '"':
+				state = codeState
+			}
+
+		case rawStringState:
+			switch c {
+			case '`':
+				state = codeState
+			case '\n':
+				buf.WriteString(newIndent)
+			}
+		}
+	}
+	return buf.String()
+}
+
+var exampleOutputRx = regexp.MustCompile(`(?i)//[[:space:]]*(unordered )?output:`)
+
+func filterOutBuildAnnotations(cg []*ast.CommentGroup) []*ast.CommentGroup {
+	if len(cg) == 0 {
+		return cg
+	}
+
+	for i := range cg {
+		if !strings.HasPrefix(cg[i].Text(), "+build ") {
+			// Found the first non-build tag, return from here until the end
+			// of the slice.
+			return cg[i:]
+		}
+	}
+
+	// There weren't any non-build tags, return an empty slice.
+	return []*ast.CommentGroup{}
+}
+
+// example_nameFunc takes an example function name and returns its display
+// name. For example, "Foo_Bar_quux" becomes "Foo.Bar (Quux)".
+func (p *Presentation) example_nameFunc(s string) string {
+	name, suffix := splitExampleName(s)
+	// replace _ with . for method names
+	name = strings.Replace(name, "_", ".", 1)
+	// use "Package" if no name provided
+	if name == "" {
+		name = "Package"
+	}
+	return name + suffix
+}
+
+// example_suffixFunc takes an example function name and returns its suffix in
+// parenthesized form. For example, "Foo_Bar_quux" becomes " (Quux)".
+func (p *Presentation) example_suffixFunc(name string) string {
+	_, suffix := splitExampleName(name)
+	return suffix
+}
+
+func splitExampleName(s string) (name, suffix string) {
+	i := strings.LastIndex(s, "_")
+	if 0 <= i && i < len(s)-1 && !startsWithUppercase(s[i+1:]) {
+		name = s[:i]
+		suffix = " (" + strings.Title(s[i+1:]) + ")"
+		return
+	}
+	name = s
+	return
+}
+
+// stripExampleSuffix strips lowercase braz in Foo_braz or Foo_Bar_braz from name
+// while keeping uppercase Braz in Foo_Braz.
+func stripExampleSuffix(name string) string {
+	if i := strings.LastIndex(name, "_"); i != -1 {
+		if i < len(name)-1 && !startsWithUppercase(name[i+1:]) {
+			name = name[:i]
+		}
+	}
+	return name
+}
+
+func startsWithUppercase(s string) bool {
+	r, _ := utf8.DecodeRuneInString(s)
+	return unicode.IsUpper(r)
+}
diff --git a/internal/godoc/godoc.go b/internal/godoc/godoc.go
index 47c2b0f..4b80021 100644
--- a/internal/godoc/godoc.go
+++ b/internal/godoc/godoc.go
@@ -5,34 +5,19 @@
 //go:build go1.16
 // +build go1.16
 
-// Package godoc is a work-in-progress (2013-07-17) package to
-// begin splitting up the godoc binary into multiple pieces.
-//
-// This package comment will evolve over time as this package splits
-// into smaller pieces.
-package godoc // import "golang.org/x/website/internal/godoc"
+package godoc
 
 import (
-	"bufio"
 	"bytes"
 	"fmt"
 	"go/ast"
 	"go/doc"
-	"go/format"
-	"go/printer"
 	"go/token"
-	"io"
-	"log"
 	pathpkg "path"
-	"regexp"
 	"strconv"
 	"strings"
 	"text/template"
 	"time"
-	"unicode"
-	"unicode/utf8"
-
-	"golang.org/x/website/internal/texthtml"
 )
 
 // Fake relative package path for built-ins. Documentation for all globals
@@ -118,80 +103,6 @@
 	return localname
 }
 
-func (p *Presentation) nodeFunc(info *PageInfo, node interface{}) string {
-	var buf bytes.Buffer
-	p.writeNode(&buf, info, info.FSet, node)
-	return buf.String()
-}
-
-func (p *Presentation) node_htmlFunc(info *PageInfo, node interface{}, linkify bool) string {
-	var buf1 bytes.Buffer
-	p.writeNode(&buf1, info, info.FSet, node)
-
-	var buf2 bytes.Buffer
-	var n ast.Node
-	if linkify && p.DeclLinks {
-		n, _ = node.(ast.Node)
-	}
-	buf2.Write(texthtml.Format(buf1.Bytes(), texthtml.Config{
-		AST:        n,
-		GoComments: true,
-	}))
-	return buf2.String()
-}
-
-func comment_htmlFunc(comment string) string {
-	var buf bytes.Buffer
-	// TODO(gri) Provide list of words (e.g. function parameters)
-	//           to be emphasized by ToHTML.
-	doc.ToHTML(&buf, comment, nil) // does html-escaping
-	return buf.String()
-}
-
-// sanitizeFunc sanitizes the argument src by replacing newlines with
-// blanks, removing extra blanks, and by removing trailing whitespace
-// and commas before closing parentheses.
-func sanitizeFunc(src string) string {
-	buf := make([]byte, len(src))
-	j := 0      // buf index
-	comma := -1 // comma index if >= 0
-	for i := 0; i < len(src); i++ {
-		ch := src[i]
-		switch ch {
-		case '\t', '\n', ' ':
-			// ignore whitespace at the beginning, after a blank, or after opening parentheses
-			if j == 0 {
-				continue
-			}
-			if p := buf[j-1]; p == ' ' || p == '(' || p == '{' || p == '[' {
-				continue
-			}
-			// replace all whitespace with blanks
-			ch = ' '
-		case ',':
-			comma = j
-		case ')', '}', ']':
-			// remove any trailing comma
-			if comma >= 0 {
-				j = comma
-			}
-			// remove any trailing whitespace
-			if j > 0 && buf[j-1] == ' ' {
-				j--
-			}
-		default:
-			comma = -1
-		}
-		buf[j] = ch
-		j++
-	}
-	// remove trailing blank, if any
-	if j > 0 && buf[j-1] == ' ' {
-		j--
-	}
-	return string(buf[:j])
-}
-
 type PageInfo struct {
 	Dirname  string // directory containing the package
 	Err      error  // error or nil
@@ -350,321 +261,6 @@
 	return pathpkg.Clean("/pkg/"+s) + "/#" + ident
 }
 
-func (p *Presentation) example_htmlFunc(info *PageInfo, funcName string) string {
-	var buf bytes.Buffer
-	for _, eg := range info.Examples {
-		name := stripExampleSuffix(eg.Name)
-
-		if name != funcName {
-			continue
-		}
-
-		// print code
-		cnode := &printer.CommentedNode{Node: eg.Code, Comments: eg.Comments}
-		code := p.node_htmlFunc(info, cnode, true)
-		out := eg.Output
-		wholeFile := true
-
-		// Additional formatting if this is a function body.
-		if n := len(code); n >= 2 && code[0] == '{' && code[n-1] == '}' {
-			wholeFile = false
-			// remove surrounding braces
-			code = code[1 : n-1]
-			// unindent
-			code = replaceLeadingIndentation(code, strings.Repeat(" ", p.TabWidth), "")
-			// remove output comment
-			if loc := exampleOutputRx.FindStringIndex(code); loc != nil {
-				code = strings.TrimSpace(code[:loc[0]])
-			}
-		}
-
-		// Write out the playground code in standard Go style
-		// (use tabs, no comment highlight, etc).
-		play := ""
-		if eg.Play != nil && p.ShowPlayground {
-			var buf bytes.Buffer
-			eg.Play.Comments = filterOutBuildAnnotations(eg.Play.Comments)
-			if err := format.Node(&buf, info.FSet, eg.Play); err != nil {
-				log.Print(err)
-			} else {
-				play = buf.String()
-			}
-		}
-
-		// Drop output, as the output comment will appear in the code.
-		if wholeFile && play == "" {
-			out = ""
-		}
-
-		if p.ExampleHTML == nil {
-			out = ""
-			return ""
-		}
-
-		err := p.ExampleHTML.Execute(&buf, struct {
-			Name, Doc, Code, Play, Output string
-			GoogleCN                      bool
-		}{eg.Name, eg.Doc, code, play, out, info.GoogleCN})
-		if err != nil {
-			log.Print(err)
-		}
-	}
-	return buf.String()
-}
-
-func filterOutBuildAnnotations(cg []*ast.CommentGroup) []*ast.CommentGroup {
-	if len(cg) == 0 {
-		return cg
-	}
-
-	for i := range cg {
-		if !strings.HasPrefix(cg[i].Text(), "+build ") {
-			// Found the first non-build tag, return from here until the end
-			// of the slice.
-			return cg[i:]
-		}
-	}
-
-	// There weren't any non-build tags, return an empty slice.
-	return []*ast.CommentGroup{}
-}
-
-// example_nameFunc takes an example function name and returns its display
-// name. For example, "Foo_Bar_quux" becomes "Foo.Bar (Quux)".
-func (p *Presentation) example_nameFunc(s string) string {
-	name, suffix := splitExampleName(s)
-	// replace _ with . for method names
-	name = strings.Replace(name, "_", ".", 1)
-	// use "Package" if no name provided
-	if name == "" {
-		name = "Package"
-	}
-	return name + suffix
-}
-
-// example_suffixFunc takes an example function name and returns its suffix in
-// parenthesized form. For example, "Foo_Bar_quux" becomes " (Quux)".
-func (p *Presentation) example_suffixFunc(name string) string {
-	_, suffix := splitExampleName(name)
-	return suffix
-}
-
 func noteTitle(note string) string {
 	return strings.Title(strings.ToLower(note))
 }
-
-func startsWithUppercase(s string) bool {
-	r, _ := utf8.DecodeRuneInString(s)
-	return unicode.IsUpper(r)
-}
-
-var exampleOutputRx = regexp.MustCompile(`(?i)//[[:space:]]*(unordered )?output:`)
-
-// stripExampleSuffix strips lowercase braz in Foo_braz or Foo_Bar_braz from name
-// while keeping uppercase Braz in Foo_Braz.
-func stripExampleSuffix(name string) string {
-	if i := strings.LastIndex(name, "_"); i != -1 {
-		if i < len(name)-1 && !startsWithUppercase(name[i+1:]) {
-			name = name[:i]
-		}
-	}
-	return name
-}
-
-func splitExampleName(s string) (name, suffix string) {
-	i := strings.LastIndex(s, "_")
-	if 0 <= i && i < len(s)-1 && !startsWithUppercase(s[i+1:]) {
-		name = s[:i]
-		suffix = " (" + strings.Title(s[i+1:]) + ")"
-		return
-	}
-	name = s
-	return
-}
-
-// replaceLeadingIndentation replaces oldIndent at the beginning of each line
-// with newIndent. This is used for formatting examples. Raw strings that
-// span multiple lines are handled specially: oldIndent is not removed (since
-// go/printer will not add any indentation there), but newIndent is added
-// (since we may still want leading indentation).
-func replaceLeadingIndentation(body, oldIndent, newIndent string) string {
-	// Handle indent at the beginning of the first line. After this, we handle
-	// indentation only after a newline.
-	var buf bytes.Buffer
-	if strings.HasPrefix(body, oldIndent) {
-		buf.WriteString(newIndent)
-		body = body[len(oldIndent):]
-	}
-
-	// Use a state machine to keep track of whether we're in a string or
-	// rune literal while we process the rest of the code.
-	const (
-		codeState = iota
-		runeState
-		interpretedStringState
-		rawStringState
-	)
-	searchChars := []string{
-		"'\"`\n", // codeState
-		`\'`,     // runeState
-		`\"`,     // interpretedStringState
-		"`\n",    // rawStringState
-		// newlineState does not need to search
-	}
-	state := codeState
-	for {
-		i := strings.IndexAny(body, searchChars[state])
-		if i < 0 {
-			buf.WriteString(body)
-			break
-		}
-		c := body[i]
-		buf.WriteString(body[:i+1])
-		body = body[i+1:]
-		switch state {
-		case codeState:
-			switch c {
-			case '\'':
-				state = runeState
-			case '"':
-				state = interpretedStringState
-			case '`':
-				state = rawStringState
-			case '\n':
-				if strings.HasPrefix(body, oldIndent) {
-					buf.WriteString(newIndent)
-					body = body[len(oldIndent):]
-				}
-			}
-
-		case runeState:
-			switch c {
-			case '\\':
-				r, size := utf8.DecodeRuneInString(body)
-				buf.WriteRune(r)
-				body = body[size:]
-			case '\'':
-				state = codeState
-			}
-
-		case interpretedStringState:
-			switch c {
-			case '\\':
-				r, size := utf8.DecodeRuneInString(body)
-				buf.WriteRune(r)
-				body = body[size:]
-			case '"':
-				state = codeState
-			}
-
-		case rawStringState:
-			switch c {
-			case '`':
-				state = codeState
-			case '\n':
-				buf.WriteString(newIndent)
-			}
-		}
-	}
-	return buf.String()
-}
-
-// writeNode writes the AST node x to w.
-//
-// The provided fset must be non-nil. The pageInfo is optional. If
-// present, the pageInfo is used to add comments to struct fields to
-// say which version of Go introduced them.
-func (p *Presentation) writeNode(w io.Writer, pageInfo *PageInfo, fset *token.FileSet, x interface{}) {
-	// convert trailing tabs into spaces using a tconv filter
-	// to ensure a good outcome in most browsers (there may still
-	// be tabs in comments and strings, but converting those into
-	// the right number of spaces is much harder)
-	//
-	// TODO(gri) rethink printer flags - perhaps tconv can be eliminated
-	//           with an another printer mode (which is more efficiently
-	//           implemented in the printer than here with another layer)
-
-	var pkgName, structName string
-	var apiInfo pkgAPIVersions
-	if gd, ok := x.(*ast.GenDecl); ok && pageInfo != nil && pageInfo.PDoc != nil &&
-		p.Corpus != nil &&
-		gd.Tok == token.TYPE && len(gd.Specs) != 0 {
-		pkgName = pageInfo.PDoc.ImportPath
-		if ts, ok := gd.Specs[0].(*ast.TypeSpec); ok {
-			if _, ok := ts.Type.(*ast.StructType); ok {
-				structName = ts.Name.Name
-			}
-		}
-		apiInfo = p.Corpus.pkgAPIInfo[pkgName]
-	}
-
-	var out = w
-	var buf bytes.Buffer
-	if structName != "" {
-		out = &buf
-	}
-
-	mode := printer.TabIndent | printer.UseSpaces
-	err := (&printer.Config{Mode: mode, Tabwidth: p.TabWidth}).Fprint(TabSpacer(out, p.TabWidth), fset, x)
-	if err != nil {
-		log.Print(err)
-	}
-
-	// Add comments to struct fields saying which Go version introduced them.
-	if structName != "" {
-		fieldSince := apiInfo.fieldSince[structName]
-		typeSince := apiInfo.typeSince[structName]
-		// Add/rewrite comments on struct fields to note which Go version added them.
-		var buf2 bytes.Buffer
-		buf2.Grow(buf.Len() + len(" // Added in Go 1.n")*10)
-		bs := bufio.NewScanner(&buf)
-		for bs.Scan() {
-			line := bs.Bytes()
-			field := firstIdent(line)
-			var since string
-			if field != "" {
-				since = fieldSince[field]
-				if since != "" && since == typeSince {
-					// Don't highlight field versions if they were the
-					// same as the struct itself.
-					since = ""
-				}
-			}
-			if since == "" {
-				buf2.Write(line)
-			} else {
-				if bytes.Contains(line, slashSlash) {
-					line = bytes.TrimRight(line, " \t.")
-					buf2.Write(line)
-					buf2.WriteString("; added in Go ")
-				} else {
-					buf2.Write(line)
-					buf2.WriteString(" // Go ")
-				}
-				buf2.WriteString(since)
-			}
-			buf2.WriteByte('\n')
-		}
-		w.Write(buf2.Bytes())
-	}
-}
-
-var slashSlash = []byte("//")
-
-// WriteNode writes x to w.
-// TODO(bgarcia) Is this method needed? It's just a wrapper for p.writeNode.
-func (p *Presentation) WriteNode(w io.Writer, fset *token.FileSet, x interface{}) {
-	p.writeNode(w, nil, fset, x)
-}
-
-// firstIdent returns the first identifier in x.
-// This actually parses "identifiers" that begin with numbers too, but we
-// never feed it such input, so it's fine.
-func firstIdent(x []byte) string {
-	x = bytes.TrimSpace(x)
-	i := bytes.IndexFunc(x, func(r rune) bool { return !unicode.IsLetter(r) && !unicode.IsNumber(r) })
-	if i == -1 {
-		return string(x)
-	}
-	return string(x[:i])
-}
