注意:我已经看过aux文件什么时候被读写?,但它并没有解决我好奇的问题。
我写了一些命令来跟踪文档中的信息。由于我希望从文档开头就可以获得这些信息,因此我认为存储这些信息的最佳方式是将其写入文件aux
。在调试过程中,我注意到——在我看来——文件中发生了一些奇怪的事情aux
。
具体来说,aux
文件似乎被处理了两次:一次是在文档开始时读取时,另一次是在文档结束时关闭时。令我感到困惑的是,当文件关闭时aux
,它似乎执行了我写入aux
文件的命令。
考虑以下代码:
\documentclass{article}
%% uncommenting this next line seems to affect what gets dumped into my
%% document before processing is completed.
% \usepackage[paperheight=3in,paperwidth=2in,margin=0.25in]{geometry}
\usepackage{etoolbox}
\newcounter{aecounter}
\makeatletter
%% A command to retrieve the logged page number, a user into value,
%% and a counter value from the 'aux' file.
%% #1=page number
%% #2=value of what was passed to \aelogdata
%% #3=counter value at time that \aelogdata was called
\def\aedocumentdata#1#2#3{%%
\ifcsname aepage#1value\endcsname\relax
\expandafter\xdef\csname aepage#1value\endcsname{\number\numexpr\csname aepage#1value\endcsname+#2}
\typeout{-[#1:#2]-->\csname aepage#1value\endcsname}%%
\else
\typeout{--------------------------------------------------------------------}
\typeout{-[#1:#2]-->#2}%%
\expandafter\xdef\csname aepage#1value\endcsname{#2}%%
\fi
}
%% logger to write information to 'aux' file.
\newcommand\aelogdata[1]{%%
\stepcounter{aecounter}%%
\protected@write\@auxout{}{%%
\string\aedocumentdata{\number\value{page}}
{#1}
{\number\value{aecounter}}}%%
}
\makeatother
\newcommand\aegetloggedinformation{%%
\ifcsname aepage\number\value{page}value\endcsname
[page \thepage] : value is \csname aepage\number\value{page}value\endcsname
\else
NOT DEFINED
\fi
}
\AtBeginDocument{\typeout{----------BEGIN DOC----------}}
\AtEndDocument{\typeout{---------- END DOC ----------}}
%% I alter the definition
\AtEndDocument{\def\aedocumentdata#1#2#3{DOES THIS CREEP INTO MY FILE?\par\vspace{1cm}\typeout{<<page #1-->the #3th input value was `#2'>>}}}
%% But here, I nevertheless can manage to input something into my document
\AtEndDocument{\par\vspace{\fill}\centering\rule{0.15in}{0.4pt} HELLO WORLD \rule{0.15in}{0.4pt}\par}
\AtEndDocument{\par\vspace{\fill}\centering\rule{0.15in}{0.4pt} BYE WORLD \rule{0.15in}{0.4pt}\par}
\begin{document}
\aegetloggedinformation
\aelogdata{2}
\aelogdata{3}
\aelogdata{1}
\pagebreak
\aegetloggedinformation
\aelogdata{5}
\aelogdata{3}
\aelogdata{2}
\pagebreak
\aegetloggedinformation
\aelogdata{1}
\aelogdata{1}
\aelogdata{1}
\end{document}
我没想到会\typeout
在文档末尾看到控制序列被执行(事实上,我花了很长时间才弄清楚它们从哪里冒出来的)。经过一些调整,我发现我的aux
文件似乎被执行了,就好像 LaTeX 正在无害地读取最后一个\input
请求一样。
再多玩一下页面几何形状,我又得到了一些惊喜。如果我似乎设置了几何形状正好,那么最后的结果显然\input
不是这样无害毕竟。
有人能解释一下为什么文件中的命令aux
似乎在写入流关闭之前就执行了(如果确实发生了这种情况)?另外,为什么输入有时会潜入我的文档,有时不会?
关于几何的影响。
和
\usepackage[paperheight=6in,paperwidth=3in,margin=0.25in]{geometry}
我的最后一页如下所示:
但随着
\usepackage[paperheight=3in,paperwidth=2in,margin=0.25in]{geometry}
我的最后一页如下所示:
答案1
是的,LaTeX\input{filename.aux}
确实具有以下功能\enddocument
:
% latex.ltx, line 4057:
\def\enddocument{%
\let\AtEndDocument\@firstofone
\@enddocumenthook
\@checkend{document}%
\clearpage
\begingroup
\if@filesw
\immediate\closeout\@mainaux
\let\@setckpt\@gobbletwo
\let\@newl@bel\@testdef
\@tempswafalse
\makeatletter \@@input\jobname.aux
\fi
[...]
\endgroup
\deadcycles\z@\@@end}
如您所见,\@enddocumenthook
先执行,因此通过 给出的指令\AtEndDocument
在此时处理,此时排版尚未被禁止;因此,如果您有\AtEndDocument{foo}
,则打印单词。但是,\AtEndDocument
完全不建议使用 排版文本: 中的最后一条指令\enddocument
基本上会刷新主垂直列表中可能剩余的所有内容。如果垂直列表中的某些内容与 相加\AtEndDocument
产生了整页,则会发生这种情况前该指令,因此创建了一个页面(但这可能不是您想要的)。
在文件关闭之前排版文本aux
并重新读入可以借助atveryend
包来完成,该包提供了更多的钩子。
.aux
当\if@filesw
设置为 false(通过命令)时,LaTeX 不会输入文件\nofiles
。宏照常处理。
禁用不用于一致性检查的宏(因此\newlabel
没有被禁用,但给出了不同的定义)是一种很好的编程,并且\AtEndDocument{\renewcommand...}
是用于此的正确工具。
答案2
latex 并不期望辅助文件排版文本,它只是用来检查交叉引用的输入后最后\clearpage
刷新所有文本和浮动。
因此,排版到主垂直列表的任何文本都可能会丢失,除非(与短页版本一样)您排版得足以触发“自然”分页符,在这种情况下(仅)会输出分页符之前的文本。