...

Source file src/github.com/noirbizarre/gonja/exec/statement.go

Documentation: github.com/noirbizarre/gonja/exec

     1  package exec
     2  
     3  /* Incomplete:
     4     -----------
     5  
     6     verbatim (only the "name" argument is missing for verbatim)
     7  
     8     Reconsideration:
     9     ----------------
    10  
    11     debug (reason: not sure what to output yet)
    12     regroup / Grouping on other properties (reason: maybe too python-specific; not sure how useful this would be in Go)
    13  
    14     Following built-in tags wont be added:
    15     --------------------------------------
    16  
    17     csrf_token (reason: web-framework specific)
    18     load (reason: python-specific)
    19     url (reason: web-framework specific)
    20  */
    21  
    22  import (
    23  	// "fmt"
    24  
    25  	"github.com/pkg/errors"
    26  
    27  	"github.com/noirbizarre/gonja/nodes"
    28  	"github.com/noirbizarre/gonja/parser"
    29  	// "github.com/noirbizarre/gonja/tokens"
    30  )
    31  
    32  // type NodeStatement interface {
    33  // 	astNode
    34  // }
    35  
    36  // This is the function signature of the tag's parser you will have
    37  // to implement in order to create a new tag.
    38  //
    39  // 'doc' is providing access to the whole document while 'arguments'
    40  // is providing access to the user's arguments to the tag:
    41  //
    42  //     {% your_tag_name some "arguments" 123 %}
    43  //
    44  // start_token will be the *Token with the tag's name in it (here: your_tag_name).
    45  //
    46  // Please see the Parser documentation on how to use the parser.
    47  // See RegisterTag()'s documentation for more information about
    48  // writing a tag as well.
    49  
    50  // type StatementExecutor func(*nodes.Node, *ExecutionContext) *Value
    51  
    52  type Statement interface {
    53  	nodes.Statement
    54  	Execute(*Renderer, *nodes.StatementBlock) error
    55  }
    56  
    57  type StatementSet map[string]parser.StatementParser
    58  
    59  // Exists returns true if the given test is already registered
    60  func (ss StatementSet) Exists(name string) bool {
    61  	_, existing := ss[name]
    62  	return existing
    63  }
    64  
    65  // Registers a new tag. You usually want to call this
    66  // function in the tag's init() function:
    67  // http://golang.org/doc/effective_go.html#init
    68  //
    69  // See http://www.florian-schlachter.de/post/gonja/ for more about
    70  // writing filters and tags.
    71  func (ss *StatementSet) Register(name string, parser parser.StatementParser) error {
    72  	if ss.Exists(name) {
    73  		return errors.Errorf("Statement '%s' is already registered", name)
    74  	}
    75  	(*ss)[name] = parser
    76  	// &statement{
    77  	// 	name:   name,
    78  	// 	parser: parserFn,
    79  	// }
    80  	return nil
    81  }
    82  
    83  // Replaces an already registered tag with a new implementation. Use this
    84  // function with caution since it allows you to change existing tag behaviour.
    85  func (ss *StatementSet) Replace(name string, parser parser.StatementParser) error {
    86  	if !ss.Exists(name) {
    87  		return errors.Errorf("Statement '%s' does not exist (therefore cannot be overridden)", name)
    88  	}
    89  	(*ss)[name] = parser
    90  	// statements[name] = &statement{
    91  	// 	name:   name,
    92  	// 	parser: parserFn,
    93  	// }
    94  	return nil
    95  }
    96  
    97  func (ss *StatementSet) Update(other StatementSet) StatementSet {
    98  	for name, parser := range other {
    99  		(*ss)[name] = parser
   100  	}
   101  	return *ss
   102  }
   103  
   104  // func (ss StatementSet) Parsers() map[string]parser.StatementParser {
   105  // 	parsers := map[string]parser.StatementParser{}
   106  // 	for key, specs := range ss {
   107  // 		parsers[key] = specs.Parse
   108  // 	}
   109  // 	return parsers
   110  // }
   111  
   112  // // Tag = "{%" IDENT ARGS "%}"
   113  // func (p *Parser) ParseStatement() (ast.Statement, *Error) {
   114  // 	p.Consume() // consume "{%"
   115  // 	tokenName := p.MatchType(TokenIdentifier)
   116  
   117  // 	// Check for identifier
   118  // 	if tokenName == nil {
   119  // 		return nil, p.Error("Statement name must be an identifier.", nil)
   120  // 	}
   121  
   122  // 	// Check for the existing statement
   123  // 	stmt, exists := statements[tokenName.Val]
   124  // 	if !exists {
   125  // 		// Does not exists
   126  // 		return nil, p.Error(fmt.Sprintf("Statement '%s' not found (or beginning not provided)", tokenName.Val), tokenName)
   127  // 	}
   128  
   129  // 	// Check sandbox tag restriction
   130  // 	if _, isBanned := p.bannedStmts[tokenName.Val]; isBanned {
   131  // 		return nil, p.Error(fmt.Sprintf("Usage of statement '%s' is not allowed (sandbox restriction active).", tokenName.Val), tokenName)
   132  // 	}
   133  
   134  // 	var argsToken []*Token
   135  // 	for p.Peek(TokenSymbol, "%}") == nil && p.Remaining() > 0 {
   136  // 		// Add token to args
   137  // 		argsToken = append(argsToken, p.Current())
   138  // 		p.Consume() // next token
   139  // 	}
   140  
   141  // 	// EOF?
   142  // 	if p.Remaining() == 0 {
   143  // 		return nil, p.Error("Unexpectedly reached EOF, no statement end found.", p.lastToken)
   144  // 	}
   145  
   146  // 	p.Match(TokenSymbol, "%}")
   147  
   148  // 	argParser := newParser(p.name, argsToken, p.template)
   149  // 	if len(argsToken) == 0 {
   150  // 		// This is done to have nice EOF error messages
   151  // 		argParser.lastToken = tokenName
   152  // 	}
   153  
   154  // 	p.template.level++
   155  // 	defer func() { p.template.level-- }()
   156  // 	return stmt.parser(p, tokenName, argParser)
   157  // }
   158  

View as plain text