From 95238ef31a8f3f109a5c0a413334cedc5dc5fcb1 Mon Sep 17 00:00:00 2001 From: "R. Tyler Ballance" Date: Tue, 7 Apr 2009 21:17:05 -0700 Subject: Add a CodeHighlighter filter for use with the #transform directive Signed-off-by: R. Tyler Ballance --- src/Filters.py | 53 ++++++++++++++++++++++++++++++++++++++++++++++++---- src/Tests/Filters.py | 28 +++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 4 deletions(-) diff --git a/src/Filters.py b/src/Filters.py index 7b4f74a..f686d44 100644 --- a/src/Filters.py +++ b/src/Filters.py @@ -99,12 +99,57 @@ class Markdown(EncodeUnicode): 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 ''' + %(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("&", "&") # Must be done first! s = s.replace("<", "<") @@ -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) diff --git a/src/Tests/Filters.py b/src/Tests/Filters.py index 47325f8..ab065b2 100644 --- a/src/Tests/Filters.py +++ b/src/Tests/Filters.py @@ -24,5 +24,33 @@ Header 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 + +$foo + ''' + 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() -- cgit v1.2.1