![将内容写入 aux 文件的基本机制是什么?](https://linux22.com/image/234699/%E5%B0%86%E5%86%85%E5%AE%B9%E5%86%99%E5%85%A5%20aux%20%E6%96%87%E4%BB%B6%E7%9A%84%E5%9F%BA%E6%9C%AC%E6%9C%BA%E5%88%B6%E6%98%AF%E4%BB%80%E4%B9%88%EF%BC%9F.png)
.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
\ifeof
TeX 按主题分类。
使用 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
,以使相同的命令立即执行,而无需创建那是什么. 但是页数计数器仍然不正确。