Ticket #6526: 6526-markdown-with-safe-options.diff

File 6526-markdown-with-safe-options.diff, 4.9 KB (added by thomaspurchas, 12 years ago)

Also includes tests

  • django/contrib/markup/templatetags/markup.py

    From 4066cb17bfced9acde6583cf937c17e1bfd6fbf3 Mon Sep 17 00:00:00 2001
    From: Thomas Purchas <tpurchas@gmail.com>
    Date: Sun, 19 Aug 2012 01:07:08 +0100
    Subject: [PATCH] Add safe modes "replace", "escape" and "remove"
    
    Improvement to the way safe modes are selected. It is now possible to choose any of the three safe modes offered by the underlying markdown library by using:
    
    "safe=replace"
    "safe=remove"
    "safe=escape"
    ---
     django/contrib/markup/templatetags/markup.py |   22 ++++++++++++++++++----
     django/contrib/markup/tests.py               |   24 ++++++++++++++++++++++++
     2 files changed, 42 insertions(+), 4 deletions(-)
    
    diff --git a/django/contrib/markup/templatetags/markup.py b/django/contrib/markup/templatetags/markup.py
    index af9c842..8c82916 100644
    a b markup syntaxes to HTML; currently there is support for:  
    1010
    1111    * reStructuredText, which requires docutils from http://docutils.sf.net/
    1212"""
     13import re
    1314
    1415from django import template
    1516from django.conf import settings
    1617from django.utils.encoding import smart_bytes, force_text
    1718from django.utils.safestring import mark_safe
    1819
     20SAFE_MARKDOWN_REGEX = re.compile('^safe(=(?P<mode>replace|remove|escape))?$')
     21
    1922register = template.Library()
    2023
    2124@register.filter(is_safe=True)
    def markdown(value, arg=''):  
    4043        {{ value|markdown:"extension1_name,extension2_name..." }}
    4144
    4245    To enable safe mode, which strips raw HTML and only returns HTML
    43     generated by actual Markdown syntax, pass "safe" as the first
    44     extension in the list.
     46    generated by actual Markdown syntax, pass one of the following:
     47
     48    "safe=replace" to replace the html
     49    "safe=escape"  to escape the html
     50    "safe=remove"  to remove the html
    4551
    4652    If the version of Markdown in use does not support extensions,
    4753    they will be silently ignored.
    def markdown(value, arg=''):  
    6268            return force_text(value)
    6369        else:
    6470            extensions = [e for e in arg.split(",") if e]
    65             if extensions and extensions[0] == "safe":
     71            if extensions and SAFE_MARKDOWN_REGEX.match(extensions[0]):
     72                # Check to see in a safe mode has been selected using a
     73                # pre-compiled regex.
     74                mode = SAFE_MARKDOWN_REGEX.match(extensions[0]).group('mode')
     75                if mode:
     76                    safe_mode = mode
     77                else:
     78                    # Use true for compatablity with older python-markdown libraries.
     79                    safe_mode = True
    6680                extensions = extensions[1:]
    6781                return mark_safe(markdown.markdown(
    68                     force_text(value), extensions, safe_mode=True, enable_attributes=False))
     82                    force_text(value), extensions, safe_mode=safe_mode, enable_attributes=False))
    6983            else:
    7084                return mark_safe(markdown.markdown(
    7185                    force_text(value), extensions, safe_mode=False))
  • django/contrib/markup/tests.py

    diff --git a/django/contrib/markup/tests.py b/django/contrib/markup/tests.py
    index 7b050ac..7935ccb 100644
    a b Paragraph 2 with a link_  
    7272        rendered = t.render(Context({'markdown_content':markdown_content})).strip()
    7373        self.assertFalse('@' in rendered)
    7474
     75    @unittest.skipUnless(markdown and markdown_version >= (2,1), 'markdown >= 2.1 not installed')
     76    def test_markdown_safe_remove(self):
     77        t = Template("{% load markup %}{{ markdown_content|markdown:'safe=remove,' }}")
     78        markdown_content = "<code>Some stuff</code>"
     79        rendered = t.render(Context({'markdown_content':markdown_content})).strip()
     80        self.assertFalse('<code>' in rendered)
     81        self.assertFalse('[HTML_REMOVED]' in rendered)
     82
     83    @unittest.skipUnless(markdown and markdown_version >= (2,1), 'markdown >= 2.1 not installed')
     84    def test_markdown_safe_replace(self):
     85        t = Template("{% load markup %}{{ markdown_content|markdown:'safe=replace,' }}")
     86        markdown_content = "<code>Some stuff</code>"
     87        rendered = t.render(Context({'markdown_content':markdown_content})).strip()
     88        self.assertFalse('<code>' in rendered)
     89        self.assertTrue('[HTML_REMOVED]' in rendered)
     90
     91    @unittest.skipUnless(markdown and markdown_version >= (2,1), 'markdown >= 2.1 not installed')
     92    def test_markdown_safe_escape(self):
     93        t = Template("{% load markup %}{{ markdown_content|markdown:'safe=escape,' }}")
     94        markdown_content = "<code>Some stuff</code>"
     95        rendered = t.render(Context({'markdown_content':markdown_content})).strip()
     96        self.assertFalse('<code>' in rendered)
     97        self.assertTrue('&lt;code&gt;' in rendered)
     98
    7599    @unittest.skipIf(markdown, 'markdown is installed')
    76100    def test_no_markdown(self):
    77101        t = Template("{% load markup %}{{ markdown_content|markdown }}")
Back to Top