mirror of
https://github.com/gohugoio/hugo.git
synced 2024-11-21 20:46:30 -05:00
parent
f9e41f6497
commit
cff2f31334
4 changed files with 1448 additions and 1122 deletions
2386
docs/data/docs.json
2386
docs/data/docs.json
File diff suppressed because it is too large
Load diff
|
@ -26,10 +26,12 @@ func New() *Namespace {
|
|||
type Namespace struct {
|
||||
}
|
||||
|
||||
// ToInt converts the given value to an int.
|
||||
func (ns *Namespace) ToInt(v interface{}) (int, error) {
|
||||
return _cast.ToIntE(v)
|
||||
}
|
||||
|
||||
// ToString converts the given value to a string.
|
||||
func (ns *Namespace) ToString(v interface{}) (string, error) {
|
||||
return _cast.ToStringE(v)
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ func init() {
|
|||
docs := make(map[string]interface{})
|
||||
d := &deps.Deps{}
|
||||
|
||||
var namespaces []*internal.TemplateFuncsNamespace
|
||||
var namespaces internal.TemplateFuncsNamespaces
|
||||
|
||||
for _, nsf := range internal.TemplateFuncsNamespaceRegistry {
|
||||
nf := nsf(d)
|
||||
|
|
|
@ -16,11 +16,20 @@
|
|||
package internal
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"go/doc"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/spf13/hugo/deps"
|
||||
)
|
||||
|
@ -42,6 +51,8 @@ type TemplateFuncsNamespace struct {
|
|||
MethodMappings map[string]TemplateFuncMethodMapping
|
||||
}
|
||||
|
||||
type TemplateFuncsNamespaces []*TemplateFuncsNamespace
|
||||
|
||||
func (t *TemplateFuncsNamespace) AddMethodMapping(m interface{}, aliases []string, examples [][2]string) {
|
||||
if t.MethodMappings == nil {
|
||||
t.MethodMappings = make(map[string]TemplateFuncMethodMapping)
|
||||
|
@ -94,35 +105,172 @@ func methodToName(m interface{}) string {
|
|||
return name
|
||||
}
|
||||
|
||||
func (t *TemplateFuncsNamespace) MarshalJSON() ([]byte, error) {
|
||||
type Func struct {
|
||||
Name string
|
||||
Description string // TODO(bep)
|
||||
Aliases []string
|
||||
Examples [][2]string
|
||||
type goDocFunc struct {
|
||||
Name string
|
||||
Description string
|
||||
Args []string
|
||||
Aliases []string
|
||||
Examples [][2]string
|
||||
}
|
||||
|
||||
func (t goDocFunc) toJSON() ([]byte, error) {
|
||||
args, err := json.Marshal(t.Args)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// TODO(bep) map/lookup from docs template Namespace + Func name.
|
||||
var funcs []Func
|
||||
aliases, err := json.Marshal(t.Aliases)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
examples, err := json.Marshal(t.Examples)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
buf.WriteString(fmt.Sprintf(`%q:
|
||||
{ "Description": %q, "Args": %s, "Aliases": %s, "Examples": %s }
|
||||
`, t.Name, t.Description, args, aliases, examples))
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (namespaces TemplateFuncsNamespaces) MarshalJSON() ([]byte, error) {
|
||||
var buf bytes.Buffer
|
||||
|
||||
buf.WriteString("{")
|
||||
|
||||
for i, ns := range namespaces {
|
||||
if i != 0 {
|
||||
buf.WriteString(",")
|
||||
}
|
||||
b, err := ns.toJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf.Write(b)
|
||||
}
|
||||
|
||||
buf.WriteString("}")
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
func (t *TemplateFuncsNamespace) toJSON() ([]byte, error) {
|
||||
|
||||
var buf bytes.Buffer
|
||||
|
||||
godoc := getGetTplPackagesGoDoc()[t.Name]
|
||||
|
||||
var funcs []goDocFunc
|
||||
|
||||
buf.WriteString(fmt.Sprintf(`%q: {`, t.Name))
|
||||
|
||||
ctx := t.Context.(func() interface{})()
|
||||
ctxType := reflect.TypeOf(ctx)
|
||||
for i := 0; i < ctxType.NumMethod(); i++ {
|
||||
method := ctxType.Method(i)
|
||||
f := Func{
|
||||
f := goDocFunc{
|
||||
Name: method.Name,
|
||||
}
|
||||
|
||||
methodGoDoc := godoc[method.Name]
|
||||
|
||||
if mapping, ok := t.MethodMappings[method.Name]; ok {
|
||||
f.Aliases = mapping.Aliases
|
||||
f.Examples = mapping.Examples
|
||||
f.Description = methodGoDoc.Description
|
||||
f.Args = methodGoDoc.Args
|
||||
}
|
||||
|
||||
funcs = append(funcs, f)
|
||||
}
|
||||
|
||||
return json.Marshal(&struct {
|
||||
Name string
|
||||
Funcs []Func
|
||||
}{
|
||||
Name: t.Name,
|
||||
Funcs: funcs,
|
||||
})
|
||||
for i, f := range funcs {
|
||||
if i != 0 {
|
||||
buf.WriteString(",")
|
||||
}
|
||||
funcStr, err := f.toJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf.Write(funcStr)
|
||||
}
|
||||
|
||||
buf.WriteString("}")
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
type methodGoDocInfo struct {
|
||||
Description string
|
||||
Args []string
|
||||
}
|
||||
|
||||
var (
|
||||
tplPackagesGoDoc map[string]map[string]methodGoDocInfo
|
||||
tplPackagesGoDocInit sync.Once
|
||||
)
|
||||
|
||||
func getGetTplPackagesGoDoc() map[string]map[string]methodGoDocInfo {
|
||||
tplPackagesGoDocInit.Do(func() {
|
||||
tplPackagesGoDoc = make(map[string]map[string]methodGoDocInfo)
|
||||
pwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
fset := token.NewFileSet()
|
||||
|
||||
// pwd will be inside one of the namespace packages during tests
|
||||
var basePath string
|
||||
if strings.Contains(pwd, "tpl") {
|
||||
basePath = filepath.Join(pwd, "..")
|
||||
} else {
|
||||
basePath = filepath.Join(pwd, "tpl")
|
||||
}
|
||||
|
||||
files, err := ioutil.ReadDir(basePath)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, fi := range files {
|
||||
if !fi.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
namespaceDoc := make(map[string]methodGoDocInfo)
|
||||
packagePath := filepath.Join(basePath, fi.Name())
|
||||
|
||||
d, err := parser.ParseDir(fset, packagePath, nil, parser.ParseComments)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, f := range d {
|
||||
p := doc.New(f, "./", 0)
|
||||
|
||||
for _, t := range p.Types {
|
||||
if t.Name == "Namespace" {
|
||||
for _, tt := range t.Methods {
|
||||
var args []string
|
||||
for _, p := range tt.Decl.Type.Params.List {
|
||||
for _, pp := range p.Names {
|
||||
args = append(args, pp.Name)
|
||||
}
|
||||
}
|
||||
|
||||
description := strings.TrimSpace(tt.Doc)
|
||||
di := methodGoDocInfo{Description: description, Args: args}
|
||||
namespaceDoc[tt.Name] = di
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tplPackagesGoDoc[fi.Name()] = namespaceDoc
|
||||
}
|
||||
})
|
||||
|
||||
return tplPackagesGoDoc
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue