2011-11-10 68 views
25

我是一名大學生,在我的大學裏,爲了呈現任何作業,它必須有一個標準的封面(帶有學院標識,課程名稱,教授姓名,我的名字和bla bla bla)。使用python腳本生成PDF-latex

因此,我有一個.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。

任何意見,建議,片段,圖書館,被接受。

+1

文本編輯器更快恕我直言。每次打印封面時,您仍然需要輸入標題,課程名稱等。我會將該PDF轉換爲單詞模板。試試:http://www.pdftoword.com/ –

+1

您可以在文本編輯器中使用代碼管理器/模板系統。 –

+2

這是個好主意!但我正在尋找更多的自制/怪胎。 – juliomalegria

回答

53

您可以通過定義模板TEX文件作爲字符串開頭:

content = r'''\documentclass{article} 
\begin{document} 
... 
\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') 

有點字符串格式化只需要將參數粘貼到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

不錯的解決方案,簡單!現在我有一個自動封面生成器:) – juliomalegria

+0

有沒有辦法檢查pdf是否成功生成?我發現如果我在文本中有'&'或'%',它會打斷pdf。 – Johan

+0

@Johan:該腳本顯示了對「pdlatex」調用的輸出。如果在處理LaTeX時出現錯誤,這些錯誤消息將告訴您未成功生成pdf。 '&'不是Python中的特殊字符,但是它是TeX中的,所以如果你想要一個字符&符號'\&',你需要反斜槓。 '%'是Python和TeX中的特殊字符。取決於'%'所在的位置,可能需要更改爲'\%'或'%%'。 – unutbu

5

當然有像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文件。如果您想進一步瞭解,還可以向用戶詢問輸出文件名或將其作爲命令行選項。

+0

我需要將'shell = True'添加到子進程調用中。 – TimP

+0

既然我們喜歡矯枉過正,我想看看Jinja的答案! – sleblanc

3

還有一個Template class(s​​ince 2.4)允許使用$that令牌而不是%(thi)s

+0

Jinja2也可以使用:http://flask.pocoo.org/snippets/55/ – alexpirine