Skip to content

Commit

Permalink
Fixed multi-breakpoints
Browse files Browse the repository at this point in the history
Raise an exception on trailing breakpoints
  • Loading branch information
ojii committed Sep 21, 2012
1 parent 5fae1b2 commit f1bc078
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 6 deletions.
5 changes: 3 additions & 2 deletions classytags/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ def __init__(self, tagname, breakpoints, got):


class TrailingBreakpoint(BaseError):
template = ("Tag ends in trailing breakpoint '%(breakpoint)s' without an argument following.")
template = ("Tag %(tagname)s ends in trailing breakpoint '%(breakpoint)s' without an argument following.")

def __init__(self, breakpoint):
def __init__(self, tagname, breakpoint):
self.tagname = tagname
self.breakpoint = breakpoint


Expand Down
23 changes: 20 additions & 3 deletions classytags/parser.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from classytags.exceptions import (BreakpointExpected, TooManyArguments,
ArgumentRequiredError)
ArgumentRequiredError, TrailingBreakpoint)
from copy import deepcopy
from django import template

Expand All @@ -21,14 +21,18 @@ def parse(self, parser, tokens):
self.tagname = self.bits.pop(0)
self.kwargs = {}
self.blocks = {}
self.forced_next = None
# Get the first chunk of arguments until the next breakpoint
self.arguments = self.options.get_arguments()
self.current_argument = None
# get a copy of the bits (tokens)
self.todo = list(self.bits)
# parse the bits (tokens)
breakpoint = False
for bit in self.bits:
self.handle_bit(bit)
breakpoint = self.handle_bit(bit)
if breakpoint:
raise TrailingBreakpoint(self.tagname, breakpoint)
# finish the bits (tokens)
self.finish()
# parse block tags
Expand All @@ -39,17 +43,31 @@ def handle_bit(self, bit):
"""
Handle the current bit
"""
breakpoint = False
if self.forced_next is not None:
if bit != self.forced_next:
raise BreakpointExpected(self.tagname, [self.forced_next], bit)
elif bit in self.options.reversed_combined_breakpoints:
expected = self.options.reversed_combined_breakpoints[bit]
raise BreakpointExpected(self.tagname, [expected], bit)
# Check if the current bit is the next breakpoint
if bit == self.options.next_breakpoint:
self.handle_next_breakpoint(bit)
breakpoint = bit
# Check if the current bit is a future breakpoint
elif bit in self.options.breakpoints:
self.handle_breakpoints(bit)
breakpoint = bit
# Otherwise it's a 'normal' argument
else:
self.handle_argument(bit)
if bit in self.options.combined_breakpoints:
self.forced_next = self.options.combined_breakpoints[bit]
else:
self.forced_next = None
# remove from todos
del self.todo[0]
return breakpoint

def handle_next_breakpoint(self, bit):
"""
Expand Down Expand Up @@ -163,7 +181,6 @@ def parse_blocks(self):
for block in blocks:
identifiers[block] = block.collect(self)
while blocks:
block_identifiers = []
current_block = blocks.pop(0)
current_identifiers = identifiers[current_block]
block_identifiers = list(current_identifiers)
Expand Down
1 change: 1 addition & 0 deletions classytags/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def __init__(self, options, breakpoints, blocks, combind_breakpoints):
self.breakpoints = copy(breakpoints)
self.blocks = copy(blocks)
self.combined_breakpoints = dict(combind_breakpoints.items())
self.reversed_combined_breakpoints = dict((v,k) for k,v in combind_breakpoints.items())
self.current_breakpoint = None
if self.breakpoints:
self.next_breakpoint = self.breakpoints.pop(0)
Expand Down
2 changes: 1 addition & 1 deletion runtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,5 @@ def runtests():

if __name__ == "__main__":
failures = runtests()
if failures:
if failures: # pragma: no cover
sys.exit(bool(failures))

0 comments on commit f1bc078

Please sign in to comment.