网上LatexMk
相关的高级功能的讲解比较少,虽然手册中有详细讲解,但是个人认为以一个比较明确的案例作为起始,在初步了解LatexMk后,通过完整阅读手册来掌握细节并满足自己的需求这个过程对于快速开发以满足需求这个目的会比较适合。
LatexMk是一个基于perl的工具,允许你编写latexmkrc
文件来自定义编译过程。简单来说类似于GNU make。
实际上,绝大部分相关信息都可以通过执行指令man latexmk
获得,在完成本指引后可以自行阅读手册以进阶。
我的环境是VS Code
下的LaTex Workshop
,它支持通过latexmkrc
来自定义编译过程,同样地,OverLeaf
也支持此功能。
需求讲解
我想实现一个功能:定义一个onlinefile
命令,参数是URL,编译时自动下载文件,从而通过执行\includegraphics[width=0.5\linewidth]{\onlinefile{https://example.com/img.png}}
间接实现直接渲染在线图片。因此我实现了一个python脚本,接受一个文件路径的参数,会自动完成以下步骤:
- 查找
\onlinefile{<URL>}
格式 - 获取
<URL>
- 下载文件并保存
- 将参数传递的文件的内容中的
\onlinefile{<URL>}
替换为本地保存路径,例如./onlinefile/<hash>.png
由于它的具体实现和本文无关,这里不过多赘述。
现在我们需要修改构建过程,在对*.tex
源码进行编译之前,需要添加以下步骤:
- 复制出新文件
*.online.tex
,以避免对原文件的修改 - 执行python脚本,对新文件
*.online.tex
进行处理以替换\onlinefile
指令 - 使用xelatex对新生成的、经过替换的源码进行编译,并产生
*.log
和*.pdf
等文件
由于Latex Workshop
的存在,在保存文件时会触发编译,并检查*.log
来检查编译是否成功,因此第三步是不可或缺的,也是比较难实现的一步。
创建latexmkrc文件
latexmk可以识别多种格式的latexmkrc,在这里我使用<workspace>/.latexmkrc
。此配置同样可以在手册中找到。
通过添加钩子以修改编译流程
可在手册中搜索Hooks
了解更多。目前的钩子有:
- before_xlatex
- after_xlatex
- after_xlatex_analysis
- after_main_pdf
- cleanup
- cleanup_extra_full
我们只需要在编译文件之前执行命令,因此只需要关注一个钩子before_xlatex
:
1 |
|
简单优化
开始之前,我们进行简单优化:如果\onlinefile
不存在,或者只存在在注释中则直接跳过处理:
1 |
|
它可能会比较有用,因为在测试时发现这个钩子会被触发两次,针对的源码文件一个是没有被处理的,一个是onlinefile被展开的,因此这个优化可以跳过第二次触发,还是比较有用的。
复制文件
1 |
|
执行脚本
1 |
|
修改后续编译目标
目前我们创建并处理了$bak_file
。此时如果直接尝试编译,会发现仍然会编译原文件,导致编译失败,因此我们还需要指定后续的流程的目标文件:
1 |
|
此时原理上应该是可以正常处理的,但是具体编译时会发现无法正常进行。为了修复这个,我们需要在全局变量上配置
1 |
|
这样可以指定最终生成的文件保持原名*.xxx
而不是*.$aux_suffix.xxx
。
完整源码
1 |
|
通过执行latexmk -xelatex
进行构建过程。
总结
通过这个案例我们可以初步了解latexmk的工作流程。一定要阅读手册来深入了解配置,进而设计出满足自己需求的代码。