使用 include 构建文档时将信息写入 aux 文件

使用 include 构建文档时将信息写入 aux 文件

.aux这可能是一个奇怪的问题,但是当我将文档拆分为多个文件时,我在主文件上写入信息时遇到了麻烦.tex

情况是这样的:我试图计算最宽的目录标签的大小,以便我可以根据这个测量值对齐目录中的所有章节/部分名称。有人已经告诉我如何进行测量,但我需要将此信息写入文件中,.aux以便在第一次传递时计算尺寸,并在第二次传递时使用它。

令我感到困扰的是,我使用的命令不起作用,我相信原因在于文档的模块化,因为当我在单文件文档中尝试它时,它可以正常工作。

以下是应该写入信息的代码部分:

\AtEndDocument{
    \protected@write\@auxout{}%
    {\string\global\string\setlength{\string\widesttoclabel}{\the\widesttoclabel}}
}

作为\widesttoclabel保存我计算的长度的宏。

但是当我检查.aux文件时,该条目并不在任何地方,既不在“主文档”的辅助文件中,也不在其他文件中。

我是否遗漏了什么?

光子发射站:我知道我可以解决这个问题,将 s 替换\include\inputs,但这会很糟糕,因为我的文档有很多页......所以如果可以选择的话,这不应该是一个选项。

答案1

当 LaTeX 执行时\end{document}

  1. 它调用钩子来收集东西\AtEndDocument
  2. `\clearpage 被调用并且
  3. .aux文件已关闭。

您使用的\protected@write是延迟写入。它会在输出页面时执行(实际写入)的输出中放置一个写入节点。但是,如果在文档末尾已经输出了最新页面,则不会发生任何事情,因为如果页面仅包含写入节点,TeX 不会创建页面。因此您需要\immediate\write

文档结尾钩子的顺序就是调用的顺序。因此,如果通过 添加标题较长的部分,则\AtEndDocument写入文件可能会太早。软件包提供了钩子命令,该命令在钩子之后 (1.) 和文件关闭之前(3.) 调用。.aux\AtEndDocumentatveryend\AfterLastShipout\AtEndDocument\clearpage.aux

因此代码示例变为:

\usepackage{atveryend}
\newdimen\widesttoclabel
\setlength{\widesttoclabel}{0pt}
\makeatletter
\AtBeginDocument{%
  \xdef\thewidesttoclabel{\the\widesttoclabel}%
}%
\AfterLastShipout{%
  \if@filesw
    \immediate\write\@mainaux{%
      \global\string\widesttoclabel=\the\widesttoclabel\relax
    }%
  \fi
}
\makeatother
% ...
\begin{document}
  % Macro \thewidesttoclabel contains the width of the widest toc label
  % from the previous run. Dimen register \widesttoclabel is initially 0pt
  % and should be updated for each longer entry found during the document.
\end{document}

进一步说明:

  • \global\setlength是不正确的,因为它依赖于宏的实现\setlength。文档不保证\global可以使用来获取全局分配。相反,包calc重新定义\setlength。然后前缀\global失败。正确的变体:

    \setlength{\mylength}{...}%
    \global\mylength=\mylength
    

    或者如果在这种情况下没有任何计算,那么我们可以使用

    \global\widesttoclabel=\the\widesttoclabel\relax
    
  • LaTeX 提供了\nofiles禁用对辅助文件的写入。 \protected@write相应地重新定义。 并且它设置了\if@filesw可以询问辅助文件是否可写的开关。 由于解决方案\immediate\write直接使用,因此将写入放在和之间\if@filesw\fi尊重\nofiles

变体

以下是使用全局宏定义\xdef而不是.aux文件中的全局赋值的变体:

\documentclass{article}

\usepackage{atveryend}

% Dimen register \widesttoclabel is used for measuring and
% finding the maximal value that is written to the `.aux` file
% at the end of document.
\newdimen\widesttoclabel
\setlength{\widesttoclabel}{0pt}

% \thewidesttoclabel is a macro with the width of the
% widest toc label. It is defined in the `.aux` file.
% In the first run, the dummy value 0pt is used.
\AtBeginDocument{%
  \providecommand*{\thewidesttoclabel}{0pt}%
}

\makeatletter
% \set@widesttoclabel is used at the end of the main .aux file
\newcommand*{\set@widesttoclabel}[1]{%
  \xdef\thewidesttoclabel{#1}%
}
\AfterLastShipout{%
  \if@filesw
    \immediate\write\@mainaux{%
      \xdef\string\thewidesttoclabel{\the\widesttoclabel}%
    }%
  \fi
}

\begin{document}
Widest entry: \thewidesttoclabel
\settowidth{\widesttoclabel}{Hello World}% dummy
\end{document}

相关内容