internal/godoc/{dochtml}: add GetSymbols

A GetSymbols function is added to packages godoc and dochtml, which
together return the symbols in the package API for a given documentation
source.

For golang/go#37102

Change-Id: Iab54a7f50101b87ed0289509c1d0d6e439f5d43c
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/289752
Trust: Julie Qiu <julie@golang.org>
Run-TryBot: Julie Qiu <julie@golang.org>
TryBot-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/internal/fetch/fetchdata_test.go b/internal/fetch/fetchdata_test.go
index 7ea6167..5efb9e0 100644
--- a/internal/fetch/fetchdata_test.go
+++ b/internal/fetch/fetchdata_test.go
@@ -57,6 +57,7 @@
 						GOOS:     internal.All,
 						GOARCH:   internal.All,
 						Synopsis: "package foo exports a helpful constant.",
+						API:      []*internal.Symbol{{Name: "OK", Synopsis: "const OK", Section: "Constants", Kind: "Constant"}},
 					}},
 					Imports: []string{"net/http"},
 				},
@@ -129,6 +130,7 @@
 						GOOS:     internal.All,
 						GOARCH:   internal.All,
 						Synopsis: "package bar",
+						API:      []*internal.Symbol{{Name: "Bar", Synopsis: "func Bar() string", Section: "Functions", Kind: "Function"}},
 					}},
 				},
 				{
@@ -140,6 +142,7 @@
 						GOOS:     internal.All,
 						GOARCH:   internal.All,
 						Synopsis: "package foo",
+						API:      []*internal.Symbol{{Name: "FooBar", Synopsis: "func FooBar() string", Section: "Functions", Kind: "Function"}},
 					}},
 					Imports: []string{"fmt", "github.com/my/module/bar"},
 				},
@@ -187,6 +190,14 @@
 						GOOS:     internal.All,
 						GOARCH:   internal.All,
 						Synopsis: "Package p is inside a module where a go.mod file hasn't been explicitly added yet.",
+						API: []*internal.Symbol{
+							{
+								Name:     "Year",
+								Synopsis: "const Year",
+								Section:  "Constants",
+								Kind:     "Constant",
+							},
+						},
 					}},
 				},
 			},
@@ -252,6 +263,7 @@
 						GOOS:     internal.All,
 						GOARCH:   internal.All,
 						Synopsis: "Package good is inside a module that has bad packages.",
+						API:      []*internal.Symbol{{Name: "Good", Synopsis: "const Good", Section: "Constants", Kind: "Constant"}},
 					}},
 				},
 			},
@@ -320,16 +332,40 @@
 							GOOS:     "linux",
 							GOARCH:   "amd64",
 							Synopsis: "Package cpu implements processor feature detection used by the Go standard library.",
+							API: []*internal.Symbol{
+								{
+									Name:     "CacheLinePadSize",
+									Synopsis: "const CacheLinePadSize",
+									Section:  "Constants",
+									Kind:     "Constant",
+								},
+							},
 						},
 						{
 							GOOS:     "windows",
 							GOARCH:   "amd64",
 							Synopsis: "Package cpu implements processor feature detection used by the Go standard library.",
+							API: []*internal.Symbol{
+								{
+									Name:     "CacheLinePadSize",
+									Synopsis: "const CacheLinePadSize",
+									Section:  "Constants",
+									Kind:     "Constant",
+								},
+							},
 						},
 						{
 							GOOS:     "darwin",
 							GOARCH:   "amd64",
 							Synopsis: "Package cpu implements processor feature detection used by the Go standard library.",
+							API: []*internal.Symbol{
+								{
+									Name:     "CacheLinePadSize",
+									Synopsis: "const CacheLinePadSize",
+									Section:  "Constants",
+									Kind:     "Constant",
+								},
+							},
 						},
 						{
 							GOOS:     "js",
@@ -429,6 +465,7 @@
 						GOOS:     internal.All,
 						GOARCH:   internal.All,
 						Synopsis: "package bar",
+						API:      []*internal.Symbol{{Name: "Bar", Synopsis: "func Bar() string", Section: "Functions", Kind: "Function"}},
 					}},
 				},
 				{
@@ -440,6 +477,7 @@
 						GOOS:     internal.All,
 						GOARCH:   internal.All,
 						Synopsis: "package baz",
+						API:      []*internal.Symbol{{Name: "Baz", Synopsis: "func Baz() string", Section: "Functions", Kind: "Function"}},
 					}},
 				},
 				{
@@ -455,6 +493,7 @@
 						GOOS:     internal.All,
 						GOARCH:   internal.All,
 						Synopsis: "package foo",
+						API:      []*internal.Symbol{{Name: "FooBar", Synopsis: "func FooBar() string", Section: "Functions", Kind: "Function"}},
 					}},
 					Imports: []string{"fmt", "github.com/my/module/bar"},
 				},
@@ -663,6 +702,7 @@
 						Synopsis: "Package js only works with wasm.",
 						GOOS:     "js",
 						GOARCH:   "wasm",
+						API:      []*internal.Symbol{{Name: "Value", Synopsis: "type Value int", Section: "Types", Kind: "Type"}},
 					}},
 				},
 			},
@@ -716,6 +756,281 @@
 						GOOS:     internal.All,
 						GOARCH:   internal.All,
 						Synopsis: "Package builtin provides documentation for Go's predeclared identifiers.",
+						API: []*internal.Symbol{
+							{
+								Name:     "true",
+								Synopsis: "const true",
+								Section:  "Constants",
+								Kind:     "Constant",
+							},
+							{
+								Name:     "false",
+								Synopsis: "const false",
+								Section:  "Constants",
+								Kind:     "Constant",
+							},
+							{
+								Name:     "iota",
+								Synopsis: "const iota",
+								Section:  "Constants",
+								Kind:     "Constant",
+							},
+							{
+								Name:     "nil",
+								Synopsis: "var nil",
+								Section:  "Variables",
+								Kind:     "Variable",
+							},
+							{
+								Name:     "append",
+								Synopsis: "func append(slice []Type, elems ...Type) []Type",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "cap",
+								Synopsis: "func cap(v Type) int",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "close",
+								Synopsis: "func close(c chan<- Type)",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "complex",
+								Synopsis: "func complex(r, i FloatType) ComplexType",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "copy",
+								Synopsis: "func copy(dst, src []Type) int",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "delete",
+								Synopsis: "func delete(m map[Type]Type1, key Type)",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "imag",
+								Synopsis: "func imag(c ComplexType) FloatType",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "len",
+								Synopsis: "func len(v Type) int",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "make",
+								Synopsis: "func make(t Type, size ...IntegerType) Type",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "new",
+								Synopsis: "func new(Type) *Type",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "panic",
+								Synopsis: "func panic(v interface{})",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "print",
+								Synopsis: "func print(args ...Type)",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "println",
+								Synopsis: "func println(args ...Type)",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "real",
+								Synopsis: "func real(c ComplexType) FloatType",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "recover",
+								Synopsis: "func recover() interface{}",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "ComplexType",
+								Synopsis: "type ComplexType complex64",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "FloatType",
+								Synopsis: "type FloatType float32",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "IntegerType",
+								Synopsis: "type IntegerType int",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "Type",
+								Synopsis: "type Type int",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "Type1",
+								Synopsis: "type Type1 int",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "bool",
+								Synopsis: "type bool bool",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "byte",
+								Synopsis: "type byte = uint8",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "complex128",
+								Synopsis: "type complex128 complex128",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "complex64",
+								Synopsis: "type complex64 complex64",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "error",
+								Synopsis: "type error interface{ ... }",
+								Section:  "Types",
+								Kind:     "Type",
+								Children: []*internal.Symbol{
+									{
+										Name:       "error.Error",
+										Synopsis:   "Error",
+										Section:    "Types",
+										Kind:       "Method",
+										ParentName: "error",
+									},
+								},
+							},
+							{
+								Name:     "float32",
+								Synopsis: "type float32 float32",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "float64",
+								Synopsis: "type float64 float64",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "int",
+								Synopsis: "type int int",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "int16",
+								Synopsis: "type int16 int16",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "int32",
+								Synopsis: "type int32 int32",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "int64",
+								Synopsis: "type int64 int64",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "int8",
+								Synopsis: "type int8 int8",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "rune",
+								Synopsis: "type rune = int32",
+								Section:  "Types",
+								Kind:     "Type"},
+
+							{
+								Name:     "string",
+								Synopsis: "type string string",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "uint",
+								Synopsis: "type uint uint",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "uint16",
+								Synopsis: "type uint16 uint16",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "uint32",
+								Synopsis: "type uint32 uint32",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "uint64",
+								Synopsis: "type uint64 uint64",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "uint8",
+								Synopsis: "type uint8 uint8",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "uintptr",
+								Synopsis: "type uintptr uintptr",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+						},
 					}},
 				},
 				{
@@ -786,6 +1101,101 @@
 						GOOS:     internal.All,
 						GOARCH:   internal.All,
 						Synopsis: "Package context defines the Context type, which carries deadlines, cancelation signals, and other request-scoped values across API boundaries and between processes.",
+						API: []*internal.Symbol{
+							{
+								Name:     "Canceled",
+								Synopsis: "var Canceled",
+								Section:  "Variables",
+								Kind:     "Variable",
+							},
+							{
+								Name:     "DeadlineExceeded",
+								Synopsis: "var DeadlineExceeded",
+								Section:  "Variables",
+								Kind:     "Variable",
+							},
+							{
+								Name:     "WithCancel",
+								Synopsis: "func WithCancel(parent Context) (ctx Context, cancel CancelFunc)",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "WithDeadline",
+								Synopsis: "func WithDeadline(parent Context, d time.Time) (Context, CancelFunc)",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "WithTimeout",
+								Synopsis: "func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc)",
+								Section:  "Functions",
+								Kind:     "Function",
+							},
+							{
+								Name:     "CancelFunc",
+								Synopsis: "type CancelFunc func()",
+								Section:  "Types",
+								Kind:     "Type",
+							},
+							{
+								Name:     "Context",
+								Synopsis: "type Context interface{ ... }",
+								Section:  "Types",
+								Kind:     "Type",
+								Children: []*internal.Symbol{
+									{
+										Name:       "Background",
+										Synopsis:   "func Background() Context",
+										Section:    "Types",
+										Kind:       "Function",
+										ParentName: "Context",
+									},
+									{
+										Name:       "TODO",
+										Synopsis:   "func TODO() Context",
+										Section:    "Types",
+										Kind:       "Function",
+										ParentName: "Context",
+									},
+									{
+										Name:       "WithValue",
+										Synopsis:   "func WithValue(parent Context, key, val interface{}) Context",
+										Section:    "Types",
+										Kind:       "Function",
+										ParentName: "Context",
+									},
+									{
+										Name:       "Context.Deadline",
+										Synopsis:   "Deadline",
+										Section:    "Types",
+										Kind:       "Method",
+										ParentName: "Context",
+									},
+									{
+										Name:       "Context.Done",
+										Synopsis:   "Done",
+										Section:    "Types",
+										Kind:       "Method",
+										ParentName: "Context",
+									},
+									{
+										Name:       "Context.Err",
+										Synopsis:   "Err",
+										Section:    "Types",
+										Kind:       "Method",
+										ParentName: "Context",
+									},
+									{
+										Name:       "Context.Value",
+										Synopsis:   "Value",
+										Section:    "Types",
+										Kind:       "Method",
+										ParentName: "Context",
+									},
+								},
+							},
+						},
 					}},
 					Imports: []string{"errors", "fmt", "reflect", "sync", "time"},
 				},
@@ -799,11 +1209,484 @@
 						Name: "json",
 						Path: "encoding/json",
 					},
-					Documentation: []*internal.Documentation{{
-						GOOS:     internal.All,
-						GOARCH:   internal.All,
-						Synopsis: "Package json implements encoding and decoding of JSON as defined in RFC 7159.",
-					}},
+					Documentation: []*internal.Documentation{
+						{
+							GOOS:     internal.All,
+							GOARCH:   internal.All,
+							Synopsis: "Package json implements encoding and decoding of JSON as defined in RFC 7159.",
+							API: []*internal.Symbol{
+								{
+									Name:     "Compact",
+									Synopsis: "func Compact(dst *bytes.Buffer, src []byte) error",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "HTMLEscape",
+									Synopsis: "func HTMLEscape(dst *bytes.Buffer, src []byte)",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Indent",
+									Synopsis: "func Indent(dst *bytes.Buffer, src []byte, prefix, indent string) error",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Marshal",
+									Synopsis: "func Marshal(v interface{}) ([]byte, error)",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "MarshalIndent",
+									Synopsis: "func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error)",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Unmarshal",
+									Synopsis: "func Unmarshal(data []byte, v interface{}) error",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Valid",
+									Synopsis: "func Valid(data []byte) bool",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Decoder",
+									Synopsis: "type Decoder struct{}",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "NewDecoder",
+											Synopsis:   "func NewDecoder(r io.Reader) *Decoder",
+											Section:    "Types",
+											Kind:       "Function",
+											ParentName: "Decoder",
+										},
+										{
+											Name:       "Decoder.Buffered",
+											Synopsis:   "func (dec *Decoder) Buffered() io.Reader",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Decoder",
+										},
+										{
+											Name:       "Decoder.Decode",
+											Synopsis:   "func (dec *Decoder) Decode(v interface{}) error",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Decoder",
+										},
+										{
+											Name:       "Decoder.DisallowUnknownFields",
+											Synopsis:   "func (dec *Decoder) DisallowUnknownFields()",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Decoder",
+										},
+										{
+											Name:       "Decoder.More",
+											Synopsis:   "func (dec *Decoder) More() bool",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Decoder",
+										},
+										{
+											Name:       "Decoder.Token",
+											Synopsis:   "func (dec *Decoder) Token() (Token, error)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Decoder",
+										},
+										{
+											Name:       "Decoder.UseNumber",
+											Synopsis:   "func (dec *Decoder) UseNumber()",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Decoder",
+										},
+									},
+								},
+								{
+									Name:     "Delim",
+									Synopsis: "type Delim rune",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "Delim.String",
+											Synopsis:   "func (d Delim) String() string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Delim",
+										},
+									},
+								},
+								{
+									Name:     "Encoder",
+									Synopsis: "type Encoder struct{}",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "NewEncoder",
+											Synopsis:   "func NewEncoder(w io.Writer) *Encoder",
+											Section:    "Types",
+											Kind:       "Function",
+											ParentName: "Encoder",
+										},
+										{
+											Name:       "Encoder.Encode",
+											Synopsis:   "func (enc *Encoder) Encode(v interface{}) error",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Encoder",
+										},
+										{
+											Name:       "Encoder.SetEscapeHTML",
+											Synopsis:   "func (enc *Encoder) SetEscapeHTML(on bool)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Encoder",
+										},
+										{
+											Name:       "Encoder.SetIndent",
+											Synopsis:   "func (enc *Encoder) SetIndent(prefix, indent string)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Encoder",
+										},
+									},
+								},
+								{
+									Name:     "InvalidUTF8Error",
+									Synopsis: "type InvalidUTF8Error struct{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "InvalidUTF8Error.S",
+											Synopsis:   "S",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "InvalidUTF8Error",
+										},
+										{
+											Name:       "InvalidUTF8Error.Error",
+											Synopsis:   "func (e *InvalidUTF8Error) Error() string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "InvalidUTF8Error",
+										},
+									},
+								},
+								{
+									Name:     "InvalidUnmarshalError",
+									Synopsis: "type InvalidUnmarshalError struct{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "InvalidUnmarshalError.Type",
+											Synopsis:   "Type",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "InvalidUnmarshalError",
+										},
+										{
+											Name:       "InvalidUnmarshalError.Error",
+											Synopsis:   "func (e *InvalidUnmarshalError) Error() string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "InvalidUnmarshalError",
+										},
+									},
+								},
+								{
+									Name:     "Marshaler",
+									Synopsis: "type Marshaler interface{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "Marshaler.MarshalJSON",
+											Synopsis:   "MarshalJSON",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Marshaler",
+										},
+									},
+								},
+								{
+									Name:     "MarshalerError",
+									Synopsis: "type MarshalerError struct{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "MarshalerError.Type",
+											Synopsis:   "Type",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "MarshalerError",
+										},
+										{
+											Name:       "MarshalerError.Err",
+											Synopsis:   "Err",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "MarshalerError",
+										},
+										{
+											Name:       "MarshalerError.Error",
+											Synopsis:   "func (e *MarshalerError) Error() string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "MarshalerError",
+										},
+									},
+								},
+								{
+									Name:     "Number",
+									Synopsis: "type Number string",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "Number.Float64",
+											Synopsis:   "func (n Number) Float64() (float64, error)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Number",
+										},
+										{
+											Name:       "Number.Int64",
+											Synopsis:   "func (n Number) Int64() (int64, error)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Number",
+										},
+										{
+											Name:       "Number.String",
+											Synopsis:   "func (n Number) String() string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Number",
+										},
+									},
+								},
+								{
+									Name:     "RawMessage",
+									Synopsis: "type RawMessage []byte",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "RawMessage.MarshalJSON",
+											Synopsis:   "func (m RawMessage) MarshalJSON() ([]byte, error)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "RawMessage",
+										},
+										{
+											Name:       "RawMessage.UnmarshalJSON",
+											Synopsis:   "func (m *RawMessage) UnmarshalJSON(data []byte) error",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "RawMessage",
+										},
+									},
+								},
+								{
+									Name:     "SyntaxError",
+									Synopsis: "type SyntaxError struct{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "SyntaxError.Offset",
+											Synopsis:   "Offset",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "SyntaxError",
+										},
+										{
+											Name:       "SyntaxError.Error",
+											Synopsis:   "func (e *SyntaxError) Error() string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "SyntaxError",
+										},
+									},
+								},
+								{
+									Name:     "Token",
+									Synopsis: "type Token interface{}",
+									Section:  "Types",
+									Kind:     "Type",
+								},
+								{
+									Name:     "UnmarshalFieldError",
+									Synopsis: "type UnmarshalFieldError struct{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "UnmarshalFieldError.Key",
+											Synopsis:   "Key",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "UnmarshalFieldError",
+										},
+										{
+											Name:       "UnmarshalFieldError.Type",
+											Synopsis:   "Type",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "UnmarshalFieldError",
+										},
+										{
+											Name:       "UnmarshalFieldError.Field",
+											Synopsis:   "Field",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "UnmarshalFieldError",
+										},
+										{
+											Name:       "UnmarshalFieldError.Error",
+											Synopsis:   "func (e *UnmarshalFieldError) Error() string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "UnmarshalFieldError",
+										},
+									},
+								},
+								{
+									Name:     "UnmarshalTypeError",
+									Synopsis: "type UnmarshalTypeError struct{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "UnmarshalTypeError.Value",
+											Synopsis:   "Value",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "UnmarshalTypeError",
+										},
+										{
+											Name:       "UnmarshalTypeError.Type",
+											Synopsis:   "Type",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "UnmarshalTypeError",
+										},
+										{
+											Name:       "UnmarshalTypeError.Offset",
+											Synopsis:   "Offset",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "UnmarshalTypeError",
+										},
+										{
+											Name:       "UnmarshalTypeError.Struct",
+											Synopsis:   "Struct",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "UnmarshalTypeError",
+										},
+										{
+											Name:       "UnmarshalTypeError.Field",
+											Synopsis:   "Field",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "UnmarshalTypeError",
+										},
+										{
+											Name:       "UnmarshalTypeError.Error",
+											Synopsis:   "func (e *UnmarshalTypeError) Error() string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "UnmarshalTypeError",
+										},
+									},
+								},
+								{
+									Name:     "Unmarshaler",
+									Synopsis: "type Unmarshaler interface{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "Unmarshaler.UnmarshalJSON",
+											Synopsis:   "UnmarshalJSON",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "Unmarshaler",
+										},
+									},
+								},
+								{
+									Name:     "UnsupportedTypeError",
+									Synopsis: "type UnsupportedTypeError struct{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "UnsupportedTypeError.Type",
+											Synopsis:   "Type",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "UnsupportedTypeError",
+										},
+										{
+											Name:       "UnsupportedTypeError.Error",
+											Synopsis:   "func (e *UnsupportedTypeError) Error() string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "UnsupportedTypeError",
+										},
+									},
+								},
+								{
+									Name:     "UnsupportedValueError",
+									Synopsis: "type UnsupportedValueError struct{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "UnsupportedValueError.Value",
+											Synopsis:   "Value",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "UnsupportedValueError",
+										},
+										{
+											Name:       "UnsupportedValueError.Str",
+											Synopsis:   "Str",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "UnsupportedValueError",
+										},
+										{
+											Name:       "UnsupportedValueError.Error",
+											Synopsis:   "func (e *UnsupportedValueError) Error() string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "UnsupportedValueError",
+										},
+									},
+								},
+							},
+						},
+					},
 					Imports: []string{
 						"bytes",
 						"encoding",
@@ -831,6 +1714,7 @@
 						GOOS:     internal.All,
 						GOARCH:   internal.All,
 						Synopsis: "Package errors implements functions to manipulate errors.",
+						API:      []*internal.Symbol{{Name: "New", Synopsis: "func New(text string) error", Section: "Functions", Kind: "Function"}},
 					}},
 				},
 				{
@@ -839,11 +1723,549 @@
 						Path: "flag",
 					},
 					Imports: []string{"errors", "fmt", "io", "os", "reflect", "sort", "strconv", "strings", "time"},
-					Documentation: []*internal.Documentation{{
-						GOOS:     internal.All,
-						GOARCH:   internal.All,
-						Synopsis: "Package flag implements command-line flag parsing.",
-					}},
+					Documentation: []*internal.Documentation{
+						{
+							GOOS:     internal.All,
+							GOARCH:   internal.All,
+							Synopsis: "Package flag implements command-line flag parsing.",
+							API: []*internal.Symbol{
+								{
+									Name:     "CommandLine",
+									Synopsis: "var CommandLine",
+									Section:  "Variables",
+									Kind:     "Variable",
+								},
+								{
+									Name:     "ErrHelp",
+									Synopsis: "var ErrHelp",
+									Section:  "Variables",
+									Kind:     "Variable",
+								},
+								{
+									Name:     "Usage",
+									Synopsis: "var Usage",
+									Section:  "Variables",
+									Kind:     "Variable",
+								},
+								{
+									Name:     "Arg",
+									Synopsis: "func Arg(i int) string",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Args",
+									Synopsis: "func Args() []string",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Bool",
+									Synopsis: "func Bool(name string, value bool, usage string) *bool",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "BoolVar",
+									Synopsis: "func BoolVar(p *bool, name string, value bool, usage string)",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Duration",
+									Synopsis: "func Duration(name string, value time.Duration, usage string) *time.Duration",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "DurationVar",
+									Synopsis: "func DurationVar(p *time.Duration, name string, value time.Duration, usage string)",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Float64",
+									Synopsis: "func Float64(name string, value float64, usage string) *float64",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Float64Var",
+									Synopsis: "func Float64Var(p *float64, name string, value float64, usage string)",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Int",
+									Synopsis: "func Int(name string, value int, usage string) *int",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Int64",
+									Synopsis: "func Int64(name string, value int64, usage string) *int64",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Int64Var",
+									Synopsis: "func Int64Var(p *int64, name string, value int64, usage string)",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "IntVar",
+									Synopsis: "func IntVar(p *int, name string, value int, usage string)",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "NArg",
+									Synopsis: "func NArg() int",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "NFlag",
+									Synopsis: "func NFlag() int",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Parse",
+									Synopsis: "func Parse()",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Parsed",
+									Synopsis: "func Parsed() bool",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "PrintDefaults",
+									Synopsis: "func PrintDefaults()",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Set",
+									Synopsis: "func Set(name, value string) error",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "String",
+									Synopsis: "func String(name string, value string, usage string) *string",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "StringVar",
+									Synopsis: "func StringVar(p *string, name string, value string, usage string)",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Uint",
+									Synopsis: "func Uint(name string, value uint, usage string) *uint",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Uint64",
+									Synopsis: "func Uint64(name string, value uint64, usage string) *uint64",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Uint64Var",
+									Synopsis: "func Uint64Var(p *uint64, name string, value uint64, usage string)",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "UintVar",
+									Synopsis: "func UintVar(p *uint, name string, value uint, usage string)",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "UnquoteUsage",
+									Synopsis: "func UnquoteUsage(flag *Flag) (name string, usage string)",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Var",
+									Synopsis: "func Var(value Value, name string, usage string)",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "Visit",
+									Synopsis: "func Visit(fn func(*Flag))",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "VisitAll",
+									Synopsis: "func VisitAll(fn func(*Flag))",
+									Section:  "Functions",
+									Kind:     "Function",
+								},
+								{
+									Name:     "ErrorHandling",
+									Synopsis: "type ErrorHandling int",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "ContinueOnError",
+											Synopsis:   "const ContinueOnError",
+											Section:    "Types",
+											Kind:       "Constant",
+											ParentName: "ErrorHandling",
+										},
+										{
+											Name:       "ExitOnError",
+											Synopsis:   "const ExitOnError",
+											Section:    "Types",
+											Kind:       "Constant",
+											ParentName: "ErrorHandling",
+										},
+										{
+											Name:       "PanicOnError",
+											Synopsis:   "const PanicOnError",
+											Section:    "Types",
+											Kind:       "Constant",
+											ParentName: "ErrorHandling",
+										},
+									},
+								},
+								{
+									Name:     "Flag",
+									Synopsis: "type Flag struct{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "Lookup",
+											Synopsis:   "func Lookup(name string) *Flag",
+											Section:    "Types",
+											Kind:       "Function",
+											ParentName: "Flag",
+										},
+										{
+											Name:       "Flag.Name",
+											Synopsis:   "Name",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "Flag",
+										},
+										{
+											Name:       "Flag.Usage",
+											Synopsis:   "Usage",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "Flag",
+										},
+										{
+											Name:       "Flag.Value",
+											Synopsis:   "Value",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "Flag",
+										},
+										{
+											Name:       "Flag.DefValue",
+											Synopsis:   "DefValue",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "Flag",
+										},
+									},
+								},
+								{
+									Name:     "FlagSet",
+									Synopsis: "type FlagSet struct{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{
+											Name:       "NewFlagSet",
+											Synopsis:   "func NewFlagSet(name string, errorHandling ErrorHandling) *FlagSet",
+											Section:    "Types",
+											Kind:       "Function",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Usage",
+											Synopsis:   "Usage",
+											Section:    "Types",
+											Kind:       "Field",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Arg",
+											Synopsis:   "func (f *FlagSet) Arg(i int) string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Args",
+											Synopsis:   "func (f *FlagSet) Args() []string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Bool",
+											Synopsis:   "func (f *FlagSet) Bool(name string, value bool, usage string) *bool",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.BoolVar",
+											Synopsis:   "func (f *FlagSet) BoolVar(p *bool, name string, value bool, usage string)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Duration",
+											Synopsis:   "func (f *FlagSet) Duration(name string, value time.Duration, usage string) *time.Duration",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.DurationVar",
+											Synopsis:   "func (f *FlagSet) DurationVar(p *time.Duration, name string, value time.Duration, usage string)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.ErrorHandling",
+											Synopsis:   "func (f *FlagSet) ErrorHandling() ErrorHandling",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Float64",
+											Synopsis:   "func (f *FlagSet) Float64(name string, value float64, usage string) *float64",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Float64Var",
+											Synopsis:   "func (f *FlagSet) Float64Var(p *float64, name string, value float64, usage string)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Init",
+											Synopsis:   "func (f *FlagSet) Init(name string, errorHandling ErrorHandling)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Int",
+											Synopsis:   "func (f *FlagSet) Int(name string, value int, usage string) *int",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Int64",
+											Synopsis:   "func (f *FlagSet) Int64(name string, value int64, usage string) *int64",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Int64Var",
+											Synopsis:   "func (f *FlagSet) Int64Var(p *int64, name string, value int64, usage string)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.IntVar",
+											Synopsis:   "func (f *FlagSet) IntVar(p *int, name string, value int, usage string)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Lookup",
+											Synopsis:   "func (f *FlagSet) Lookup(name string) *Flag",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.NArg",
+											Synopsis:   "func (f *FlagSet) NArg() int",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.NFlag",
+											Synopsis:   "func (f *FlagSet) NFlag() int",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Name",
+											Synopsis:   "func (f *FlagSet) Name() string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Output",
+											Synopsis:   "func (f *FlagSet) Output() io.Writer",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Parse",
+											Synopsis:   "func (f *FlagSet) Parse(arguments []string) error",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Parsed",
+											Synopsis:   "func (f *FlagSet) Parsed() bool",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.PrintDefaults",
+											Synopsis:   "func (f *FlagSet) PrintDefaults()",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Set",
+											Synopsis:   "func (f *FlagSet) Set(name, value string) error",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.SetOutput",
+											Synopsis:   "func (f *FlagSet) SetOutput(output io.Writer)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.String",
+											Synopsis:   "func (f *FlagSet) String(name string, value string, usage string) *string",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.StringVar",
+											Synopsis:   "func (f *FlagSet) StringVar(p *string, name string, value string, usage string)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Uint",
+											Synopsis:   "func (f *FlagSet) Uint(name string, value uint, usage string) *uint",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Uint64",
+											Synopsis:   "func (f *FlagSet) Uint64(name string, value uint64, usage string) *uint64",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Uint64Var",
+											Synopsis:   "func (f *FlagSet) Uint64Var(p *uint64, name string, value uint64, usage string)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.UintVar",
+											Synopsis:   "func (f *FlagSet) UintVar(p *uint, name string, value uint, usage string)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Var",
+											Synopsis:   "func (f *FlagSet) Var(value Value, name string, usage string)",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.Visit",
+											Synopsis:   "func (f *FlagSet) Visit(fn func(*Flag))",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+										{
+											Name:       "FlagSet.VisitAll",
+											Synopsis:   "func (f *FlagSet) VisitAll(fn func(*Flag))",
+											Section:    "Types",
+											Kind:       "Method",
+											ParentName: "FlagSet",
+										},
+									},
+								},
+								{
+									Name:     "Getter",
+									Synopsis: "type Getter interface{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{{
+										Name:       "Getter.Get",
+										Synopsis:   "Get",
+										Section:    "Types",
+										Kind:       "Method",
+										ParentName: "Getter",
+									}},
+								},
+								{
+									Name:     "Value",
+									Synopsis: "type Value interface{ ... }",
+									Section:  "Types",
+									Kind:     "Type",
+									Children: []*internal.Symbol{
+										{Name: "Value.String", Synopsis: "String", Section: "Types", Kind: "Method", ParentName: "Value"},
+										{Name: "Value.Set", Synopsis: "Set", Section: "Types", Kind: "Method", ParentName: "Value"},
+									},
+								},
+							},
+						},
+					},
 				},
 			},
 		},
@@ -881,6 +2303,7 @@
 						GOOS:     internal.All,
 						GOARCH:   internal.All,
 						Synopsis: "package foo exports a helpful constant.",
+						API:      []*internal.Symbol{{Name: "Bar", Synopsis: "const Bar", Section: "Constants", Kind: "Constant"}},
 					}},
 				},
 			},
@@ -919,6 +2342,7 @@
 						GOOS:     internal.All,
 						GOARCH:   internal.All,
 						Synopsis: "package foo exports a helpful constant.",
+						API:      []*internal.Symbol{{Name: "Bar", Synopsis: "const Bar", Section: "Constants", Kind: "Constant"}},
 					}},
 				},
 			},
@@ -933,7 +2357,7 @@
 // The fetch result's documentation HTML is treated as a set
 // of substrings that should appear in the generated documentation.
 // The substrings are separated by a '~' character.
-func moduleWithExamples(path, source, test string, docSubstrings ...string) *testModule {
+func moduleWithExamples(path string, api []*internal.Symbol, source, test string, docSubstrings ...string) *testModule {
 	return &testModule{
 		mod: &proxy.Module{
 			ModulePath: path,
@@ -970,6 +2394,7 @@
 							GOOS:     internal.All,
 							GOARCH:   internal.All,
 							Synopsis: "Package example contains examples.",
+							API:      api,
 						}},
 					},
 				},
@@ -982,6 +2407,7 @@
 }
 
 var modulePackageExample = moduleWithExamples("package.example",
+	nil,
 	``,
 	`import "fmt"
 
@@ -993,6 +2419,14 @@
 `, "Documentation-exampleButtonsContainer")
 
 var moduleFuncExample = moduleWithExamples("func.example",
+	[]*internal.Symbol{
+		{
+			Name:     "F",
+			Synopsis: "func F()",
+			Section:  "Functions",
+			Kind:     "Function",
+		},
+	},
 	`func F() {}
 `, `import "func.example/example"
 
@@ -1003,6 +2437,7 @@
 `, "Documentation-exampleButtonsContainer")
 
 var moduleTypeExample = moduleWithExamples("type.example",
+	[]*internal.Symbol{{Name: "T", Synopsis: "type T struct{}", Section: "Types", Kind: "Type"}},
 	`type T struct{}
 `, `import "type.example/example"
 
@@ -1013,6 +2448,23 @@
 `, "Documentation-exampleButtonsContainer")
 
 var moduleMethodExample = moduleWithExamples("method.example",
+	[]*internal.Symbol{
+		{
+			Name:     "T",
+			Synopsis: "type T struct{}",
+			Section:  "Types",
+			Kind:     "Type",
+			Children: []*internal.Symbol{
+				{
+					Name:       "T.M",
+					Synopsis:   "func (*T) M()",
+					Section:    "Types",
+					Kind:       "Method",
+					ParentName: "T",
+				},
+			},
+		},
+	},
 	`type T struct {}
 
 func (*T) M() {}
diff --git a/internal/fetch/load.go b/internal/fetch/load.go
index e2999aa..9ed68e1 100644
--- a/internal/fetch/load.go
+++ b/internal/fetch/load.go
@@ -53,7 +53,8 @@
 //
 // If a package is fine except that its documentation is too large, loadPackage
 // returns a goPackage whose err field is a non-nil error with godoc.ErrTooLarge in its chain.
-func loadPackage(ctx context.Context, zipGoFiles []*zip.File, innerPath string, sourceInfo *source.Info, modInfo *godoc.ModuleInfo) (_ *goPackage, err error) {
+func loadPackage(ctx context.Context, zipGoFiles []*zip.File, innerPath string,
+	sourceInfo *source.Info, modInfo *godoc.ModuleInfo) (_ *goPackage, err error) {
 	defer derrors.Wrap(&err, "loadPackage(ctx, zipGoFiles, %q, sourceInfo, modInfo)", innerPath)
 	ctx, span := trace.StartSpan(ctx, "fetch.loadPackage")
 	defer span.End()
@@ -97,7 +98,7 @@
 			pkg.docs = append(pkg.docs, &doc2)
 			continue
 		}
-		name, imports, synopsis, source, err := loadPackageForBuildContext(ctx, mfiles, innerPath, sourceInfo, modInfo)
+		name, imports, synopsis, source, api, err := loadPackageForBuildContext(ctx, mfiles, innerPath, sourceInfo, modInfo)
 		switch {
 		case errors.Is(err, derrors.NotFound):
 			// No package for this build context.
@@ -117,6 +118,7 @@
 					GOARCH:   internal.All,
 					Synopsis: synopsis,
 					Source:   source,
+					API:      api,
 				}},
 			}, nil
 		case err != nil:
@@ -145,6 +147,7 @@
 				GOARCH:   bc.GOARCH,
 				Synopsis: synopsis,
 				Source:   source,
+				API:      api,
 			}
 			docsByFiles[filesKey] = doc
 			pkg.docs = append(pkg.docs, doc)
@@ -194,13 +197,14 @@
 //
 // If it returns an error with ErrTooLarge in its chain, the other return values
 // are still valid.
-func loadPackageForBuildContext(ctx context.Context, files map[string][]byte, innerPath string, sourceInfo *source.Info, modInfo *godoc.ModuleInfo) (name string, imports []string, synopsis string, source []byte, err error) {
+func loadPackageForBuildContext(ctx context.Context, files map[string][]byte, innerPath string, sourceInfo *source.Info, modInfo *godoc.ModuleInfo) (
+	name string, imports []string, synopsis string, source []byte, api []*internal.Symbol, err error) {
 	modulePath := modInfo.ModulePath
 	defer derrors.Wrap(&err, "loadPackageWithBuildContext(files, %q, %q, %+v)", innerPath, modulePath, sourceInfo)
 
 	packageName, goFiles, fset, err := loadFilesWithBuildContext(innerPath, files)
 	if err != nil {
-		return "", nil, "", nil, err
+		return "", nil, "", nil, nil, err
 	}
 	docPkg := godoc.NewPackage(fset, modInfo.ModulePackages)
 	for _, pf := range goFiles {
@@ -216,14 +220,14 @@
 	// Encode first, because Render messes with the AST.
 	src, err := docPkg.Encode(ctx)
 	if err != nil {
-		return "", nil, "", nil, err
+		return "", nil, "", nil, nil, err
 	}
 
-	synopsis, imports, _, err = docPkg.Render(ctx, innerPath, sourceInfo, modInfo)
+	synopsis, imports, _, api, err = docPkg.Render(ctx, innerPath, sourceInfo, modInfo)
 	if err != nil && !errors.Is(err, godoc.ErrTooLarge) {
-		return "", nil, "", nil, err
+		return "", nil, "", nil, nil, err
 	}
-	return packageName, imports, synopsis, src, err
+	return packageName, imports, synopsis, src, api, err
 }
 
 // loadFilesWithBuildContext loads all the given Go files at innerPath. It
diff --git a/internal/godoc/dochtml/dochtml_test.go b/internal/godoc/dochtml/dochtml_test.go
index fa59dcc..49330cc 100644
--- a/internal/godoc/dochtml/dochtml_test.go
+++ b/internal/godoc/dochtml/dochtml_test.go
@@ -30,7 +30,7 @@
 	in           = htmlcheck.In
 	hasAttr      = htmlcheck.HasAttr
 	hasHref      = htmlcheck.HasHref
-	hasText 		 = htmlcheck.HasText
+	hasText      = htmlcheck.HasText
 	hasExactText = htmlcheck.HasExactText
 )
 
@@ -472,6 +472,8 @@
 		{"I1.M1", "method"},
 		{"I2", "type"},
 		{"I2.M2", "method"},
+		{"A", "type"},
+		{"B", "type"},
 	}
 
 	var got []attrs
diff --git a/internal/godoc/dochtml/symbol.go b/internal/godoc/dochtml/symbol.go
new file mode 100644
index 0000000..11336d8
--- /dev/null
+++ b/internal/godoc/dochtml/symbol.go
@@ -0,0 +1,209 @@
+// Copyright 2021 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 dochtml
+
+import (
+	"fmt"
+	"go/ast"
+	"go/token"
+
+	"golang.org/x/pkgsite/internal"
+	"golang.org/x/pkgsite/internal/derrors"
+	"golang.org/x/pkgsite/internal/godoc/dochtml/internal/render"
+	"golang.org/x/pkgsite/internal/godoc/internal/doc"
+)
+
+// GetSymbols renders package documentation HTML for the
+// provided file set and package, in separate parts.
+//
+// If any of the rendered documentation part HTML sizes exceeds the specified
+// limit, an error with ErrTooLarge in its chain will be returned.
+func GetSymbols(p *doc.Package, fset *token.FileSet) (_ []*internal.Symbol, err error) {
+	defer derrors.Wrap(&err, "GetSymbols for %q", p.ImportPath)
+	if docIsEmpty(p) {
+		return nil, nil
+	}
+	typs, err := types(p, fset)
+	if err != nil {
+		return nil, err
+	}
+	return append(append(append(
+		constants(p), variables(p)...), functions(p, fset)...), typs...), nil
+}
+
+func constants(p *doc.Package) []*internal.Symbol {
+	var syms []*internal.Symbol
+	for _, c := range p.Consts {
+		for _, n := range c.Names {
+			syms = append(syms, &internal.Symbol{
+				Name:     n,
+				Synopsis: "const " + n,
+				Section:  internal.SymbolSectionConstants,
+				Kind:     internal.SymbolKindConstant,
+			})
+		}
+	}
+	return syms
+}
+
+func variables(p *doc.Package) []*internal.Symbol {
+	var syms []*internal.Symbol
+	for _, v := range p.Vars {
+		for _, n := range v.Names {
+			syms = append(syms, &internal.Symbol{
+				Name:     n,
+				Synopsis: "var " + n,
+				Section:  internal.SymbolSectionVariables,
+				Kind:     internal.SymbolKindVariable,
+			})
+		}
+	}
+	return syms
+}
+
+func functions(p *doc.Package, fset *token.FileSet) []*internal.Symbol {
+	var syms []*internal.Symbol
+	for _, f := range p.Funcs {
+		syms = append(syms, &internal.Symbol{
+			Name:     f.Name,
+			Synopsis: render.OneLineNodeDepth(fset, f.Decl, 0),
+			Section:  internal.SymbolSectionFunctions,
+			Kind:     internal.SymbolKindFunction,
+		})
+	}
+	return syms
+}
+
+func types(p *doc.Package, fset *token.FileSet) ([]*internal.Symbol, error) {
+	var syms []*internal.Symbol
+	for _, typ := range p.Types {
+		specs := typ.Decl.Specs
+		if len(specs) != 1 {
+			return nil, fmt.Errorf("unexpected number of t.Decl.Specs: %d (wanted len = 1)", len(typ.Decl.Specs))
+		}
+		spec, ok := specs[0].(*ast.TypeSpec)
+		if !ok {
+			return nil, fmt.Errorf("unexpected type for Spec node: %q", typ.Name)
+		}
+		mthds, err := methodsForType(typ, spec, fset)
+		if err != nil {
+			return nil, err
+		}
+		t := &internal.Symbol{
+			Name:     typ.Name,
+			Synopsis: render.OneLineNodeDepth(fset, spec, 0),
+			Section:  internal.SymbolSectionTypes,
+			Kind:     internal.SymbolKindType,
+		}
+		syms = append(syms, t)
+		t.Children = append(append(append(append(append(
+			t.Children,
+			constantsForType(typ)...),
+			variablesForType(typ)...),
+			functionsForType(typ, fset)...),
+			fieldsForType(typ.Name, spec, fset)...),
+			mthds...)
+	}
+	return syms, nil
+}
+
+func constantsForType(t *doc.Type) []*internal.Symbol {
+	var syms []*internal.Symbol
+	for _, c := range t.Consts {
+		for _, n := range c.Names {
+			syms = append(syms, &internal.Symbol{
+				Name:       n,
+				ParentName: t.Name,
+				Kind:       internal.SymbolKindConstant,
+				Synopsis:   "const " + n,
+				Section:    internal.SymbolSectionTypes,
+			})
+		}
+	}
+	return syms
+}
+
+func variablesForType(t *doc.Type) []*internal.Symbol {
+	var syms []*internal.Symbol
+	for _, v := range t.Vars {
+		for _, n := range v.Names {
+			syms = append(syms, &internal.Symbol{
+				Name:       n,
+				ParentName: t.Name,
+				Kind:       internal.SymbolKindVariable,
+				Synopsis:   "var " + n,
+				Section:    internal.SymbolSectionTypes,
+			})
+		}
+	}
+	return syms
+}
+
+func functionsForType(t *doc.Type, fset *token.FileSet) []*internal.Symbol {
+	var syms []*internal.Symbol
+	for _, f := range t.Funcs {
+		syms = append(syms, &internal.Symbol{
+			Name:       f.Name,
+			ParentName: t.Name,
+			Kind:       internal.SymbolKindFunction,
+			Synopsis:   render.OneLineNodeDepth(fset, f.Decl, 0),
+			Section:    internal.SymbolSectionTypes,
+		})
+	}
+	return syms
+}
+
+func fieldsForType(typName string, spec *ast.TypeSpec, fset *token.FileSet) []*internal.Symbol {
+	st, ok := spec.Type.(*ast.StructType)
+	if !ok {
+		return nil
+	}
+	var syms []*internal.Symbol
+	for _, f := range st.Fields.List {
+		for _, n := range f.Names {
+			syms = append(syms, &internal.Symbol{
+				Name:       typName + "." + n.Name,
+				ParentName: typName,
+				Kind:       internal.SymbolKindField,
+				Synopsis:   render.OneLineNodeDepth(fset, n, 0),
+				Section:    internal.SymbolSectionTypes,
+			})
+		}
+	}
+	return syms
+}
+
+func methodsForType(t *doc.Type, spec *ast.TypeSpec, fset *token.FileSet) ([]*internal.Symbol, error) {
+	var syms []*internal.Symbol
+	for _, m := range t.Methods {
+		syms = append(syms, &internal.Symbol{
+			Name:       t.Name + "." + m.Name,
+			ParentName: t.Name,
+			Kind:       internal.SymbolKindMethod,
+			Synopsis:   render.OneLineNodeDepth(fset, m.Decl, 0),
+			Section:    internal.SymbolSectionTypes,
+		})
+	}
+	if st, ok := spec.Type.(*ast.InterfaceType); ok {
+		for _, m := range st.Methods.List {
+			// It's not possible for there to be more than one name.
+			// FieldList is also used by go/ast for st.Methods, which is the
+			// only reason this type is a list.
+			if len(m.Names) > 1 {
+				return nil, fmt.Errorf("len(m.Names) = %d; expected 0 or 1", len(m.Names))
+			}
+			for _, n := range m.Names {
+				syms = append(syms, &internal.Symbol{
+					Name:       t.Name + "." + n.Name,
+					ParentName: t.Name,
+					Kind:       internal.SymbolKindMethod,
+					Synopsis:   render.OneLineNodeDepth(fset, n, 0),
+					Section:    internal.SymbolSectionTypes,
+				})
+			}
+		}
+	}
+	return syms, nil
+}
diff --git a/internal/godoc/dochtml/symbol_test.go b/internal/godoc/dochtml/symbol_test.go
new file mode 100644
index 0000000..259bcff
--- /dev/null
+++ b/internal/godoc/dochtml/symbol_test.go
@@ -0,0 +1,155 @@
+// Copyright 2021 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 dochtml
+
+import (
+	"testing"
+
+	"github.com/google/go-cmp/cmp"
+	"golang.org/x/pkgsite/internal"
+)
+
+func TestGetSymbols(t *testing.T) {
+	LoadTemplates(templateSource)
+	fset,
+		d := mustLoadPackage("everydecl")
+	got,
+		err := GetSymbols(d,
+		fset)
+	if err != nil {
+		t.Fatal(err)
+	}
+	want := []*internal.Symbol{
+		{
+			Name:     "C",
+			Synopsis: "const C",
+			Section:  "Constants",
+			Kind:     "Constant",
+		},
+		{
+			Name:     "V",
+			Synopsis: "var V",
+			Section:  "Variables",
+			Kind:     "Variable",
+		},
+		{
+			Name:     "F",
+			Synopsis: "func F()",
+			Section:  "Functions",
+			Kind:     "Function",
+		},
+		{
+			Name:     "A",
+			Synopsis: "type A int",
+			Section:  "Types",
+			Kind:     "Type",
+		},
+		{
+			Name:     "B",
+			Synopsis: "type B bool",
+			Section:  "Types",
+			Kind:     "Type",
+		},
+		{
+			Name:     "I1",
+			Synopsis: "type I1 interface{ ... }",
+			Section:  "Types",
+			Kind:     "Type",
+			Children: []*internal.Symbol{
+				{
+					Name:       "I1.M1",
+					Synopsis:   "M1",
+					Section:    "Types",
+					ParentName: "I1",
+					Kind:       "Method",
+				},
+			},
+		},
+		{
+			Name:     "I2",
+			Synopsis: "type I2 interface{ ... }",
+			Section:  "Types",
+			Kind:     "Type",
+			Children: []*internal.Symbol{
+				{
+					Name:       "I2.M2",
+					Synopsis:   "M2",
+					Section:    "Types",
+					ParentName: "I2",
+					Kind:       "Method",
+				},
+			},
+		},
+		{
+			Name:     "S1",
+			Synopsis: "type S1 struct{ ... }",
+			Section:  "Types",
+			Kind:     "Type",
+			Children: []*internal.Symbol{
+				{
+					Name:       "S1.F",
+					Synopsis:   "F",
+					Section:    "Types",
+					ParentName: "S1",
+					Kind:       "Field",
+				},
+			},
+		},
+		{
+			Name:     "S2",
+			Synopsis: "type S2 struct{ ... }",
+			Section:  "Types",
+			Kind:     "Type",
+			Children: []*internal.Symbol{
+				{
+					Name:       "S2.G",
+					Synopsis:   "G",
+					Section:    "Types",
+					ParentName: "S2",
+					Kind:       "Field",
+				},
+			},
+		},
+		{
+			Name:     "T",
+			Synopsis: "type T int",
+			Section:  "Types",
+			Kind:     "Type",
+			Children: []*internal.Symbol{
+				{
+					Name:       "CT",
+					Synopsis:   "const CT",
+					Section:    "Types",
+					ParentName: "T",
+					Kind:       "Constant",
+				},
+				{
+					Name:       "VT",
+					Synopsis:   "var VT",
+					Section:    "Types",
+					ParentName: "T",
+					Kind:       "Variable",
+				},
+				{
+					Name:       "TF",
+					Synopsis:   "func TF() T",
+					Section:    "Types",
+					ParentName: "T",
+					Kind:       "Function",
+				},
+				{
+					Name:       "T.M",
+					Synopsis:   "func (T) M()",
+					Section:    "Types",
+					ParentName: "T",
+					Kind:       "Method",
+				},
+			},
+		},
+	}
+	if diff := cmp.Diff(got, want); diff != "" {
+		t.Fatal(diff)
+	}
+}
diff --git a/internal/godoc/dochtml/testdata/everydecl.go b/internal/godoc/dochtml/testdata/everydecl.go
index 4c6be86..bf610ed 100644
--- a/internal/godoc/dochtml/testdata/everydecl.go
+++ b/internal/godoc/dochtml/testdata/everydecl.go
@@ -56,3 +56,8 @@
 	I1 // embedded interface; should not have an id
 	M2()
 }
+
+type (
+	A int
+	B bool
+)
diff --git a/internal/godoc/render.go b/internal/godoc/render.go
index 4927d32..d3f54c3 100644
--- a/internal/godoc/render.go
+++ b/internal/godoc/render.go
@@ -44,14 +44,20 @@
 
 // Render renders the documentation for the package.
 // Rendering destroys p's AST; do not call any methods of p after it returns.
-func (p *Package) Render(ctx context.Context, innerPath string, sourceInfo *source.Info, modInfo *ModuleInfo) (synopsis string, imports []string, html safehtml.HTML, err error) {
+func (p *Package) Render(ctx context.Context, innerPath string, sourceInfo *source.Info, modInfo *ModuleInfo) (
+	synopsis string, imports []string, html safehtml.HTML, api []*internal.Symbol, err error) {
 	// This is mostly copied from internal/fetch/fetch.go.
 	defer derrors.Wrap(&err, "godoc.Package.Render(%q, %q, %q)", modInfo.ModulePath, modInfo.ResolvedVersion, innerPath)
 
 	p.renderCalled = true
 	d, err := p.docPackage(innerPath, modInfo)
 	if err != nil {
-		return "", nil, safehtml.HTML{}, err
+		return "", nil, safehtml.HTML{}, nil, err
+	}
+
+	api, err = dochtml.GetSymbols(d, p.Fset)
+	if err != nil {
+		return "", nil, safehtml.HTML{}, nil, err
 	}
 
 	// Render documentation HTML.
@@ -60,9 +66,9 @@
 	if errors.Is(err, ErrTooLarge) {
 		docHTML = template.MustParseAndExecuteToHTML(DocTooLargeReplacement)
 	} else if err != nil {
-		return "", nil, safehtml.HTML{}, fmt.Errorf("dochtml.Render: %v", err)
+		return "", nil, safehtml.HTML{}, nil, fmt.Errorf("dochtml.Render: %v", err)
 	}
-	return doc.Synopsis(d.Doc), d.Imports, docHTML, err
+	return doc.Synopsis(d.Doc), d.Imports, docHTML, api, err
 }
 
 // docPackage computes and returns a doc.Package.
diff --git a/internal/godoc/render_test.go b/internal/godoc/render_test.go
index 066b5dd..64dc6f9 100644
--- a/internal/godoc/render_test.go
+++ b/internal/godoc/render_test.go
@@ -34,7 +34,7 @@
 		t.Fatal(err)
 	}
 
-	wantSyn, wantImports, wantDoc, err := p.Render(ctx, "p", si, mi)
+	wantSyn, wantImports, wantDoc, _, err := p.Render(ctx, "p", si, mi)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -44,7 +44,7 @@
 
 	check := func(p *Package) {
 		t.Helper()
-		gotSyn, gotImports, gotDoc, err := p.Render(ctx, "p", si, mi)
+		gotSyn, gotImports, gotDoc, _, err := p.Render(ctx, "p", si, mi)
 		if err != nil {
 			t.Fatal(err)
 		}
diff --git a/internal/symbol.go b/internal/symbol.go
new file mode 100644
index 0000000..f9ded9b
--- /dev/null
+++ b/internal/symbol.go
@@ -0,0 +1,57 @@
+// Copyright 2021 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 internal
+
+// SymbolSection is the documentation section where a symbol appears.
+type SymbolSection string
+
+const (
+	SymbolSectionConstants SymbolSection = "Constants"
+	SymbolSectionVariables SymbolSection = "Variables"
+	SymbolSectionFunctions SymbolSection = "Functions"
+	SymbolSectionTypes     SymbolSection = "Types"
+)
+
+// SymbolKind is the type of a symbol.
+type SymbolKind string
+
+const (
+	SymbolKindConstant SymbolKind = "Constant"
+	SymbolKindVariable SymbolKind = "Variable"
+	SymbolKindFunction SymbolKind = "Function"
+	SymbolKindType     SymbolKind = "Type"
+	SymbolKindField    SymbolKind = "Field"
+	SymbolKindMethod   SymbolKind = "Method"
+)
+
+// Symbol is an element in the package API. A symbol can be a constant,
+// variable, function of type.
+type Symbol struct {
+	// Name is the name of the symbol.
+	Name string
+
+	// Synopsis is the one line description of the symbol as displayed
+	// in the package documentation.
+	Synopsis string
+
+	// Section is the section that a symbol appears in.
+	Section SymbolSection
+
+	// Kind is the type of a symbol, which is either a constant, variable,
+	// function, type, field or method.
+	Kind SymbolKind
+
+	// ParentName if name of the parent type if available, otherwise
+	// the empty string. For example, the parent type for
+	// net/http.FileServer is Handler.
+	ParentName string
+
+	// Children contain the child symbols for this symbol. This will
+	// only be populated when the SymbolType is "Type". For example, the
+	// children of net/http.Handler are FileServer, NotFoundHandler,
+	// RedirectHandler, StripPrefix, and TimeoutHandler. Each child
+	// symbol will have ParentName set to the Name of this type.
+	Children []*Symbol
+}
diff --git a/internal/unit.go b/internal/unit.go
index 3a1a36a..3e1e3c3 100644
--- a/internal/unit.go
+++ b/internal/unit.go
@@ -68,6 +68,7 @@
 	GOARCH   string
 	Synopsis string
 	Source   []byte // encoded ast.Files; see godoc.Package.Encode
+	API      []*Symbol
 }
 
 // Readme is a README at the specified filepath.