in static/downloads/ezt.py [0:0]
def _parse(self, reader, for_names=None, file_args=(), base_printer=None):
"""text -> string object containing the template.
This is a private helper function doing the real work for method parse.
It returns the parsed template as a 'program'. This program is a sequence
made out of strings or (function, argument) 2-tuples.
Note: comment directives [# ...] are automatically dropped by _re_parse.
"""
filename = reader.filename()
# parse the template program into: (TEXT NEWLINE DIRECTIVE BRACKET)* TEXT
parts = _re_parse.split(reader.text)
program = [ ]
stack = [ ]
if not for_names:
for_names = [ ]
if base_printer is None:
base_printer = ()
printers = [ base_printer ]
one_newline_copied = False
line_number = 1
for i in range(len(parts)):
piece = parts[i]
which = i % 4 # discriminate between: TEXT NEWLINE DIRECTIVE BRACKET
if which == 0:
# TEXT. append if non-empty.
if piece:
if self.compress_whitespace:
piece = _re_whitespace.sub(' ', piece)
program.append(piece)
one_newline_copied = False
elif which == 1:
# NEWLINE. append unless compress_whitespace requested
if piece:
line_number += 1
if self.compress_whitespace:
if not one_newline_copied:
program.append('\n')
one_newline_copied = True
else:
program.append(piece)
elif which == 3:
# BRACKET directive. append '[' if present.
if piece:
program.append('[')
one_newline_copied = False
elif piece:
# DIRECTIVE is present.
one_newline_copied = False
args = _re_args.findall(piece)
cmd = args[0]
if cmd == 'else':
if len(args) > 1:
raise ArgCountSyntaxError(str(args[1:]), filename, line_number)
### check: don't allow for 'for' cmd
idx = stack[-1][1]
true_section = program[idx:]
del program[idx:]
stack[-1][3] = true_section
elif cmd == 'end':
if len(args) > 1:
raise ArgCountSyntaxError(str(args[1:]), filename, line_number)
# note: true-section may be None
try:
cmd, idx, args, true_section, start_line_number = stack.pop()
except IndexError:
raise UnmatchedEndError(None, filename, line_number)
else_section = program[idx:]
if cmd == 'format':
printers.pop()
else:
func = getattr(self, '_cmd_' + re.sub('-', '_', cmd))
program[idx:] = [ (func, (args, true_section, else_section),
filename, line_number) ]
if cmd == 'for':
for_names.pop()
elif cmd in _block_cmds:
if len(args) > _block_cmd_specs[cmd] + 1:
raise ArgCountSyntaxError(str(args[1:]), filename, line_number)
### this assumes arg1 is always a ref unless cmd is 'define'
if cmd != 'define':
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]) # append the refname
elif cmd == 'format':
if args[1][0]:
raise BadFormatConstantError(str(args[1:]), filename, line_number)
printers.append(_parse_format(args[1][1]))
# remember the cmd, current pos, args, and a section placeholder
stack.append([cmd, len(program), args[1:], None, line_number])
elif cmd == 'include' or cmd == 'insertfile':
is_insertfile = (cmd == 'insertfile')
# extra arguments are meaningless when using insertfile
if is_insertfile and len(args) != 2:
raise ArgCountSyntaxError(str(args), filename, line_number)
if args[1][0] == '"':
include_filename = args[1][1:-1]
if is_insertfile:
program.append(reader.read_other(include_filename).text)
else:
f_args = [ ]
for arg in args[2:]:
f_args.append(_prepare_ref(arg, for_names, file_args))
program.extend(self._parse(reader.read_other(include_filename),
for_names, f_args, printers[-1]))
else:
if len(args) != 2:
raise ArgCountSyntaxError(str(args), filename, line_number)
if is_insertfile:
cmd = self._cmd_insertfile
else:
cmd = self._cmd_include
program.append((cmd,
(_prepare_ref(args[1], for_names, file_args),
reader, printers[-1]), filename, line_number))
elif cmd == 'if-any':
f_args = [ ]
for arg in args[1:]:
f_args.append(_prepare_ref(arg, for_names, file_args))
stack.append(['if-any', len(program), f_args, None, line_number])
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_subst,
(printers[-1], f_args[0], f_args[1:]),
filename, line_number))
else:
valref = _prepare_ref(args[0], for_names, file_args)
program.append((self._cmd_print, (printers[-1], valref),
filename, line_number))
if stack:
raise UnclosedBlocksError('Block opened at line %s' % stack[-1][4],
filename=filename)
return program