XeTeX - 检测何时需要重新运行
我试图确定何时由于未定义的引用而需要重新运行 Xe(La)TeX。我已在 SCons 邮件列表,问题如下:
SCons 和其他构建系统目前有时无法检测到需要多次运行 XeLaTeX 的页数和其他引用。下面是一个示例文件(我们将其称为 job.tex
):
\documentclass[oneside,12pt]{memoir}
\usepackage{xltxtra}
\usepackage[T1]{fontenc}
\makepagestyle{plain}
\makeoddfoot{plain}{}{}{Page \thepage\ of \arabic{lastpage}}
\makeevenfoot{plain}{}{}{Page \thepage\ of \arabic{lastpage}}
\begin{document}
\pagestyle{plain}
Page 1
\newpage
Page 2
\newpage
Page 3
\newpage
\end{document}
如果运行 xelatex job
,生成的 .pdf 的页码为“Page 1 of 0”, “第 2 页,共 0 页”和“第 3 页,共 0 页”表示三页。如果您第二次运行 xelatex job,您会得到“第 1 页,共 3 页”等(即正确的页数)。
为了解决这个问题,我在 SCons 邮件列表上建议,检查是否运行 xelatex 来解析未定义的引用是更改以下正则表达式(在 SCons.Tools.tex
的第 71 行)版本 2.0.1.beta.20100627.r5064):
- warning_rerun_str = '(^LaTeX Warning:.*Rerun)|(^Package \w+ Warning:.*Rerun)'
+ warning_rerun_str = '(^LaTeX Warning:.*Rerun)|(^Package \w+ Warning:.*Rerun)'\
+ '|(^No file \w+\.\w{3}\.$)'
实际上,这是对“No file job.aux”的检查。事实证明这在所有情况下都有效,因为 Xe(La)TeX 在第一次运行时总是会打印“No file job.aux”,因此 Xe(La)TeX 总是运行两次。实际上,这与让 job.aux
成为 job.tex
和 job.pdf
之间的临时构建目标相同。
这里存在问题:即使没有未定义的引用(例如从上面的job.tex
中删除\arabic{lastpage}
)Xe(La)TeX被调用两次,一次生成.aux
,一次生成.pdf
。显然,如果没有未定义的引用,则第二次调用是多余的。
因此,我的问题是:当存在或不存在需要重新编译的未定义引用(例如 \arabic{lastpage})时,如何检测(大概通过针对 job.log 进行正则表达式测试的方式)。
感谢您的阅读。
最好的问候,
布莱恩
I'm trying to determine when a re-run of Xe(La)TeX is required because of undefined references. I've posted a related question on the SCons mailing list, and the problem is as follows:
Page counts and other references that require multiple runs of XeLaTeX are sometimes not at present detected by SCons and other build systems. Here's an example file (which we'll call job.tex
):
\documentclass[oneside,12pt]{memoir}
\usepackage{xltxtra}
\usepackage[T1]{fontenc}
\makepagestyle{plain}
\makeoddfoot{plain}{}{}{Page \thepage\ of \arabic{lastpage}}
\makeevenfoot{plain}{}{}{Page \thepage\ of \arabic{lastpage}}
\begin{document}
\pagestyle{plain}
Page 1
\newpage
Page 2
\newpage
Page 3
\newpage
\end{document}
If you run xelatex job
, the .pdf that's produced has page numbers "Page 1 of 0", "Page 2 of 0", and "Page 3 of 0" for the three pages. If you run xelatex job
a second time you get "Page 1 of 3", etc. (i.e. the correct page count).
To fix this, I've suggested on the SCons mailing list that the check for whether to run xelatex to resolve undefined references is to change the following regular expression (in SCons.Tools.tex
at line 71 of version 2.0.1.beta.20100627.r5064):
- warning_rerun_str = '(^LaTeX Warning:.*Rerun)|(^Package \w+ Warning:.*Rerun)'
+ warning_rerun_str = '(^LaTeX Warning:.*Rerun)|(^Package \w+ Warning:.*Rerun)'\
+ '|(^No file \w+\.\w{3}\.$)'
In practice, this is a check for "No file job.aux". It turns out this works in all cases because Xe(La)TeX will always print "No file job.aux" on the first run, and therefore Xe(La)TeX always runs twice. In effect, this is the same as having job.aux
become an interim build target between job.tex
and job.pdf
.
Therein lies the problem: Even if there is no undefined reference (e.g. remove the \arabic{lastpage}
from job.tex
above) Xe(La)TeX is called twice, once to produce the .aux
, once to produce the .pdf
. Obviously, if there are no undefined references, this second call is superfluous.
Thus my question: how can one detect - presumably by way of a regular expression testing against the job.log
- when there are or are not undefined references (e.g. \arabic{lastpage}) that require recompilation.
Thank you for reading.
Best regards,
Brian
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
能否不直接将 .aux 文件复制到备份中,并在 Xetex 运行结束时比较备份是否与新生成的 .aux 文件相同?
Can you not just copy the .aux file to a backup, and compare whether the backup is the same as the newly generated .aux file at the end of Xetex's run?
您可能想要的解决方案是引用最后一页,以便在计数器“lastpage”未定义时发出警告。然后,原始的重新运行正则表达式将拾取该值。
我使用的另一种方法是继续运行 LaTeX,直到 aux 文件不再更改(从概念上讲,aux 文件既是 LaTeX 运行的输入又是输出,并且继续运行 LaTeX 直到达到固定点) aux 文件)。这应该保证重新运行 LaTeX 不会再更改生成的文档。
我不知道你是否可以将这种行为合并到 scons 中。从 Makefile 来看,使用一些 shell 逻辑是相当容易的。
The solution you probably want is to reference the last page in such a way that a warning is given when the counter "lastpage" is undefined. This would then be picked up by the original rerun regular expression.
An alternative approach that I use, is to keep running LaTeX until the aux-file does not change anymore (conceptually, the aux-file is both an input and output of the LaTeX run, and you keep running LaTeX until you reach a fixpoint for the aux-file). This should give the guarantee that rerunning LaTeX does not change the resulting document anymore.
I don't know if you can incorporate this behavior into scons. From a Makefile, it is fairly easy with some shell logic.
Rubber 正是这样做的。它不是万无一失的,但它在大多数情况下都能工作,而且输出很干净,更容易发现错误。例如,我会像这样运行它:(
也就是说,如果 4 年后这仍然有用:-)
Rubber does exactly that. It is not bulletproof, but it works most of the times, and the output is clean, making easier to spot the errors. For example, I would run it like:
(That is, if after 4 years this is still useful :-)