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

https://code.google.com/p/mango-py/ · Python · 91 lines · 73 code · 7 blank · 11 comment · 21 complexity · 350547130289d690f028ee179e74f505 MD5 · raw file

  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. * Textile, which requires the PyTextile library available at
  5. http://loopcore.com/python-textile/
  6. * Markdown, which requires the Python-markdown library from
  7. http://www.freewisdom.org/projects/python-markdown
  8. * reStructuredText, which requires docutils from http://docutils.sf.net/
  9. """
  10. from django import template
  11. from django.conf import settings
  12. from django.utils.encoding import smart_str, force_unicode
  13. from django.utils.safestring import mark_safe
  14. register = template.Library()
  15. def textile(value):
  16. try:
  17. import textile
  18. except ImportError:
  19. if settings.DEBUG:
  20. raise template.TemplateSyntaxError("Error in {% textile %} filter: The Python textile library isn't installed.")
  21. return force_unicode(value)
  22. else:
  23. return mark_safe(force_unicode(textile.textile(smart_str(value), encoding='utf-8', output='utf-8')))
  24. textile.is_safe = True
  25. def markdown(value, arg=''):
  26. """
  27. Runs Markdown over a given value, optionally using various
  28. extensions python-markdown supports.
  29. Syntax::
  30. {{ value|markdown:"extension1_name,extension2_name..." }}
  31. To enable safe mode, which strips raw HTML and only returns HTML
  32. generated by actual Markdown syntax, pass "safe" as the first
  33. extension in the list.
  34. If the version of Markdown in use does not support extensions,
  35. they will be silently ignored.
  36. """
  37. try:
  38. import markdown
  39. except ImportError:
  40. if settings.DEBUG:
  41. raise template.TemplateSyntaxError("Error in {% markdown %} filter: The Python markdown library isn't installed.")
  42. return force_unicode(value)
  43. else:
  44. # markdown.version was first added in 1.6b. The only version of markdown
  45. # to fully support extensions before 1.6b was the shortlived 1.6a.
  46. if hasattr(markdown, 'version'):
  47. extensions = [e for e in arg.split(",") if e]
  48. if len(extensions) > 0 and extensions[0] == "safe":
  49. extensions = extensions[1:]
  50. safe_mode = True
  51. else:
  52. safe_mode = False
  53. # Unicode support only in markdown v1.7 or above. Version_info
  54. # exist only in markdown v1.6.2rc-2 or above.
  55. if getattr(markdown, "version_info", None) < (1,7):
  56. return mark_safe(force_unicode(markdown.markdown(smart_str(value), extensions, safe_mode=safe_mode)))
  57. else:
  58. return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode))
  59. else:
  60. return mark_safe(force_unicode(markdown.markdown(smart_str(value))))
  61. markdown.is_safe = True
  62. def restructuredtext(value):
  63. try:
  64. from docutils.core import publish_parts
  65. except ImportError:
  66. if settings.DEBUG:
  67. raise template.TemplateSyntaxError("Error in {% restructuredtext %} filter: The Python docutils library isn't installed.")
  68. return force_unicode(value)
  69. else:
  70. docutils_settings = getattr(settings, "RESTRUCTUREDTEXT_FILTER_SETTINGS", {})
  71. parts = publish_parts(source=smart_str(value), writer_name="html4css1", settings_overrides=docutils_settings)
  72. return mark_safe(force_unicode(parts["fragment"]))
  73. restructuredtext.is_safe = True
  74. register.filter(textile)
  75. register.filter(markdown)
  76. register.filter(restructuredtext)