Ticket #6526: markup.py

File markup.py, 3.4 KB (added by taojian, 8 years ago)

new version of the markup filter

Line 
1"""
2Set of "markup" template filters for Django.  These filters transform plain text
3markup syntaxes to HTML; currently there is support for:
4
5    * Textile, which requires the PyTextile library available at
6      http://dealmeida.net/projects/textile/
7
8    * Markdown, which requires the Python-markdown library from
9      http://www.freewisdom.org/projects/python-markdown
10
11    * ReStructuredText, which requires docutils from http://docutils.sf.net/
12
13In each case, if the required library is not installed, the filter will
14silently fail and return the un-marked-up text.
15"""
16
17from django import template
18from django.conf import settings
19from django.utils.encoding import smart_str, force_unicode
20from django.utils.safestring import mark_safe
21
22register = template.Library()
23
24def textile(value):
25    try:
26        import textile
27    except ImportError:
28        if settings.DEBUG:
29            raise template.TemplateSyntaxError, "Error in {% textile %} filter: The Python textile library isn't installed."
30        return force_unicode(value)
31    else:
32        return mark_safe(force_unicode(textile.textile(smart_str(value), encoding='utf-8', output='utf-8')))
33textile.is_safe = True
34
35def markdown(value, arg=''):
36    """
37    Runs Markdown over a given value, optionally using various
38    extensions python-markdown supports.
39
40    Syntax::
41
42        {{ value|markdown:"extension1_name,extension2_name..." }}
43
44    To enable safe mode, which replaces raw HTML with an
45    "HTML_REMOVED" message and only returns HTML generated by
46    actual Markdown syntax, pass "safe" or "replace" as the first
47    extension in the list. Alternately, pass "remove" to remove raw
48    HTML altogether, or "escape" to escape it.
49
50    If the version of Markdown in use does not support extensions,
51    they will be silently ignored.
52
53    """
54    try:
55        import markdown
56    except ImportError:
57        if settings.DEBUG:
58            raise template.TemplateSyntaxError, "Error in {% markdown %} filter: The Python markdown library isn't installed."
59        return force_unicode(value)
60    else:
61        # markdown.version was first added in 1.6b. The only version of markdown
62        # to fully support extensions before 1.6b was the shortlived 1.6a.
63        if hasattr(markdown, 'version'):
64            extensions = [e for e in arg.split(",") if e]
65            if len(extensions) > 0 and extensions[0] in ('safe','replace','remove','escape'):
66                safe_mode = extensions[0]
67                extensions = extensions[1:]
68            else:
69                safe_mode = False
70            return mark_safe(force_unicode(markdown.markdown(smart_str(value), extensions, safe_mode=safe_mode)))
71        else:
72            return mark_safe(force_unicode(markdown.markdown(smart_str(value))))
73markdown.is_safe = True
74
75def restructuredtext(value):
76    try:
77        from docutils.core import publish_parts
78    except ImportError:
79        if settings.DEBUG:
80            raise template.TemplateSyntaxError, "Error in {% restructuredtext %} filter: The Python docutils library isn't installed."
81        return force_unicode(value)
82    else:
83        docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {})
84        parts = publish_parts(source=smart_str(value), writer_name="html4css1", settings_overrides=docutils_settings)
85        return mark_safe(force_unicode(parts["fragment"]))
86restructuredtext.is_safe = True
87
88register.filter(textile)
89register.filter(markdown)
90register.filter(restructuredtext)
Back to Top