internal/frontend: add frontend rendering for unit page

Change-Id: Ia6eae1c9cface4bf40d980cd0c03447aa98a4d87
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/259098
Trust: Jonathan Amsterdam <jba@google.com>
Run-TryBot: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/internal/frontend/unit.go b/internal/frontend/unit.go
index 6f8acd1..139dedb 100644
--- a/internal/frontend/unit.go
+++ b/internal/frontend/unit.go
@@ -11,7 +11,9 @@
 	"github.com/google/safehtml"
 	"golang.org/x/pkgsite/internal"
 	"golang.org/x/pkgsite/internal/derrors"
+	"golang.org/x/pkgsite/internal/experiment"
 	"golang.org/x/pkgsite/internal/godoc"
+	"golang.org/x/pkgsite/internal/log"
 	"golang.org/x/pkgsite/internal/middleware"
 	"golang.org/x/pkgsite/internal/stdlib"
 )
@@ -149,17 +151,19 @@
 
 	var docBody, docOutline, mobileOutline safehtml.HTML
 	if unit.Documentation != nil {
-		b, err := godoc.Parse(unit.Documentation.HTML, godoc.BodySection)
+
+		docHTML := getHTML(ctx, unit)
+		b, err := godoc.Parse(docHTML, godoc.BodySection)
 		if err != nil {
 			return err
 		}
 		docBody = b
-		o, err := godoc.Parse(unit.Documentation.HTML, godoc.SidenavSection)
+		o, err := godoc.Parse(docHTML, godoc.SidenavSection)
 		if err != nil {
 			return err
 		}
 		docOutline = o
-		m, err := godoc.Parse(unit.Documentation.HTML, godoc.SidenavMobileSection)
+		m, err := godoc.Parse(docHTML, godoc.SidenavMobileSection)
 		if err != nil {
 			return err
 		}
@@ -224,6 +228,19 @@
 	return nil
 }
 
+func getHTML(ctx context.Context, u *internal.Unit) safehtml.HTML {
+	if experiment.IsActive(ctx, internal.ExperimentFrontendRenderDoc) && len(u.Documentation.Source) > 0 {
+		dd, err := renderDoc(ctx, u)
+		if err != nil {
+			log.Errorf(ctx, "render doc failed: %v", err)
+			// Fall through to use stored doc.
+		} else {
+			return dd.Documentation
+		}
+	}
+	return u.Documentation.HTML
+}
+
 // moduleInfo extracts module info from a unit. This is a shim
 // for functions ReadmeHTML and createDirectory that will be removed
 // when we complete the switch to units.