⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ezt.py

📁 PHP写的图片查看器
💻 PY
📖 第 1 页 / 共 2 页
字号:
          cmd, idx, args, true_section = stack.pop()          else_section = program[idx:]          func = getattr(self, '_cmd_' + re.sub('-', '_', cmd))          program[idx:] = [ (func, (args, true_section, else_section)) ]          if cmd == 'for':            for_names.pop()        elif cmd in _block_cmds:          if len(args) > _block_cmd_specs[cmd] + 1:            raise ArgCountSyntaxError()          ### this assumes arg1 is always a ref          args[1] = _prepare_ref(args[1], for_names, file_args)          # handle arg2 for the 'is' command          if cmd == 'is':            args[2] = _prepare_ref(args[2], for_names, file_args)          elif cmd == 'for':            for_names.append(args[1][0])          # remember the cmd, current pos, args, and a section placeholder          stack.append([cmd, len(program), args[1:], None])        elif cmd == 'include':          if args[1][0] == '"':            include_filename = args[1][1:-1]            if base:              include_filename = os.path.join(base, include_filename)            f_args = [ ]            for arg in args[2:]:              f_args.append(_prepare_ref(arg, for_names, file_args))            program.extend(self._parse_file(include_filename, for_names,                                            f_args))          else:            if len(args) != 2:              raise ArgCountSyntaxError()            program.append((self._cmd_include,                            (_prepare_ref(args[1], for_names, file_args),                             base)))        else:          # implied PRINT command          if len(args) > 1:            f_args = [ ]            for arg in args:              f_args.append(_prepare_ref(arg, for_names, file_args))            program.append((self._cmd_format, (f_args[0], f_args[1:])))          else:            program.append((self._cmd_print,                            _prepare_ref(args[0], for_names, file_args)))    if stack:      ### would be nice to say which blocks...      raise UnclosedBlocksError()    return program  def _execute(self, program, fp, ctx):    """This private helper function takes a 'program' sequence as created    by the method '_parse' and executes it step by step.  strings are written    to the file object 'fp' and functions are called.    """    for step in program:      if isinstance(step, StringType):        fp.write(step)      else:        step[0](step[1], fp, ctx)  def _cmd_print(self, valref, fp, ctx):    value = _get_value(valref, ctx)    # if the value has a 'read' attribute, then it is a stream: copy it    if hasattr(value, 'read'):      while 1:        chunk = value.read(16384)        if not chunk:          break        fp.write(chunk)    else:      fp.write(value)  def _cmd_format(self, (valref, args), fp, ctx):    fmt = _get_value(valref, ctx)    parts = _re_subst.split(fmt)    for i in range(len(parts)):      piece = parts[i]      if i%2 == 1 and piece != '%':        idx = int(piece)        if idx < len(args):          piece = _get_value(args[idx], ctx)        else:          piece = '<undef>'      fp.write(piece)  def _cmd_include(self, (valref, base), fp, ctx):    fname = _get_value(valref, ctx)    if base:      fname = os.path.join(base, fname)    ### note: we don't have the set of for_names to pass into this parse.    ### I don't think there is anything to do but document it.    self._execute(self._parse_file(fname), fp, ctx)  def _cmd_if_any(self, args, fp, ctx):    "If the value is a non-empty string or non-empty list, then T else F."    ((valref,), t_section, f_section) = args    value = _get_value(valref, ctx)    self._do_if(value, t_section, f_section, fp, ctx)  def _cmd_if_index(self, args, fp, ctx):    ((valref, value), t_section, f_section) = args    list, idx = ctx.for_index[valref[0]]    if value == 'even':      value = idx % 2 == 0    elif value == 'odd':      value = idx % 2 == 1    elif value == 'first':      value = idx == 0    elif value == 'last':      value = idx == len(list)-1    else:      value = idx == int(value)    self._do_if(value, t_section, f_section, fp, ctx)  def _cmd_is(self, args, fp, ctx):    ((left_ref, right_ref), t_section, f_section) = args    value = _get_value(right_ref, ctx)    value = string.lower(_get_value(left_ref, ctx)) == string.lower(value)    self._do_if(value, t_section, f_section, fp, ctx)  def _do_if(self, value, t_section, f_section, fp, ctx):    if t_section is None:      t_section = f_section      f_section = None    if value:      section = t_section    else:      section = f_section    if section is not None:      self._execute(section, fp, ctx)  def _cmd_for(self, args, fp, ctx):    ((valref,), unused, section) = args    list = _get_value(valref, ctx)    if isinstance(list, StringType):      raise NeedSequenceError()    refname = valref[0]    ctx.for_index[refname] = idx = [ list, 0 ]    for item in list:      self._execute(section, fp, ctx)      idx[1] = idx[1] + 1    del ctx.for_index[refname]def boolean(value):  "Return a value suitable for [if-any bool_var] usage in a template."  if value:    return 'yes'  return Nonedef _prepare_ref(refname, for_names, file_args):  """refname -> a string containing a dotted identifier. example:"foo.bar.bang"  for_names -> a list of active for sequences.  Returns a `value reference', a 3-Tupel made out of (refname, start, rest),   for fast access later.  """  # is the reference a string constant?  if refname[0] == '"':    return None, refname[1:-1], None  # if this is an include-argument, then just return the prepared ref  if refname[:3] == 'arg':    try:      idx = int(refname[3:])    except ValueError:      pass    else:      if idx < len(file_args):        return file_args[idx]  parts = string.split(refname, '.')  start = parts[0]  rest = parts[1:]  while rest and (start in for_names):    # check if the next part is also a "for name"    name = start + '.' + rest[0]    if name in for_names:      start = name      del rest[0]    else:      break  return refname, start, restdef _get_value((refname, start, rest), ctx):  """(refname, start, rest) -> a prepared `value reference' (see above).  ctx -> an execution context instance.  Does a name space lookup within the template name space.  Active   for blocks take precedence over data dictionary members with the   same name.  """  if rest is None:    # it was a string constant    return start  if ctx.for_index.has_key(start):    list, idx = ctx.for_index[start]    ob = list[idx]  elif ctx.data.has_key(start):    ob = ctx.data[start]  else:    raise UnknownReference(refname)  # walk the rest of the dotted reference  for attr in rest:    try:      ob = getattr(ob, attr)    except AttributeError:      raise UnknownReference(refname)  # make sure we return a string instead of some various Python types  if isinstance(ob, IntType) or isinstance(ob, FloatType):    return str(ob)  if ob is None:    return ''  # string or a sequence  return obclass _context:  """A container for the execution context"""class ArgCountSyntaxError(Exception):  passclass UnknownReference(Exception):  passclass NeedSequenceError(Exception):  passclass UnclosedBlocksError(Exception):  pass# --- standard test environment ---def test_parse():  assert _re_parse.split('[a]') == ['', '[a]', None, '']  assert _re_parse.split('[a] [b]') == \         ['', '[a]', None, ' ', '[b]', None, '']  assert _re_parse.split('[a c] [b]') == \         ['', '[a c]', None, ' ', '[b]', None, '']  assert _re_parse.split('x [a] y [b] z') == \         ['x ', '[a]', None, ' y ', '[b]', None, ' z']  assert _re_parse.split('[a "b" c "d"]') == \         ['', '[a "b" c "d"]', None, '']  assert _re_parse.split(r'["a \"b[foo]" c.d f]') == \         ['', '["a \\"b[foo]" c.d f]', None, '']def _test(argv):  import doctest, ezt             verbose = "-v" in argv  return doctest.testmod(ezt, verbose=verbose)if __name__ == "__main__":  # invoke unit test for this module:  import sys  sys.exit(_test(sys.argv)[0])

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -