From 7ff00e2c0db6c65d203d57fddb30789fafd7a488 Mon Sep 17 00:00:00 2001 From: Ian Wahbe Date: Tue, 3 Sep 2024 15:04:10 +0200 Subject: [PATCH] WIP Render tables --- pkg/tfgen/parse/extension.go | 76 ++++++++++++++++++++++++++----- pkg/tfgen/parse/extension_test.go | 53 +++++++++++++++++++++ 2 files changed, 117 insertions(+), 12 deletions(-) create mode 100644 pkg/tfgen/parse/extension_test.go diff --git a/pkg/tfgen/parse/extension.go b/pkg/tfgen/parse/extension.go index 103d3e017e..152655c264 100644 --- a/pkg/tfgen/parse/extension.go +++ b/pkg/tfgen/parse/extension.go @@ -22,6 +22,7 @@ import ( "github.com/yuin/goldmark" "github.com/yuin/goldmark/ast" "github.com/yuin/goldmark/extension" + extast "github.com/yuin/goldmark/extension/ast" "github.com/yuin/goldmark/parser" "github.com/yuin/goldmark/renderer" "github.com/yuin/goldmark/text" @@ -92,18 +93,69 @@ func WalkNode[T ast.Node](node ast.Node, f func(T)) { func RenderMarkdown() renderer.Renderer { // [markdown.NewRenderer] does not produce a renderer that can render [ast.String], // so we augment the [renderer.Renderer] with that type. - r := renderMarkdown{markdown.NewRenderer()} - writeString := func( - writer util.BufWriter, _ []byte, n ast.Node, entering bool, - ) (ast.WalkStatus, error) { - if !entering { - return ast.WalkContinue, nil - } - _, err := writer.Write(n.(*ast.String).Value) - return ast.WalkContinue, err - } - r.Register(ast.KindString, writeString) - return r + + gm := goldmark.New( + goldmark.WithExtensions(TFRegistryExtension), + goldmark.WithRenderer(markdown.NewRenderer()), + ) + + gm.Renderer().AddOptions(renderer.WithNodeRenderers( + util.Prioritized(renderType{ + kind: ast.KindString, + f: func( + writer util.BufWriter, + _ []byte, n ast.Node, entering bool, + ) (ast.WalkStatus, error) { + if !entering { + return ast.WalkContinue, nil + } + _, err := writer.Write(n.(*ast.String).Value) + return ast.WalkContinue, err + }, + }, 100), + // [markdown] does not know how to render tables,[^1] so they are + // rendered as HTML. We don't want that, as that causes HTML to + // show up in our rendered SDK docs. + // + // [^1]: https://github.com/teekennedy/goldmark-markdown/issues/19 + util.Prioritized(tableRenderer{gm.Renderer()}, 499), + util.Prioritized(tableRenderer{gm.Renderer()}, 501), + )) + + return gm.Renderer() +} + +type renderType struct { + kind ast.NodeKind + f renderer.NodeRendererFunc +} + +func (t renderType) RegisterFuncs(r renderer.NodeRendererFuncRegisterer) { + r.Register(t.kind, t.f) +} + +func panicOnRender(writer util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) { + contract.Failf("The renderer for %s should not have been called", n.Kind()) + return ast.WalkStop, nil +} + +var _ renderer.NodeRenderer = (*tableRenderer)(nil) + +type tableRenderer struct { + // A reference the the renderer so that we can render the contents of inner nodes. + r renderer.Renderer +} + +func (t tableRenderer) RegisterFuncs(r renderer.NodeRendererFuncRegisterer) { + r.Register(extast.KindTable, t.render) + r.Register(extast.KindTableHeader, panicOnRender) + r.Register(extast.KindTableRow, panicOnRender) + r.Register(extast.KindTableCell, panicOnRender) +} + +func (t tableRenderer) render(writer util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) { + panic("TEST") + return ast.WalkSkipChildren, nil } type renderMarkdown struct{ *markdown.Renderer } diff --git a/pkg/tfgen/parse/extension_test.go b/pkg/tfgen/parse/extension_test.go new file mode 100644 index 0000000000..43d40c559f --- /dev/null +++ b/pkg/tfgen/parse/extension_test.go @@ -0,0 +1,53 @@ +// Copyright 2016-2024, Pulumi Corporation. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package parse_test + +import ( + "bytes" + "testing" + + "github.com/hexops/autogold/v2" + "github.com/stretchr/testify/require" + "github.com/yuin/goldmark" + + "github.com/pulumi/pulumi-terraform-bridge/v3/pkg/tfgen/parse" +) + +func TestRenderTable(t *testing.T) { + t.Parallel() + + md := `# hi + +| t1 | t2 | +|---|---| +| r1c1 | r1c2 | +| r2c1 | r2c2 | +` + + var out bytes.Buffer + err := goldmark.New( + goldmark.WithExtensions(parse.TFRegistryExtension), + goldmark.WithRenderer(parse.RenderMarkdown()), + ).Convert([]byte(md), &out) + require.NoError(t, err) + + autogold.Expect(`# hi + +| t1 | t2 | +|---|---| +| r1c1 | r1c2 | +| r2c1 | r2c2 | +`).Equal(t, out.String()) +}