Commits

Anonymous committed 54bcfe9

adding the markdown template filter with pygments code highlighting

Comments (0)

Files changed (3)

+syntax: glob
+.*.swp
+*.pyc
+
+syntax: regexp
+

templatetags/__init__.py

Empty file added.

templatetags/mdwn.py

+#
+# Copyright (c) 2008 Daniel Truemper truemped@googlemail.com
+#
+# mdwn.py 22-Mar-2009
+#
+# All programs in this directory and
+# subdirectories are published under the GNU General Public License as
+# described below.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA
+#
+# Further information about the GNU GPL is available at:
+# http://www.gnu.org/copyleft/gpl.html
+#
+#
+
+from django import template
+from django.template.defaultfilters import stringfilter
+from django.conf import settings
+from django.utils.encoding import smart_str, force_unicode
+from django.utils.safestring import mark_safe
+
+import re
+
+from markdown import TextPreprocessor, Markdown
+
+from pygments import highlight
+from pygments.formatters import HtmlFormatter
+from pygments.lexers import get_lexer_by_name, TextLexer
+
+
+register = template.Library()
+
+@register.filter(name='mdwn')
+@stringfilter
+def mdwn(value, arg=''):
+    """
+    Runs Markdown over a given value, optionally using various
+    extensions python-markdown supports.
+
+    Syntax::
+
+        {{ value|markdown:"extension1_name,extension2_name..." }}
+
+    To enable safe mode, which strips raw HTML and only returns HTML
+    generated by actual Markdown syntax, pass "safe" as the first
+    extension in the list.
+
+    If the version of Markdown in use does not support extensions,
+    they will be silently ignored.
+
+    """
+    try:
+        import markdown
+    except ImportError:
+        if settings.DEBUG:
+            raise template.TemplateSyntaxError, "Error in {% markdown %} filter: The Python markdown library isn't installed."
+        return force_unicode(value)
+    else:
+        # markdown.version was first added in 1.6b. The only version of markdown
+        # to fully support extensions before 1.6b was the shortlived 1.6a.
+        if hasattr(markdown, 'version'):
+            extensions = [e for e in arg.split(",") if e]
+            if len(extensions) > 0 and extensions[0] == "safe":
+                extensions = extensions[1:]
+                safe_mode = True
+            else:
+                safe_mode = False
+
+            md = Markdown( extensions=extensions, safe_mode=safe_mode )
+            md.textPreprocessors.insert(0, CodeBlockPreprocessor())
+
+            # Unicode support only in markdown v1.7 or above. Version_info
+            # exist only in markdown v1.6.2rc-2 or above.
+            if getattr(markdown, "version_info", None) < (1,7):
+                return mark_safe(force_unicode(md.convert(smart_str(value))))
+            else:
+                return mark_safe(md.convert(force_unicode(value)))
+        else:
+            return mark_safe(force_unicode(markdown.markdown(smart_str(value))))
+mdwn.is_safe = True
+
+
+"""
+The Pygments Markdown Preprocessor
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This fragment is a Markdown_ preprocessor that renders source code
+to HTML via Pygments.  To use it, invoke Markdown like so::
+
+from markdown import Markdown
+
+md = Markdown()
+md.textPreprocessors.insert(0, CodeBlockPreprocessor())
+html = md.convert(someText)
+
+markdown is then a callable that can be passed to the context of
+a template and used in that template, for example.
+
+This uses CSS classes by default, so use
+``pygmentize -S <some style> -f html > pygments.css``
+to create a stylesheet to be added to the website.
+
+You can then highlight source code in your markdown markup::
+
+[sourcecode:lexer]
+some code
+[/sourcecode]
+
+.. _Markdown: http://www.freewisdom.org/projects/python-markdown/
+
+:copyright: Copyright 2006-2009 by the Pygments team, see AUTHORS.
+:license: BSD, see LICENSE for details.
+"""
+
+# Options
+# ~~~~~~~
+
+# Set to True if you want inline CSS styles instead of classes
+INLINESTYLES = False
+
+class CodeBlockPreprocessor(TextPreprocessor):
+
+    pattern = re.compile(r'\[sourcecode:(.+?)\](.+?)\[/sourcecode\]', re.S)
+
+    formatter = HtmlFormatter(noclasses=INLINESTYLES)
+
+    def run(self, lines):
+        def repl(m):
+            try:
+                lexer = get_lexer_by_name(m.group(1))
+            except ValueError:
+                lexer = TextLexer()
+            code = highlight(m.group(2), lexer, self.formatter)
+            code = code.replace('\n\n', '\n&nbsp;\n').replace('\n', '<br />')
+            return '\n\n<div class="code">%s</div>\n\n' % code
+        return self.pattern.sub( repl, lines)
+