internal/frontend: use GFM features in markdown parser

This enables all the GFM features in the markdown parser, and adds
table support to walkBlocks and cases in rewriteHeadingsBlocks.

For golang/go#61399

Change-Id: I6563a5c8b0b9a838e8875e3a2ef5afe3cc155281
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/550035
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
kokoro-CI: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
diff --git a/go.mod b/go.mod
index cd6727f..4c7736b 100644
--- a/go.mod
+++ b/go.mod
@@ -27,7 +27,7 @@
 	github.com/jba/templatecheck v0.6.0
 	github.com/lib/pq v1.10.9
 	github.com/russross/blackfriday/v2 v2.1.0
-	github.com/yuin/goldmark v1.4.13
+	github.com/yuin/goldmark v1.6.0
 	github.com/yuin/goldmark-emoji v1.0.1
 	go.opencensus.io v0.24.0
 	golang.org/x/mod v0.14.0
@@ -40,7 +40,7 @@
 	google.golang.org/grpc v1.57.0
 	google.golang.org/protobuf v1.31.0
 	gopkg.in/yaml.v3 v3.0.1
-	rsc.io/markdown v0.0.0-20231114125513-6fc7bf989e0c
+	rsc.io/markdown v0.0.0-20231214224604-88bb533a6020
 )
 
 require (
diff --git a/go.sum b/go.sum
index bf6c6e7..533ec47 100644
--- a/go.sum
+++ b/go.sum
@@ -1037,8 +1037,9 @@
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
-github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yuin/goldmark v1.6.0 h1:boZcn2GTjpsynOsC0iJHnBWa4Bi0qzfJjthwauItG68=
+github.com/yuin/goldmark v1.6.0/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18Wa1os=
 github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ=
 github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da h1:NimzV1aGyq29m5ukMK0AMWEhFaL/lrEOaephfuoiARg=
@@ -1742,8 +1743,8 @@
 modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
 modernc.org/zappy v1.0.0/go.mod h1:hHe+oGahLVII/aTTyWK/b53VDHMAGCBYYeZ9sn83HC4=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
-rsc.io/markdown v0.0.0-20231114125513-6fc7bf989e0c h1:HaCtoXmNbydct3DDtBACBsvfOdbU5sH7TdtkrBmylco=
-rsc.io/markdown v0.0.0-20231114125513-6fc7bf989e0c/go.mod h1:NAB5d9ChqypB0BfWUzhyn7GTyPwr2Q0KxmrAFJnOT/g=
+rsc.io/markdown v0.0.0-20231214224604-88bb533a6020 h1:GqQcl3Kno/rOntek8/d8axYjau8r/c1zVFojXS6WJFI=
+rsc.io/markdown v0.0.0-20231214224604-88bb533a6020/go.mod h1:8xcPgWmwlZONN1D9bjxtHEjrUtSEa3fakVF8iaewYKQ=
 rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
diff --git a/internal/frontend/markdown.go b/internal/frontend/markdown.go
index 50bfc85..98e8c69 100644
--- a/internal/frontend/markdown.go
+++ b/internal/frontend/markdown.go
@@ -49,7 +49,15 @@
 		return &Readme{HTML: h}, nil
 	}
 
-	var p markdown.Parser
+	p := markdown.Parser{
+		HeadingIDs:         true,
+		Strikethrough:      true,
+		TaskListItems:      true,
+		AutoLinkText:       true,
+		AutoLinkAssumeHTTP: true,
+		Table:              true,
+		Emoji:              true,
+	}
 	doc := p.Parse(readme.Contents)
 	(&linkRewriter{info, readme}).rewriteLinks(doc)
 	rewriteImgSrc(doc, info, readme)
@@ -133,6 +141,15 @@
 		case *markdown.HTMLBlock:
 		case *markdown.CodeBlock:
 		case *markdown.Empty:
+		case *markdown.Table:
+			for _, t := range x.Header {
+				walkBlocks([]markdown.Block{t}, walkFunc)
+			}
+			for _, r := range x.Rows {
+				for _, t := range r {
+					walkBlocks([]markdown.Block{t}, walkFunc)
+				}
+			}
 		case *markdown.ThematicBreak:
 		default:
 			return fmt.Errorf("unhandled block type %T", x)
@@ -296,6 +313,12 @@
 	rewriteHeadingsBlocks = func(blocks []markdown.Block) {
 		for i, b := range blocks {
 			switch x := b.(type) {
+			case *markdown.Text:
+			case *markdown.HTMLBlock:
+			case *markdown.Table:
+			case *markdown.Empty:
+			case *markdown.CodeBlock:
+			case *markdown.ThematicBreak:
 			case *markdown.Paragraph:
 				rewriteHeadingsBlocks([]markdown.Block{x.Text})
 			case *markdown.List: