p.tokens.discardUntil(TEMPLATE_CLOSE)
}
return &TemplateElse{}, nil
+ case "range":
+ return p.templateRangeNode(callback)
case "with":
return p.templateWithNode(callback)
case "end":
return node, nil
}
+type TemplateRange struct {
+ Expression string
+ Content []any
+}
+
+func (node *TemplateRange) String() string {
+ return fmt.Sprintf("{{ range %s }}%s{{ end }}", node.Expression, fmt.Sprint(node.Content...))
+}
+
+func (p *parser) templateRangeNode(callback contentFunc) (*TemplateRange, error) {
+ p.debug.Println("reading template range")
+ node := new(TemplateRange)
+ for tok := range p.tokens.until(TEMPLATE_CLOSE) {
+ switch tok.Type {
+ case TEXT, WHITESPACE:
+ node.Expression += tok.Literal
+ }
+ }
+ node.Expression = strings.TrimSpace(node.Expression)
+
+ acc := make([]any, 0)
+ for {
+ then, err := callback(TEMPLATE_OPEN)
+ if err != nil {
+ return nil, err
+ }
+ if len(then) == 0 {
+ break
+ }
+ acc = append(acc, then...)
+ last := acc[len(acc)-1]
+ if _, ok := last.(*TemplateEnd); ok {
+ node.Content = acc[:len(acc)-1]
+ break
+ }
+ }
+ p.debug.Printf("read template range %s", node)
+ return node, nil
+}
+
var voidElems = []string{
"area", "base", "br", "col",
"embed", "hr", "img", "input",
{name: "if-elif-else-nested", input: "{{ if .m1 }}{{ .m1 }}{{ else if m2 }}{{ .m2 }}{{ else }}{{ .m3 }}{{ end }}"},
{name: "with", input: "{{ with .message }}hello{{ end }}"},
{name: "with-nested", input: "{{ with .message }}{{ . }}{{ end }}"},
+ {name: "range", input: "{{ range .messages }}hellp{{ end }}"},
+ {name: "range-nested", input: "{{ range .messages }}{{ . }}{{ end }}"},
}
/*
testStrings := map[string]string{