用python scrip生成pdf乳胶

2024-05-12 21:49:54 发布

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

我是一个大学生,在我的大学里,要呈现任何一种家庭作业,都必须有一个标准的封面(上面有大学的标志、课程名称、教授的名字、我的名字和bla bla bla)。

所以,我有一个.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。

接受任何意见、建议、片段、库。


Tags: name标准名字大学endtexcenterlarge
3条回答

还有一个Template类(从2.4开始)允许使用$that标记,而不是%(thi)s标记。

首先,可以将模板tex文件定义为字符串:

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')

当然也有像Jinja这样的模板系统,但它们可能会对你的要求造成过度破坏。您还可以使用RST格式化页面,并使用它生成乳胶,但这可能是过分了。见鬼,自动生成页面对于你必须定义的字段的数量来说可能是多余的,但是从什么时候开始,多余的就阻止了我们!:)

我做了一些类似于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。如果您想更进一步,还可以要求用户输入输出文件名或将其作为命令行选项。

相关问题 更多 >