markdown.go

 1package markdown
 2
 3import (
 4	"fmt"
 5	"io"
 6	"os"
 7	"strings"
 8
 9	md "github.com/gomarkdown/markdown"
10	"github.com/gomarkdown/markdown/ast"
11	"github.com/gomarkdown/markdown/parser"
12)
13
14func Render(source string, lineWidth int, leftPad int, opts ...Options) []byte {
15	extensions := parser.CommonExtensions
16	extensions |= parser.LaxHTMLBlocks          // more in HTMLBlock, less in HTMLSpan
17	extensions |= parser.NoEmptyLineBeforeBlock // no need for NL before a list
18
19	p := parser.NewWithExtensions(extensions)
20	nodes := md.Parse([]byte(source), p)
21	renderer := newRenderer(lineWidth, leftPad, opts...)
22
23	// astRenderer, err := newAstRenderer()
24	// if err != nil {
25	// 	panic(err)
26	// }
27	// md.Render(nodes, astRenderer)
28
29	return md.Render(nodes, renderer)
30}
31
32var _ md.Renderer = &astRenderer{}
33
34type astRenderer struct {
35	set map[string]struct{}
36	f   *os.File
37}
38
39func newAstRenderer() (*astRenderer, error) {
40	f, err := os.OpenFile("/tmp/ast.puml", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
41	if err != nil {
42		return nil, err
43	}
44
45	_, _ = fmt.Fprintln(f, "(*) --> Document")
46
47	return &astRenderer{
48		f:   f,
49		set: make(map[string]struct{}),
50	}, nil
51}
52
53func (a *astRenderer) RenderNode(w io.Writer, node ast.Node, entering bool) ast.WalkStatus {
54	if entering {
55		for _, child := range node.GetChildren() {
56			str := fmt.Sprintf("%T --> %T\n", node, child)
57			if _, has := a.set[str]; !has {
58				a.set[str] = struct{}{}
59				_, _ = fmt.Fprintf(a.f, strings.Replace(str, "*ast.", "", -1))
60			}
61		}
62	}
63
64	return ast.GoToNext
65}
66
67func (a *astRenderer) RenderHeader(w io.Writer, ast ast.Node) {
68	// _, _ = fmt.Fprintln(a.f, "@startuml")
69}
70
71func (a *astRenderer) RenderFooter(w io.Writer, ast ast.Node) {
72	// _, _ = fmt.Fprintln(a.f, "@enduml")
73	_ = a.f.Close()
74}