diff --git a/internal/godoc/dochtml/internal/render/linkify.go b/internal/godoc/dochtml/internal/render/linkify.go
index 542fd50..93fb3d2 100644
--- a/internal/godoc/dochtml/internal/render/linkify.go
+++ b/internal/godoc/dochtml/internal/render/linkify.go
@@ -9,6 +9,7 @@
 	"errors"
 	"fmt"
 	"go/ast"
+	"go/doc/comment"
 	"go/format"
 	"go/printer"
 	"go/scanner"
@@ -18,7 +19,7 @@
 	"strings"
 	"unicode"
 
-	"github.com/google/safehtml"
+	safe "github.com/google/safehtml"
 	"github.com/google/safehtml/legacyconversions"
 	"github.com/google/safehtml/template"
 	"golang.org/x/pkgsite/internal/godoc/internal/doc"
@@ -56,15 +57,135 @@
 	badAnchorRx = regexp.MustCompile(`[^a-zA-Z0-9]`)
 )
 
-func (r *Renderer) declHTML(doc string, decl ast.Decl, extractLinks bool) (out struct{ Doc, Decl safehtml.HTML }) {
-	if doc != "" {
-		out.Doc = r.formatDocHTML(doc, extractLinks)
+type link struct {
+	Class string
+	Href  string
+	Text  any // string or safe.HTML
+}
+
+type heading struct {
+	ID    safe.Identifier
+	Title safe.HTML
+}
+
+var (
+	// tocTemplate expects a []heading.
+	tocTemplate = template.Must(template.New("toc").Parse(`<div role="navigation" aria-label="Table of Contents">
+  <ul class="Documentation-toc{{if gt (len .) 5}} Documentation-toc-columns{{end}}">
+    {{range . -}}
+      <li class="Documentation-tocItem">
+        <a href="#{{.ID}}">{{.Title}}</a>
+      </li>
+    {{end -}}
+  </ul>
+</div>
+`))
+
+	italicTemplate = template.Must(template.New("italics").Parse(`<i>{{.}}</i>`))
+
+	codeTemplate = template.Must(template.New("code").Parse(`<pre>{{.}}</pre>`))
+
+	paraTemplate = template.Must(template.New("para").Parse("<p>{{.}}\n</p>"))
+
+	headingTemplate = template.Must(template.New("heading").Parse(
+		`<h4 id="{{.ID}}">{{.Title}} <a class="Documentation-idLink" href="#{{.ID}}">¶</a></h4>`))
+
+	linkTemplate = template.Must(template.New("link").Parse(
+		`<a{{with .Class}}class="{{.}}" {{end}} href="{{.Href}}">{{.Text}}</a>`))
+
+	uListTemplate = template.Must(template.New("ulist").Parse(
+		`<ul>
+{{- range .}}
+  {{.}}
+{{- end}}
+</ul>`))
+
+	oListTemplate = template.Must(template.New("olist").Parse(
+		`<ol>
+		   {{range .}}
+		     {{.}}
+           {{end}}
+         </ol>`))
+
+	listItemTemplate = template.Must(template.New("li").Parse(
+		`<li{{with .Number}}value="{{.}}" {{end}}>{{.Content}}</li>`))
+)
+
+func (r *Renderer) formatDocHTML(text string, extractLinks bool) safe.HTML {
+	p := comment.Parser{}
+	doc := p.Parse(text)
+	if extractLinks {
+		r.removeLinks(doc)
 	}
-	if decl != nil {
-		idr := &identifierResolver{r.pids, newDeclIDs(decl), r.packageURL}
-		out.Decl = r.formatDeclHTML(decl, idr)
+	var headings []heading
+	for _, b := range doc.Content {
+		if h, ok := b.(*comment.Heading); ok {
+			headings = append(headings, r.newHeading(h))
+		}
 	}
-	return out
+	h := r.blocksToHTML(doc.Content, true, extractLinks)
+	if r.enableCommandTOC && len(headings) > 0 {
+		h = safe.HTMLConcat(ExecuteToHTML(tocTemplate, headings), h)
+	}
+	return h
+}
+
+func (r *Renderer) removeLinks(doc *comment.Doc) {
+	var bs []comment.Block
+	inLinks := false
+	for _, b := range doc.Content {
+		switch b := b.(type) {
+		case *comment.Heading:
+			if textsToString(b.Text) == "Links" {
+				inLinks = true
+			} else {
+				inLinks = false
+				bs = append(bs, b)
+			}
+		case *comment.List:
+			if inLinks {
+				for _, item := range b.Items {
+					fmt.Println("    ", item)
+					if link, ok := itemLink(item); ok {
+						r.links = append(r.links, link)
+					}
+				}
+			} else {
+				bs = append(bs, b)
+			}
+		case *comment.Paragraph:
+			if inLinks {
+				// Links section doesn't require leading whitespace, so
+				// the link may be in a paragraph.
+				s := textsToString(b.Text)
+				r.links = append(r.links, parseLinks(strings.Split(s, "\n"))...)
+			} else {
+				bs = append(bs, b)
+			}
+
+		default:
+			if !inLinks {
+				bs = append(bs, b)
+			}
+		}
+	}
+	doc.Content = bs
+}
+
+func itemLink(item *comment.ListItem) (l Link, ok bool) {
+	// Should be a single Paragraph.
+	if len(item.Content) != 1 {
+		return l, false
+	}
+	p, ok := item.Content[0].(*comment.Paragraph)
+	if !ok {
+		return l, false
+	}
+	// TODO: clean up.
+	if lp := parseLink("- " + textsToString(p.Text)); lp != nil {
+		return *lp, true
+	}
+	return l, false
 }
 
 // parseLinks extracts links from lines.
@@ -95,6 +216,176 @@
 	}
 }
 
+func (r *Renderer) blocksToHTML(bs []comment.Block, useParagraph, extractLinks bool) safe.HTML {
+	return concatHTML(bs, func(b comment.Block) safe.HTML {
+		return r.blockToHTML(b, useParagraph, extractLinks)
+	})
+}
+
+func (r *Renderer) blockToHTML(b comment.Block, useParagraph, extractLinks bool) safe.HTML {
+	switch b := b.(type) {
+	case *comment.Paragraph:
+		th := r.textsToHTML(b.Text)
+		if useParagraph {
+			return ExecuteToHTML(paraTemplate, th)
+		}
+		return th
+
+	case *comment.Code:
+		return ExecuteToHTML(codeTemplate, b.Text)
+
+	case *comment.Heading:
+		return ExecuteToHTML(headingTemplate, r.newHeading(b))
+
+	case *comment.List:
+		var items []safe.HTML
+		useParagraph = b.BlankBetween()
+		for _, item := range b.Items {
+			items = append(items, ExecuteToHTML(listItemTemplate, struct {
+				Number  string
+				Content safe.HTML
+			}{item.Number, r.blocksToHTML(item.Content, useParagraph, false)}))
+		}
+		t := oListTemplate
+		if b.Items[0].Number == "" {
+			t = uListTemplate
+		}
+		return ExecuteToHTML(t, items)
+	default:
+		return badType(b)
+	}
+}
+
+func (r *Renderer) newHeading(h *comment.Heading) heading {
+	return heading{headingID(h), r.textsToHTML(h.Text)}
+}
+
+func (r *Renderer) textsToHTML(ts []comment.Text) safe.HTML {
+	return concatHTML(ts, r.textToHTML)
+}
+
+func (r *Renderer) textToHTML(t comment.Text) safe.HTML {
+	switch t := t.(type) {
+	case comment.Plain:
+		// Don't auto-link URLs. The doc/comment package already does that.
+		return linkRFCs(string(t))
+	case comment.Italic:
+		return ExecuteToHTML(italicTemplate, t)
+	case *comment.Link:
+		return ExecuteToHTML(linkTemplate, link{"", t.URL, r.textsToHTML(t.Text)})
+	case *comment.DocLink:
+		url := r.docLinkURL(t)
+		return ExecuteToHTML(linkTemplate, link{"", url, r.textsToHTML(t.Text)})
+	default:
+		return badType(t)
+	}
+}
+
+func (r *Renderer) docLinkURL(dl *comment.DocLink) string {
+	var url string
+	if dl.ImportPath != "" {
+		url = "/" + dl.ImportPath
+		if r.packageURL != nil {
+			url = r.packageURL(dl.ImportPath)
+		}
+	}
+	id := dl.Name
+	if dl.Recv != "" {
+		id = dl.Recv + "." + id
+	}
+	if id != "" {
+		url += "#" + id
+	}
+	return url
+}
+
+// TODO: any -> *comment.Text | *comment.Block
+func concatHTML[T any](xs []T, toHTML func(T) safe.HTML) safe.HTML {
+	var hs []safe.HTML
+	for _, x := range xs {
+		hs = append(hs, toHTML(x))
+	}
+	return safe.HTMLConcat(hs...)
+}
+
+func badType(x interface{}) safe.HTML {
+	return safe.HTMLEscaped(fmt.Sprintf("bad type %T", x))
+}
+
+func headingID(h *comment.Heading) safe.Identifier {
+	s := textsToString(h.Text)
+	id := badAnchorRx.ReplaceAllString(s, "_")
+	return safe.IdentifierFromConstantPrefix("hdr", id)
+}
+
+func textsToString(ts []comment.Text) string {
+	var b strings.Builder
+	for _, t := range ts {
+		switch t := t.(type) {
+		case comment.Plain:
+			b.WriteString(string(t))
+		case comment.Italic:
+			b.WriteString(string(t))
+		case *comment.Link:
+			b.WriteString(textsToString(t.Text))
+		case *comment.DocLink:
+			b.WriteString(textsToString(t.Text))
+		default:
+			fmt.Fprintf(&b, "bad text type %T", t)
+		}
+	}
+	return b.String()
+}
+
+var rfcRegexp = regexp.MustCompile(rfcRx)
+
+// TODO: merge/replace Renderer.formatLineHTML.
+// TODO: make more efficient.
+func linkRFCs(s string) safe.HTML {
+	var hs []safe.HTML
+	for len(s) > 0 {
+		m0, m1 := len(s), len(s)
+		if m := rfcRegexp.FindStringIndex(s); m != nil {
+			m0, m1 = m[0], m[1]
+		}
+		if m0 > 0 {
+			hs = append(hs, safe.HTMLEscaped(s[:m0]))
+		}
+		if m1 > m0 {
+			word := s[m0:m1]
+			// Strip all characters except for letters, numbers, and '.' to
+			// obtain RFC fields.
+			rfcFields := strings.FieldsFunc(word, func(c rune) bool {
+				return !unicode.IsLetter(c) && !unicode.IsNumber(c) && c != '.'
+			})
+			var url string
+			if len(rfcFields) >= 4 {
+				// RFC x Section y
+				url = fmt.Sprintf("https://rfc-editor.org/rfc/rfc%s.html#section-%s",
+					rfcFields[1], rfcFields[3])
+			} else if len(rfcFields) >= 2 {
+				url = fmt.Sprintf("https://rfc-editor.org/rfc/rfc%s.html", rfcFields[1])
+			}
+			if url != "" {
+				hs = append(hs, ExecuteToHTML(linkTemplate, link{"", url, word}))
+			}
+		}
+		s = s[m1:]
+	}
+	return safe.HTMLConcat(hs...)
+}
+
+func (r *Renderer) declHTML(doc string, decl ast.Decl, extractLinks bool) (out struct{ Doc, Decl safe.HTML }) {
+	if doc != "" {
+		out.Doc = r.formatDocHTML(doc, extractLinks)
+	}
+	if decl != nil {
+		idr := &identifierResolver{r.pids, newDeclIDs(decl), r.packageURL}
+		out.Decl = r.formatDeclHTML(decl, idr)
+	}
+	return out
+}
+
 func (r *Renderer) codeString(ex *doc.Example) (string, error) {
 	if ex == nil || ex.Code == nil {
 		return "", errors.New("please include an example with code")
@@ -118,7 +409,7 @@
 	return buf.String(), nil
 }
 
-func (r *Renderer) codeHTML(ex *doc.Example) safehtml.HTML {
+func (r *Renderer) codeHTML(ex *doc.Example) safe.HTML {
 	codeStr, err := r.codeString(ex)
 	if err != nil {
 		log.Errorf(r.ctx, "Error converting *doc.Example into string: %v", err)
@@ -132,7 +423,7 @@
 	Comment bool
 }
 
-func codeHTML(src string, codeTmpl *template.Template) safehtml.HTML {
+func codeHTML(src string, codeTmpl *template.Template) safe.HTML {
 	var els []codeElement
 	// If code is an *ast.BlockStmt, then trim the braces.
 	var indent string
@@ -191,8 +482,8 @@
 // formatLineHTML formats the line as HTML-annotated text.
 // URLs and Go identifiers are linked to corresponding declarations.
 // If pre is true no conversion of doubled ` and ' to “ and ” is performed.
-func (r *Renderer) formatLineHTML(line string, pre bool) safehtml.HTML {
-	var htmls []safehtml.HTML
+func (r *Renderer) formatLineHTML(line string, pre bool) safe.HTML {
+	var htmls []safe.HTML
 	addLink := func(href, text string) {
 		htmls = append(htmls, ExecuteToHTML(LinkTemplate, Link{Href: href, Text: text}))
 	}
@@ -207,7 +498,7 @@
 		}
 		if m0 > 0 {
 			nonWord := line[:m0]
-			htmls = append(htmls, safehtml.HTMLEscaped(nonWord))
+			htmls = append(htmls, safe.HTMLEscaped(nonWord))
 		}
 		if m1 > m0 {
 			word := line[m0:m1]
@@ -251,25 +542,25 @@
 					addLink(fmt.Sprintf("https://rfc-editor.org/rfc/rfc%s.html", rfcFields[1]), word)
 				}
 			default:
-				htmls = append(htmls, safehtml.HTMLEscaped(word))
+				htmls = append(htmls, safe.HTMLEscaped(word))
 			}
 		}
 		line = line[m1:]
 	}
-	return safehtml.HTMLConcat(htmls...)
+	return safe.HTMLConcat(htmls...)
 }
 
-func ExecuteToHTML(tmpl *template.Template, data interface{}) safehtml.HTML {
+func ExecuteToHTML(tmpl *template.Template, data interface{}) safe.HTML {
 	h, err := tmpl.ExecuteToHTML(data)
 	if err != nil {
-		return safehtml.HTMLEscaped("[" + err.Error() + "]")
+		return safe.HTMLEscaped("[" + err.Error() + "]")
 	}
 	return h
 }
 
 // formatDeclHTML formats the decl as HTML-annotated source code for the
 // provided decl. Type identifiers are linked to corresponding declarations.
-func (r *Renderer) formatDeclHTML(decl ast.Decl, idr *identifierResolver) safehtml.HTML {
+func (r *Renderer) formatDeclHTML(decl ast.Decl, idr *identifierResolver) safe.HTML {
 	// Generate all anchor points and links for the given decl.
 	anchorPointsMap := generateAnchorPoints(decl)
 	anchorLinksMap := generateAnchorLinks(idr, decl)
@@ -309,7 +600,7 @@
 	numLines := bytes.Count(src, []byte("\n")) + 1
 	anchorLines := make([][]idKind, numLines)
 	lineTypes := make([]lineType, numLines)
-	htmlLines := make([][]safehtml.HTML, numLines)
+	htmlLines := make([][]safe.HTML, numLines)
 
 	// Scan through the source code, appropriately annotating it with HTML spans
 	// for comments, and HTML links and anchors for relevant identifiers.
@@ -331,7 +622,7 @@
 			if n < 0 { // possible at EOF
 				n = 0
 			}
-			htmlLines[n] = append(htmlLines[n], safehtml.HTMLEscaped(ln))
+			htmlLines[n] = append(htmlLines[n], safe.HTMLEscaped(ln))
 		}
 
 		lastOffset = offset
@@ -373,7 +664,7 @@
 	}
 
 	// Emit anchor IDs and data-kind attributes for each relevant line.
-	var htmls []safehtml.HTML
+	var htmls []safe.HTML
 	for line, iks := range anchorLines {
 		inAnchor := false
 		for _, ik := range iks {
@@ -395,7 +686,7 @@
 			htmls = append(htmls, template.MustParseAndExecuteToHTML("</span>"))
 		}
 	}
-	return safehtml.HTMLConcat(htmls...)
+	return safe.HTMLConcat(htmls...)
 }
 
 var anchorTemplate = template.Must(template.New("anchor").Parse(`<span id="{{.ID}}" data-kind="{{.Kind}}">`))
@@ -464,13 +755,13 @@
 // An idKind holds an anchor ID and the kind of the identifier being anchored.
 // The valid kinds are: "constant", "variable", "type", "function", "method" and "field".
 type idKind struct {
-	ID   safehtml.Identifier
+	ID   safe.Identifier
 	Kind string
 }
 
 // SafeGoID constructs a safe identifier from a Go symbol or dotted concatenation of symbols
 // (e.g. "Time.Equal").
-func SafeGoID(s string) safehtml.Identifier {
+func SafeGoID(s string) safe.Identifier {
 	ValidateGoDottedExpr(s)
 	return legacyconversions.RiskilyAssumeIdentifier(s)
 }
diff --git a/internal/godoc/dochtml/internal/render/linkify_comment.go b/internal/godoc/dochtml/internal/render/linkify_comment.go
deleted file mode 100644
index 057ccec..0000000
--- a/internal/godoc/dochtml/internal/render/linkify_comment.go
+++ /dev/null
@@ -1,306 +0,0 @@
-// Copyright 2022 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 render
-
-import (
-	"fmt"
-	"go/doc/comment"
-	"regexp"
-	"strings"
-	"unicode"
-
-	safe "github.com/google/safehtml"
-	"github.com/google/safehtml/template"
-)
-
-type link struct {
-	Class string
-	Href  string
-	Text  any // string or safe.HTML
-}
-
-type heading struct {
-	ID    safe.Identifier
-	Title safe.HTML
-}
-
-var (
-	// tocTemplate expects a []heading.
-	tocTemplate = template.Must(template.New("toc").Parse(`<div role="navigation" aria-label="Table of Contents">
-  <ul class="Documentation-toc{{if gt (len .) 5}} Documentation-toc-columns{{end}}">
-    {{range . -}}
-      <li class="Documentation-tocItem">
-        <a href="#{{.ID}}">{{.Title}}</a>
-      </li>
-    {{end -}}
-  </ul>
-</div>
-`))
-
-	italicTemplate = template.Must(template.New("italics").Parse(`<i>{{.}}</i>`))
-
-	codeTemplate = template.Must(template.New("code").Parse(`<pre>{{.}}</pre>`))
-
-	paraTemplate = template.Must(template.New("para").Parse("<p>{{.}}\n</p>"))
-
-	headingTemplate = template.Must(template.New("heading").Parse(
-		`<h4 id="{{.ID}}">{{.Title}} <a class="Documentation-idLink" href="#{{.ID}}">¶</a></h4>`))
-
-	linkTemplate = template.Must(template.New("link").Parse(
-		`<a{{with .Class}}class="{{.}}" {{end}} href="{{.Href}}">{{.Text}}</a>`))
-
-	uListTemplate = template.Must(template.New("ulist").Parse(
-		`<ul>
-{{- range .}}
-  {{.}}
-{{- end}}
-</ul>`))
-
-	oListTemplate = template.Must(template.New("olist").Parse(
-		`<ol>
-		   {{range .}}
-		     {{.}}
-           {{end}}
-         </ol>`))
-
-	listItemTemplate = template.Must(template.New("li").Parse(
-		`<li{{with .Number}}value="{{.}}" {{end}}>{{.Content}}</li>`))
-)
-
-func (r *Renderer) formatDocHTML(text string, extractLinks bool) safe.HTML {
-	p := comment.Parser{}
-	doc := p.Parse(text)
-	if extractLinks {
-		r.removeLinks(doc)
-	}
-	var headings []heading
-	for _, b := range doc.Content {
-		if h, ok := b.(*comment.Heading); ok {
-			headings = append(headings, r.newHeading(h))
-		}
-	}
-	h := r.blocksToHTML(doc.Content, true, extractLinks)
-	if r.enableCommandTOC && len(headings) > 0 {
-		h = safe.HTMLConcat(ExecuteToHTML(tocTemplate, headings), h)
-	}
-	return h
-}
-
-func (r *Renderer) removeLinks(doc *comment.Doc) {
-	var bs []comment.Block
-	inLinks := false
-	for _, b := range doc.Content {
-		switch b := b.(type) {
-		case *comment.Heading:
-			if textsToString(b.Text) == "Links" {
-				inLinks = true
-			} else {
-				inLinks = false
-				bs = append(bs, b)
-			}
-		case *comment.List:
-			if inLinks {
-				for _, item := range b.Items {
-					fmt.Println("    ", item)
-					if link, ok := itemLink(item); ok {
-						r.links = append(r.links, link)
-					}
-				}
-			} else {
-				bs = append(bs, b)
-			}
-		case *comment.Paragraph:
-			if inLinks {
-				// Links section doesn't require leading whitespace, so
-				// the link may be in a paragraph.
-				s := textsToString(b.Text)
-				r.links = append(r.links, parseLinks(strings.Split(s, "\n"))...)
-			} else {
-				bs = append(bs, b)
-			}
-
-		default:
-			if !inLinks {
-				bs = append(bs, b)
-			}
-		}
-	}
-	doc.Content = bs
-}
-
-func itemLink(item *comment.ListItem) (l Link, ok bool) {
-	// Should be a single Paragraph.
-	if len(item.Content) != 1 {
-		return l, false
-	}
-	p, ok := item.Content[0].(*comment.Paragraph)
-	if !ok {
-		return l, false
-	}
-	// TODO: clean up.
-	if lp := parseLink("- " + textsToString(p.Text)); lp != nil {
-		return *lp, true
-	}
-	return l, false
-}
-
-func (r *Renderer) blocksToHTML(bs []comment.Block, useParagraph, extractLinks bool) safe.HTML {
-	return concatHTML(bs, func(b comment.Block) safe.HTML {
-		return r.blockToHTML(b, useParagraph, extractLinks)
-	})
-}
-
-func (r *Renderer) blockToHTML(b comment.Block, useParagraph, extractLinks bool) safe.HTML {
-	switch b := b.(type) {
-	case *comment.Paragraph:
-		th := r.textsToHTML(b.Text)
-		if useParagraph {
-			return ExecuteToHTML(paraTemplate, th)
-		}
-		return th
-
-	case *comment.Code:
-		return ExecuteToHTML(codeTemplate, b.Text)
-
-	case *comment.Heading:
-		return ExecuteToHTML(headingTemplate, r.newHeading(b))
-
-	case *comment.List:
-		var items []safe.HTML
-		useParagraph = b.BlankBetween()
-		for _, item := range b.Items {
-			items = append(items, ExecuteToHTML(listItemTemplate, struct {
-				Number  string
-				Content safe.HTML
-			}{item.Number, r.blocksToHTML(item.Content, useParagraph, false)}))
-		}
-		t := oListTemplate
-		if b.Items[0].Number == "" {
-			t = uListTemplate
-		}
-		return ExecuteToHTML(t, items)
-	default:
-		return badType(b)
-	}
-}
-
-func (r *Renderer) newHeading(h *comment.Heading) heading {
-	return heading{headingID(h), r.textsToHTML(h.Text)}
-}
-
-func (r *Renderer) textsToHTML(ts []comment.Text) safe.HTML {
-	return concatHTML(ts, r.textToHTML)
-}
-
-func (r *Renderer) textToHTML(t comment.Text) safe.HTML {
-	switch t := t.(type) {
-	case comment.Plain:
-		// Don't auto-link URLs. The doc/comment package already does that.
-		return linkRFCs(string(t))
-	case comment.Italic:
-		return ExecuteToHTML(italicTemplate, t)
-	case *comment.Link:
-		return ExecuteToHTML(linkTemplate, link{"", t.URL, r.textsToHTML(t.Text)})
-	case *comment.DocLink:
-		url := r.docLinkURL(t)
-		return ExecuteToHTML(linkTemplate, link{"", url, r.textsToHTML(t.Text)})
-	default:
-		return badType(t)
-	}
-}
-
-func (r *Renderer) docLinkURL(dl *comment.DocLink) string {
-	var url string
-	if dl.ImportPath != "" {
-		url = "/" + dl.ImportPath
-		if r.packageURL != nil {
-			url = r.packageURL(dl.ImportPath)
-		}
-	}
-	id := dl.Name
-	if dl.Recv != "" {
-		id = dl.Recv + "." + id
-	}
-	if id != "" {
-		url += "#" + id
-	}
-	return url
-}
-
-// TODO: any -> *comment.Text | *comment.Block
-func concatHTML[T any](xs []T, toHTML func(T) safe.HTML) safe.HTML {
-	var hs []safe.HTML
-	for _, x := range xs {
-		hs = append(hs, toHTML(x))
-	}
-	return safe.HTMLConcat(hs...)
-}
-
-func badType(x interface{}) safe.HTML {
-	return safe.HTMLEscaped(fmt.Sprintf("bad type %T", x))
-}
-
-func headingID(h *comment.Heading) safe.Identifier {
-	s := textsToString(h.Text)
-	id := badAnchorRx.ReplaceAllString(s, "_")
-	return safe.IdentifierFromConstantPrefix("hdr", id)
-}
-
-func textsToString(ts []comment.Text) string {
-	var b strings.Builder
-	for _, t := range ts {
-		switch t := t.(type) {
-		case comment.Plain:
-			b.WriteString(string(t))
-		case comment.Italic:
-			b.WriteString(string(t))
-		case *comment.Link:
-			b.WriteString(textsToString(t.Text))
-		case *comment.DocLink:
-			b.WriteString(textsToString(t.Text))
-		default:
-			fmt.Fprintf(&b, "bad text type %T", t)
-		}
-	}
-	return b.String()
-}
-
-var rfcRegexp = regexp.MustCompile(rfcRx)
-
-// TODO: merge/replace Renderer.formatLineHTML.
-// TODO: make more efficient.
-func linkRFCs(s string) safe.HTML {
-	var hs []safe.HTML
-	for len(s) > 0 {
-		m0, m1 := len(s), len(s)
-		if m := rfcRegexp.FindStringIndex(s); m != nil {
-			m0, m1 = m[0], m[1]
-		}
-		if m0 > 0 {
-			hs = append(hs, safe.HTMLEscaped(s[:m0]))
-		}
-		if m1 > m0 {
-			word := s[m0:m1]
-			// Strip all characters except for letters, numbers, and '.' to
-			// obtain RFC fields.
-			rfcFields := strings.FieldsFunc(word, func(c rune) bool {
-				return !unicode.IsLetter(c) && !unicode.IsNumber(c) && c != '.'
-			})
-			var url string
-			if len(rfcFields) >= 4 {
-				// RFC x Section y
-				url = fmt.Sprintf("https://rfc-editor.org/rfc/rfc%s.html#section-%s",
-					rfcFields[1], rfcFields[3])
-			} else if len(rfcFields) >= 2 {
-				url = fmt.Sprintf("https://rfc-editor.org/rfc/rfc%s.html", rfcFields[1])
-			}
-			if url != "" {
-				hs = append(hs, ExecuteToHTML(linkTemplate, link{"", url, word}))
-			}
-		}
-		s = s[m1:]
-	}
-	return safe.HTMLConcat(hs...)
-}
