Шаблон HTML to Context с использованием Pandoc и Django: как избежать слишком большого количества вызовов подпроцесса?

Я создаю PDF-файлы, используя пакет макросов TeX Context. Исходный файл Context создается с использованием шаблонов Django, а содержимое преобразуется из HTML (сохраненного в базе данных) в синтаксис Context с использованием Pandoc. Поскольку для Pandoc нет встроенной привязки Python, я создал следующий шаблонный фильтр для преобразования HTML в контекст:

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 не охватывает все возможности, которые мне нужны в контексте. Минимальный пример моего шаблона выглядит так:

{% for plugin in intro %}
    {{ plugin.text.body|html2context }}
    \page[emptyodd]
{% endfor %}

У вас есть идеи, как я могу сделать процесс преобразования менее оптимальным?

Спасибо


person Alex    schedule 27.04.2013    source источник
comment
Я думаю, у вас есть проблема XY. Пожалуйста, укажите ваш X. Я серьезно считаю, что вы, вероятно, можете сделать это только с ConTeXt MkIV без пандока. До встречи на TeX.SX.   -  person Martin Schröder    schedule 02.05.2013


Ответы (1)


я думаю, что лучшим решением является непосредственное создание шаблона в ConTeXT и создание такого представления:

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, если у вас есть что-то вроде оглавления или библиографических ссылок для включения в документ,

person Kaddour Kardio    schedule 08.02.2017
comment
похоже, что context не нужно запускать дважды, чтобы дать оглавление, ссылки и т. д... - person Kaddour Kardio; 17.03.2017