mdx_neboard.py
178 lines
| 3.9 KiB
| text/x-python
|
PythonLexer
/ boards / mdx_neboard.py
neko259
|
r699 | # coding=utf-8 | ||
neko259
|
r736 | import re | ||
import bbcode | ||||
neko259
|
r721 | |||
neko259
|
r98 | import boards | ||
neko259
|
r52 | |||
neko259
|
r721 | |||
neko259
|
r89 | __author__ = 'neko259' | ||
neko259
|
r52 | |||
neko259
|
r736 | REFLINK_PATTERN = re.compile(r'\d+') | ||
neko259
|
r754 | MULTI_NEWLINES_PATTERN = re.compile(r'(\r?\n){2,}') | ||
ONE_NEWLINE = '\n' | ||||
neko259
|
r302 | |||
neko259
|
r398 | |||
neko259
|
r438 | class TextFormatter(): | ||
""" | ||||
An interface for formatter that can be used in the text format panel | ||||
""" | ||||
neko259
|
r721 | def __init__(self): | ||
pass | ||||
neko259
|
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 = '' | ||||
neko259
|
r736 | class AutolinkPattern(): | ||
neko259
|
r52 | 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
|
r736 | class QuotePattern(TextFormatter): | ||
name = 'q' | ||||
preview_left = '<span class="multiquote">' | ||||
neko259
|
r438 | preview_right = '</span>' | ||
neko259
|
r736 | format_left = '[quote]' | ||
format_right = '[/quote]' | ||||
neko259
|
r52 | |||
neko259
|
r736 | class SpoilerPattern(TextFormatter): | ||
name = 'spoiler' | ||||
neko259
|
r438 | preview_left = '<span class="spoiler">' | ||
preview_right = '</span>' | ||||
neko259
|
r736 | format_left = '[spoiler]' | ||
format_right = '[/spoiler]' | ||||
neko259
|
r438 | |||
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
|
r736 | class CommentPattern(TextFormatter): | ||
neko259
|
r438 | name = '' | ||
preview_left = '<span class="comment">// ' | ||||
preview_right = '</span>' | ||||
neko259
|
r736 | format_left = '[comment]' | ||
format_right = '[/comment]' | ||||
neko259
|
r56 | |||
neko259
|
r755 | # TODO Use <s> tag here | ||
neko259
|
r736 | class StrikeThroughPattern(TextFormatter): | ||
neko259
|
r438 | name = 's' | ||
preview_left = '<span class="strikethrough">' | ||||
preview_right = '</span>' | ||||
neko259
|
r736 | format_left = '[s]' | ||
format_right = '[/s]' | ||||
neko259
|
r330 | |||
neko259
|
r438 | class ItalicPattern(TextFormatter): | ||
name = 'i' | ||||
preview_left = '<i>' | ||||
preview_right = '</i>' | ||||
neko259
|
r736 | format_left = '[i]' | ||
format_right = '[/i]' | ||||
neko259
|
r438 | |||
class BoldPattern(TextFormatter): | ||||
name = 'b' | ||||
preview_left = '<b>' | ||||
preview_right = '</b>' | ||||
neko259
|
r736 | format_left = '[b]' | ||
format_right = '[/b]' | ||||
neko259
|
r438 | |||
neko259
|
r440 | class CodePattern(TextFormatter): | ||
name = 'code' | ||||
preview_left = '<code>' | ||||
preview_right = '</code>' | ||||
neko259
|
r736 | format_left = '[code]' | ||
format_right = '[/code]' | ||||
neko259
|
r699 | |||
neko259
|
r736 | def render_reflink(tag_name, value, options, parent, context): | ||
if not REFLINK_PATTERN.match(value): | ||||
return u'>>%s' % value | ||||
neko259
|
r100 | |||
neko259
|
r736 | post_id = int(value) | ||
neko259
|
r100 | |||
neko259
|
r736 | posts = boards.models.Post.objects.filter(id=post_id) | ||
if posts.exists(): | ||||
post = posts[0] | ||||
neko259
|
r52 | |||
neko259
|
r736 | return u'<a href=%s>>>%s</a>' % (post.get_url(), post_id) | ||
else: | ||||
return u'>>%s' % value | ||||
neko259
|
r90 | |||
neko259
|
r52 | |||
neko259
|
r755 | def render_quote(tag_name, value, options, parent, context): | ||
source = u'' | ||||
if 'source' in options: | ||||
source = options['source'] | ||||
result = u'' | ||||
if source: | ||||
result = u'<div class="multiquote"><div class="quote-header">%s</div><div class="quote-text">%s</div></div>' % (source, value) | ||||
else: | ||||
result = u'<div class="multiquote"><div class="quote-text">%s</div></div>' % value | ||||
return result | ||||
neko259
|
r754 | def preparse_text(text): | ||
""" | ||||
Performs manual parsing before the bbcode parser is used. | ||||
""" | ||||
return MULTI_NEWLINES_PATTERN.sub(ONE_NEWLINE, text) | ||||
neko259
|
r736 | def bbcode_extended(markup): | ||
neko259
|
r750 | parser = bbcode.Parser() | ||
neko259
|
r736 | parser.add_formatter('post', render_reflink, strip=True) | ||
neko259
|
r755 | parser.add_formatter('quote', render_quote, strip=True) | ||
neko259
|
r736 | parser.add_simple_formatter('comment', | ||
u'<span class="comment">//%(value)s</span>') | ||||
parser.add_simple_formatter('spoiler', | ||||
u'<span class="spoiler">%(value)s</span>') | ||||
parser.add_simple_formatter('s', | ||||
u'<span class="strikethrough">%(value)s</span>') | ||||
parser.add_simple_formatter('code', | ||||
u'<pre><code>%(value)s</pre></code>') | ||||
neko259
|
r754 | |||
text = preparse_text(markup) | ||||
return parser.format(text) | ||||
neko259
|
r438 | |||
formatters = [ | ||||
QuotePattern, | ||||
SpoilerPattern, | ||||
ItalicPattern, | ||||
BoldPattern, | ||||
CommentPattern, | ||||
StrikeThroughPattern, | ||||
neko259
|
r440 | CodePattern, | ||
neko259
|
r438 | ] | ||