Browse Source

Getting started with Misago markup

Rafał Pitoń 11 years ago
parent
commit
2b6c80b584

+ 1 - 0
misago/conf/defaults.py

@@ -104,6 +104,7 @@ INSTALLED_APPS = (
     'misago.conf',
     'misago.faker',
     'misago.forums',
+    'misago.markup',
 )
 
 MIDDLEWARE_CLASSES = (

+ 0 - 0
misago/markup/__init__.py


+ 0 - 0
misago/markup/bbcode/__init__.py


+ 0 - 0
misago/markup/bbcode/blocks.py


+ 30 - 0
misago/markup/bbcode/inline.py

@@ -0,0 +1,30 @@
+"""
+Supported inline BBCodes: b, u, i
+"""
+import re
+
+from markdown.inlinepatterns import SimpleTagPattern
+
+
+class SimpleBBCodePattern(SimpleTagPattern):
+    """
+    Case insensitive simple BBCode
+    """
+    def __init__(self, bbcode, tag=None):
+        self.pattern = r'(\[%s\](.*?)\[/%s\])' % (bbcode, bbcode)
+        self.compiled_re = re.compile("^(.*?)%s(.*?)$" % self.pattern,
+                                      re.DOTALL | re.UNICODE | re.IGNORECASE)
+
+        # Api for Markdown to pass safe_mode into instance
+        self.safe_mode = False
+
+        # Store tag
+        self.tag = tag or bbcode.lower()
+
+
+"""
+Register basic BBCodes
+"""
+bold = SimpleBBCodePattern('b')
+italics = SimpleBBCodePattern('i')
+underline = SimpleBBCodePattern('u')

+ 0 - 0
misago/markup/emoji.py


+ 30 - 0
misago/markup/flavours.py

@@ -0,0 +1,30 @@
+from misago.markup.parser import parse_text
+
+
+def common(text, author=None, allow_mentions=True):
+    """
+    Common flavour
+
+    Used in places where full Misago flavour is desired
+
+    Breaks text into paragraphs, supports code, spoiler and quote blocks,
+    headers, lists, images, spoilers, text styles
+
+    Returns dict object
+    """
+    return parse_text(text, author=author, allow_mentions=allow_mentions)
+
+
+def limited(text):
+    """
+    Limited flavour
+
+    Breaks text in paragraphs, supports strong, em, i, u, b,
+    automatically linkifies links.
+
+    Returns parsed text
+    """
+    result =  parse_text(text, allow_mentions=False, allow_links=True,
+                         allow_images=False, allow_blocks=False)
+
+    return result['parsed_text']

+ 0 - 0
misago/markup/mentions.py


+ 87 - 0
misago/markup/parser.py

@@ -0,0 +1,87 @@
+import markdown
+from misago.markup.bbcode import inline
+
+
+def parse_text(text, author=None, allow_mentions=True, allow_links=True,
+           allow_images=True, allow_blocks=True):
+    """
+    Message parser
+
+    Utility for flavours to call
+
+    Breaks text into paragraphs, supports code, spoiler and quote blocks,
+    headers, lists, images, spoilers, text styles
+
+    Returns dict object
+    """
+    md = md_factory(author=author, allow_mentions=allow_mentions,
+                    allow_links=allow_links, allow_images=allow_images,
+                    allow_blocks=allow_blocks)
+
+    parsing_result = {
+        'original_text': text,
+        'parsed_text': '',
+        'markdown': md,
+    }
+
+    # Parse text
+    parsed_text = md.convert(text).strip()
+
+    # Store parsed text on object and return it
+    parsing_result['parsed_text'] = parsed_text
+    return parsing_result
+
+
+def md_factory(author=None, allow_mentions=True, allow_links=True,
+               allow_images=True, allow_blocks=True):
+    """
+    Create and confifure markdown object
+    """
+    md = markdown.Markdown(safe_mode='escape',
+                           extensions=['nl2br'])
+
+    # Remove references
+    del md.preprocessors['reference']
+    del md.inlinePatterns['reference']
+    del md.inlinePatterns['image_reference']
+    del md.inlinePatterns['short_reference']
+
+    # Add [b], [i], [u]
+    md.inlinePatterns.add('bb_b', inline.bold, '<strong')
+    md.inlinePatterns.add('bb_i', inline.italics, '<emphasis')
+    md.inlinePatterns.add('bb_u', inline.underline, '<emphasis2')
+
+    if allow_mentions:
+        # Register mentions
+        pass
+
+    if allow_links:
+        # Add [url]
+        pass
+    else:
+        # Remove links
+        del md.inlinePatterns['link']
+        del md.inlinePatterns['autolink']
+        del md.inlinePatterns['automail']
+
+    if allow_images:
+        # Add [img]
+        pass
+    else:
+        # Remove images
+        del md.inlinePatterns['image_link']
+
+    if allow_blocks:
+        # Add [quote], [spoiler], [list] and [code] blocks
+        pass
+    else:
+        # Remove blocks
+        del md.parser.blockprocessors['hashheader']
+        del md.parser.blockprocessors['setextheader']
+        del md.parser.blockprocessors['code']
+        del md.parser.blockprocessors['quote']
+        del md.parser.blockprocessors['hr']
+        del md.parser.blockprocessors['olist']
+        del md.parser.blockprocessors['ulist']
+
+    return md

+ 38 - 0
misago/markup/tests.py

@@ -0,0 +1,38 @@
+from django.test import TestCase
+from misago.markup.parser import parse_text
+
+
+class ParserTests(TestCase):
+    def test_inline_text(self):
+        """inline elements are correctly parsed"""
+        test_text = """
+Lorem **ipsum** dolor met.
+
+Lorem [b]ipsum[/b] [i]dolor[/i] [u]met[/u].
+
+Lorem [b]**ipsum**[/b] [i]dolor[/i] [u]met[/u].
+
+Lorem [b]**ipsum[/b]** [i]dolor[/i] [u]met[/u].
+
+Lorem [b]__ipsum[/b]__ [i]dolor[/i] [u]met[/u].
+
+Lorem [b][i]ipsum[/i][/b].
+
+Lorem [b][i]ipsum[/b][/i].
+
+Lorem [b]ipsum[/B].
+""".strip()
+
+        expected_result = """
+<p>Lorem <strong>ipsum</strong> dolor met.</p>
+<p>Lorem <b>ipsum</b> <i>dolor</i> <u>met</u>.</p>
+<p>Lorem <b><strong>ipsum</strong></b> <i>dolor</i> <u>met</u>.</p>
+<p>Lorem <b>**ipsum</b>** <i>dolor</i> <u>met</u>.</p>
+<p>Lorem <b>__ipsum</b>__ <i>dolor</i> <u>met</u>.</p>
+<p>Lorem <b><i>ipsum</i></b>.</p>
+<p>Lorem <b>[i]ipsum</b>[/i].</p>
+<p>Lorem <b>ipsum</b>.</p>
+""".strip()
+
+        result = parse_text(test_text)
+        self.assertEqual(expected_result, result['parsed_text'])