golang.org/x/build@v0.0.0-20240506185731-218518f32b70/relnote/dump.go (about) 1 // Copyright 2024 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package relnote 6 7 import ( 8 "fmt" 9 "strings" 10 11 md "rsc.io/markdown" 12 ) 13 14 // DumpMarkdown writes the internal structure of a markdown 15 // document to standard output. 16 // It is intended for debugging. 17 func DumpMarkdown(d *md.Document) { 18 dumpBlocks(d.Blocks, 0) 19 } 20 21 func dumpBlocks(bs []md.Block, depth int) { 22 for _, b := range bs { 23 dumpBlock(b, depth) 24 } 25 } 26 27 func dumpBlock(b md.Block, depth int) { 28 typeName := strings.TrimPrefix(fmt.Sprintf("%T", b), "*markdown.") 29 dprintf(depth, "%s\n", typeName) 30 switch b := b.(type) { 31 case *md.Paragraph: 32 dumpInlines(b.Text.Inline, depth+1) 33 case *md.Heading: 34 dumpInlines(b.Text.Inline, depth+1) 35 case *md.List: 36 dumpBlocks(b.Items, depth+1) 37 case *md.Item: 38 dumpBlocks(b.Blocks, depth+1) 39 default: 40 // TODO(jba): additional cases as needed. 41 } 42 } 43 44 func dumpInlines(ins []md.Inline, depth int) { 45 for _, in := range ins { 46 switch in := in.(type) { 47 case *md.Plain: 48 dprintf(depth, "Plain(%q)\n", in.Text) 49 case *md.Code: 50 dprintf(depth, "Code(%q)\n", in.Text) 51 case *md.Link: 52 dprintf(depth, "Link:\n") 53 dumpInlines(in.Inner, depth+1) 54 dprintf(depth+1, "URL: %q\n", in.URL) 55 case *md.Strong: 56 dprintf(depth, "Strong(%q):\n", in.Marker) 57 dumpInlines(in.Inner, depth+1) 58 case *md.Emph: 59 dprintf(depth, "Emph(%q):\n", in.Marker) 60 dumpInlines(in.Inner, depth+1) 61 case *md.Del: 62 dprintf(depth, "Del(%q):\n", in.Marker) 63 dumpInlines(in.Inner, depth+1) 64 default: 65 fmt.Printf("%*s%#v\n", depth*4, "", in) 66 } 67 } 68 } 69 70 func dprintf(depth int, format string, args ...any) { 71 fmt.Printf("%*s%s", depth*4, "", fmt.Sprintf(format, args...)) 72 }