import (
"errors"
"html/template"
- "maps"
"regexp"
"strings"
return result, err
}
- fullDependencies := make(Sources)
+ fullDependencies := Sources{root.Name(): root}
mapSources(fullDependencies, root.Includes())
computeRoot := &computeNode{
- name: "root",
+ name: root.Name(),
compute: root.OnLoad(),
}
// Insert an assignment to $compute so we can always raise scope, even
}, document.FirstChild)
// Replace template functions in the root before we add any subsources
+ // fmt.Println(root.TemplateFuncs())
htmltree.Walk(document, func(n *html.Node) (bool, error) {
- // Replace template functions with namespaced functions.
replaceTemplateFuncs(root, n)
return false, nil
})
// gather global template funcs
// Start with the root's template, then add template funcs for all subsource
// with a namespace
- templateFuncs := maps.Clone(root.TemplateFuncs())
+ templateFuncs := make(template.FuncMap)
+ for fname, f := range root.TemplateFuncs() {
+ templateFuncs[snakeCase(root.Name())+"_"+fname] = f
+ }
var process func(n *html.Node, c *computeNode) error
process = func(n *html.Node, c *computeNode) error {
tokenCloseTemplate = "}}"
)
-var funcRegexp = regexp.MustCompile(`^[a-zA-Z]\w*$`)
+var funcRegexp = regexp.MustCompile(`^\(?([a-zA-Z]\w*)\)?$`)
var fieldRegexp = regexp.MustCompile(`^(?:\.[a-zA-Z]\w*)+$`)
+var scopesDownRegexp = regexp.MustCompile(`[\{\s]end[\}\s]`)
var setsDotRegexp = regexp.MustCompile(`^\{\{-?\s*(?:with|range).*?\}\}$`)
var templateRegexp = regexp.MustCompile(`\{\{.*\}\}`)
-func isFunc(token string) bool {
- return funcRegexp.MatchString(token)
+func funcFrom(token string) string {
+ submatches := funcRegexp.FindStringSubmatch(token)
+ if len(submatches) > 1 {
+ return submatches[1]
+ }
+ return ""
}
func isField(token string) bool {
}
func scopesDown(token string) bool {
- return strings.Contains(token, "end")
+ return scopesDownRegexp.MatchString(token)
}
func setsDot(token string) bool {
if depth == 0 {
// If we're just starting a pipeline, set the "template"
// cursor to the template open position
+ splitNodes = append(splitNodes, n.Data[t:i+open])
t += open
}
depth++
}
i += close + 2
} else {
+ splitNodes = append(splitNodes, n.Data[i:])
break
}
}
var done, inTemplate bool
var output []string
for {
- endToken := strings.Index(data, " ")
+ endToken := strings.IndexAny(data, " ")
if endToken == -1 {
endToken = len(data)
done = true
}
+
token := data[:endToken]
// Track when we're in a template using open/close brackets
if token == tokenOpenTemplate {
}
// If we're in a template and found a function identifier, replace it
// with a namespaced version
- if inTemplate && isFunc(token) {
+ if inTemplate {
+ funcName := funcFrom(token)
+ if funcName == "" {
+ goto done
+ }
+ // fmt.Println("func", token)
+ // fmt.Println(source.TemplateFuncs())
// Skip anything that the target source doesn't have as a templatefunc
- if _, ok := source.TemplateFuncs()[token]; ok {
- token = snakeCase(source.Name()) + "_" + token
+ if _, ok := source.TemplateFuncs()[funcName]; ok {
+ // fmt.Println("found", token)
+ namespaced := snakeCase(source.Name()) + "_" + funcName
+ token = strings.Replace(token, funcName, namespaced, -1)
}
}
+ done:
output = append(output, token)
if done {
break