summaryrefslogtreecommitdiff
path: root/mako/pygen.py
diff options
context:
space:
mode:
Diffstat (limited to 'mako/pygen.py')
-rw-r--r--mako/pygen.py86
1 files changed, 43 insertions, 43 deletions
diff --git a/mako/pygen.py b/mako/pygen.py
index 9415305..fd19a99 100644
--- a/mako/pygen.py
+++ b/mako/pygen.py
@@ -14,48 +14,48 @@ class PythonPrinter(object):
def __init__(self, stream):
# indentation counter
self.indent = 0
-
+
# a stack storing information about why we incremented
# the indentation counter, to help us determine if we
# should decrement it
self.indent_detail = []
-
+
# the string of whitespace multiplied by the indent
# counter to produce a line
self.indentstring = " "
-
+
# the stream we are writing to
self.stream = stream
-
+
# a list of lines that represents a buffered "block" of code,
# which can be later printed relative to an indent level
self.line_buffer = []
-
+
self.in_indent_lines = False
-
+
self._reset_multi_line_flags()
def write(self, text):
self.stream.write(text)
-
+
def write_indented_block(self, block):
"""print a line or lines of python which already contain indentation.
-
+
The indentation of the total block of lines will be adjusted to that of
the current indent level."""
self.in_indent_lines = False
for l in re.split(r'\r?\n', block):
self.line_buffer.append(l)
-
+
def writelines(self, *lines):
"""print a series of lines of python."""
for line in lines:
self.writeline(line)
-
+
def writeline(self, line):
"""print a line of python, indenting it according to the current
indent level.
-
+
this also adjusts the indentation counter according to the
content of the line.
@@ -66,7 +66,7 @@ class PythonPrinter(object):
self.in_indent_lines = True
decreased_indent = False
-
+
if (line is None or
re.match(r"^\s*#",line) or
re.match(r"^\s*$", line)
@@ -76,29 +76,29 @@ class PythonPrinter(object):
hastext = True
is_comment = line and len(line) and line[0] == '#'
-
+
# see if this line should decrease the indentation level
if (not decreased_indent and
not is_comment and
(not hastext or self._is_unindentor(line))
):
-
+
if self.indent > 0:
self.indent -=1
# if the indent_detail stack is empty, the user
# probably put extra closures - the resulting
- # module wont compile.
- if len(self.indent_detail) == 0:
+ # module wont compile.
+ if len(self.indent_detail) == 0:
raise exceptions.SyntaxException(
"Too many whitespace closures")
self.indent_detail.pop()
-
+
if line is None:
return
-
+
# write the line
self.stream.write(self._indent_line(line) + "\n")
-
+
# see if this line should increase the indentation level.
# note that a line can both decrase (before printing) and
# then increase (after printing) the indentation level.
@@ -127,39 +127,39 @@ class PythonPrinter(object):
def close(self):
"""close this printer, flushing any remaining lines."""
self._flush_adjusted_lines()
-
+
def _is_unindentor(self, line):
"""return true if the given line is an 'unindentor',
relative to the last 'indent' event received.
-
+
"""
-
+
# no indentation detail has been pushed on; return False
if len(self.indent_detail) == 0:
return False
indentor = self.indent_detail[-1]
-
+
# the last indent keyword we grabbed is not a
# compound statement keyword; return False
if indentor is None:
return False
-
+
# if the current line doesnt have one of the "unindentor" keywords,
# return False
match = re.match(r"^\s*(else|elif|except|finally).*\:", line)
if not match:
return False
-
+
# whitespace matches up, we have a compound indentor,
# and this line has an unindentor, this
# is probably good enough
return True
-
+
# should we decide that its not good enough, heres
# more stuff to check.
#keyword = match.group(1)
-
+
# match the original indent keyword
#for crit in [
# (r'if|elif', r'else|elif'),
@@ -168,12 +168,12 @@ class PythonPrinter(object):
#]:
# if re.match(crit[0], indentor) and re.match(crit[1], keyword):
# return True
-
+
#return False
-
+
def _indent_line(self, line, stripspace=''):
"""indent the given line according to the current indent level.
-
+
stripspace is a string of space that will be truncated from the
start of the line before indenting."""
@@ -185,7 +185,7 @@ class PythonPrinter(object):
or triple-quoted section."""
self.backslashed, self.triplequoted = False, False
-
+
def _in_multi_line(self, line):
"""return true if the given line is part of a multi-line block,
via backslash or triple-quote."""
@@ -195,24 +195,24 @@ class PythonPrinter(object):
# guard against the possibility of modifying the space inside of
# a literal multiline string with unfortunately placed
# whitespace
-
+
current_state = (self.backslashed or self.triplequoted)
-
+
if re.search(r"\\$", line):
self.backslashed = True
else:
self.backslashed = False
-
+
triples = len(re.findall(r"\"\"\"|\'\'\'", line))
if triples == 1 or triples % 2 != 0:
self.triplequoted = not self.triplequoted
-
+
return current_state
def _flush_adjusted_lines(self):
stripspace = None
self._reset_multi_line_flags()
-
+
for entry in self.line_buffer:
if self._in_multi_line(entry):
self.stream.write(entry + "\n")
@@ -221,32 +221,32 @@ class PythonPrinter(object):
if stripspace is None and re.search(r"^[ \t]*[^# \t]", entry):
stripspace = re.match(r"^([ \t]*)", entry).group(1)
self.stream.write(self._indent_line(entry, stripspace) + "\n")
-
+
self.line_buffer = []
self._reset_multi_line_flags()
def adjust_whitespace(text):
"""remove the left-whitespace margin of a block of Python code."""
-
+
state = [False, False]
(backslashed, triplequoted) = (0, 1)
def in_multi_line(line):
start_state = (state[backslashed] or state[triplequoted])
-
+
if re.search(r"\\$", line):
state[backslashed] = True
else:
state[backslashed] = False
-
+
def match(reg, t):
m = re.match(reg, t)
if m:
return m, t[len(m.group(0)):]
else:
return None, t
-
+
while line:
if state[triplequoted]:
m, line = match(r"%s" % state[triplequoted], line)
@@ -258,14 +258,14 @@ def adjust_whitespace(text):
m, line = match(r'#', line)
if m:
return start_state
-
+
m, line = match(r"\"\"\"|\'\'\'", line)
if m:
state[triplequoted] = m.group(0)
continue
m, line = match(r".*?(?=\"\"\"|\'\'\'|#|$)", line)
-
+
return start_state
def _indent_line(line, stripspace = ''):