2020-04-30 00:47:43 +02:00
|
|
|
package render
|
2020-04-29 16:39:37 +02:00
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"fmt"
|
2020-05-12 22:48:02 +02:00
|
|
|
"path"
|
2020-04-29 16:39:37 +02:00
|
|
|
"sort"
|
|
|
|
|
"strings"
|
|
|
|
|
|
2020-04-30 00:47:43 +02:00
|
|
|
"github.com/sh0rez/docsonnet/pkg/docsonnet"
|
2020-04-29 16:39:37 +02:00
|
|
|
"github.com/sh0rez/docsonnet/pkg/md"
|
|
|
|
|
"github.com/sh0rez/docsonnet/pkg/slug"
|
|
|
|
|
)
|
|
|
|
|
|
2020-05-12 22:48:02 +02:00
|
|
|
type Opts struct {
|
|
|
|
|
URLPrefix string
|
2020-05-02 19:54:34 +02:00
|
|
|
}
|
|
|
|
|
|
2020-05-12 22:48:02 +02:00
|
|
|
func Render(pkg docsonnet.Package, opts Opts) map[string]string {
|
|
|
|
|
return render(pkg, nil, true, opts.URLPrefix)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func render(pkg docsonnet.Package, parents []string, root bool, urlPrefix string) map[string]string {
|
|
|
|
|
link := path.Join("/", urlPrefix, strings.Join(append(parents, pkg.Name), "/"))
|
2020-05-02 19:54:34 +02:00
|
|
|
if root {
|
2020-05-12 22:48:02 +02:00
|
|
|
link = path.Join("/", urlPrefix)
|
2020-05-02 19:54:34 +02:00
|
|
|
}
|
|
|
|
|
|
2020-04-29 16:39:37 +02:00
|
|
|
// head
|
|
|
|
|
elems := []md.Elem{
|
2020-05-02 19:54:34 +02:00
|
|
|
md.Frontmatter(map[string]interface{}{
|
|
|
|
|
"permalink": link,
|
|
|
|
|
}),
|
2020-04-29 16:39:37 +02:00
|
|
|
md.Headline(1, "package "+pkg.Name),
|
|
|
|
|
}
|
2020-05-12 15:23:24 +02:00
|
|
|
if pkg.Import != "" {
|
|
|
|
|
elems = append(elems, md.CodeBlock("jsonnet", fmt.Sprintf(`local %s = import "%s"`, pkg.Name, pkg.Import)))
|
|
|
|
|
}
|
|
|
|
|
elems = append(elems, md.Text(pkg.Help))
|
2020-04-29 16:39:37 +02:00
|
|
|
|
2020-04-30 00:47:43 +02:00
|
|
|
if len(pkg.Sub) > 0 {
|
|
|
|
|
elems = append(elems, md.Headline(2, "Subpackages"))
|
2020-05-12 15:23:24 +02:00
|
|
|
|
|
|
|
|
keys := make([]string, 0, len(pkg.Sub))
|
2020-05-02 19:54:34 +02:00
|
|
|
for _, s := range pkg.Sub {
|
2020-05-12 15:23:24 +02:00
|
|
|
keys = append(keys, s.Name)
|
|
|
|
|
}
|
|
|
|
|
sort.Strings(keys)
|
|
|
|
|
|
|
|
|
|
var items []md.Elem
|
|
|
|
|
for _, k := range keys {
|
|
|
|
|
s := pkg.Sub[k]
|
|
|
|
|
|
2020-05-02 19:54:34 +02:00
|
|
|
link := strings.Join(append(parents, pkg.Name, s.Name), "-")
|
|
|
|
|
if root {
|
|
|
|
|
link = strings.Join(append(parents, s.Name), "-")
|
2020-04-30 00:47:43 +02:00
|
|
|
}
|
2020-05-02 19:54:34 +02:00
|
|
|
items = append(items, md.Link(md.Text(s.Name), link+".md"))
|
2020-04-30 00:47:43 +02:00
|
|
|
}
|
2020-05-12 15:23:24 +02:00
|
|
|
|
2020-04-30 00:47:43 +02:00
|
|
|
elems = append(elems, md.List(items...))
|
|
|
|
|
}
|
2020-04-29 16:39:37 +02:00
|
|
|
|
2020-04-30 00:47:43 +02:00
|
|
|
// fields of this package
|
|
|
|
|
if len(pkg.API) > 0 {
|
|
|
|
|
// index
|
|
|
|
|
elems = append(elems,
|
|
|
|
|
md.Headline(2, "Index"),
|
|
|
|
|
md.List(renderIndex(pkg.API, "", slug.New())...),
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// api
|
|
|
|
|
elems = append(elems, md.Headline(2, "Fields"))
|
|
|
|
|
elems = append(elems, renderApi(pkg.API, "")...)
|
|
|
|
|
}
|
2020-04-29 16:39:37 +02:00
|
|
|
|
2020-05-02 19:54:34 +02:00
|
|
|
content := md.Doc(elems...).String()
|
|
|
|
|
key := strings.Join(append(parents, pkg.Name+".md"), "-")
|
|
|
|
|
if root {
|
|
|
|
|
key = "README.md"
|
|
|
|
|
}
|
|
|
|
|
out := map[string]string{
|
|
|
|
|
key: content,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(pkg.Sub) != 0 {
|
|
|
|
|
for _, s := range pkg.Sub {
|
|
|
|
|
path := append(parents, pkg.Name)
|
|
|
|
|
if root {
|
|
|
|
|
path = parents
|
|
|
|
|
}
|
2020-05-12 22:48:02 +02:00
|
|
|
got := render(s, path, false, urlPrefix)
|
2020-05-02 19:54:34 +02:00
|
|
|
for k, v := range got {
|
|
|
|
|
out[k] = v
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return out
|
2020-04-29 16:39:37 +02:00
|
|
|
}
|
|
|
|
|
|
2020-04-30 00:47:43 +02:00
|
|
|
func renderIndex(api docsonnet.Fields, path string, s *slug.Slugger) []md.Elem {
|
2020-04-29 16:39:37 +02:00
|
|
|
var elems []md.Elem
|
|
|
|
|
for _, k := range sortFields(api) {
|
|
|
|
|
v := api[k]
|
|
|
|
|
switch {
|
|
|
|
|
case v.Function != nil:
|
|
|
|
|
fn := v.Function
|
2020-04-30 00:47:43 +02:00
|
|
|
name := md.Text(fmt.Sprintf("fn %s(%s)", fn.Name, renderParams(fn.Args)))
|
2020-04-29 16:39:37 +02:00
|
|
|
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))
|
2020-04-30 00:47:43 +02:00
|
|
|
elems = append(elems, md.List(renderIndex(obj.Fields, path+obj.Name+".", s)...))
|
2020-04-29 16:39:37 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return elems
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-30 00:47:43 +02:00
|
|
|
func renderApi(api docsonnet.Fields, path string) []md.Elem {
|
2020-04-29 16:39:37 +02:00
|
|
|
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)),
|
2020-04-30 00:47:43 +02:00
|
|
|
md.CodeBlock("ts", fmt.Sprintf("%s(%s)", fn.Name, renderParams(fn.Args))),
|
2020-04-29 16:39:37 +02:00
|
|
|
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),
|
|
|
|
|
)
|
2020-04-30 00:47:43 +02:00
|
|
|
elems = append(elems, renderApi(obj.Fields, path+obj.Name+".")...)
|
2020-04-29 16:39:37 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return elems
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-30 00:47:43 +02:00
|
|
|
func sortFields(api docsonnet.Fields) []string {
|
2020-04-29 16:39:37 +02:00
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-30 00:47:43 +02:00
|
|
|
func renderParams(a []docsonnet.Argument) string {
|
2020-04-29 16:39:37 +02:00
|
|
|
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, ", ")
|
|
|
|
|
}
|