github.com/jimmyfrasche/autoreadme@v0.0.0-20240504231658-aacd7e11c8ba/godoc.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "go/ast" 6 "go/doc" 7 "go/doc/comment" 8 "go/format" 9 "go/token" 10 "strings" 11 ) 12 13 func Synopsis(text string) string { 14 d := ParseDoc(text) 15 text = string(newPrinter(1).Text(d)) 16 var p doc.Package 17 return p.Synopsis(text) 18 } 19 20 func ParseDoc(text string) *comment.Doc { 21 p := &comment.Parser{ 22 LookupPackage: func(string) (string, bool) { 23 return "", true 24 }, 25 LookupSym: func(string, string) bool { 26 return true 27 }, 28 } 29 return p.Parse(text) 30 } 31 32 type Doc struct { 33 Empty bool 34 Synopsis string 35 *comment.Doc 36 } 37 38 func NewDoc(text string) *Doc { 39 return &Doc{ 40 Empty: strings.TrimSpace(strings.ReplaceAll(text, "\n", "")) == "", 41 Synopsis: Synopsis(text), 42 Doc: ParseDoc(text), 43 } 44 } 45 46 func epsilon(*comment.Heading) string { 47 return "" 48 } 49 50 func noLink(*comment.DocLink) string { 51 return "" 52 } 53 54 func newPrinter(headingLevel int) *comment.Printer { 55 return &comment.Printer{ 56 HeadingLevel: headingLevel, 57 HeadingID: epsilon, 58 DocLinkURL: noLink, 59 } 60 } 61 62 func (d *Doc) Markdown(headingLevel int) string { 63 p := newPrinter(headingLevel) 64 return string(p.Markdown(d.Doc)) 65 } 66 67 func renderExample(buf *bytes.Buffer, fset *token.FileSet, in *doc.Example) Example { 68 out := Example{ 69 Name: in.Name, 70 Documentation: NewDoc(in.Doc), 71 Playable: in.Play != nil, 72 Unordered: in.Unordered, 73 EmptyOutput: in.EmptyOutput, 74 } 75 76 code := []any{in.Play} 77 if !out.Playable { 78 code = []any{} 79 for _, line := range in.Code.(*ast.BlockStmt).List { 80 code = append(code, line) 81 } 82 } 83 84 buf.Reset() 85 buf.WriteString("```go\n") 86 for _, line := range code { 87 format.Node(buf, fset, line) 88 89 // playable examples end with a newline already 90 if !out.Playable { 91 buf.WriteString("\n") 92 } 93 } 94 buf.WriteString("```\n") 95 out.Code = buf.String() 96 97 if in.Output != "" { 98 out.Output = "```\n" + in.Output + "```\n" 99 } 100 return out 101 }