def include(self, nameargs): # [% INCLUDE template foo = bar %] file, args = unpack(nameargs, 2) hash = args.pop(0) file = self.filenames(file) if hash: file += ", Dict(%s)" % ", ".join(hash) return "output.write(context.include(%s))" % file
def __init__(self, context, path, config=None): """Initialize a new File object. Takes the pathname of the file as the argument following the context and an optional dictionary of configuration parameters. """ if not isinstance(config, dict): config = {} if not path: self.throw("no file specified") if os.path.isabs(path): root = "" else: root = config.get("root") if root: if root.endswith("/"): root = root[:-1] else: root = "" dir, name = os.path.split(path) name, ext = util.unpack(re.split(r"(\.\w+)$", name), 2) if ext is None: ext = "" if dir.endswith("/"): dir = dir[:-1] if dir == ".": dir = "" name = name + ext if ext.startswith("."): ext = ext[1:] fields = splitpath(dir) if fields and not fields[0]: fields.pop(0) home = "/".join(("..", ) * len(fields)) abspath = os.path.join(root, path) self.path = path self.name = name self.root = root self.home = home self.dir = dir self.ext = ext self.abs = abspath self.user = "" self.group = "" self.isdir = "" self.stat = config.get("stat") or not config.get("nostat") if self.stat: try: stat = os.stat(abspath) except OSError as e: self.throw("%s: %s" % (abspath, e)) for key in STAT_KEYS: setattr(self, key, getattr(stat, "st_%s" % key, None)) if not config.get("noid"): self.user = pwd and getpwuid(self.uid) self.group = grp and getgrgid(self.gid) self.isdir = os.path.isdir(abspath) else: for key in STAT_KEYS: setattr(self, key, "")
def process(self, nameargs): # [% PROCESS template foo = bar %] file, args = unpack(nameargs, 2) hash = args.pop(0) file = self.filenames(file) if hash: file += ", Dict(%s)" % ", ".join(hash) return "output.write(context.process(%s))" % file
def use(self, lnameargs): # [% USE alias = plugin(args) %] file, args, alias = unpack(lnameargs, 3) file = file[0] alias = alias or file args = self.args(args) if args: file = "%s, %s" % (file, args) return "stash.set(%s, context.plugin(%s))" % (alias, file)
def __init__(self, context, path, config=None): """Initialize a new File object. Takes the pathname of the file as the argument following the context and an optional dictionary of configuration parameters. """ if not isinstance(config, dict): config = {} if not path: self.throw("no file specified") if os.path.isabs(path): root = "" else: root = config.get("root") if root: if root.endswith("/"): root = root[:-1] else: root = "" dir, name = os.path.split(path) name, ext = util.unpack(re.split(r"(\.\w+)$", name), 2) if ext is None: ext = "" if dir.endswith("/"): dir = dir[:-1] if dir == ".": dir = "" name = name + ext if ext.startswith("."): ext = ext[1:] fields = splitpath(dir) if fields and not fields[0]: fields.pop(0) home = "/".join(("..",) * len(fields)) abspath = os.path.join(root, path) self.path = path self.name = name self.root = root self.home = home self.dir = dir self.ext = ext self.abs = abspath self.user = "" self.group = "" self.isdir = "" self.stat = config.get("stat") or not config.get("nostat") if self.stat: try: stat = os.stat(abspath) except OSError, e: self.throw("%s: %s" % (abspath, e)) for key in STAT_KEYS: setattr(self, key, getattr(stat, "st_%s" % key, None)) if not config.get("noid"): self.user = pwd and getpwuid(self.uid) self.group = grp and getgrgid(self.gid) self.isdir = os.path.isdir(abspath)
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())")
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())")
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()")
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())")
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()")
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())")
def _parse(self, tokens, info): """Parses the list of input tokens passed by reference and returns an object which contains the compiled representation of the template. This is the main parser DFA loop. See embedded comments for further details. """ self.grammar.install_factory(self.factory) stack = [[0, None]] # DFA stack coderet = None token = None in_string = False in_python = False status = CONTINUE lhs = None text = None self.line = 0 self.file = info and info.name self.inpython = 0 value = None while True: stateno = stack[-1][0] state = self.states[stateno] # see if any lookaheads exist for the current state if "ACTIONS" in state: # get next token and expand any directives (ie. token is a # list) onto the front of the token list while token is None and tokens: token = tokens.pop(0) if isinstance(token, (list, tuple)): text, self.line, token = util.unpack(token, 3) if isinstance(token, (list, tuple)): tokens[:0] = token + [";", ";"] token = None # force redo elif token == "ITEXT": if in_python: # don't perform interpolation in PYTHON blocks token = "TEXT" value = text else: tokens[:0] = self.interpolate_text( text, self.line) token = None # force redo else: # toggle string flag to indicate if we're crossing # a string boundary if token == '"': in_string = not in_string value = tokens and tokens.pop(0) or None if token is None: token = "" # get the next state for the current lookahead token lookup = state["ACTIONS"].get(token) if lookup: action = lookup else: action = state.get("DEFAULT") else: # no lookahead assertions action = state.get("DEFAULT") # ERROR: no ACTION if action is None: break # shift (positive ACTION) if action > 0: stack.append([action, value]) token = value = None else: # reduce (negative ACTION) lhs, len_, code = self.rules[-action] # no action implies ACCEPTance if not action: status = ACCEPT # use dummy sub if code ref doesn't exist if not code: code = lambda *arg: len(arg) >= 2 and arg[1] or None if len_ > 0: codevars = [x[1] for x in stack[-len_:]] else: codevars = [] try: coderet = code(self, *codevars) except TemplateException, e: self._parse_error(str(e), info.name) # reduce stack by len_ if len_ > 0: stack[-len_:] = [] # ACCEPT if status == ACCEPT: return coderet elif status == ABORT: return None elif status == ERROR: break stack.append([ self.states[stack[-1][0]].get("GOTOS", {}).get(lhs), coderet ])
def _parse(self, tokens, info): """Parses the list of input tokens passed by reference and returns an object which contains the compiled representation of the template. This is the main parser DFA loop. See embedded comments for further details. """ self.grammar.install_factory(self.factory) stack = [[0, None]] # DFA stack coderet = None token = None in_string = False in_python = False status = CONTINUE lhs = None text = None self.line = 0 self.file = info and info.name self.inpython = 0 value = None while True: stateno = stack[-1][0] state = self.states[stateno] # see if any lookaheads exist for the current state if "ACTIONS" in state: # get next token and expand any directives (ie. token is a # list) onto the front of the token list while token is None and tokens: token = tokens.pop(0) if isinstance(token, (list, tuple)): text, self.line, token = util.unpack(token, 3) if isinstance(token, (list, tuple)): tokens[:0] = token + [";", ";"] token = None # force redo elif token == "ITEXT": if in_python: # don't perform interpolation in PYTHON blocks token = "TEXT" value = text else: tokens[:0] = self.interpolate_text(text, self.line) token = None # force redo else: # toggle string flag to indicate if we're crossing # a string boundary if token == '"': in_string = not in_string value = tokens and tokens.pop(0) or None if token is None: token = "" # get the next state for the current lookahead token lookup = state["ACTIONS"].get(token) if lookup: action = lookup else: action = state.get("DEFAULT") else: # no lookahead assertions action = state.get("DEFAULT") # ERROR: no ACTION if action is None: break # shift (positive ACTION) if action > 0: stack.append([action, value]) token = value = None else: # reduce (negative ACTION) lhs, len_, code = self.rules[-action] # no action implies ACCEPTance if not action: status = ACCEPT # use dummy sub if code ref doesn't exist if not code: code = lambda *arg: len(arg) >= 2 and arg[1] or None if len_ > 0: codevars = [x[1] for x in stack[-len_:]] else: codevars = [] try: coderet = code(self, *codevars) except TemplateException, e: self._parse_error(str(e), info.name) # reduce stack by len_ if len_ > 0: stack[-len_:] = [] # ACCEPT if status == ACCEPT: return coderet elif status == ABORT: return None elif status == ERROR: break stack.append([self.states[stack[-1][0]].get("GOTOS", {}).get(lhs), coderet])