diff --git a/boards/mdx_neboard.py b/boards/mdx_neboard.py --- a/boards/mdx_neboard.py +++ b/boards/mdx_neboard.py @@ -2,6 +2,9 @@ import re import bbcode + +from urllib.parse import unquote + from django.core.exceptions import ObjectDoesNotExist from django.core.urlresolvers import reverse @@ -14,6 +17,7 @@ import boards REFLINK_PATTERN = re.compile(r'^\d+$') MULTI_NEWLINES_PATTERN = re.compile(r'(\r?\n){2,}') ONE_NEWLINE = '\n' +REGEX_URL = re.compile(r'https?\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(/\S*)?') class TextFormatter(): @@ -169,36 +173,6 @@ def render_notification(tag_name, value, reverse('notifications', kwargs={'username': username}), username) -def preparse_text(text): - """ - Performs manual parsing before the bbcode parser is used. - """ - - return MULTI_NEWLINES_PATTERN.sub(ONE_NEWLINE, text) - - -def bbcode_extended(markup): - # The newline hack is added because br's margin does not work in all - # browsers except firefox, when the div's does. - parser = bbcode.Parser(newline='
') - parser.add_formatter('post', render_reflink, strip=True) - parser.add_formatter('thread', render_multithread, strip=True) - parser.add_formatter('quote', render_quote, strip=True) - parser.add_formatter('user', render_notification, strip=True) - parser.add_simple_formatter('comment', - '//%(value)s') - parser.add_simple_formatter('spoiler', - '%(value)s') - parser.add_simple_formatter('s', - '%(value)s') - # TODO Why not use built-in tag? - parser.add_simple_formatter('code', - '%(value)s
',
- render_embedded=False)
-
- text = preparse_text(markup)
- return parser.format(text)
-
formatters = [
QuotePattern,
SpoilerPattern,
@@ -208,3 +182,52 @@ formatters = [
StrikeThroughPattern,
CodePattern,
]
+
+
+PREPARSE_PATTERNS = {
+ r'>>>(\d+)': r'[thread]\1[/thread]', # Multi-thread post ">>>123"
+ r'(?)>>(\d+)': r'[post]\1[/post]', # Reflink ">>123"
+ r'^>([^>].+)': r'[quote]\1[/quote]', # Quote ">text"
+ r'^//(.+)': r'[comment]\1[/comment]', # Comment "//text"
+ r'\B@(\w+)': r'[user]\1[/user]', # User notification "@user"
+}
+
+
+class Parser:
+ def __init__(self):
+ # The newline hack is added because br's margin does not work in all
+ # browsers except firefox, when the div's does.
+ self.parser = bbcode.Parser(newline='')
+
+ self.parser.add_formatter('post', render_reflink, strip=True)
+ self.parser.add_formatter('thread', render_multithread, strip=True)
+ self.parser.add_formatter('quote', render_quote, strip=True)
+ self.parser.add_formatter('user', render_notification, strip=True)
+ self.parser.add_simple_formatter(
+ 'comment', '//%(value)s')
+ self.parser.add_simple_formatter(
+ 'spoiler', '%(value)s')
+ self.parser.add_simple_formatter(
+ 's', '%(value)s')
+ # TODO Why not use built-in tag?
+ self.parser.add_simple_formatter('code',
+ '%(value)s
',
+ render_embedded=False)
+
+ def preparse(self, text):
+ """
+ Performs manual parsing before the bbcode parser is used.
+ Preparsed text is saved as raw and the text before preparsing is lost.
+ """
+ new_text = MULTI_NEWLINES_PATTERN.sub(ONE_NEWLINE, text)
+
+ for key, value in PREPARSE_PATTERNS.items():
+ new_text = re.sub(key, value, new_text, flags=re.MULTILINE)
+
+ for link in REGEX_URL.findall(text):
+ new_text = new_text.replace(link, unquote(link))
+
+ return new_text
+
+ def parse(self, text):
+ return self.parser.format(text)
\ No newline at end of file
diff --git a/boards/models/post.py b/boards/models/post.py
--- a/boards/models/post.py
+++ b/boards/models/post.py
@@ -3,8 +3,6 @@ from datetime import time as dtime
import logging
import re
-from urllib.parse import unquote
-
from adjacent import Client
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
@@ -14,7 +12,7 @@ from django.template.loader import rende
from django.utils import timezone
from boards import settings
-from boards.mdx_neboard import bbcode_extended
+from boards.mdx_neboard import Parser
from boards.models import PostImage
from boards.models.base import Viewable
from boards.utils import datetime_to_epoch, cached_result
@@ -45,7 +43,6 @@ UNKNOWN_UA = ''
REGEX_REPLY = re.compile(r'\[post\](\d+)\[/post\]')
REGEX_MULTI_THREAD = re.compile(r'\[thread\](\d+)\[/thread\]')
-REGEX_URL = re.compile(r'https?\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(/\S*)?')
REGEX_NOTIFICATION = re.compile(r'\[user\](\w+)\[/user\]')
PARAMETER_TRUNCATED = 'truncated'
@@ -64,14 +61,6 @@ PARAMETER_REPLY_LINK = 'reply_link'
DIFF_TYPE_HTML = 'html'
DIFF_TYPE_JSON = 'json'
-PREPARSE_PATTERNS = {
- r'>>>(\d+)': r'[thread]\1[/thread]', # Multi-thread post ">>>123"
- r'(?)>>(\d+)': r'[post]\1[/post]', # Reflink ">>123"
- r'^>([^>].+)': r'[quote]\1[/quote]', # Quote ">text"
- r'^//(.+)': r'[comment]\1[/comment]', # Comment "//text"
- r'\B@(\w+)': r'[user]\1[/user]', # User notification "@user"
-}
-
class PostManager(models.Manager):
@transaction.atomic
@@ -92,7 +81,7 @@ class PostManager(models.Manager):
else:
new_thread = False
- pre_text = self._preparse_text(text)
+ pre_text = Parser().preparse(text)
post = self.create(title=title,
text=pre_text,
@@ -158,21 +147,6 @@ class PostManager(models.Manager):
return ppd
- # TODO Make a separate parser module and move preparser there
- def _preparse_text(self, text: str) -> str:
- """
- Preparses text to change patterns like '>>' to a proper bbcode
- tags.
- """
-
- for key, value in PREPARSE_PATTERNS.items():
- text = re.sub(key, value, text, flags=re.MULTILINE)
-
- for link in REGEX_URL.findall(text):
- text = text.replace(link, unquote(link))
-
- return text
-
class Post(models.Model, Viewable):
"""A post is a message."""
@@ -398,7 +372,7 @@ class Post(models.Model, Viewable):
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
- self._text_rendered = bbcode_extended(self.get_raw_text())
+ self._text_rendered = Parser().parse(self.get_raw_text())
super().save(force_insert, force_update, using, update_fields)
diff --git a/boards/templates/boards/posting_general.html b/boards/templates/boards/posting_general.html
--- a/boards/templates/boards/posting_general.html
+++ b/boards/templates/boards/posting_general.html
@@ -136,7 +136,6 @@