| 1 |
""" |
|---|
| 2 |
Set of "markup" template filters for Django. These filters transform plain text |
|---|
| 3 |
markup 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 |
|
|---|
| 13 |
In each case, if the required library is not installed, the filter will |
|---|
| 14 |
silently fail and return the un-marked-up text. |
|---|
| 15 |
""" |
|---|
| 16 |
|
|---|
| 17 |
from django import template |
|---|
| 18 |
from django.conf import settings |
|---|
| 19 |
from django.utils.encoding import smart_str, force_unicode |
|---|
| 20 |
from django.utils.safestring import mark_safe |
|---|
| 21 |
|
|---|
| 22 |
register = template.Library() |
|---|
| 23 |
|
|---|
| 24 |
def 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'))) |
|---|
| 33 |
textile.is_safe = True |
|---|
| 34 |
|
|---|
| 35 |
def 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 strips raw HTML and only returns HTML |
|---|
| 45 |
generated by actual Markdown syntax, pass "safe" as the first |
|---|
| 46 |
extension in the list. |
|---|
| 47 |
|
|---|
| 48 |
If the version of Markdown in use does not support extensions, |
|---|
| 49 |
they will be silently ignored. |
|---|
| 50 |
|
|---|
| 51 |
""" |
|---|
| 52 |
try: |
|---|
| 53 |
import markdown |
|---|
| 54 |
except ImportError: |
|---|
| 55 |
if settings.DEBUG: |
|---|
| 56 |
raise template.TemplateSyntaxError, "Error in {% markdown %} filter: The Python markdown library isn't installed." |
|---|
| 57 |
return force_unicode(value) |
|---|
| 58 |
else: |
|---|
| 59 |
# markdown.version was first added in 1.6b. The only version of markdown |
|---|
| 60 |
# to fully support extensions before 1.6b was the shortlived 1.6a. |
|---|
| 61 |
if hasattr(markdown, 'version'): |
|---|
| 62 |
extensions = [e for e in arg.split(",") if e] |
|---|
| 63 |
if len(extensions) > 0 and extensions[0] == "safe": |
|---|
| 64 |
extensions = extensions[1:] |
|---|
| 65 |
safe_mode = True |
|---|
| 66 |
else: |
|---|
| 67 |
safe_mode = False |
|---|
| 68 |
|
|---|
| 69 |
# Unicode support only in markdown v1.7 or above. Version_info |
|---|
| 70 |
# exist only in markdown v1.6.2rc-2 or above. |
|---|
| 71 |
if getattr(markdown, "version_info", None) < (1,7): |
|---|
| 72 |
return mark_safe(force_unicode(markdown.markdown(smart_str(value), extensions, safe_mode=safe_mode))) |
|---|
| 73 |
else: |
|---|
| 74 |
return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode)) |
|---|
| 75 |
else: |
|---|
| 76 |
return mark_safe(force_unicode(markdown.markdown(smart_str(value)))) |
|---|
| 77 |
markdown.is_safe = True |
|---|
| 78 |
|
|---|
| 79 |
def restructuredtext(value): |
|---|
| 80 |
try: |
|---|
| 81 |
from docutils.core import publish_parts |
|---|
| 82 |
except ImportError: |
|---|
| 83 |
if settings.DEBUG: |
|---|
| 84 |
raise template.TemplateSyntaxError, "Error in {% restructuredtext %} filter: The Python docutils library isn't installed." |
|---|
| 85 |
return force_unicode(value) |
|---|
| 86 |
else: |
|---|
| 87 |
docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {}) |
|---|
| 88 |
parts = publish_parts(source=smart_str(value), writer_name="html4css1", settings_overrides=docutils_settings) |
|---|
| 89 |
return mark_safe(force_unicode(parts["fragment"])) |
|---|
| 90 |
restructuredtext.is_safe = True |
|---|
| 91 |
|
|---|
| 92 |
register.filter(textile) |
|---|
| 93 |
register.filter(markdown) |
|---|
| 94 |
register.filter(restructuredtext) |
|---|