pygments2xpre.py 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. """Helps you output colourised code snippets in ReportLab documents.
  2. Platypus has an 'XPreformatted' flowable for handling preformatted
  3. text, with variations in fonts and colors. If Pygments is installed,
  4. calling 'pygments2xpre' will return content suitable for display in
  5. an XPreformatted object. If it's not installed, you won't get colours.
  6. For a list of available lexers see http://pygments.org/docs/
  7. """
  8. __all__ = ('pygments2xpre',)
  9. from reportlab.lib.utils import asBytes, getBytesIO, getStringIO, asUnicode, isUnicode
  10. import re
  11. def _2xpre(s,styles):
  12. "Helper to transform Pygments HTML output to ReportLab markup"
  13. s = s.replace('<div class="highlight">','')
  14. s = s.replace('</div>','')
  15. s = s.replace('<pre>','')
  16. s = s.replace('</pre>','')
  17. for k,c in styles+[('p','#000000'),('n','#000000'),('err','#000000')]:
  18. s = s.replace('<span class="%s">' % k,'<span color="%s">' % c)
  19. s = re.sub(r'<span class="%s\s+.*">'% k,'<span color="%s">' % c,s)
  20. s = re.sub(r'<span class=".*">','<span color="#0f0f0f">',s)
  21. return s
  22. def pygments2xpre(s, language="python"):
  23. "Return markup suitable for XPreformatted"
  24. try:
  25. from pygments import highlight
  26. from pygments.formatters import HtmlFormatter
  27. except ImportError:
  28. return s
  29. from pygments.lexers import get_lexer_by_name
  30. rconv = lambda x: x
  31. out = getStringIO()
  32. l = get_lexer_by_name(language)
  33. h = HtmlFormatter()
  34. highlight(s,l,h,out)
  35. styles = [(cls, style.split(';')[0].split(':')[1].strip())
  36. for cls, (style, ttype, level) in h.class2style.items()
  37. if cls and style and style.startswith('color:')]
  38. return rconv(_2xpre(out.getvalue(),styles))
  39. def convertSourceFiles(filenames):
  40. "Helper function - makes minimal PDF document"
  41. from reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer, XPreformatted
  42. from reportlab.lib.styles import getSampleStyleSheet
  43. styT=getSampleStyleSheet()["Title"]
  44. styC=getSampleStyleSheet()["Code"]
  45. doc = SimpleDocTemplate("pygments2xpre.pdf")
  46. S = [].append
  47. for filename in filenames:
  48. S(Paragraph(filename,style=styT))
  49. src = open(filename, 'r').read()
  50. fmt = pygments2xpre(src)
  51. S(XPreformatted(fmt, style=styC))
  52. doc.build(S.__self__)
  53. print('saved pygments2xpre.pdf')
  54. if __name__=='__main__':
  55. import sys
  56. filenames = sys.argv[1:]
  57. if not filenames:
  58. print('usage: pygments2xpre.py file1.py [file2.py] [...]')
  59. sys.exit(0)
  60. convertSourceFiles(filenames)