Permalink
Browse files

Add a CodeHighlighter filter for use with the #transform directive

Signed-off-by: R. Tyler Ballance <tyler@slide.com>
  • Loading branch information...
1 parent 12254c4 commit 95238ef31a8f3f109a5c0a413334cedc5dc5fcb1 R. Tyler Ballance committed Apr 8, 2009
Showing with 77 additions and 4 deletions.
  1. +49 −4 src/Filters.py
  2. +28 −0 src/Tests/Filters.py
View
@@ -99,12 +99,57 @@ def filter(self, value, **kwargs):
encoded = super(Markdown, self).filter(value, **kwargs)
return markdown.markdown(encoded)
+class CodeHighlighter(EncodeUnicode):
+ '''
+ The CodeHighlighter filter depends on the "pygments" module which you can
+ download and install from: http://pygments.org
+
+ What the CodeHighlighter assumes the string that it's receiving is source
+ code and uses pygments.lexers.guess_lexer() to try to guess which parser
+ to use when highlighting it.
+
+ CodeHighlighter will return the HTML and CSS to render the code block, syntax
+ highlighted, in a browser
+
+ NOTE: I had an issue installing pygments on Linux/amd64/Python 2.6 dealing with
+ importing of pygments.lexers, I was able to correct the failure by adding:
+ raise ImportError
+ to line 39 of pygments/plugin.py (since importing pkg_resources was causing issues)
+ '''
+ def filter(self, source, **kwargs):
+ encoded = super(CodeHighlighter, self).filter(source, **kwargs)
+ try:
+ from pygments import highlight
+ from pygments import lexers
+ from pygments import formatters
+ except ImportError, ex:
+ print '<%s> - Failed to import pygments! (%s)' % (self.__class__.__name__, ex)
+ print '-- You may need to install it from: http://pygments.org'
+ return encoded
+
+ lexer = None
+ try:
+ lexer = lexers.guess_lexer(source)
+ except lexers.ClassNotFound:
+ lexer = lexers.PythonLexer()
+
+ formatter = formatters.HtmlFormatter(cssclass='code_highlighter')
+ encoded = highlight(encoded, lexer, formatter)
+ css = formatter.get_style_defs('.code_highlighter')
+ return '''<style type="text/css">
+ <!--
+ %(css)s
+ -->
+ </style>
+ %(source)s''' % {'css' : css, 'source' : encoded}
+
+
class MaxLen(Filter):
def filter(self, val, **kw):
"""Replace None with '' and cut off at maxlen."""
- output = super(MaxLen, self).filter(val, **kw)
+ output = super(MaxLen, self).filter(val, **kw)
if kw.has_key('maxlen') and len(output) > kw['maxlen']:
return output[:kw['maxlen']]
return output
@@ -113,7 +158,7 @@ class WebSafe(Filter):
"""Escape HTML entities in $placeholders.
"""
def filter(self, val, **kw):
- s = super(WebSafe, self).filter(val, **kw)
+ s = super(WebSafe, self).filter(val, **kw)
# These substitutions are copied from cgi.escape().
s = s.replace("&", "&amp;") # Must be done first!
s = s.replace("<", "&lt;")
@@ -147,7 +192,7 @@ class Strip(Filter):
with the proposed #sed directive (which has not been ratified yet.)
"""
def filter(self, val, **kw):
- s = super(Strip, self).filter(val, **kw)
+ s = super(Strip, self).filter(val, **kw)
result = []
start = 0 # The current line will be s[start:end].
while 1: # Loop through each line.
@@ -170,7 +215,7 @@ class StripSqueeze(Filter):
input is joined into one ling line with NO trailing newline.
"""
def filter(self, val, **kw):
- s = super(StripSqueeze, self).filter(val, **kw)
+ s = super(StripSqueeze, self).filter(val, **kw)
s = s.split()
return " ".join(s)
View
@@ -24,5 +24,33 @@ def test_BasicHeader(self):
template = str(template)
assert template == expected
+class BasicCodeHighlighterFilterTest(unittest.TestCase):
+ '''
+ Test that our code highlighter filter works
+ '''
+ def test_Python(self):
+ template = '''
+#from Cheetah.Filters import CodeHighlighter
+#transform CodeHighlighter
+
+def foo(self):
+ return '$foo'
+ '''
+ template = Cheetah.Template.Template(template, searchList=[{'foo' : 'bar'}])
+ template = str(template)
+ assert template, (template, 'We should have some content here...')
+
+ def test_Html(self):
+ template = '''
+#from Cheetah.Filters import CodeHighlighter
+#transform CodeHighlighter
+
+<html><head></head><body>$foo</body></html>
+ '''
+ template = Cheetah.Template.Template(template, searchList=[{'foo' : 'bar'}])
+ template = str(template)
+ assert template, (template, 'We should have some content here...')
+
+
if __name__ == '__main__':
unittest.main()

0 comments on commit 95238ef

Please sign in to comment.