使用python脚本生成pdf-latex

jul*_*ria 29 python latex pdflatex

我是一个大学生,在我的大学里,要提供任何类型的家庭作业,它必须有一个标准的封面(大学标志,课程名称,教授的名字,我的名字和bla bla bla).

所以,我有一个.tex文档,它生成我的标准封面pdfs.它类似于:

...
\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}
...
Run Code Online (Sandbox Code Playgroud)

所以,我在想,如果有一种方法,使一个Python脚本,问我的标题我的功课,课程名称和字符串的其余部分,并使用它们生成的封页.之后,它应该编译.tex并生成带有给定信息的pdf.

任何意见,建议,摘要,图书馆,都被接受.

unu*_*tbu 60

您可以从将模板tex文件定义为字符串开始:

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

接下来,使用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')
Run Code Online (Sandbox Code Playgroud)

只需要一些字符串格式就可以将args插入content:

args = parser.parse_args()
content%args.__dict__
Run Code Online (Sandbox Code Playgroud)

将内容写入文件后,cover.tex,

with open('cover.tex','w') as f:
    f.write(content%args.__dict__)
Run Code Online (Sandbox Code Playgroud)

你可以subprocess用来打电话pdflatex cover.tex.

proc = subprocess.Popen(['pdflatex', 'cover.tex'])
proc.communicate()
Run Code Online (Sandbox Code Playgroud)

您也可以lpr在此处添加命令以向工作流添加打印.

删除不需要的文件:

os.unlink('cover.tex')
os.unlink('cover.log')
Run Code Online (Sandbox Code Playgroud)

然后可以像这样调用脚本:

make_cover.py -c "Hardest Class Ever" -t "Theoretical Theory" -n Me
Run Code Online (Sandbox Code Playgroud)

把它们放在一起,

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')
Run Code Online (Sandbox Code Playgroud)

  • 很好的解决方案,简单!现在我有一个自动盖子发电机:) (5认同)

Nat*_*han 5

当然还有像Jinja这样的模板系统,但是对于你所要求的东西来说,它们可能有些过分.您也可以使用RST格式化页面并使用它来生成LaTeX,但这又可能是矫枉过正.哎呀,自动生成页面对于你必须定义的字段数量来说可能有些过分,但是从什么时候开始就会过度杀死我们!:)

我用Python的字符串格式做了类似的事情.获取上面的LaTeX文档,并通过将%(placeholder_name1)s标记放入文档来"标记化" 文件.例如,您希望您的班级名称去哪里,请使用%(course_name)s

\textbf{\Large "%(homework_title)s" \\}
\vspace{1cm}
\textbf{\Large "%(course_name)s" \\}
Run Code Online (Sandbox Code Playgroud)

然后,从Python中,您可以加载该模板并将其格式化为:

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

如果你想自动找到这些令牌,下面应该做得很好:

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')
Run Code Online (Sandbox Code Playgroud)

代码将遍历令牌并向控制台打印提示,要求您输入每个令牌.在上面的示例中,您将获得两个提示(示例答案):

Enter value for homework_title: NP-Complete
Enter value for course_name: Computer Science 500
Run Code Online (Sandbox Code Playgroud)

最后一行调用pdflatex生成的文件并从中生成PDF.如果您想要更进一步,您还可以询问用户输出文件名或将其作为命令行选项.


Jil*_*Vie 5

还有一个模板类(自 2.4 起)允许使用$that令牌而不是%(thi)s一个。


Fel*_*der 5

有一个专门用于此目的的 Python 库:PyLaTeX。以下代码直接取自文档

from pylatex import Document, Section, Subsection, Command
from pylatex.utils import italic, NoEscape


def fill_document(doc):
    """Add a section, a subsection and some text to the document.

    :param doc: the document
    :type doc: :class:`pylatex.document.Document` instance
    """
    with doc.create(Section('A section')):
        doc.append('Some regular text and some ')
        doc.append(italic('italic text. '))

        with doc.create(Subsection('A subsection')):
            doc.append('Also some crazy characters: $&#{}')


if __name__ == '__main__':
    # Basic document
    doc = Document('basic')
    fill_document(doc)

    doc.generate_pdf(clean_tex=False)
    doc.generate_tex()

    # Document with `\maketitle` command activated
    doc = Document()

    doc.preamble.append(Command('title', 'Awesome Title'))
    doc.preamble.append(Command('author', 'Anonymous author'))
    doc.preamble.append(Command('date', NoEscape(r'\today')))
    doc.append(NoEscape(r'\maketitle'))

    fill_document(doc)

    doc.generate_pdf('basic_maketitle', clean_tex=False)

    # Add stuff to the document
    with doc.create(Section('A second section')):
        doc.append('Some text.')

    doc.generate_pdf('basic_maketitle2', clean_tex=False)
    tex = doc.dumps()  # The document as string in LaTeX syntax
Run Code Online (Sandbox Code Playgroud)

它对于生成自动报告或幻灯片特别有用。

  • 请注意,诸如``generate_pdf```之类的东西需要安装````pdflatex```或类似的东西(我认为这又取决于**Perl**?)。我最终在 ``PythonAnywhere``` 上使用了 ``PyLaTeX````,因为它是免费的,而且几乎默认情况下所有这些都可以工作。 (2认同)