Генерация pdf-латекса с помощью скрипта Python - PullRequest
28 голосов
/ 10 ноября 2011

Я парень из колледжа, и в моем колледже, чтобы представить любую домашнюю работу, она должна иметь стандартную титульную страницу (с логотипом колледжа, названием курса, именем профессора, моим именем и бла-бла-бла).

Итак, у меня есть документ .tex, который генерирует мои стандартные страницы в формате pdf.Это выглядит примерно так:

...
\begin{document}
%% College logo
\vspace{5cm}
\begin{center}
\textbf{\huge "School and Program Name" \\}
\vspace{1cm}
\textbf{\Large "Homework Title" \\}
\vspace{1cm}
\textbf{\Large "Course Name" \\}
\end{center}
\vspace{2.5cm}
\begin{flushright}
{\large "My name" }
\end{flushright}
...

Итак, мне было интересно, есть ли способ сделать скрипт на Python, который спрашивает у меня название моей домашней работы, название курса и остальные строки и использовать ихсоздать обложку.После этого он должен скомпилировать .tex и сгенерировать pdf с предоставленной информацией.

Любые мнения, советы, фрагмент, библиотека принимаются.

Ответы [ 3 ]

59 голосов
/ 11 ноября 2011

Вы можете начать с определения текстового файла шаблона в виде строки:

content = r'''\documentclass{article}
\begin{document}
...
\textbf{\huge %(school)s \\}
\vspace{1cm}
\textbf{\Large %(title)s \\}
...
\end{document}
'''

Далее, используйте argparse, чтобы принять значения для курса, названия, названия и школы:

parser = argparse.ArgumentParser()
parser.add_argument('-c', '--course')
parser.add_argument('-t', '--title')
parser.add_argument('-n', '--name',) 
parser.add_argument('-s', '--school', default='My U')

Немного строкового форматирования - все, что нужно, чтобы вставить аргументы в content:

args = parser.parse_args()
content%args.__dict__

После записи содержимого в файл cover.tex,

with open('cover.tex','w') as f:
    f.write(content%args.__dict__)

Вы можете использовать subprocess для вызова pdflatex cover.tex.

proc = subprocess.Popen(['pdflatex', 'cover.tex'])
proc.communicate()

Вы также можете добавить сюда команду lpr, чтобы добавить печать в рабочий процесс.

Удалить ненужные файлы:

os.unlink('cover.tex')
os.unlink('cover.log')

Сценарий может быть вызван так:

make_cover.py -c "Hardest Class Ever" -t "Theoretical Theory" -n Me

Собираем все вместе,

import argparse
import os
import subprocess

content = r'''\documentclass{article}
\begin{document}
... P \& B 
\textbf{\huge %(school)s \\}
\vspace{1cm}
\textbf{\Large %(title)s \\}
...
\end{document}
'''

parser = argparse.ArgumentParser()
parser.add_argument('-c', '--course')
parser.add_argument('-t', '--title')
parser.add_argument('-n', '--name',) 
parser.add_argument('-s', '--school', default='My U')

args = parser.parse_args()

with open('cover.tex','w') as f:
    f.write(content%args.__dict__)

cmd = ['pdflatex', '-interaction', 'nonstopmode', 'cover.tex']
proc = subprocess.Popen(cmd)
proc.communicate()

retcode = proc.returncode
if not retcode == 0:
    os.unlink('cover.pdf')
    raise ValueError('Error {} executing command: {}'.format(retcode, ' '.join(cmd))) 

os.unlink('cover.tex')
os.unlink('cover.log')
5 голосов
/ 11 ноября 2011

Конечно, существуют системы шаблонов, такие как Jinja, но они, вероятно, излишни для того, что вы просите.Вы также можете отформатировать страницу с помощью RST и использовать ее для генерации LaTeX, но, опять же, это, вероятно, излишне.Черт возьми, автоматическая генерация страницы, вероятно, излишня для количества полей, которые вы должны определить, но с тех пор, когда излишняя остановка остановила нас!:)

Я сделал нечто похожее с форматированием строк в Python.Возьмите вышеупомянутый документ LaTeX и «токенизируйте» файл, поместив в документ токены %(placeholder_name1)s.Например, если вы хотите, чтобы имя вашего класса указывало, используйте %(course_name)s

\textbf{\Large "%(homework_title)s" \\}
\vspace{1cm}
\textbf{\Large "%(course_name)s" \\}

Затем из Python вы можете загрузить этот шаблон и отформатировать его как:

template = file('template.tex', 'r').read()
page = template % {'course_name' : 'Computer Science 500', 
                   'homework_title' : 'NP-Complete'}
file('result.tex', 'w').write(page)

Если вы хотите найти эти токены автоматически, следующее должно работать очень хорошо:

import sys
import re
import subprocess

template = file('template.tex', 'r').read()
pattern = re.compile('%\(([^}]+)\)[bcdeEfFgGnosxX%]')
tokens = pattern.findall(template)

token_values = dict()
for token in tokens:
    sys.stdout.write('Enter value for ' + token + ': ')
    token_values[token] = sys.stdin.readline().strip()

page = template % token_values
file('result.tex', 'w').write(page)

subprocess.call('pdflatex result.tex')

Код будет перебирать токены и выводить на консоль приглашение с запросом ввода для каждого токена.В приведенном выше примере вы получите два запроса (с примерами ответов):

Enter value for homework_title: NP-Complete
Enter value for course_name: Computer Science 500

Последняя строка вызывает pdflatex для полученного файла и генерирует из него PDF.Если вы хотите пойти дальше, вы также можете попросить пользователя указать имя выходного файла или использовать его в качестве параметра командной строки.

3 голосов
/ 26 марта 2012

Существует также класс Template (начиная с версии 2.4), позволяющий использовать токен $that вместо %(thi)s one.

...