Ticket #5172: numerical-foo-loop.diff
File numerical-foo-loop.diff, 5.6 KB (added by , 17 years ago) |
---|
-
django/template/defaulttags.py
69 69 return smart_unicode(value) 70 70 return u'' 71 71 72 class NumForNode(Node): 73 def __init__(self, loopvar, start, end, step, exclusive, nodelist_loop): 74 self.loopvar = loopvar 75 self.start = Variable(start) 76 self.end = Variable(end) 77 self.step = Variable(step) 78 self.exclusive = exclusive 79 self.nodelist_loop = nodelist_loop 80 81 def __repr__(self): 82 if self.exclusive: 83 exclusive = ' exclusive' 84 else: 85 exclusive = '' 86 87 if step != 1: 88 step_str = ' by %s' % step 89 else: 90 step_str = '' 91 92 return '<For Node: for %s %s to %s%s%s>' % \ 93 (self.loopvar, self.start, self.end, 94 step_str, exclusive) 95 96 def __iter__(self): 97 for node in self.nodelist_loop: 98 yield node 99 100 def make_seq(self, context): 101 start = int(self.start.resolve(context)) 102 end = int(self.end.resolve(context)) 103 step = int(self.step.resolve(context)) 104 105 if step < 0: 106 end -= int(not self.exclusive) 107 else: 108 end += int(not self.exclusive) 109 110 return xrange(start, end, step) 111 112 113 def render(self, context): 114 nodelist = NodeList() 115 context.push() 116 seq = self.make_seq(context) 117 for i in seq: 118 context[self.loopvar] = i 119 for node in self.nodelist_loop: 120 nodelist.append(node.render(context)) 121 context.pop() 122 return nodelist.render(context) 123 124 72 125 class ForNode(Node): 73 126 def __init__(self, loopvars, sequence, reversed, nodelist_loop): 74 127 self.loopvars, self.sequence = loopvars, sequence … … 565 618 566 619 """ 567 620 bits = token.contents.split() 621 568 622 if len(bits) < 4: 569 623 raise TemplateSyntaxError, "'for' statements should have at least four words: %s" % token.contents 570 624 625 if bits[-3] != 'in' and bits[-2] != 'in': 626 return do_numfor(parser, token) 627 571 628 reversed = bits[-1] == 'reversed' 572 629 in_index = reversed and -3 or -2 573 630 if bits[in_index] != 'in': … … 584 641 return ForNode(loopvars, sequence, reversed, nodelist_loop) 585 642 do_for = register.tag("for", do_for) 586 643 644 def do_numfor(parser, token): 645 bits = token.split_contents() 646 647 if len(bits) < 5: 648 raise TemplateSyntaxError("num 'for' tag should have at least 5 arguments: %s" % token.contents) 649 if bits[3] != 'to': 650 raise TemplateSyntaxError("num 'for' tag should use the format 'for i 1 to 5': %s" % token.contents) 651 try: 652 start, end = bits[2], bits[4] 653 except ValueError: 654 raise TemplateSyntaxError("num 'for' tag should use the format 'for i 1 to 5': %s" % token.contents) 655 656 step = '1' 657 try: 658 if bits[5] == 'by': 659 try: 660 step = bits[6] 661 except IndexError: 662 raise TemplateSyntaxError("step value required after 'by' keyword: %s" % token.contents) 663 except IndexError: 664 pass 665 exclusive = bits[-1] == 'exclusive' 666 667 loopvar = bits[1] 668 669 nodelist_loop = parser.parse(('endfor',)) 670 parser.delete_first_token() 671 return NumForNode(loopvar, start, end, step, exclusive, nodelist_loop) 672 587 673 def do_ifequal(parser, token, negate): 588 674 bits = list(token.split_contents()) 589 675 if len(bits) != 3: -
tests/regressiontests/templates/tests.py
365 365 'for-tag-unpack12': ("{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}", {"items": (('one', 1, 'carrot'), ('two', 2))}, ("one:1,carrot/two:2,/", "one:1,carrot/two:2,INVALID/")), 366 366 'for-tag-unpack13': ("{% for x,y,z in items %}{{ x }}:{{ y }},{{ z }}/{% endfor %}", {"items": (('one', 1, 'carrot'), ('two', 2, 'cheese'))}, ("one:1,carrot/two:2,cheese/", "one:1,carrot/two:2,cheese/")), 367 367 368 369 ### NUMERICAL FOR TAG ##################################################### 370 'numfor-tag01': ("{% for i 1 to 5 %}{{ i }}{% endfor %}", {}, "12345"), 371 'numfor-tag02': ("{% for i 1 to 5 exclusive %}{{ i }}{% endfor %}", {}, u"1234"), 372 'numfor-tag03': ("{% for i 1 to 5 by 2 %}{{ i }}{% endfor %}", {}, "135"), 373 'numfor-tag04': ("{% for i 1 to 5 by 2 exclusive %}{{ i }}{% endfor %}", {}, "13"), 374 375 'numfor-tag05': ("{% for i 5 to 1 by -1 %}{{ i }}{% endfor %}", {}, "54321"), 376 'numfor-tag06': ("{% for i 5 to 1 by -1 exclusive %}{{ i }}{% endfor %}", {}, "5432"), 377 'numfor-tag07': ("{% for i 5 to 1 by -2 %}{{ i }}{% endfor %}", {}, "531"), 378 'numfor-tag08': ("{% for i 5 to 1 by -2 exclusive %}{{ i }}{% endfor %}", {}, "53"), 379 380 'numfor-tag09': ("{% for i 1 to 5 by -1 %}{{ i }}{% endfor %}", {}, ""), 381 'numfor-tag10': ("{% for i 5 to 1 by 1 %}{{ i }}{% endfor %}", {}, ""), 382 383 'numfor-tag11': ("{% for i x to y by z %}{{ i }}{% endfor %}", {'x': 1, 'y': 5, 'z': 1}, "12345"), 384 368 385 ### IF TAG ################################################################ 369 386 'if-tag01': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": True}, "yes"), 370 387 'if-tag02': ("{% if foo %}yes{% else %}no{% endif %}", {"foo": False}, "no"),