]> git.earlybird.gay Git - today/commitdiff
Fix issues with function namespacing
authorearly <me@earlybird.gay>
Wed, 23 Oct 2024 04:59:53 +0000 (22:59 -0600)
committerearly <me@earlybird.gay>
Wed, 23 Oct 2024 04:59:53 +0000 (22:59 -0600)
internal/compile/compile.go
internal/compile/template.go

index 2cbcc706196a922143a2905abde8b91914c00684..9b8880730781957dd502958d7cbfc9155d16f9ad 100644 (file)
@@ -4,7 +4,6 @@ package compile
 import (
        "errors"
        "html/template"
-       "maps"
        "regexp"
        "strings"
 
@@ -53,10 +52,10 @@ func Compile(root TemplateSource, transform ...func(root *html.Node)) (Result, e
                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
@@ -67,8 +66,8 @@ func Compile(root TemplateSource, transform ...func(root *html.Node)) (Result, e
        }, 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
        })
@@ -90,7 +89,10 @@ func Compile(root TemplateSource, transform ...func(root *html.Node)) (Result, e
        // 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 {
index a1e0e2b26067c1112e04810f829f71dd9d83926c..1fd6f5b7191178d97e3d868ff5624de313906a10 100644 (file)
@@ -17,13 +17,18 @@ const (
        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 {
@@ -41,7 +46,7 @@ func scopesUp(token string) bool {
 }
 
 func scopesDown(token string) bool {
-       return strings.Contains(token, "end")
+       return scopesDownRegexp.MatchString(token)
 }
 
 func setsDot(token string) bool {
@@ -85,6 +90,7 @@ func splitTemplateNodes(n *html.Node) {
                                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++
@@ -100,6 +106,7 @@ func splitTemplateNodes(n *html.Node) {
                                }
                                i += close + 2
                        } else {
+                               splitNodes = append(splitNodes, n.Data[i:])
                                break
                        }
                }
@@ -195,11 +202,12 @@ func replaceTemplateFuncs(source TemplateSource, n *html.Node) {
                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 {
@@ -210,13 +218,22 @@ func replaceTemplateFuncs(source TemplateSource, n *html.Node) {
                        }
                        // 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