Skip to content

Instantly share code, notes, and snippets.

@RobertSudwarts
Last active August 29, 2015 14:11
Show Gist options
  • Save RobertSudwarts/ebf16daba7115689f799 to your computer and use it in GitHub Desktop.
Save RobertSudwarts/ebf16daba7115689f799 to your computer and use it in GitHub Desktop.
generate PDFs on the fly (ie in a browser) using LaTeX, with Turbogears, mako templates and texcaller
"""
Installation for debian based distros
You will of course need the tex library installed:
$ sudo apt-get install texlive
And SWIG is required for dealing with texcaller's 'C' wrapper.
$ sudo apt-get install swig
Download the texcaller package from github and 'make' the
python wrapper:
$ cd ~/mylib
$ git clone https://github.com/vog/texcaller.git
$ cd texcaller
$ make -C swig
$ cd python
$ python setup.py build_ext --inplace
We'll assume that you have a turbogears installation up and
running in a virtual environment (naturally!) so the virtualenv
needs to know where texcaller's python package lives (ie its
absolute path). The easiest way to accomplish this is to add a
.pth file to the virtualenv's 'site-packages' directory, thusly:
$ cd /../../virtualenvs/tg23/lib/python2.7/site-packages
$ echo "~/mylib/texcaller/python" > texcaller.pth
With the .pth in place, and with the virtualenv activated,
the following command should operate without error:
$ python -c "import texcaller"
We start with a document string to be parsed by mako
And see the bottom of this file for the Turbogears controller
which renders the final PDF.
"""
import texcaller
from tg import expose
from mako.template import Template
from myproject.lib.base import BaseController
document = r'''
\documentclass{scrartcl}
\usepackage[latin1]{inputenc}
\usepackage{tabularx}
\usepackage[letterpaper,top=3cm,bottom=-3cm,left=2cm,right=2cm]{geometry}
\usepackage{graphicx}
\begin{document}
\fontfamily{cmss}\fontsize{10pt}{12pt}\selectfont
\section{Simple Stuff}
\textbf{Hello ${name}!}
This \LaTeX-document has been created using a mako template.
\textit{This text will be italicised...}
In the next section we will display some subsections and render some
parameters passed from python.
\section{Control Structures}
\subsection{iterating over a simple list}
Here we demonstrate how mako can loop over a simple list to generate
some output -- look at the document string/template to see how a new line
character is used to cause a line break:
% for i, j in enumerate(simple_list):
${i} - ${j} ${'\n'}
% endfor
\subsection{generating a \LaTeX table}
Here we generate a tex table using a list of dicts. In order to get the
double backslash (required by the table markup), you use python's raw
text flag on the string ie r''. Notice also how the string concatenation
operates per line (ie per dict) followed by the double backslash which
is included (and this is the key point) in the \emph{raw} string.
\hfill \break
\hspace*{5cm}
\begin{tabular}{ lcc }
\hline
Fruit & eaten & uneaten ${r'\\'}
\hline
% for row in list_of_dicts:
${r'%(fruit)s & %(eaten)d & %(uneaten)d \\' % (row) }
% endfor
\hline
\end{tabular}
\end{document}
'''
class PDFController(BaseController):
'''Your root Turbogears controller will need to mount this eg:
pdf = PDFController()
And call this example with http://localhost:8080/pdf
'''
@expose(content_type="application/pdf")
def index(self):
# see texcaller's python specific documentation
# for why the .decode() is required.
# https://vog.github.io/texcaller/group__python.html
mytemplate = Template(document.decode('utf-8'))
list_of_dicts = [
{'fruit': 'apples', 'eaten': 2, 'uneaten': 8},
{'fruit': 'bananas', 'eaten': 4, 'uneaten': 10},
{'fruit': 'oranges', 'eaten': 6, 'uneaten': 12},
]
doc_params = dict(
name='World',
simple_list=['apples', 'bananas', 'oranges'],
list_of_dicts=list_of_dicts,
)
pdf, info = texcaller.convert(
mytemplate.render(**doc_params), 'LaTeX', 'PDF', 5
)
return pdf
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment