docsonnet/markdown.go

112 lines
2.4 KiB
Go
Raw Normal View History

2020-04-29 16:39:37 +02:00
package main
import (
"fmt"
"sort"
"strings"
"github.com/sh0rez/docsonnet/pkg/md"
"github.com/sh0rez/docsonnet/pkg/slug"
)
func render(pkg Package) string {
// head
elems := []md.Elem{
md.Headline(1, "package "+pkg.Name),
md.CodeBlock("jsonnet", fmt.Sprintf(`local %s = import "%s"`, pkg.Name, pkg.Import)),
md.Text(pkg.Help),
}
// index
elems = append(elems,
md.Headline(2, "Index"),
md.List(mdIndex(pkg.API, "", slug.New())...),
)
// api
elems = append(elems, md.Headline(2, "Fields"))
elems = append(elems, mdApi(pkg.API, "")...)
return md.Doc(elems...).String()
}
func mdIndex(api Fields, path string, s *slug.Slugger) []md.Elem {
var elems []md.Elem
for _, k := range sortFields(api) {
v := api[k]
switch {
case v.Function != nil:
fn := v.Function
name := md.Text(fmt.Sprintf("fn %s(%s)", fn.Name, params(fn.Args)))
link := "#" + s.Slug("fn "+path+fn.Name)
elems = append(elems, md.Link(md.Code(name), link))
case v.Object != nil:
obj := v.Object
name := md.Text("obj " + path + obj.Name)
link := "#" + s.Slug("obj "+path+obj.Name)
elems = append(elems, md.Link(md.Code(name), link))
elems = append(elems, md.List(mdIndex(obj.Fields, path+obj.Name+".", s)...))
}
}
return elems
}
func mdApi(api Fields, path string) []md.Elem {
var elems []md.Elem
for _, k := range sortFields(api) {
v := api[k]
switch {
case v.Function != nil:
fn := v.Function
elems = append(elems,
md.Headline(3, fmt.Sprintf("fn %s%s", path, fn.Name)),
md.CodeBlock("ts", fmt.Sprintf("%s(%s)", fn.Name, params(fn.Args))),
md.Text(fn.Help),
)
case v.Object != nil:
obj := v.Object
elems = append(elems,
md.Headline(2, fmt.Sprintf("obj %s%s", path, obj.Name)),
md.Text(obj.Help),
)
elems = append(elems, mdApi(obj.Fields, path+obj.Name+".")...)
}
}
return elems
}
func sortFields(api Fields) []string {
keys := make([]string, len(api))
for k := range api {
keys = append(keys, k)
}
sort.Slice(keys, func(i, j int) bool {
iK, jK := keys[i], keys[j]
if api[iK].Function != nil && api[jK].Function == nil {
return true
}
if api[iK].Function == nil && api[jK].Function != nil {
return false
}
return iK < jK
})
return keys
}
func params(a []Argument) string {
args := make([]string, 0, len(a))
for _, a := range a {
arg := a.Name
if a.Default != nil {
arg = fmt.Sprintf("%s=%v", arg, a.Default)
}
args = append(args, arg)
}
return strings.Join(args, ", ")
}