latexmk+make+条件编译一键编译论文生成 明评版/盲评版 单面版/双面版

发布时间 2023-10-19 19:22:52作者: lavateinn

用latexmk+make编译latex项目

假设latex项目的目录结构如下:

.
├── build
│   ├── aux
│       ├── 各种临时文件
│   └── release
│       ├── thesis.pdf
│       └── thesis.synctex.gz
├── data
│   ├── abstract.tex
│   ├── chap01.tex
│   ├── chap02.tex
│   ├── resume.tex
├── Figures / 图片
├── latexmkrc
├── Makefile
├── readme.md
├── ref/参考文献
├── thesis.tex

首先是latexmkrc

# 默认值为1, 即使用pdflatex
# pdflatex 1
# xelatex 5
$pdf_mode = 5;

$pdflatex = "pdflatex -file-line-error -halt-on-error -interaction=nonstopmode -synctex=1 %O %S";
$xelatex = "xelatex -file-line-error -halt-on-error -interaction=nonstopmode -synctex=1 %O %S";
$bibtex_use = 1.5;

$out_dir = "build/release";
$aux_dir = "build/aux";

$clean_ext = "hd nav snm synctex.gz xdv thm";

假设latex的项目根文件是thesis.tex, 使用latexmk编译的条件是文件头有如下的注释

% !TEX TS-program = xelatex
% !TEX encoding = UTF-8 Unicode

注: 在这里中文论文使用xelatex, 英文论文使用pdflatex

使用latexmk命令编译

我在使用vimtex+vim/neovim编写latex文档的过程中, 发觉连续编译不好好用, 保存后自动编译太频繁了, 加上想尝试下make, 就写了个Makefile, 每次写一大段之后再编译, 就不会那么卡顿了

all:
	latexmk

clean:
	latexmk -C -c -norc
	latexmk -C -c
	trash *.thm *.synctex.gz *.bbl

view:
	nohup okular build/release/thesis.pdf >/dev/null 2>&1 &

总体还可以

latex条件编译

这个需求主要是出现在撰写毕业论文的时候, 需要提交的论文可能分为明评版/盲评版, 而盲评版在已发表成果一节又需要隐去自己成果, 而且还可能分为电子版和双面打印版(双面打印版需要保证奇数页在右侧)

为此学习了一下条件编译, 用的是ifthen这个包, 首先在thesis.tex导言区引用这个包

\documentclass[master,ttf]{paper}
% ...
\usepackage{ifthen}
% ...

使用的基本格式如下:

	\ifthenelse{condition}{
	% if true
	}{
	% if false
	}

data/resume.tex这个文件中设置条件编译生成明评版论文和盲评版论文
这个condition可以用是否定义了一个宏来控制, 比如我定义了一个宏publicReview(明评)

% data/resume.tex
\newcommand{\publicReview}{1}
\ifthenelse{\isundefined{\publicReview}}{
	% 未定义, 盲评
	该论文作者在学期间取得的阶段性成果(学术论文等)已满足我校硕士学位评阅相关要求。
	为避免阶段性成果信息对专家评价学位论文本身造成干扰,特将论文作者的阶段性成果信息隐去。
}{
	% 定义了, 明评
	列举论文...
}

控制明评与否的关键就是是否注释\newcommand{\publicReview}{1}这一句, 我又不想每次手动改, 怎么进一步自动话呢?
可以用sed这个命令行工具来修改这一行, 首先在这行末尾加上一个注释标志%:FLAG_REVIEW:, sed就知道是这一行了

	% \newcommand{\publicReview}{1} %:FLAG_REVIEW:

sed命令如下:

# 明评, 取消注释
sed -i '/:FLAG_REVIEW:/ s/.*/  \\newcommand\{\\publicReview\}\{1\} %:FLAG_REVIEW:/g' data/resume.tex

# 盲评, 加上注释
sed -i '/:FLAG_REVIEW:/ s/.*/  % \\newcommand\{\\publicReview\}\{1\} %:FLAG_REVIEW:/g' data/resume.tex

稍微解释一下

  1. 第一部分/:FLAG_REVIEW:/匹配满足条件的行
  2. s/.*/ \\newcommand\{\\publicReview\}\{1\} %:FLAG_REVIEW:/g 明评
  3. s/.*/ % \\newcommand\{\\publicReview\}\{1\} %:FLAG_REVIEW:/g 盲评
  4. 对满足条件的行进行匹配然后替换的动作, 格式为 s/pattern1/pattern2/g
  5. 3.4区别只是在于是否有注释符号%

类似的, 可以控制论文是电子版还是打印版, 我的论文模板控制这一项是在\documentclass这里, 传递twoside参数即可. 这里可以不用额外添加FLAG, 可以用匹配行首的\documentclass的方式, 得到

sed -i '/^\\documentclass/ s/\[.*\]/\[指定的参数\]/g' ./thesis.tex
\documentclass[当前参数]{paper}
% 结果
\documentclass[指定的参数]{paper}

将这些操作放进makefile中, 排列组合出来四种情况, 最终的makefile如下:

title = 硕士大论文题目
all:
	# 明评版,电子版
	sed -i '/^\\documentclass/ s/\[.*\]/\[master,ttf\]/g' ./thesis.tex
	sed -i '/:FLAG_REVIEW:/ s/.*/  \\newcommand\{\\publicReview\}\{1\} %:FLAG_REVIEW:/g' data/resume.tex
	latexmk
	cp ./build/release/thesis.pdf ./build/release/thesis_明评版_电子版.pdf

ALL:
	# 明评版,电子版
	sed -i '/^\\documentclass/ s/\[.*\]/\[master,ttf\]/g' ./thesis.tex
	sed -i '/:FLAG_REVIEW:/ s/.*/  \\newcommand\{\\publicReview\}\{1\} %:FLAG_REVIEW:/g' data/resume.tex
	latexmk
	cp ./build/release/thesis.pdf ./build/release/$(title)_明评版_电子版.pdf
	# 明评版,双面打印版
	sed -i '/^\\documentclass/ s/\[.*\]/\[master,ttf,twoside\]/g' ./thesis.tex
	sed -i '/:FLAG_REVIEW:/ s/.*/  \\newcommand\{\\publicReview\}\{1\} %:FLAG_REVIEW:/g' data/resume.tex
	latexmk
	cp ./build/release/thesis.pdf ./build/release/$(title)_明评版_双面打印版.pdf
	# 盲评版,电子版
	sed -i '/^\\documentclass/ s/\[.*\]/\[master,ttf,anon\]/g' ./thesis.tex
	sed -i '/:FLAG_REVIEW:/ s/.*/  % \\newcommand\{\\publicReview\}\{1\} %:FLAG_REVIEW:/g' data/resume.tex
	latexmk
	cp ./build/release/thesis.pdf ./build/release/$(title)_盲评版_电子版.pdf
	# 盲评版,双面打印版
	sed -i '/^\\documentclass/ s/\[.*\]/\[master,ttf,twoside,anon\]/g' ./thesis.tex
	sed -i '/:FLAG_REVIEW:/ s/.*/  % \\newcommand\{\\publicReview\}\{1\} %:FLAG_REVIEW:/g' data/resume.tex
	latexmk
	cp ./build/release/thesis.pdf ./build/release/$(title)_盲评版_双面打印版.pdf

clean:
	latexmk -C -c -norc
	latexmk -C -c
	trash *.thm *.synctex.gz *.bbl

view:
	nohup okular build/release/thesis.pdf >/dev/null 2>&1 &

在撰写过程中可以直接用make命令默认生成明评电子版, 然后没问题之后用make ALL一键生成所有版本

build/release
	thesis.pdf
	thesis_明评版_电子版.pdf
	硕士大论文题目_明评版_电子版.pdf
	硕士大论文题目_明评版_双面打印.pdf
	硕士大论文题目_盲评版_电子版.pdf
	硕士大论文题目_盲评版_双面打印.pdf