mdx_neboard.py
198 lines
| 4.8 KiB
| text/x-python
|
PythonLexer
/ boards / mdx_neboard.py
neko259
|
r98 | from django.core.urlresolvers import reverse | ||
neko259
|
r52 | import markdown | ||
from markdown.inlinepatterns import Pattern | ||||
from markdown.util import etree | ||||
neko259
|
r98 | import boards | ||
neko259
|
r52 | |||
neko259
|
r89 | __author__ = 'neko259' | ||
neko259
|
r52 | |||
neko259
|
r302 | AUTOLINK_PATTERN = r'(https?://\S+)' | ||
neko259
|
r303 | QUOTE_PATTERN = r'^(?<!>)(>[^>].+)$' | ||
neko259
|
r302 | REFLINK_PATTERN = r'((>>)(\d+))' | ||
SPOILER_PATTERN = r'%%(.+)%%' | ||||
COMMENT_PATTERN = r'^(//(.+))' | ||||
neko259
|
r330 | STRIKETHROUGH_PATTERN = r'~(.+)~' | ||
neko259
|
r302 | |||
neko259
|
r398 | |||
neko259
|
r438 | class TextFormatter(): | ||
""" | ||||
An interface for formatter that can be used in the text format panel | ||||
""" | ||||
name = '' | ||||
# Left and right tags for the button preview | ||||
preview_left = '' | ||||
preview_right = '' | ||||
# Left and right characters for the textarea input | ||||
format_left = '' | ||||
format_right = '' | ||||
neko259
|
r52 | class AutolinkPattern(Pattern): | ||
def handleMatch(self, m): | ||||
link_element = etree.Element('a') | ||||
href = m.group(2) | ||||
link_element.set('href', href) | ||||
link_element.text = href | ||||
return link_element | ||||
neko259
|
r438 | class QuotePattern(Pattern, TextFormatter): | ||
name = '' | ||||
preview_left = '<span class="quote">> ' | ||||
preview_right = '</span>' | ||||
format_left = '>' | ||||
neko259
|
r52 | def handleMatch(self, m): | ||
quote_element = etree.Element('span') | ||||
quote_element.set('class', 'quote') | ||||
neko259
|
r90 | quote_element.text = m.group(2) | ||
neko259
|
r52 | |||
return quote_element | ||||
class ReflinkPattern(Pattern): | ||||
def handleMatch(self, m): | ||||
post_id = m.group(4) | ||||
Pavel Ryapolov
|
r310 | |||
neko259
|
r311 | posts = boards.models.Post.objects.filter(id=post_id) | ||
if posts.count() > 0: | ||||
Pavel Ryapolov
|
r310 | ref_element = etree.Element('a') | ||
neko259
|
r398 | post = posts[0] | ||
neko259
|
r406 | if not post.is_opening(): | ||
link = reverse(boards.views.thread, kwargs={ | ||||
'post_id': post.thread_new.get_opening_post().id})\ | ||||
+ '#' + post_id | ||||
Pavel Ryapolov
|
r310 | else: | ||
neko259
|
r398 | link = reverse(boards.views.thread, kwargs={'post_id': post_id}) | ||
Pavel Ryapolov
|
r310 | |||
ref_element.set('href', link) | ||||
ref_element.text = m.group(2) | ||||
neko259
|
r52 | |||
neko259
|
r398 | return ref_element | ||
neko259
|
r52 | |||
neko259
|
r438 | class SpoilerPattern(Pattern, TextFormatter): | ||
name = 's' | ||||
preview_left = '<span class="spoiler">' | ||||
preview_right = '</span>' | ||||
format_left = '%%' | ||||
format_right = '%%' | ||||
neko259
|
r56 | def handleMatch(self, m): | ||
quote_element = etree.Element('span') | ||||
quote_element.set('class', 'spoiler') | ||||
quote_element.text = m.group(2) | ||||
return quote_element | ||||
neko259
|
r438 | class CommentPattern(Pattern, TextFormatter): | ||
name = '' | ||||
preview_left = '<span class="comment">// ' | ||||
preview_right = '</span>' | ||||
format_left = '//' | ||||
neko259
|
r56 | def handleMatch(self, m): | ||
quote_element = etree.Element('span') | ||||
quote_element.set('class', 'comment') | ||||
quote_element.text = '//' + m.group(3) | ||||
return quote_element | ||||
neko259
|
r438 | class StrikeThroughPattern(Pattern, TextFormatter): | ||
name = 's' | ||||
preview_left = '<span class="strikethrough">' | ||||
preview_right = '</span>' | ||||
format_left = '~' | ||||
format_right = '~' | ||||
neko259
|
r330 | def handleMatch(self, m): | ||
quote_element = etree.Element('span') | ||||
quote_element.set('class', 'strikethrough') | ||||
quote_element.text = m.group(2) | ||||
return quote_element | ||||
neko259
|
r438 | class ItalicPattern(TextFormatter): | ||
name = 'i' | ||||
preview_left = '<i>' | ||||
preview_right = '</i>' | ||||
format_left = '_' | ||||
format_right = '_' | ||||
class BoldPattern(TextFormatter): | ||||
name = 'b' | ||||
preview_left = '<b>' | ||||
preview_right = '</b>' | ||||
format_left = '__' | ||||
format_right = '__' | ||||
neko259
|
r440 | class CodePattern(TextFormatter): | ||
name = 'code' | ||||
preview_left = '<code>' | ||||
preview_right = '</code>' | ||||
format_left = ' ' | ||||
neko259
|
r52 | class NeboardMarkdown(markdown.Extension): | ||
def extendMarkdown(self, md, md_globals): | ||||
neko259
|
r100 | self._add_neboard_patterns(md) | ||
self._delete_patterns(md) | ||||
def _delete_patterns(self, md): | ||||
del md.parser.blockprocessors['quote'] | ||||
del md.inlinePatterns['image_link'] | ||||
del md.inlinePatterns['image_reference'] | ||||
def _add_neboard_patterns(self, md): | ||||
neko259
|
r302 | autolink = AutolinkPattern(AUTOLINK_PATTERN, md) | ||
quote = QuotePattern(QUOTE_PATTERN, md) | ||||
reflink = ReflinkPattern(REFLINK_PATTERN, md) | ||||
spoiler = SpoilerPattern(SPOILER_PATTERN, md) | ||||
comment = CommentPattern(COMMENT_PATTERN, md) | ||||
neko259
|
r406 | strikethrough = StrikeThroughPattern(STRIKETHROUGH_PATTERN, md) | ||
neko259
|
r52 | |||
md.inlinePatterns[u'autolink_ext'] = autolink | ||||
neko259
|
r56 | md.inlinePatterns[u'spoiler'] = spoiler | ||
neko259
|
r406 | md.inlinePatterns[u'strikethrough'] = strikethrough | ||
neko259
|
r56 | md.inlinePatterns[u'comment'] = comment | ||
neko259
|
r90 | md.inlinePatterns[u'reflink'] = reflink | ||
md.inlinePatterns[u'quote'] = quote | ||||
neko259
|
r52 | |||
neko259
|
r442 | def make_extension(configs=None): | ||
neko259
|
r52 | return NeboardMarkdown(configs=configs) | ||
neko259
|
r442 | neboard_extension = make_extension() | ||
neko259
|
r52 | |||
def markdown_extended(markup): | ||||
neko259
|
r90 | return markdown.markdown(markup, [neboard_extension], safe_mode=True) | ||
neko259
|
r438 | |||
formatters = [ | ||||
QuotePattern, | ||||
SpoilerPattern, | ||||
ItalicPattern, | ||||
BoldPattern, | ||||
CommentPattern, | ||||
StrikeThroughPattern, | ||||
neko259
|
r440 | CodePattern, | ||
neko259
|
r438 | ] | ||