parameters: (self, node, frame)
return_statement: return frame, macro_ref
docstring: Dump the function def of a macro or call block.
docstring_summary: Dump the function def of a macro or call block.
docstring_tokens: Dump the function def of a macro or call block .
function: def macro_body(self, node, frame):
          """Dump the function def of a macro or call block."""
          frame = frame.inner()
          frame.symbols.analyze_node(node)
          macro_ref = MacroRef(node)
  
          explicit_caller = None
          skip_special_params = set()
          args = []
          for idx, arg in enumerate(node.args):
              if arg.name == 'caller':
                  explicit_caller = idx
              if arg.name in ('kwargs', 'varargs'):
                  skip_special_params.add(arg.name)
              args.append(frame.symbols.ref(arg.name))
  
          undeclared = find_undeclared(node.body, ('caller', 'kwargs', 'varargs'))
  
          if 'caller' in undeclared:
              # In older Jinja2 versions there was a bug that allowed caller
              # to retain the special behavior even if it was mentioned in
              # the argument list.  However thankfully this was only really
              # working if it was the last argument.  So we are explicitly
              # checking this now and error out if it is anywhere else in
              # the argument list.
              if explicit_caller is not None:
                  try:
                      node.defaults[explicit_caller - len(node.args)]
                  except IndexError:
                      self.fail('When defining macros or call blocks the '
                                'special "caller" argument must be omitted '
                                'or be given a default.', node.lineno)
              else:
                  args.append(frame.symbols.declare_parameter('caller'))
              macro_ref.accesses_caller = True
          if 'kwargs' in undeclared and not 'kwargs' in skip_special_params:
              args.append(frame.symbols.declare_parameter('kwargs'))
              macro_ref.accesses_kwargs = True
          if 'varargs' in undeclared and not 'varargs' in skip_special_params:
              args.append(frame.symbols.declare_parameter('varargs'))
              macro_ref.accesses_varargs = True
  
          # macros are delayed, they never require output checks
          frame.require_output_check = False
          frame.symbols.analyze_node(node)
          self.writeline('%s(%s):' % (self.func('macro'), ', '.join(args)), node)
          self.indent()
  
          self.buffer(frame)
          self.enter_frame(frame)
  
          self.push_parameter_definitions(frame)
          for idx, arg in enumerate(node.args):
              ref = frame.symbols.ref(arg.name)
              self.writeline('if %s is missing:' % ref)
              self.indent()
              try:
                  default = node.defaults[idx - len(node.args)]
              except IndexError:
                  self.writeline('%s = undefined(%r, name=%r)' % (
                      ref,
                      'parameter %r was not provided' % arg.name,
                      arg.name))
              else:
                  self.writeline('%s = ' % ref)
                  self.visit(default, frame)
              self.mark_parameter_stored(ref)
              self.outdent()
          self.pop_parameter_definitions()
  
          self.blockvisit(node.body, frame)
          self.return_buffer_contents(frame, force_unescaped=True)
          self.leave_frame(frame, with_python_scope=True)
          self.outdent()
  
          return frame, macro_ref
function_tokens: def macro_body ( self , node , frame ) : frame = frame . inner ( ) frame . symbols . analyze_node ( node ) macro_ref = MacroRef ( node ) explicit_caller = None skip_special_params = set ( ) args = [ ] for idx , arg in enumerate ( node . args ) : if arg . name == 'caller' : explicit_caller = idx if arg . name in ( 'kwargs' , 'varargs' ) : skip_special_params . add ( arg . name ) args . append ( frame . symbols . ref ( arg . name ) ) undeclared = find_undeclared ( node . body , ( 'caller' , 'kwargs' , 'varargs' ) ) if 'caller' in undeclared : # In older Jinja2 versions there was a bug that allowed caller # to retain the special behavior even if it was mentioned in # the argument list.  However thankfully this was only really # working if it was the last argument.  So we are explicitly # checking this now and error out if it is anywhere else in # the argument list. if explicit_caller is not None : try : node . defaults [ explicit_caller - len ( node . args ) ] except IndexError : self . fail ( 'When defining macros or call blocks the ' 'special "caller" argument must be omitted ' 'or be given a default.' , node . lineno ) else : args . append ( frame . symbols . declare_parameter ( 'caller' ) ) macro_ref . accesses_caller = True if 'kwargs' in undeclared and not 'kwargs' in skip_special_params : args . append ( frame . symbols . declare_parameter ( 'kwargs' ) ) macro_ref . accesses_kwargs = True if 'varargs' in undeclared and not 'varargs' in skip_special_params : args . append ( frame . symbols . declare_parameter ( 'varargs' ) ) macro_ref . accesses_varargs = True # macros are delayed, they never require output checks frame . require_output_check = False frame . symbols . analyze_node ( node ) self . writeline ( '%s(%s):' % ( self . func ( 'macro' ) , ', ' . join ( args ) ) , node ) self . indent ( ) self . buffer ( frame ) self . enter_frame ( frame ) self . push_parameter_definitions ( frame ) for idx , arg in enumerate ( node . args ) : ref = frame . symbols . ref ( arg . name ) self . writeline ( 'if %s is missing:' % ref ) self . indent ( ) try : default = node . defaults [ idx - len ( node . args ) ] except IndexError : self . writeline ( '%s = undefined(%r, name=%r)' % ( ref , 'parameter %r was not provided' % arg . name , arg . name ) ) else : self . writeline ( '%s = ' % ref ) self . visit ( default , frame ) self . mark_parameter_stored ( ref ) self . outdent ( ) self . pop_parameter_definitions ( ) self . blockvisit ( node . body , frame ) self . return_buffer_contents ( frame , force_unescaped = True ) self . leave_frame ( frame , with_python_scope = True ) self . outdent ( ) return frame , macro_ref