将内容写入 aux 文件的基本机制是什么?

将内容写入 aux 文件的基本机制是什么?

.aux我对将内容写入文件(或其他辅助文件)背后的基本机制感兴趣。

假设我想为自己编写一个用于在文件上做笔记的基本软件包。(我知道已经存在可以执行此操作的软件包。这个问题的重点不是弄清楚如何获得对我的论文的评论,而是了解 TeX/LaTeX 基础知识的一个方面。)

因此,我在序言中写了类似这样的内容:

\usepackage{xcolor}
\newif\ifcomments
\commentstrue
\newcommand\comment[1]{%
  \ifcomments
  \textcolor{red}{\textsf{#1}}
  \else
  \fi
}

这意味着我可以打开和关闭评论。现在,下一步是我想在itemize文档末尾显示一个评论列表,每个评论都与其页码一起列出。为了实现这一点,最简单的方法似乎是将每个评论(加上其页码)写入辅助文件,然后使用命令\writecomments打印该文件的内容。(或类似的东西)。

简单来说,我怎样才能实现这一目标?

注意:这个问题旨在帮助我了解 TeX/LaTeX 的基础知识,因此涉及使用软件包完成大量工作的解决方案将不受欢迎。

编辑我有两个非常有趣的答案,它们提供了实现我示例中想要的不同方法。然而,这两个答案都没有真正达到我想要的真正答案,那就是对 TeX/LaTeX 的“写入辅助文件”机制的简单介绍。

我想要的是基本的答案是 TeX/LaTeX 新手可以阅读和理解的。我觉得目前的答案有点太高级了。

答案1

有一个用户友好的 LaTeX 包:newfile。您可以使用它轻松地读取和写入文件。它提供常规文件 IO 函数,以及逐字文件 IO 函数。它比那些低级宏更适合您的示例。包文档中有一些很好的例子。

一个简单的例子(类似于目录):

\documentclass{article}
\usepackage{newfile}
\newoutputstream{comment}
\openoutputfile{\jobname.comment}{comment}

\begin{document}

\section{Test}
text one
\addtostream{comment}{\noexpand\item comment one at page \thepage}

text two
\addtostream{comment}{\noexpand\item comment two}


\section{Comments}

\closeoutputstream{comment}
\begin{enumerate}
    \input{\jobname.comment}
\end{enumerate}

\end{document}

宏在写入文件时会扩展。控制扩展非常重要。有些宏应该不是被扩展,像\item这里;而有些宏应该被扩展,像\thepage\thesection这里。


在 TeX 中,有\newwrite,,,,,等。一个很好的资源是\openout\immediate\write\closeout\ifeofTeX 按主题分类

使用 TeX 基元的相同示例:

\documentclass{article}
\newwrite\commentfile
\openout\commentfile=\jobname.comment

\begin{document}

\section{Test}
text one
\write\commentfile{\noexpand\item comment one at page \thepage}

text two
\write\commentfile{\noexpand\item comment two in section \thesection}

\section{Comments}

\closeout\commentfile
\begin{enumerate}
    \input{\jobname.comment}
\end{enumerate}

\end{document}

在 LaTeX 内核中,你可以参考source2e,您可以从\@starttoc、、(针对内容)等处学习\@wirtefile\addcontentsline

相同示例(工作方式与标准 TOC 类似):

\documentclass{article}

\makeatletter
\newcommand\addcommentitem[1]{%
  \write\@auxout{\noexpand\@writefile{comment}{\noexpand\item #1}}}
\newcommand\printcomment{%
  \section*{Comments}
  \begin{enumerate}
    \item[] Here are some comments:
    \@starttoc{comment}
  \end{enumerate}}
\makeatother

\begin{document}

\section{Test}
text one
\addcommentitem{comment one at page \thepage}

text two
\addcommentitem{comment two in section \thesection}

\printcomment

\end{document}

答案2

如果您还剩下一个写入句柄,您可以使用以下命令来执行此操作,这些命令也用于.toc、、等。.lof.lot

\@starttoc{<extension>}

读取具有指定扩展名 ( ) 的文件\jobname.<extension>,然后将其打开以供写入。该文件最初为空。创建输出文件句柄\tf@<extension>

\@writefile{<extension>}{<code>}

\tf@<extension>如果存在,则使用输出句柄写入代码。

我有这些宏宏2e并计划为该应用程序添加一个简短的 HowTo。

\listofcomments您可以最初将 定义为\relax\writecomments(或\makecomments)将其定义为\@starttoc{cmt},以读取/创建“ \jobname.cmt”。


您应该能够使用以下命令直接写入当前.aux文件(主文件或包含文件):

 \write\@auxout{...}

或者,如果您想明确写入主.aux文件:

 \write\@mainaux{...}

他们创造了那是什么所以页码应该是正确的。

对于其他新文件,您需要先创建写入句柄并打开文件。这是通过以下方式完成的:

 \newwrite\myhandle% There are only 16 write handles, even with eTeX!
 \openout\myhandle=<filename>\relax% or space
 % ...
 \closeout\myhandle % to close the file

您可以在所有这些命令(除了\newwrite)前加上前缀\immediate,以使相同的命令立即执行,而无需创建那是什么. 但是页数计数器仍然不正确。

相关内容