@register.filter def paragraphs(var, arg): """ Retrieves n number of paragraphs from the supplied text. It doesn't remove any existing tags inside paragraphs.""" class ParagraphParser(HTMLParser): def __init__(self, *args, **kwargs): HTMLParser.__init__(self) self.stack = [] self.paragraphs = int(arg) self.in_p = False self.p_count = 0 def handle_starttag(self, tag, attrs): if tag == 'p': if self.p_count < self.paragraphs: self.in_p = True self.p_count += 1 else: self.in_p = False if self.in_p: self.stack.append(self.__html_start_tag(tag, attrs)) def handle_endtag(self, tag): if self.in_p: self.stack.append(u"" % (tag)) if tag == 'p': self.in_p = False def handle_startendtag(self, tag, attrs): if self.in_p: self.stack.append(self.__html_startend_tag(tag, attrs)) def handle_data(self, data): if self.in_p: self.stack.append(data) def __html_attrs(self, attrs): _attrs = u"" if attrs: _attrs = u" %s" % (' '.join([('%s="%s"' % (k,v)) for k,v in attrs.iteritems()])) return _attrs def __html_start_tag(self, tag, attrs): return u"<%s%s>" % (tag, self.__html_attrs(attrs)) def __html_startend_tag(self, tag, attrs): return "<%s%s/>" % (tag, self.__html_attrs(attrs)) def render(self): return u"".join(self.stack) parseme = ParagraphParser() try: parseme.feed(var) except HTMLParseError: return var return parseme.render() # make sure output is not escaped... it contains HTML! paragraphs.is_safe = True