Skip to content

Commit 5dfadfe

Browse files
committedApr 13, 2011
Upgrading PyHAML since @mikeboers was kind enough to fix those few bugs I reported. Thanks!
1 parent 46b3ba8 commit 5dfadfe

File tree

4 files changed

+66
-22
lines changed

4 files changed

+66
-22
lines changed
 

‎packages/haml/backwards.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
# For compatibility with 2.5
3+
# Lifted from http://stackoverflow.com/questions/1716428/def-next-for-python-pre-2-6-instead-of-object-next-method/1716464#1716464
4+
5+
class Throw(object): pass
6+
throw = Throw() # easy sentinel hack
7+
8+
def next(iterator, default=throw):
9+
"""next(iterator[, default])
10+
11+
Return the next item from the iterator. If default is given
12+
and the iterator is exhausted, it is returned instead of
13+
raising StopIteration.
14+
"""
15+
try:
16+
iternext = iterator.next.__call__
17+
# this way an AttributeError while executing next() isn't hidden
18+
# (2.6 does this too)
19+
except AttributeError:
20+
raise TypeError("%s object is not an iterator" % type(iterator).__name__)
21+
try:
22+
return iternext()
23+
except StopIteration:
24+
if default is throw:
25+
raise
26+
return default

‎packages/haml/codegen.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,16 @@ def start_document(self):
120120
)
121121

122122

123+
123124
def flatten_attr_list(input):
124125
if not input:
125126
return
126127
if isinstance(input, basestring):
127128
yield input
128129
return
129-
if not isinstance(input, collections.Iterable):
130+
try:
131+
input = iter(input)
132+
except TypeError:
130133
yield input
131134
return
132135
for element in input:

‎packages/haml/nodes.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def print_tree(self, _depth=0, _inline=False):
6565

6666

6767
class GreedyBase(Base):
68-
68+
6969
def __init__(self, *args, **kwargs):
7070
super(GreedyBase, self).__init__(*args, **kwargs)
7171
self._greedy_parent = None
@@ -123,6 +123,10 @@ def __repr__(self):
123123
return '%s(%r)' % (self.__class__.__name__, self.content)
124124

125125

126+
127+
class GreedyContent(Content, GreedyBase):
128+
pass
129+
126130
class Expression(Content, GreedyBase):
127131

128132
def __init__(self, content, filters=''):
@@ -142,7 +146,6 @@ def __repr__(self):
142146

143147

144148

145-
146149
class Tag(Base):
147150

148151
self_closing_names = set('''

‎packages/haml/parse.py

+31-19
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11

2+
try:
3+
next
4+
except NameError:
5+
from .backwards import next
26
import re
37

48
from . import nodes
@@ -51,33 +55,41 @@ def parse(self, source):
5155

5256
line = raw_line.lstrip()
5357

54-
# We track the inter-line depth seperate from the intra-line depth
55-
# so that indentation due to whitespace always results in more
56-
# depth in the graph than many nested nodes from a single line.
57-
# We treat a whitespace-only line as if the indentation level has
58-
# not changed
59-
inter_depth = len(raw_line) - len(line)
60-
intra_depth = 0
61-
62-
# Cleanup the stack. We should only need to do this here as the
63-
# depth only goes up until it is calculated from the next line.
64-
self._prep_stack_for_depth((inter_depth, intra_depth))
65-
58+
if line:
59+
60+
# We track the inter-line depth seperate from the intra-line depth
61+
# so that indentation due to whitespace always results in more
62+
# depth in the graph than many nested nodes from a single line.
63+
inter_depth = len(raw_line) - len(line)
64+
intra_depth = 0
65+
66+
# Cleanup the stack. We should only need to do this here as the
67+
# depth only goes up until it is calculated from the next line.
68+
self._prep_stack_for_depth((inter_depth, intra_depth))
69+
70+
else:
71+
72+
# Pretend that a blank line is at the same depth as the
73+
# previous.
74+
inter_depth, intra_depth = self._stack[-1][0]
75+
6676
# Greedy nodes recieve all content until we fall out of their scope.
6777
if isinstance(self._topmost_node, nodes.GreedyBase):
78+
topmost = self._topmost_node
79+
# Blank lines go at the same level as the previous if it is
80+
# not the parent greedy node.
81+
if not line and topmost is not topmost.outermost_node:
82+
self._stack.pop()
6883
self._add_node(
69-
self._topmost_node.__class__.with_parent(self._topmost_node, line),
84+
topmost.with_parent(topmost, line),
7085
(inter_depth, intra_depth)
7186
)
7287
continue
7388

89+
# Discard all empty lines that are not in a greedy context.
7490
if not line:
75-
# I am unsure if I should just be discarding all empty lines
76-
# like this. There are some scenarios in which an empty line
77-
# would still be used, such as in a multiline string inside a
78-
# source block.
7991
continue
80-
92+
8193
# Main loop. We process a series of tokens, which consist of either
8294
# nodes to add to the stack, or strings to be re-parsed and
8395
# attached as inline.
@@ -143,7 +155,7 @@ def _parse_line(self, line):
143155

144156
# Tags.
145157
m = re.match(r'''
146-
(?:%(%?\w*))? # tag name. the extra % is for mako
158+
(?:%(%?(?:\w+:)?\w*))? # tag name. the extra % is for mako
147159
(?:
148160
\[(.+?)(?:,(.+?))?\] # object reference and prefix
149161
)?

0 commit comments

Comments
 (0)
Please sign in to comment.