mdx_neboard.py
207 lines
| 4.8 KiB
| text/x-python
|
PythonLexer
/ boards / mdx_neboard.py
|
r699 | # coding=utf-8 | ||
|
r52 | import markdown | ||
|
r721 | from markdown.inlinepatterns import Pattern | ||
|
r52 | from markdown.util import etree | ||
|
r721 | |||
|
r98 | import boards | ||
|
r52 | |||
|
r721 | |||
|
r89 | __author__ = 'neko259' | ||
|
r52 | |||
|
r302 | AUTOLINK_PATTERN = r'(https?://\S+)' | ||
|
r644 | QUOTE_PATTERN = r'^(?<!>)(>[^>].*)$' | ||
|
r302 | REFLINK_PATTERN = r'((>>)(\d+))' | ||
|
r487 | SPOILER_PATTERN = r'%%([^(%%)]+)%%' | ||
|
r302 | COMMENT_PATTERN = r'^(//(.+))' | ||
|
r330 | STRIKETHROUGH_PATTERN = r'~(.+)~' | ||
|
r699 | DASH_PATTERN = r'--' | ||
|
r302 | |||
|
r398 | |||
|
r438 | class TextFormatter(): | ||
""" | ||||
An interface for formatter that can be used in the text format panel | ||||
""" | ||||
|
r721 | def __init__(self): | ||
pass | ||||
|
r438 | 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 = '' | ||||
|
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 | ||||
|
r438 | class QuotePattern(Pattern, TextFormatter): | ||
name = '' | ||||
preview_left = '<span class="quote">> ' | ||||
preview_right = '</span>' | ||||
format_left = '>' | ||||
|
r52 | def handleMatch(self, m): | ||
quote_element = etree.Element('span') | ||||
quote_element.set('class', 'quote') | ||||
|
r90 | quote_element.text = m.group(2) | ||
|
r52 | |||
return quote_element | ||||
class ReflinkPattern(Pattern): | ||||
def handleMatch(self, m): | ||||
post_id = m.group(4) | ||||
|
r310 | |||
|
r311 | posts = boards.models.Post.objects.filter(id=post_id) | ||
if posts.count() > 0: | ||||
|
r310 | ref_element = etree.Element('a') | ||
|
r398 | post = posts[0] | ||
|
r310 | |||
|
r589 | ref_element.set('href', post.get_url()) | ||
|
r310 | ref_element.text = m.group(2) | ||
|
r52 | |||
|
r398 | return ref_element | ||
|
r52 | |||
|
r438 | class SpoilerPattern(Pattern, TextFormatter): | ||
name = 's' | ||||
preview_left = '<span class="spoiler">' | ||||
preview_right = '</span>' | ||||
format_left = '%%' | ||||
format_right = '%%' | ||||
|
r56 | def handleMatch(self, m): | ||
quote_element = etree.Element('span') | ||||
quote_element.set('class', 'spoiler') | ||||
quote_element.text = m.group(2) | ||||
return quote_element | ||||
|
r438 | class CommentPattern(Pattern, TextFormatter): | ||
name = '' | ||||
preview_left = '<span class="comment">// ' | ||||
preview_right = '</span>' | ||||
format_left = '//' | ||||
|
r56 | def handleMatch(self, m): | ||
quote_element = etree.Element('span') | ||||
quote_element.set('class', 'comment') | ||||
quote_element.text = '//' + m.group(3) | ||||
return quote_element | ||||
|
r438 | class StrikeThroughPattern(Pattern, TextFormatter): | ||
name = 's' | ||||
preview_left = '<span class="strikethrough">' | ||||
preview_right = '</span>' | ||||
format_left = '~' | ||||
format_right = '~' | ||||
|
r330 | def handleMatch(self, m): | ||
quote_element = etree.Element('span') | ||||
quote_element.set('class', 'strikethrough') | ||||
quote_element.text = m.group(2) | ||||
return quote_element | ||||
|
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 = '__' | ||||
|
r440 | class CodePattern(TextFormatter): | ||
name = 'code' | ||||
preview_left = '<code>' | ||||
preview_right = '</code>' | ||||
format_left = ' ' | ||||
|
r699 | class DashPattern(Pattern): | ||
def handleMatch(self, m): | ||||
return u'—' | ||||
|
r52 | class NeboardMarkdown(markdown.Extension): | ||
def extendMarkdown(self, md, md_globals): | ||||
|
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): | ||||
|
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) | ||||
|
r406 | strikethrough = StrikeThroughPattern(STRIKETHROUGH_PATTERN, md) | ||
|
r699 | dash = DashPattern(DASH_PATTERN, md) | ||
|
r52 | |||
md.inlinePatterns[u'autolink_ext'] = autolink | ||||
|
r56 | md.inlinePatterns[u'spoiler'] = spoiler | ||
|
r406 | md.inlinePatterns[u'strikethrough'] = strikethrough | ||
|
r56 | md.inlinePatterns[u'comment'] = comment | ||
|
r90 | md.inlinePatterns[u'reflink'] = reflink | ||
md.inlinePatterns[u'quote'] = quote | ||||
|
r699 | md.inlinePatterns[u'dash'] = dash | ||
|
r90 | |||
|
r52 | |||
|
r442 | def make_extension(configs=None): | ||
|
r52 | return NeboardMarkdown(configs=configs) | ||
|
r442 | neboard_extension = make_extension() | ||
|
r52 | |||
def markdown_extended(markup): | ||||
|
r651 | return markdown.markdown(markup, [neboard_extension, 'nl2br'], | ||
|
r654 | safe_mode='escape') | ||
|
r438 | |||
formatters = [ | ||||
QuotePattern, | ||||
SpoilerPattern, | ||||
ItalicPattern, | ||||
BoldPattern, | ||||
CommentPattern, | ||||
StrikeThroughPattern, | ||||
|
r440 | CodePattern, | ||
|
r438 | ] | ||