我的.tex
文件以以下指令开始。
% arara: lualatex
% arara: biber
% arara: makeglossaries
% arara: makeindex
% arara: lualatex
% arara: lualatex
如果此步骤的输出文件已经存在,并且完成此步骤所需的输入文件没有改变,我该如何指示 Arara 跳过此步骤,这意味着输出文件不会因此步骤而改变,因此该步骤是多余的?
最小示例
这是一个最小的例子,包含三个文件。
文件 #1:Test.tex
% arara: lualatex
% arara: biber
% arara: makeglossaries
% arara: makeindex
% arara: lualatex
% arara: lualatex
\documentclass[Bibliography=totoc,index=totoc]{scrbook}
\usepackage{biblatex}
\addbibresource{TestBibliography.bib}
\usepackage{imakeidx}
\makeindex
\usepackage[automake,sort=def]{glossaries-extra}
\makeglossaries
\input{TestGlossary}
\newtheorem{definition}{Definition}[chapter]
\title{Title}
\date{}
\begin{document}
\maketitle
\tableofcontents
\chapter{Chapter}
\section{Section}
\begin{definition}[Natural Numbers](\cite{Nat})\label{d:natural}\index{natural numbers}\glsadd{natural} The set of non-negative whole numbers shall be denoted by $\{0,1,2,\dots\}$. This is the set of \emph{natural numbers}.
\end{definition}
Natural numbers (see~\ref{d:natural}) are the best!
\printglossary[title={Notation Glossary}]
\printindex
\printbibliography[heading=bibintoc]
\end{document}
文件 #2:TestBibliography.bib
@Book{Nat,
author = {Poo, Winnie},
title = {Natural Numbers},
edition={3rd},
publisher = {Ex Libris},
year = {2019}}
文件 #3:TestGlossary.tex
\newglossaryentry{natural}{name={\ensuremath{\{0,1,2,\dots\}}},description={the natural numbers}}
答案1
在arara
可以通过检查各种文件来有条件地执行。这些检查在现行手册(版本 4.0)第 6.1 节 - 文件。
一些有用的方法是missing
和changed
,它们检查文件是否丢失或更改(这并不奇怪)。这些方法可以以两种方式使用:通过提供文件扩展名,在这种情况下,主文件的名称将添加到扩展名前面,或者通过使用语法 提供完整文件名toFile('yourfile.ext')
。另一个有用的方法是found
,它在提供的文件中执行字符串搜索,true
如果找到字符串则返回。这可用于搜索主日志文件或任何其他文件(如果需要),以查找指示需要重新运行的消息。
对于问题中的文档,例如可以使用以下规则:
% arara: lualatex
% arara: biber if missing('bbl') || found('log', 'Citation')
% arara: makeglossaries if missing('gls') || changed('glo') || changed(toFile('TestGlossary.tex'))
% arara: makeindex if changed('idx')
% arara: lualatex if found('log', 'No file ') || found('log', 'undefined references') || found('log', 'Rerun required') || found('log', 'Rerun to get cross-references')
% arara: lualatex
规则biber
现在意味着如果没有bbl
文件,则运行 Biber(该文件包含已编译的参考书目)或者如果日志中有关于引用的消息(表示尚未包含在编译的参考书目中的新参考文献)。请注意,这里使用了第一个语法变体,因此Test.tex
命令missing('bbl')
扩展为检查是否Test.bbl
缺失并类似地log
扩展为Test.log
。
该makeglossaries
规则检查gls
文件是否存在(命令的输出makeglossaries
或glo
文件是否已更改(遇到命令lualatex
时写入glsadd
)或包含词汇表的输入文件是否已更改。最后这项检查实际上并不是很有用,因为文件可以在没有将新的词汇表项目添加到正文的情况下更改,并且可以在不更改文件的情况下添加新条目,但它可以作为构造的演示toFile()
。
该makeindex
规则检查idx
包含索引条目的文件中是否存在更改。
第二条lualatex
规则检查日志文件中表明需要重新运行的各种短语。请注意,日志文件上的字符串匹配是检查重新运行需求的间接方法,这可能会导致错过必要的重新运行或执行冗余的重新运行。软件包和工具可能会在不同情况下或在更新后等在日志中写入不同的信息,并且字符串可能出于完全不相关的原因而出现在日志文件中,例如在\typeout
命令中。Arara 本身似乎不提供强大的重新运行检查功能 - 手册中有一些示例,但这些都使用日志匹配。
上述规则导致以下三次运行:
运行 1
__ _ _ __ __ _ _ __ __ _
/ _` | '__/ _` | '__/ _` |
| (_| | | | (_| | | | (_| |
\__,_|_| \__,_|_| \__,_|
Processing 'archange.tex' (size: 1 KB, last modified: 05/07/2019
13:29:24), please wait.
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
(Biber) The Biber reference management software ......... SUCCESS
(MakeGlossaries) The MakeGlossaries software ............ SUCCESS
(MakeIndex) The MakeIndex software ...................... SUCCESS
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
Total: 4.53 seconds
运行 2
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
(MakeGlossaries) The MakeGlossaries software ............ SUCCESS
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
Total: 2.73 seconds
运行 3
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
Total: 2.62 seconds
答案2
这是我的建议:
% arara: lualatex: { draft: yes, shell: yes }
% arara: biber if changed (toFile('TestBibliography.bib'))
% arara: --> || found ('log', 'Please \\(re\\)run Biber')
% arara: makeglossaries if changed ('glo') || missing ('gls')
% arara: makeindex if changed ('idx') || missing ('ind')
% arara: lualatex until !found('log', '\\(?(R|r)e\\)?run (to get|LaTeX)')
我们一一来看吧。
% arara: lualatex: { draft: yes, shell: yes }
启用后,此命令将在草稿模式下运行 LuaLaTeX -shell-escape
。草稿模式使 LuaLaTeX不是生成.pdf
文件,因此它不会包含图形。LuaLaTeX 的运行只会生成其他程序所需的辅助文件。这节省了几秒钟的编译时间。是-shell-escape
可选的;我需要它,但如果您不使用任何需要它的包,您可以删除它(我用它来外部化 Ti钾Z 图片)。
% arara: biber if changed (toFile('TestBibliography.bib'))
% arara: --> || found ('log', 'Please \\(re\\)run Biber')
此指令仅在文件指定的情况下运行 Biber。BibLaTeX.log
会告诉您何时需要(重新)运行 Biber,因此您可以依靠它来了解何时运行。BibLaTeX 无法告知您何时更改了文件.bib
,因此我添加了一个替代条件,即如果我更改了.bib
文件(由于名称与主文件不同.tex
,因此我需要使用 将其变成文件引用toFile('TestBibliography.bib')
)。
这里有几个观察结果:该% arara: -->
行是一条续行。这意味着后面的内容-->
属于上一行。它只是为了使代码清晰。它记录在手册的第 20 页。因此,上面的指令可以写成:
% arara: biber if changed (toFile('TestBibliography.bib')) || found ('log', 'Please \\(re\\)run Biber')
意思不变。
found
(其他类似命令)的语法是:
found(<string extension or file reference>,<regular expression>)
<string extension>
在这种情况下, 是,是'log'
。在正则表达式中,一对括号组成一个组,因此与文件中的文字字符串不匹配,因此您必须使用反斜杠 ( ) 对括号进行转义,以便它们表示文字括号。但是在 Java(Arara 使用的语言)中, a转换为单个1,因此您也需要对反斜杠进行转义。因此,指令中的将被 Arara 读取为(第一个转义级别),然后将传递给正则表达式引擎,后者将理解为文件中的文字字符串。呼 :)<regular expression>
'Please \\(re\\)run Biber'
(re)run
(re)run
.log
\(re\)
\\
\
\\(re\\)run
\(re\)run
\(re\)run
(re)run
log
[1]:字符串“\\”是单个反斜杠。在正则表达式中,反斜杠也是转义字符。正则表达式“\\”与单个反斜杠匹配。此正则表达式作为 Java 字符串,变为“\\\\”。
% arara: makeglossaries if changed ('glo') || missing ('gls')
% arara: makeindex if changed ('idx') || missing ('ind')
仅当输入文件和分别发生变化(如果文件之前不存在,则已经计算为真,这是第一次运行的情况)或这些工具的输出文件和之前不存在时,该指令才会运行makeglossaries
和,这涵盖了您需要运行这些工具的情况。makeindex
.glo
.idx
.gls
.ind
% arara: lualatex until !found('log', '\\(?(R|r)e\\)?run (to get|LaTeX)')
最后,该指令将根据需要多次运行 LuaLaTeX,直到.log
文件中不再出现以下任一字符串的消息:
Rerun LaTeX
rerun LaTeX
(Re)run LaTeX
(re)run LaTeX
Rerun to get
rerun to get
(Re)run to get
(re)run to get
它涵盖了我在文件中找到的大多数消息.log
。如果您添加另一个需要多次运行并使用不同消息的包,则需要对其进行调整。例如,如果包中说(在.log
)“再次执行 LaTeX”(与上述任何模式都不匹配),那么您可以将该指令更改为:
% arara: lualatex until !found('log', '\\(?(R|r)e\\)?run (to get|LaTeX)')
% arara: --> && !found('log','Execute LaTeX again')
或类似的东西。几乎不可能考虑所有 LaTeX 包的所有情况,因此您需要根据您的文档定制指令,但该rerun LaTeX
指令非常通用。
对此的注释:再次强调,'\\(?(R|r)e\\)?run (to get|LaTeX)'
是一个正则表达式(如果您知道这些,则可以跳过此部分)。请记住,Arara 会消耗一级转义,因此上面的内容转换为'\(?(R|r)e\)?run (to get|LaTeX)'
。此正则表达式匹配:
\(? | A (optional) literal '('
(R|r) | One of 'R' or 'r'
e | The letter 'e'
\)? | A (optional) literal ')'
run | The string 'run ' (note the trailing space)
(to get|LaTeX) | Either 'to get' or 'LaTeX'
也就是说,上面列出的情况也是如此。
使用您的示例文档,第一次运行arara test.tex
得到的结果如下:
phelype@phelype ~/testing> arara test.tex
__ _ _ __ __ _ _ __ __ _
/ _` | '__/ _` | '__/ _` |
| (_| | | | (_| | | | (_| |
\__,_|_| \__,_|_| \__,_|
Processing 'test.tex' (size: 30 KB, last modified: 05/07/2019
12:05:44), please wait.
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
(Biber) The Biber reference management software ......... SUCCESS
(MakeGlossaries) The MakeGlossaries software ............ SUCCESS
(MakeIndex) The MakeIndex software ...................... SUCCESS
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
Total: 6.75 seconds
进一步运行(不修改源)得到以下结果:
phelype@phelype ~/testing> arara test.tex
__ _ _ __ __ _ _ __ __ _
/ _` | '__/ _` | '__/ _` |
| (_| | | | (_| | | | (_| |
\__,_|_| \__,_|_| \__,_|
Processing 'test.tex' (size: 30 KB, last modified: 05/07/2019
12:05:44), please wait.
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
Total: 2.69 seconds
从第二次运行开始,您将在草稿模式下第一次运行 LuaLaTeX 来读取输入.tex
文件并生成 Biber、Makeglossaries 和 Makeindex 的文件(它们是相同的,因此这些工具不会运行),然后进行第二次运行来生成文件.pdf
。
答案3
而不是重新发明轮子(尽管它可能很有趣):https://www.youtube.com/watch?v=QF7odK55gkI),我会使用
% arara: latexmk
latexmk 将自动确定必须运行哪些工具。
答案4
% arara: halt if
% arara: --> (unchanged('tex') &&
% arara: --> unchanged('TestBibliography.bib') &&
% arara: --> unchanged('TestGlossary.tex') &&
% arara: --> exists('log'))
% arara: --> ||
% arara: --> (changed('TestBibliography.bib') && false) ||
% arara: --> (changed('TestGlossary.tex') && false) ||
% arara: --> (changed('bbl') && false) ||
% arara: --> (changed('gls') && false) ||
% arara: --> (changed('ind') && false)
% arara: lualatex
% arara: biber
% arara: makeglossaries
% arara: halt if (changed('glo') && false) ||
% arara: --> (changed('log') && false)
% arara: lualatex if
% arara: --> (changed('bbl') || changed('gls') || changed('ind')) &&
% arara: --> (changed('gls') || changed('ind') || true) &&
% arara: --> (changed('ind') || true)
% arara: makeglossaries if changed('glo')
% arara: lualatex if
% arara: --> (changed('gls') || changed('ind')) &&
% arara: --> (changed('ind') || true)
% arara: makeglossaries if changed('glo')
% arara: lualatex if changed('gls') || changed('ind')
第一次运行
__ _ _ __ __ _ _ __ __ _
/ _` | '__/ _` | '__/ _` |
| (_| | | | (_| | | | (_| |
\__,_|_| \__,_|_| \__,_|
Processing 'Test.tex' (size: 1 KB, last modified: 05/09/2019
23:18:43), please wait.
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
(Biber) The Biber reference management software ......... SUCCESS
(MakeGlossaries) The MakeGlossaries software ............ SUCCESS
(LuaLaTeX) LuaLaTeX engine .............................. SUCCESS
Total: 30.52 seconds
第二次运行
__ _ _ __ __ _ _ __ __ _
/ _` | '__/ _` | '__/ _` |
| (_| | | | (_| | | | (_| |
\__,_|_| \__,_|_| \__,_|
Processing 'Test.tex' (size: 1 KB, last modified: 05/09/2019
23:18:43), please wait.
(Halt) The halt trigger ................................. SUCCESS
Total: 0.36 seconds