...
1 package statements
2
3 import (
4
5
6
7 "fmt"
8 "strings"
9
10 "github.com/pkg/errors"
11
12 "github.com/noirbizarre/gonja/exec"
13 "github.com/noirbizarre/gonja/nodes"
14 "github.com/noirbizarre/gonja/parser"
15 "github.com/noirbizarre/gonja/tokens"
16 )
17
18 type FilterStmt struct {
19 position *tokens.Token
20 bodyWrapper *nodes.Wrapper
21 filterChain []*nodes.FilterCall
22 }
23
24 func (stmt *FilterStmt) Position() *tokens.Token { return stmt.position }
25 func (stmt *FilterStmt) String() string {
26 t := stmt.Position()
27 return fmt.Sprintf("FilterStmt(Line=%d Col=%d)", t.Line, t.Col)
28 }
29
30 func (node *FilterStmt) Execute(r *exec.Renderer, tag *nodes.StatementBlock) error {
31 var out strings.Builder
32 sub := r.Inherit()
33 sub.Out = &out
34
35
36 err := sub.ExecuteWrapper(node.bodyWrapper)
37 if err != nil {
38 return err
39 }
40
41 value := exec.AsValue(out.String())
42
43 for _, call := range node.filterChain {
44 value = r.Evaluator().ExecuteFilter(call, value)
45 if value.IsError() {
46 return errors.Wrapf(value, `Unable to apply filter %s (Line: %d Col: %d, near %s`,
47 call.Name, call.Token.Line, call.Token.Col, call.Token.Val)
48 }
49 }
50
51 r.WriteString(value.String())
52
53 return nil
54 }
55
56 func filterParser(p *parser.Parser, args *parser.Parser) (nodes.Statement, error) {
57 stmt := &FilterStmt{
58 position: p.Current(),
59 }
60
61 wrapper, _, err := p.WrapUntil("endfilter")
62 if err != nil {
63 return nil, err
64 }
65 stmt.bodyWrapper = wrapper
66
67 for !args.End() {
68 filterCall, err := args.ParseFilter()
69 if err != nil {
70 return nil, err
71 }
72
73 stmt.filterChain = append(stmt.filterChain, filterCall)
74
75 if args.Match(tokens.Pipe) == nil {
76 break
77 }
78 }
79
80 if !args.End() {
81 return nil, p.Error("Malformed filter-tag args.", nil)
82 }
83
84 return stmt, nil
85 }
86
87 func init() {
88 All.Register("filter", filterParser)
89 }
90
View as plain text