Reputation: 247
I'm generating pdfs using the TeX macro package Context. The Context source file is generated using Django templates, and the content is converted from HTML (as stored in the database) to Context's syntax using Pandoc. Since there is no native python binding for Pandoc, I have created the following template filter to convert HTML to Context:
def html2context(value):
"""
Runs pandoc to convert from HTML to Context.
Syntax::
{{ value|html2context }}
"""
cmd = 'pandoc -f html -t context'
p1 = subprocess.Popen(cmd.split(" "), stdout=subprocess.PIPE, stdin=subprocess.PIPE)
(stdout, stderr) = p1.communicate(input=value.encode('utf-8'))
return mark_safe(stdout)
The problem is that to generate my pdf I have call many times the template filter, ending in a very slow conversion process. The reason I have to call many times the filter is because my template mixes content from the database and raw Context commands to structure my document: HTML doesn't cover all the possibilities I need in Context. A minimal example of my template looks like this:
{% for plugin in intro %}
{{ plugin.text.body|html2context }}
\page[emptyodd]
{% endfor %}
Do you have any idea how I could make the conversion process less sub-optimal?
Thanks
Upvotes: 1
Views: 1043
Reputation: 11
i think a better solution is to directly create a template in ConTeXT, and generate the view like that:
from django.http import HttpResponse
from django.template import Context
from django.template.loader import get_template
from subprocess import Popen, PIPE
import tempfile
from .models import Entry
def entry_as_pdf(request, pk):
entry = Entry.objects.get(pk=pk)
context = Context({
'content': entry.content,
})
template = get_template('my_latex_template.tex')
rendered_tpl = template.render(context).encode('utf-8')
# Python3 only. For python2 check out the docs!
with tempfile.TemporaryDirectory() as tempdir:
# Create subprocess, supress output with PIPE and
# run latex twice to generate the TOC properly.
# Finally read the generated pdf.
for i in range(2):
process = Popen(
['context', '-output-directory', tempdir],
stdin=PIPE,
stdout=PIPE,
)
process.communicate(rendered_tpl)
with open(os.path.join(tempdir, 'texput.pdf'), 'rb') as f:
pdf = f.read()
r = HttpResponse(content_type='application/pdf')
# r['Content-Disposition'] = 'attachment; filename=texput.pdf'
r.write(pdf)
return r
notice that there is a loop to run the context
command twice in case you have something like TOC or bibliography references to include in the document,
Upvotes: 0