def macro(self, ident, block, args=None):
   code = Code()
   if args:
     proto = ("arg%d=None" % n for n in range(len(args)))
     params = ("%r: arg%d" % (arg, n) for n, arg in enumerate(args))
     code.write(
       "def block(%s, extra=None):" % ", ".join(proto),
       code.indent,
         "params = { %s }" % ", ".join(params),
         "params.update(extra or {})")
   else:
     code.write(
       "def block(params=None):",
       code.indent,
         "params = params or {}")
   code.write(
     "output = Buffer()",
     "stash = context.localise(params)",
     "try:",
     code.indent,
       block,
     code.unindent,
     "finally:",
     " stash = context.delocalise()",
     "return output.get()")
   code.write(code.unindent, "stash.set(%r, block)" % str(ident))
   return code.text()
  def try_(self, block, catches):  # [% TRY %] ... [% CATCH %] ... [% END %]
    handlers = []
    final = catches.pop()
    default = None
    catchblock = Code()
    n = 0

    for catch in catches:
      if catch[0]:
        match = catch[0]
      else:
        if default is None:
          default = catch[1]
        continue
      mblock = catch[1]
      handlers.append("'%s'" % match)
      catchblock.write((n == 0 and "if" or "elif")
                       + " handler == '%s':" % match)
      n += 1
      catchblock.write(catchblock.indent, mblock, catchblock.unindent)
    catchblock.write("error = 0")
    if default:
      default = Code.format("else:", Code.indent, default, "error = ''")
    else:
      default = "# NO DEFAULT"
    handlers = "[%s]" % ", ".join(handlers)

    return Code.format(
      "def block():",
      Code.indent,
        "output = Buffer()",
        "error = None",
        "try:",
        Code.indent,
          block,
        Code.unindent,
        "except Exception, e:",
        Code.indent,
          "error = context.catch(e, output)",
          "if error.type() in ('return', 'stop'):",
          " raise error",
          "stash.set('error', error)",
          "stash.set('e', error)",
          "handler = error.select_handler(%s)" % handlers,
          "if handler:",
          Code.indent,
            catchblock.text(),
          Code.unindent,
          default,
        Code.unindent,
        final,
        "if error:",
        " raise error",
        "return output.get()",
      Code.unindent,
      "output.write(block())")
예제 #3
0
 def multi_wrapper(self, file, hash, block):
     hash.append("('content', output.get())")
     return Code.format(
         "def block():", Code.indent, "output = Buffer()", block,
         "for file in %s:" % ", ".join(reversed(file)),
         " output.reset(context.include(file, Dict(%s)))" % ", ".join(hash),
         "return output.get()", Code.unindent, "output.write(block())")
예제 #4
0
 def anon_block(self, block):  # [% BLOCK %] ... [% END %]
     return Code.format("def block():", Code.indent, "output = Buffer()",
                        "try:", Code.indent, block, Code.unindent,
                        "except Error as e:",
                        " error = context.catch(e, output)",
                        " if error.type() != 'return':", "  raise error",
                        "return output.get()", Code.unindent, "block()")
예제 #5
0
 def python(self, block):
     return Code.format("if not context.eval_python():",
                        " context.throw('python', 'EVAL_PYTHON not set')",
                        "def block():", Code.indent, "output = Buffer()",
                        block,
                        "return Evaluate(output.get(), context, stash)",
                        Code.unindent, "output.write(block())")
예제 #6
0
 def capture(self, name, block):
     if isinstance(name, list):
         if len(name) == 2 and not name[1]:
             name = name[0]
         else:
             name = "[" + ", ".join(name) + "]"
     return Code.format("def block():", Code.indent, "output = Buffer()",
                        block, "return output.get()", Code.unindent,
                        "stash.set(%s, block())" % name)
 def switch(self, expr, cases):  # [% SWITCH %] [% CASE foo %] ... [% END %]
   code = Code()
   code.write("def block():",
              code.indent,
                "result = Regex(str(%s) + '$')" % expr)
   default = cases.pop()
   for match, block in cases:
     code.write("for match in Switch(%s):" % match,
                code.indent,
                  "if result.match(str(match)):",
                  code.indent,
                    block,
                    "return",
                  code.unindent,
                code.unindent)
   if default is not None:
     code.write(default)
   code.write(code.unindent, "block()")
   return code.text()
예제 #8
0
 def while_(self, expr, block):  # [% WHILE x < 10 %] ... [% END %]
     return Code.format(
         "def block():", Code.indent,
         "failsafe = %d" % (self.WHILE_MAX - 1),
         "while failsafe and (%s):" % expr, Code.indent, "try:",
         Code.indent, "failsafe -= 1", block, Code.unindent,
         "except Continue:", " continue", "except Break:", " break",
         Code.unindent, "if not failsafe:",
         " raise Error(None, 'WHILE loop terminated (> %d iterations)')" %
         self.WHILE_MAX, Code.unindent, "block()")
예제 #9
0
 def template(self, block):
     if not block or block.isspace():
         return "def block(context):\n return ''\n"
     return Code.format("def block(context):", Code.indent,
                        "stash = context.stash()", "output = Buffer()",
                        "try:", Code.indent, block, Code.unindent,
                        "except Error as e:",
                        " error = context.catch(e, output)",
                        " if error.type() != 'return':", "  raise error",
                        "return output.get()")
예제 #10
0
 def python(self, block):
   return Code.format(
     "if not context.eval_python():",
     " context.throw('python', 'EVAL_PYTHON not set')",
     "def block():",
     Code.indent,
       "output = Buffer()",
       block,
       "return Evaluate(output.get(), context, stash)",
     Code.unindent,
     "output.write(block())")
예제 #11
0
 def wrapper(self, nameargs, block):  # [% WRAPPER template foo = bar %]
     file, args = unpack(nameargs, 2)
     hash = args.pop(0)
     if len(file) > 1:
         return self.multi_wrapper(file, hash, block)
     file = file[0]
     hash.append("('content', output.get())")
     file += ", Dict(%s)" % ", ".join(hash)
     return Code.format("def block():", Code.indent, "output = Buffer()",
                        block, "return context.include(%s)" % file,
                        Code.unindent, "output.write(block())")
예제 #12
0
 def if_(self, expr, block, else_=None):
     # [% IF foo < bar %] ... [% ELSE %] ... [% END %]
     if else_:
         elses = else_[:]
     else:
         elses = []
     if elses:
         else_ = elses.pop()
     else:
         else_ = None
     code = Code()
     code.write("if %s:" % expr, code.indent, block)
     for expr, block in elses:
         code.write(code.unindent, "elif %s:" % expr, code.indent, block)
     if else_ is not None:
         code.write(code.unindent, "else:", code.indent, else_)
     return code.text()
예제 #13
0
 def multi_wrapper(self, file, hash, block):
   hash.append("('content', output.get())")
   return Code.format(
     "def block():",
     Code.indent,
       "output = Buffer()",
       block,
       "for file in %s:" % ", ".join(reversed(file)),
       " output.reset(context.include(file, Dict(%s)))" % ", ".join(hash),
       "return output.get()",
     Code.unindent,
     "output.write(block())")
예제 #14
0
 def capture(self, name, block):
   if isinstance(name, list):
     if len(name) == 2 and not name[1]:
       name = name[0]
     else:
       name = "[" + ", ".join(name) + "]"
   return Code.format(
     "def block():",
     Code.indent,
       "output = Buffer()",
       block,
       "return output.get()",
     Code.unindent,
     "stash.set(%s, block())" % name)
예제 #15
0
 def filter(self, lnameargs, block):
     name, args, alias = unpack(lnameargs, 3)
     name = name[0]
     args = self.args(args)
     if alias:
         if args:
             args = "%s, %s" % (args, alias)
         else:
             args = ", None, %s" % alias
     if args:
         name += ", %s" % args
     return Code.format("def block():", Code.indent, "output = Buffer()",
                        "filter = context.filter(%s)" % name, block,
                        "return filter(output.get())", Code.unindent,
                        "output.write(block())")
예제 #16
0
 def view(self, nameargs, block, defblocks):  # [% VIEW name args %]
     name, args = unpack(nameargs, 2)
     hash = args.pop(0)
     name = name.pop(0)
     if defblocks:
         hash.append("('blocks', dict((%s,)))" %
                     ", ".join("(%r, Document.evaluate(%r, 'block'))" % pair
                               for pair in defblocks.items()))
     return Code.format("def block():", Code.indent, "output = Buffer()",
                        "oldv = stash.get('view')",
                        "view = context.view(Dict(%s))" % ", ".join(hash),
                        "stash.set(%s, view)" % (name, ),
                        "stash.set('view', view)", block,
                        "stash.set('view', oldv)", "view.seal()",
                        Code.unindent, "block()")
예제 #17
0
 def wrapper(self, nameargs, block):  # [% WRAPPER template foo = bar %]
   file, args = unpack(nameargs, 2)
   hash = args.pop(0)
   if len(file) > 1:
     return self.multi_wrapper(file, hash, block)
   file = file[0]
   hash.append("('content', output.get())")
   file += ", Dict(%s)" % ", ".join(hash)
   return Code.format(
     "def block():",
     Code.indent,
       "output = Buffer()",
       block,
       "return context.include(%s)" % file,
     Code.unindent,
     "output.write(block())")
예제 #18
0
 def anon_block(self, block):   # [% BLOCK %] ... [% END %]
   return Code.format(
     "def block():",
     Code.indent,
       "output = Buffer()",
       "try:",
       Code.indent,
         block,
       Code.unindent,
       "except Error, e:",
       " error = context.catch(e, output)",
       " if error.type() != 'return':",
       "  raise error",
       "return output.get()",
     Code.unindent,
     "block()")
예제 #19
0
 def if_(self, expr, block, else_=None):
   # [% IF foo < bar %] ... [% ELSE %] ... [% END %]
   if else_:
     elses = else_[:]
   else:
     elses = []
   if elses:
     else_ = elses.pop()
   else:
     else_ = None
   code = Code()
   code.write("if %s:" % expr, code.indent, block)
   for expr, block in elses:
     code.write(code.unindent, "elif %s:" % expr,
                code.indent, block)
   if else_ is not None:
     code.write(code.unindent, "else:", code.indent, else_)
   return code.text()
예제 #20
0
 def template(self, block):
   if not block or block.isspace():
     return "def block(context):\n return ''\n"
   return Code.format(
     "def block(context):",
     Code.indent,
       "stash = context.stash()",
       "output = Buffer()",
       "try:",
       Code.indent,
         block,
       Code.unindent,
       "except Error, e:",
       " error = context.catch(e, output)",
       " if error.type() != 'return':",
       "  raise error",
       "return output.get()")
예제 #21
0
 def view(self, nameargs, block, defblocks):  # [% VIEW name args %]
   name, args = unpack(nameargs, 2)
   hash = args.pop(0)
   name = name.pop(0)
   if defblocks:
     hash.append("('blocks', dict((%s,)))" % ", ".join("(%r, Document.evaluate(%r, 'block'))" % pair for pair in defblocks.items()))
   return Code.format(
     "def block():",
     Code.indent,
       "output = Buffer()",
       "oldv = stash.get('view')",
       "view = context.view(Dict(%s))" % ", ".join(hash),
       "stash.set(%s, view)" % (name,),
       "stash.set('view', view)",
       block,
       "stash.set('view', oldv)",
       "view.seal()",
     Code.unindent,
     "block()")
예제 #22
0
 def filter(self, lnameargs, block):
   name, args, alias = unpack(lnameargs, 3)
   name = name[0]
   args = self.args(args)
   if alias:
     if args:
       args = "%s, %s" % (args, alias)
     else:
       args = ", None, %s" % alias
   if args:
     name += ", %s" % args
   return Code.format(
     "def block():",
     Code.indent,
       "output = Buffer()",
       "filter = context.filter(%s)" % name,
       block,
       "return filter(output.get())",
     Code.unindent,
     "output.write(block())")
예제 #23
0
 def foreach(self, target, list, args, block):
     # [% FOREACH x = [ foo bar ] %] ... [% END %]
     if target:
         loop_save = "oldloop = %s" % (self.ident(["'loop'"]), )
         loop_set = "stash['%s'] = value" % (target, )
         loop_restore = "stash.set('loop', oldloop)"
     else:
         loop_save = "stash = context.localise()"
         loop_set = ("if isinstance(value, dict):\n"
                     " stash.get(['import', [value]])")
         loop_restore = "stash = context.delocalise()"
     return Code.format("def block(stash):", Code.indent, "oldloop = None",
                        "loop = Iterator(%s)" % list, loop_save,
                        "stash.set('loop', loop)", "try:", Code.indent,
                        "for value in loop:", Code.indent, "try:",
                        Code.indent, loop_set, block, Code.unindent,
                        "except Continue:", " continue", "except Break:",
                        " break", Code.unindent, Code.unindent, "finally:",
                        Code.indent, loop_restore, Code.unindent,
                        Code.unindent, "block(stash)")
예제 #24
0
 def foreach(self, target, list, args, block):
   # [% FOREACH x = [ foo bar ] %] ... [% END %]
   if target:
     loop_save = "oldloop = %s" % (self.ident(["'loop'"]),)
     loop_set = "stash['%s'] = value" % (target,)
     loop_restore = "stash.set('loop', oldloop)"
   else:
     loop_save = "stash = context.localise()"
     loop_set = ("if isinstance(value, dict):\n"
                 " stash.get(['import', [value]])")
     loop_restore = "stash = context.delocalise()"
   return Code.format(
     "def block(stash):",
     Code.indent,
       "oldloop = None",
       "loop = Iterator(%s)" % list,
       loop_save,
       "stash.set('loop', loop)",
       "try:",
       Code.indent,
         "for value in loop:",
         Code.indent,
           "try:",
           Code.indent,
             loop_set,
             block,
           Code.unindent,
           "except Continue:",
           " continue",
           "except Break:",
           " break",
         Code.unindent,
       Code.unindent,
       "finally:",
       Code.indent,
         loop_restore,
       Code.unindent,
     Code.unindent,
     "block(stash)")
예제 #25
0
 def while_(self, expr, block):  # [% WHILE x < 10 %] ... [% END %]
   return Code.format(
     "def block():",
     Code.indent,
       "failsafe = %d" % (self.WHILE_MAX - 1),
       "while failsafe and (%s):" % expr,
       Code.indent,
         "try:",
         Code.indent,
           "failsafe -= 1",
           block,
         Code.unindent,
         "except Continue:",
         " continue",
         "except Break:",
         " break",
       Code.unindent,
       "if not failsafe:",
       " raise Error(None, 'WHILE loop terminated (> %d iterations)')"
         % self.WHILE_MAX,
     Code.unindent,
     "block()")
예제 #26
0
 def macro(self, ident, block, args=None):
     code = Code()
     if args:
         proto = ("arg%d=None" % n for n in range(len(args)))
         params = ("%r: arg%d" % (arg, n) for n, arg in enumerate(args))
         code.write("def block(%s, extra=None):" % ", ".join(proto),
                    code.indent, "params = { %s }" % ", ".join(params),
                    "params.update(extra or {})")
     else:
         code.write("def block(params=None):", code.indent,
                    "params = params or {}")
     code.write("output = Buffer()", "stash = context.localise(params)",
                "try:", code.indent, block, code.unindent, "finally:",
                " stash = context.delocalise()", "return output.get()")
     code.write(code.unindent, "stash.set(%r, block)" % str(ident))
     return code.text()
예제 #27
0
    def try_(self, block, catches):  # [% TRY %] ... [% CATCH %] ... [% END %]
        handlers = []
        final = catches.pop()
        default = None
        catchblock = Code()
        n = 0

        for catch in catches:
            if catch[0]:
                match = catch[0]
            else:
                if default is None:
                    default = catch[1]
                continue
            mblock = catch[1]
            handlers.append("'%s'" % match)
            catchblock.write((n == 0 and "if" or "elif") +
                             " handler == '%s':" % match)
            n += 1
            catchblock.write(catchblock.indent, mblock, catchblock.unindent)
        catchblock.write("error = 0")
        if default:
            default = Code.format("else:", Code.indent, default, "error = ''")
        else:
            default = "# NO DEFAULT"
        handlers = "[%s]" % ", ".join(handlers)

        return Code.format(
            "def block():", Code.indent, "output = Buffer()", "error = None",
            "try:", Code.indent, block, Code.unindent,
            "except Exception as e:", Code.indent,
            "error = context.catch(e, output)",
            "if error.type() in ('return', 'stop'):", " raise error",
            "stash.set('error', error)", "stash.set('e', error)",
            "handler = error.select_handler(%s)" % handlers, "if handler:",
            Code.indent, catchblock.text(), Code.unindent, default,
            Code.unindent, final, "if error:", " raise error",
            "return output.get()", Code.unindent, "output.write(block())")
예제 #28
0
 def switch(self, expr, cases):  # [% SWITCH %] [% CASE foo %] ... [% END %]
     code = Code()
     code.write("def block():", code.indent,
                "result = Regex(str(%s) + '$')" % expr)
     default = cases.pop()
     for match, block in cases:
         code.write("for match in Switch(%s):" % match, code.indent,
                    "if result.match(str(match)):", code.indent, block,
                    "return", code.unindent, code.unindent)
     if default is not None:
         code.write(default)
     code.write(code.unindent, "block()")
     return code.text()