Code snippets are bits of re-usable code submitted by the ReportLab community. We don't promise that they are accurate, up-to-date or correct - use them at your own risk!
We'd love it if you could participate by submitting your own snippets and sharing your experience with others by commenting. You will need to create a user account by filling out our very simple form.
View all snippets
Colourising code with Pygments
A long time ago, Dinu Gherman created a demo to output colourised Python code in PDF. Since then the Pygments library has become the standard, and does most of the heavy work for us. It turned out that its output only needs modest tweaks to work within our own XPreformatted flowables.
The attached script shows how Pygments can be used to transform Python code.
The 'pygments2xpre' function is available in reportlab.lib.pygments2xpre as of revision 3622 (17 Dec 2009); for anyone on older versions, just use the code in this snippet.
"""Helps you output colourised code snippets in ReportLab documents. Platypus has an 'XPreformatted' flowable for handling preformatted text, with variations in fonts and colors. If Pygments is installed, calling 'pygments2xpre' will return content suitable for display in an XPreformatted object. If it's not installed, you won't get colours. """ __all__ = ('pygments2xpre',) def _2xpre(s,styles): "Helper to transform Pygments HTML output to ReportLab markup" s = s.replace('<div class="highlight">','') s = s.replace('</div>','') s = s.replace('<pre>','') s = s.replace('</pre>','') s = s.replace('</span>','</font>') for k,c in styles+[('p','#000000'),('n','#000000')]: s = s.replace('<span class="%s">' % k,'<font color="%s">' % c) return s def pygments2xpre(s): "Return markup suitable for XPreformatted" try: from pygments import highlight from pygments.lexers import PythonLexer from pygments.formatters import HtmlFormatter except ImportError: return s l = PythonLexer() h = HtmlFormatter() from StringIO import StringIO out = StringIO() highlight(s,l,h,out) styles = [(cls, style.split(';').split(':').strip()) for cls, (style, ttype, level) in h.class2style.iteritems() if cls and style and style.startswith('color:')] return _2xpre(out.getvalue(),styles) def convertSourceFiles(filenames): "Helper function - makes minimal PDF document" from reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer, XPreformatted from reportlab.lib.styles import getSampleStyleSheet styT=getSampleStyleSheet()["Title"] styC=getSampleStyleSheet()["Code"] doc = SimpleDocTemplate("pygments2xpre.pdf") S = .append for filename in filenames: S(Paragraph(filename,style=styT)) src = open(filename, 'r').read() fmt = pygments2xpre(src) S(XPreformatted(fmt, style=styC)) doc.build(S.__self__) print 'saved pygments2xpre.pdf' if __name__=='__main__': import sys filenames = sys.argv[1:] if not filenames: print 'usage: pygments2xpre.py file1.py [file2.py] [...]' sys.exit(0) convertSourceFiles(filenames)