def find_closing_tag(tag, max_tags=sys.maxint):
 if tag.self_closing:
  return None
 stack = []
 (block, offset) = (tag.end_block, tag.end_offset)
 while (block.isValid() and (max_tags > 0)):
  (block, tag_start) = next_tag_boundary(block, offset)
  if ((block is None) or (not tag_start.is_start)):
   break
  (endblock, tag_end) = next_tag_boundary(block, tag_start.offset)
  if ((endblock is None) or tag_end.is_start):
   break
  if tag_start.closing:
   try:
    (prefix, name) = stack.pop()
   except IndexError:
    prefix = name = None
   if ((prefix, name) != (tag_start.prefix, tag_start.name)):
    return Tag(block, tag_start, endblock, tag_end)
  elif tag_end.self_closing:
   pass
  else:
   stack.append((tag_start.prefix, tag_start.name))
  (block, offset) = (endblock, tag_end.offset)
  max_tags -= 1
 return None

def find_closing_tag ( tag , max_tags = sys . maxint ) : if tag . self_closing : return None stack = [ ] ( block , offset ) = ( tag . end_block , tag . end_offset ) while ( block . isValid ( ) and ( max_tags > 0 ) ) : ( block , tag_start ) = next_tag_boundary ( block , offset ) if ( ( block is None ) or ( not tag_start . is_start ) ) : break ( endblock , tag_end ) = next_tag_boundary ( block , tag_start . offset ) if ( ( endblock is None ) or tag_end . is_start ) : break if tag_start . closing : try : ( prefix , name ) = stack . pop ( ) except IndexError : prefix = name = None if ( ( prefix , name ) != ( tag_start . prefix , tag_start . name ) ) : return Tag ( block , tag_start , endblock , tag_end ) elif tag_end . self_closing : pass else : stack . append ( ( tag_start . prefix , tag_start . name ) ) ( block , offset ) = ( endblock , tag_end . offset ) max_tags -= 1 return None
find the closing tag corresponding to the specified tag .