使用Pandoc和Django的HTML-to-Context模板:如何避免调用子进程太多次?

2024-10-01 17:25:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用TeX宏包上下文生成pdf。上下文源文件使用Django模板生成,内容使用Pandoc从HTML(存储在数据库中)转换为Context的语法。由于Pandoc没有本机python绑定,我创建了以下模板过滤器来将HTML转换为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)

问题是,为了生成我的pdf,我多次调用模板过滤器,结果转换过程非常缓慢。我不得不多次调用过滤器的原因是,我的模板混合了来自数据库的内容和原始上下文命令来构建我的文档:HTML并没有涵盖上下文中需要的所有可能性。我的模板的一个最小示例如下所示:

^{pr2}$

你知道我怎样才能使转换过程不那么次优吗?在

谢谢


Tags: tocmd模板数据库过滤器内容pdfvalue
1条回答
网友
1楼 · 发布于 2024-10-01 17:25:45

我认为更好的解决方案是直接在上下文中创建一个模板,然后生成这样的视图:

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

请注意,有一个循环可以运行context命令两次,以防文档中包含类似TOC或书目引用的内容

相关问题 更多 >

    热门问题