Rafał Pitoń 8 лет назад
Родитель
Сommit
1159edee2c
3 измененных файлов с 67 добавлено и 1 удалено
  1. 47 1
      misago/markup/bbcode/inline.py
  2. 1 0
      misago/markup/parser.py
  3. 19 0
      misago/markup/tests/test_parser.py

+ 47 - 1
misago/markup/bbcode/inline.py

@@ -3,7 +3,7 @@ Supported inline BBCodes: b, u, i
 """
 import re
 
-from markdown.inlinepatterns import SimpleTagPattern
+from markdown.inlinepatterns import IMAGE_LINK_RE, ImagePattern, SimpleTagPattern, util
 
 
 class SimpleBBCodePattern(SimpleTagPattern):
@@ -27,3 +27,49 @@ class SimpleBBCodePattern(SimpleTagPattern):
 bold = SimpleBBCodePattern('b')
 italics = SimpleBBCodePattern('i')
 underline = SimpleBBCodePattern('u')
+
+
+class BBcodePattern(object):
+    def __init__(self, pattern, markdown_instance=None):
+        self.pattern = pattern
+        self.compiled_re = re.compile(
+            "^(.*?)%s(.*)$" % pattern, re.DOTALL | re.UNICODE  | re.IGNORECASE)
+
+        self.safe_mode = False
+        if markdown_instance:
+            self.markdown = markdown_instance
+
+
+class BBCodeImagePattern(BBcodePattern, ImagePattern):
+    def handleMatch(self, m):
+        el = util.etree.Element("img")
+        src_parts = m.group(2).split()
+        if src_parts:
+            src = src_parts[0]
+            if src[0] == "<" and src[-1] == ">":
+                src = src[1:-1]
+            el.set('src', self.sanitize_url(self.unescape(src)))
+        else:
+            el.set('src', "")
+        if len(src_parts) > 1:
+            el.set('title', dequote(self.unescape(" ".join(src_parts[1:]))))
+
+        if self.markdown.enable_attributes:
+            truealt = handleAttributes(m.group(2), el)
+        else:
+            truealt = m.group(2)
+
+        el.set('alt', self.unescape(truealt))
+        return el
+
+
+IMAGE_PATTERN = r'\[img\](.*?)\[/img\]'
+
+
+def image(md):
+    return BBCodeImagePattern(IMAGE_PATTERN, md)
+
+
+# todo: URL
+# note: can't just replace url's bbcode with md cos:
+# [url=http://onet.pl][1][/url] => [[1]](http://onet.pl)

+ 1 - 0
misago/markup/parser.py

@@ -108,6 +108,7 @@ def md_factory(allow_links=True, allow_images=True, allow_blocks=True):
 
     if allow_images:
         # Add [img]
+        md.inlinePatterns.add('bb_img', inline.image(md), '<image_link')
         short_images_md = ShortImagesExtension()
         short_images_md.extendMarkdown(md)
     else:

+ 19 - 0
misago/markup/tests/test_parser.py

@@ -77,6 +77,25 @@ Dolor met.
         result = parse(test_text, MockRequest(), MockPoster(), minify=False)
         self.assertEqual(expected_result, result['parsed_text'])
 
+    def test_img(self):
+        """img bbcode is correctly parsed"""
+        test_text = """
+Lorem ipsum [img]https://placekitten.com/g/1200/500[/img]
+
+Lorem ipsum [iMg]https://placekitten.com/g/1200/500[/ImG]
+
+Lorem ipsum !(https://placekitten.com/g/1200/500)
+""".strip()
+
+        expected_result = """
+<p>Lorem ipsum <img alt="placekitten.com/g/1200/500" src="https://placekitten.com/g/1200/500"/></p>
+<p>Lorem ipsum <img alt="placekitten.com/g/1200/500" src="https://placekitten.com/g/1200/500"/></p>
+<p>Lorem ipsum <img alt="placekitten.com/g/1200/500" src="https://placekitten.com/g/1200/500"/></p>
+""".strip()
+
+        result = parse(test_text, MockRequest(), MockPoster(), minify=False)
+        self.assertEqual(expected_result, result['parsed_text'])
+
 
 class MinifyTests(TestCase):
     def test_minified_text(self):