import re from django.shortcuts import get_object_or_404 from django import template from django.utils.text import re_tag from django.core.urlresolvers import reverse from boards.mdx_neboard import LINE_BREAK_HTML from boards import settings IMG_ACTION_URL = '[{}]' REGEX_NEWLINE = re.compile(LINE_BREAK_HTML) TRUNCATOR = '...' HTML4_SINGLETS =( 'br', 'col', 'link', 'base', 'img', 'param', 'area', 'hr', 'input' ) register = template.Library() @register.simple_tag(name='post_url') def post_url(*args, **kwargs): post_id = args[0] post = get_object_or_404('Post', id=post_id) return post.get_absolute_url() @register.inclusion_tag('boards/post.html', name='post_view', takes_context=True) def post_view(context, post, *args, **kwargs): kwargs['perms'] = context['perms'] return post.get_view_params(*args, **kwargs) @register.simple_tag(name='page_url') def page_url(paginator, page_number, *args, **kwargs): if paginator.supports_urls(): return paginator.get_page_url(page_number) @register.filter(name='truncatenewlines_html') def truncatenewlines_html(value, arg): end_pos = 0 start_pos = 0 match_count = 0 # Collect places for truncation while match_count <= arg: m = REGEX_NEWLINE.search(value, end_pos) if m is None: break else: match_count += 1 end_pos = m.end() start_pos = m.start() # Find and close open tags if match_count > arg: truncate_pos = start_pos open_tags = [] text = value[:truncate_pos] current_pos = 0 while True: tag = re_tag.search(text, current_pos) if tag is None: break else: closing_tag, tagname, self_closing = tag.groups() tagname = tagname.lower() if self_closing or tagname in HTML4_SINGLETS: pass elif closing_tag: # Check for match in open tags list try: i = open_tags.index(tagname) except ValueError: pass else: # SGML: An end tag closes, back to the matching start tag, # all unclosed intervening start tags with omitted end tags open_tags = open_tags[i + 1:] else: # Add it to the start of the open tags list open_tags.insert(0, tagname) current_pos = tag.end() if not text.endswith(TRUNCATOR): text += TRUNCATOR for tag in open_tags: text += ''.format(tag) else: text = value return text