internal/godoc: split spec markup into internal/spec

Change-Id: Ife4429f4c75a50fdd1caae72db5cdb0d876e78e6
Reviewed-on: https://go-review.googlesource.com/c/website/+/295410
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/internal/godoc/server.go b/internal/godoc/server.go
index 2cf200b..9df87ae 100644
--- a/internal/godoc/server.go
+++ b/internal/godoc/server.go
@@ -32,6 +32,7 @@
 	"text/template"
 	"time"
 
+	"golang.org/x/website/internal/spec"
 	"golang.org/x/website/internal/texthtml"
 )
 
@@ -708,7 +709,7 @@
 	// if it's the language spec, add tags to EBNF productions
 	if strings.HasSuffix(abspath, "go_spec.html") {
 		var buf bytes.Buffer
-		Linkify(&buf, src)
+		spec.Linkify(&buf, src)
 		src = buf.Bytes()
 	}
 
diff --git a/internal/godoc/spec.go b/internal/spec/spec.go
similarity index 91%
rename from internal/godoc/spec.go
rename to internal/spec/spec.go
index 2c2db4b..abff27f 100644
--- a/internal/godoc/spec.go
+++ b/internal/spec/spec.go
@@ -2,16 +2,8 @@
 // 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
-
-// This file contains the mechanism to "linkify" html source
-// text containing EBNF sections (as found in go_spec.html).
-// The result is the input source text with the EBNF sections
-// modified such that identifiers are linked to the respective
-// definitions.
+// Package spec implements hyperlinking of the Go language specification.
+package spec
 
 import (
 	"bytes"
@@ -20,6 +12,42 @@
 	"text/scanner"
 )
 
+// Linkify adds links to HTML source text containing EBNF sections,
+// as found in go_spec.html, linking identifiers to their definitions.
+// It writes the modified HTML to out.
+func Linkify(out io.Writer, src []byte) {
+	for len(src) > 0 {
+		// i: beginning of EBNF text (or end of source)
+		i := bytes.Index(src, openTag)
+		if i < 0 {
+			i = len(src) - len(openTag)
+		}
+		i += len(openTag)
+
+		// j: end of EBNF text (or end of source)
+		j := bytes.Index(src[i:], closeTag) // close marker
+		if j < 0 {
+			j = len(src) - i
+		}
+		j += i
+
+		// write text before EBNF
+		out.Write(src[0:i])
+		// process EBNF
+		var p ebnfParser
+		p.parse(out, src[i:j])
+
+		// advance
+		src = src[j:]
+	}
+}
+
+// Markers around EBNF sections
+var (
+	openTag  = []byte(`<pre class="ebnf">`)
+	closeTag = []byte(`</pre>`)
+)
+
 type ebnfParser struct {
 	out     io.Writer // parser output
 	src     []byte    // parser input
@@ -147,36 +175,3 @@
 	}
 	p.flush()
 }
-
-// Markers around EBNF sections
-var (
-	openTag  = []byte(`<pre class="ebnf">`)
-	closeTag = []byte(`</pre>`)
-)
-
-func Linkify(out io.Writer, src []byte) {
-	for len(src) > 0 {
-		// i: beginning of EBNF text (or end of source)
-		i := bytes.Index(src, openTag)
-		if i < 0 {
-			i = len(src) - len(openTag)
-		}
-		i += len(openTag)
-
-		// j: end of EBNF text (or end of source)
-		j := bytes.Index(src[i:], closeTag) // close marker
-		if j < 0 {
-			j = len(src) - i
-		}
-		j += i
-
-		// write text before EBNF
-		out.Write(src[0:i])
-		// process EBNF
-		var p ebnfParser
-		p.parse(out, src[i:j])
-
-		// advance
-		src = src[j:]
-	}
-}
diff --git a/internal/godoc/spec_test.go b/internal/spec/spec_test.go
similarity index 89%
rename from internal/godoc/spec_test.go
rename to internal/spec/spec_test.go
index 77373f1..20eb9a8 100644
--- a/internal/godoc/spec_test.go
+++ b/internal/spec/spec_test.go
@@ -2,10 +2,7 @@
 // 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
+package spec
 
 import (
 	"bytes"