views:

237

answers:

1

Hello!

I'm trying to generate some LaTeX code which from thereon should generate PDF documents. Currently, I'm using the Django templating system for dynamically creating the code, but I have no idea on as how to move on from here. I understand that I could save the code in a .tex file, and use subprocess to run pdflatex for generating the PDF. But I had so much trouble escaping the LaTeX code in "plain" Python that I decided to use the Django templating system. Is there a way that I could somehow maybe pipe the output produced by Django to pdflatex? The code produced is working properly, it's just that I do not know what to do with it.

Thanks in advance

+2  A: 

I was tackling the same issue in a project I had previously worked on, and instead of piping the output, I created temporary files in a temporary folder, since I was worried about handling the intermediate files LaTeX produces. This is the code I used (note that it's a few years old, from when I was still new to Python/Django; I'm sure I could come up with something better if I was writing this today, but this definitely worked for me):

import os
from subprocess import call
from tempfile import mkdtemp, mkstemp
from django.template.loader import render_to_string
# In a temporary folder, make a temporary file
tmp_folder = mkdtemp()
os.chdir(tmp_folder)        
texfile, texfilename = mkstemp(dir=tmp_folder)
# Pass the TeX template through Django templating engine and into the temp file
os.write(texfile, render_to_string('tex/base.tex', {'var': 'whatever'}))
os.close(texfile)
# Compile the TeX file with PDFLaTeX
call(['pdflatex', texfilename])
# Move resulting PDF to a more permanent location
os.rename(texfilename + '.pdf', dest_folder)
# Remove intermediate files
os.remove(texfilename)
os.remove(texfilename + '.aux')
os.remove(texfilename + '.log')
os.rmdir(tmp_folder)
return os.path.join(dest_folder, texfilename + '.pdf')

The dest_folder variable is usually set to somewhere in the media directory, so that the PDF can then be served statically. The value returned is the path to the file on disk. The logic of what its URL would be is handled by whatever function sets the dest_folder.

Aram Dulyan
Thank you! But I still have an issue. Would it somehow be possible use the templating engine on an existing file? So, that it would change the variables properly? And I could write to a proper tex file. Atm I have the code in the templating system sytanx stored in a file.
Uku Loskit
I'm not sure I fully follow your question, but in the example above, "tex/base.tex" is a TeX file in the templates directory that has Django templating tags/filters inside it as well, which get replaced by variables when it goes through `render_to_string()`. If you wanted to load just any old file (from outside the templates directories), you can do: `t = Template(open('/path/to/your/file.tex').read()); os.write(texfile, t.render(Context({'var':'whatever'}))`. If you want to write to particular place, do: `os.write(open('/path/to/new/file.tex', 'w').fileno(), t.render(...))`.
Aram Dulyan
Ok, for a sec I misunderstood your code, now it's OK :D. Dealing with a weird bug atm, dunno if it is related.
Uku Loskit