web-dev-qa-db-ja.com

pythonスクリプトを使用したpdf-latexの生成

私は大学生です。私の大学では、あらゆる種類の宿題を提示するために、標準の表紙(大学のロゴ、コース名、教授の名前、私の名前、bla bla bla)が必要です。

したがって、標準のカバーページPDFを生成する.texドキュメントがあります。次のようになります:

...
\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を生成する必要があります。

意見、アドバイス、スニペット、ライブラリはすべて受け入れられます。

29
juliomalegria

テンプレート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')
59
unutbu

もちろん、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')

コードはトークンを反復処理し、各トークンの入力を求めるプロンプトをコンソールに出力します。上記の例では、2つのプロンプトが表示されます(回答の例を示します)。

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

最後の行は、結果のファイルでpdflatexを呼び出し、そこからPDFを生成します。さらに先に進みたい場合は、出力ファイル名をユーザーに尋ねるか、コマンドラインオプションとして。

5
Nathan

Template クラス(2.4以降)もあり、%(thi)s oneの代わりに$thatトークンを使用できます。

3
Jill-Jênn Vie