[工具使用]-利用latex管理建立自己的ACM模板
從很早入坑ACM開始,便和各種演算法的模板打著交道,雖然kaungbin的模板已經足夠強大,但是自己在平常做題中也逐漸有著自己的一些模板,也有一些kuangbin模板中沒有的更快的板子,雖然不確定時候以後會用到,但是能夠記錄下來形成自己的模板是最好的,,這樣也對自己所學有個大致的總結,所以在搜尋網路上各種解決思路後,選擇一位博主的解決方法: 利用python管理資料夾形式的模板庫,生成 latex
的 .tex
檔案,然後通過兩次編譯後得到 .pdf
的模板檔案,,這樣的好處是顯而易見的,首先是程式碼的管理十分的方便,只需將整理的板子扔到對應的分類資料夾下,然後在需要列印 .pdf
的板子時執行一下py指令碼就行了,同時用 latex
latex
語言的瞭解。
準備工作
為了能夠最後能正常的生成板子,,首先要保證一些軟體能夠正常的使用: python3
, tex
等等
這個 Tex Live
我很早之前就安裝了,所以也忘記具體的安裝過程了,,只記得這玩意的下載檔案多而大,,安裝也費事,,不過具體的安裝步驟網上有很多教程(注意要保證xecjk使用,,支援中文的包
最後的板子的管理資料夾大致是這樣的:
卷 檔案 的資料夾 PATH 列表 卷序列號為 D0B1-CFE7 G:. │ 1.pdf //生成的pdf檔案 │ 1.tex //生成的tex檔案 │ logo.jpg //板子的封面 │ README.md │ setting.dat //儲存的配置,名字啊等等 │ template.py //我們的指令碼 │ tree.txt //這個目錄的大致結構 │ ├─dp │ 線性dp.cpp │ ├─_MyTemplate │ init.cpp │ ├─博弈論 │ sg函式.cpp │ ├─圖論 │ ├─2-sat │ │ 輸出字典序最小的解.cpp │ │ │ ├─二分圖 │ │ 匈牙利演算法_鄰接矩陣實現.cpp │ │ │ ├─割點、橋、連通分支 │ │ 基本內容.cpp │ │ │ ├─差分約束 │ │ 差分約束.cpp │ │ │ ├─強連通分量 │ │ Kosaraju.cpp │ │ Tarjan_kuangbin.cpp │ │ Tarjan_red_bool.cpp │ │ │ ├─拓撲排序 │ │ 拓撲排序.cpp │ │ │ ├─最短路 │ │ └─spfa │ │ spfa_1_前向星.cpp │ │ spfa_2_鄰接表_good.cpp │ │ spfa_棧優化.cpp │ │ │ └─網路流 │ └─最大流 │ dinic.cpp │ hlpp.cpp │ ├─字串 │ hash.cpp │ 序列自動機.cpp │ ├─資料結構 │ └─並查集 │ 並查集.cpp │ ├─數論 │ │ 常用數論板子.cpp │ │ │ ├─中國剩餘定理 │ │ 中國剩餘定理_擴充套件歐幾里得.cpp │ │ 中國剩餘定理_模數不保證互質.cpp │ │ 中國剩餘定理_逆元.cpp │ │ │ ├─大整數_java │ │ java.cpp │ │ │ └─快速冪 │ 杜教板子.cpp │ 矩陣快速冪.cpp │ ├─樹 │ 線段樹.cpp │ └─線性基 線性基.cpp
可以看到我們需要在一個資料夾下放置指令碼程式,板子的封面,以及最重要的就是我們的板子,每一個板子都是 .cpp
檔案,直接將板子扔進去就行了,,
指令碼
總的指令碼是這樣的,直接執行就行了,,原博主 的這個程式貌似只能在 Linux下的python2使用,,所以我做了一些更改,在我的環境下(win10+python3.7)是可以正常使用的,,具體的內容可以看註釋
有一個小bug:目錄貌似不能顯示很多,,,emmmm有時間再改吧,,,
還有編譯中間會有一些warning 得手動按回車才能進行下一步
# coding=utf-8 import os import sys import json # tex的標頭檔案,lstset就是板子的樣式 TexHead = r""" \documentclass[twocolumn, a4]{article} \usepackage[colorlinks,linkcolor=black]{hyperref} \usepackage{xeCJK} \usepackage{fancyhdr} \usepackage{amsmath, amsthm} \usepackage{listings,xcolor} \usepackage{geometry} \usepackage{fontspec} \usepackage{graphicx} \setsansfont{Consolas} \setmonofont[Mapping={}]{Consolas} \newcommand{\HRule}{\rule{\linewidth}{0.5mm}} \geometry{left=2.5cm,right=2.5cm,top=1cm,bottom=1cm} \lstset{ language = c++, numbers = left, numberstyle = \tiny, breaklines = true, captionpos = b, tabsize = 4, frame = shadowbox, columns = fullflexible, commentstyle = \color[RGB]{0,128,0}, keywordstyle = \color[RGB]{0,0,255}, basicstyle = \normalsize\ttfamily, stringstyle = \color[RGB]{148,0,209}\ttfamily, rulesepcolor = \color{red!20!green!20!blue!20}, showstringspaces = true, } """ # 初始化設定,主要是板子的名字等等 def InitSetting(): try: SettingFile = open('setting.dat') SettingData = json.load(SettingFile) print (u'讀取到儲存的設定: ') for key in SettingData: print ('[%s] %s' % (key, SettingData[key])) op = input('是否使用已儲存的設定?[Y/n]') if not op in ['n', 'N', 'no', 'No', 'NO']: global TITLE, SCHOOL, TEAM, FILE for key in ['TITLE', 'SCHOOL', 'TEAM', 'FILE']: globals()[key] = SettingData[key] else: NewSetting() except: print (u'讀取設定失敗') NewSetting() # 輸入資訊,儲存到本地 def NewSetting(): global TITLE, SCHOOL, TEAM, FILE TITLE = input('請輸入標題: ') SCHOOL = input('請輸入學校: ') TEAM = input('請輸入隊名: ') FILE = input('請輸入檔名: ') Data = dict() for key in ['TITLE', 'SCHOOL', 'TEAM', 'FILE']: Data[key] = globals()[key] json.dump(Data, open('setting.dat', 'w')) # 刪除當前目錄下的所有中間臨時檔案 def Clear(): for suffix in ['aux', 'log', 'toc', 'out']: filename = '%s.%s' % (FILE, suffix) if os.path.exists(filename): os.remove(filename) # 呼叫兩次生成模板來使 .tex 轉為 .pdf def Generate(): Clear() os.system('xelatex %s.tex -quiet' % FILE) os.system('xelatex %s.tex -quiet' % FILE) # 兩到三次的生成才能生成目錄https://zhidao.baidu.com/question/1541025230634017307.html Clear() os.system('open %s.pdf' % FILE) # 對每個板子檔案進行讀取寫入 def ReadCpp(file): f = open(file, 'r', encoding='UTF-8') print (file + ' 2333333333333333333333333333') Tex = 0 TargetFile.write('\\begin{lstlisting}\n') for line in f: if line[:-1] == '// ---': Tex = not Tex ToWrite = '\\%s{lstlisting}\n' % ('begin', 'end')[Tex] TargetFile.write(ToWrite) continue TargetFile.write(line[(0, 3)[Tex]:]) TargetFile.write('\\end{lstlisting}\n') f.close() # 讀入tex檔案 def ReadTex(file): f = open(file, 'r') for line in f: TargetFile.write(line) f.close() # 遞迴遍歷當前資料夾下的所有檔案 def Search(level, pwd, folder=''): ls = os.popen('dir /b "%s"' % pwd).read().split('\n')[:-1] for item in ls: print (item) if folder: print (level) TargetFile.write(SECTION[level] % folder[0:]) for item in ls: print (item + '2333' + item[:-3]) item.replace(' ', '\\ ') if '.cpp' in item: if not item[:2] == '00': TargetFile.write(SECTION[level + 1] % item[:-4]) ReadCpp(pwd + item) elif '.tex' in item: continue if not item[:2] == '00': TargetFile.write(SECTION[level + 1] % item[:-4]) ReadTex(pwd + item) elif 'jpg' in item: continue elif 'md' in item: continue elif 'dat' in item: continue elif 'py' in item: continue elif 'txt' in item: continue elif 'pdf' in item: continue else: cd = os.popen('cd "%s%s/"' % (pwd, item)).read() if 'Not a directory' in cd or 'No such file or directory' in cd: print ('[Unknown File] %s/%s' % (pwd, item)) else: Search(level + 1, pwd + item + '/', item) if __name__ == '__main__': # 全域性設定 TITLE, SCHOOL, TEAM, FILE = '', '', '', '' SECTION = ['', '\\clearpage\\section{%s}\n', '\\subsection{%s}\n', '\\subsubsection{%s}\n', '\\paragraph{%s}\n', '\\subparagraph{%s}\n'] InitSetting() Clear() TargetFile = open('%s.tex' % FILE, 'w', encoding='utf-8') # Output Head File TargetFile.write(TexHead) TargetFile.write('\\title{%s}\n' % TITLE) TargetFile.write('\\author{%s}\n' % TEAM) TargetFile.write('\\pagestyle{fancy}\n\\fancyhf{}\n\\fancyhead[C]{%s}\n' % (TITLE)) TargetFile.write('\\begin{document}\\small\n') TargetFile.write('\\begin{titlepage}\n\\begin{center}\n\\vspace*{0.5cm}\\includegraphics[width=0.75\\textwidth]{logo.jpg} \\\\ [2cm]\n') TargetFile.write('\\HRule \\\\ [1cm]\n') TargetFile.write('\\textbf{\\Huge{%s}} \\\\ [0.5cm]\n' % TITLE) TargetFile.write('\\HRule \\\\ [4cm]\n') TargetFile.write('\\textbf{\\Huge{%s}} \\\\ [1cm]\n\\LARGE{%s}\n' % (SCHOOL, TEAM)) TargetFile.write('\\vfill\n\\Large{\\today}\n\\end{center}\n') TargetFile.write('\\clearpage\n\end{titlepage}\n') TargetFile.write('\\tableofcontents\\clearpage\n') TargetFile.write('\\pagestyle{fancy}\n\\lfoot{}\n\\cfoot{\\thepage}\\rfoot{}\n') TargetFile.write('\\setcounter{section}{-1}\n\\setcounter{page}{1}\n') # Search Files Search(0, './') # End Output TargetFile.write('\n\\end{document}\n') TargetFile.close() # Gen Generate()
最後的效果如下;
參考的部落格:
主程式
latex語法的介紹
latex官網
latex的某個大佬的筆記
(應該沒了吧,,,,