假设我想将以下内容写入.aux
文件
\gdef\hello{\world\foobar}
我这样做:
\documentclass{article}
\makeatletter
\def\auxdef#1#2{
\immediate\write\@auxout{\string\gdef\string#1{\unexpanded{#2}}}
}
\makeatother
\begin{document}
\def\world{world}
\def\foobar{foo bar}
\auxdef\hello{\world\foobar}
\ifcsname hello\endcsname%
\hello
\else%
not set yet
\fi
\end{document}
然后运行pdflatex
一次并检查.aux
文件,它显示:
\relax
\gdef\hello{\world \foobar }
现在有两个空格我没有在任何地方明确插入:一个在\world
和之间\foobar
,另一个在\foobar
和之间}
。
问题是:空格从何而来?如何去除它们?
答案1
空格由\write
: TeX添加总是在控制字后添加一个空格\write
;这样的空格在阅读时是无害的,但在以下情况下是必不可少的:
\write\file{\relax x}
因为后面的空格\relax
(或任何其他不可扩展的控制字,或在您的情况下由 构成的控制字\unexpanded
)甚至不会被看到,并且如果 TeX 没有添加空格,您最终会得到\relaxx
。
请注意,它的\detokenize
作用相同,因为它是使用与 相同的代码实现的\write
。
这些空间不会造成任何不良影响,除非您碰巧在读取文件时该空间的类别代码不同于 10。
答案2
我不知道\immediate\write\@auxout
这是怎么做到的。
但完全没有必要删除它们,因为 LaTeX 命令(如)总是会吞噬其后的(常规)空格。因此和\world
的结果预计完全相同。\hello{\world\foobar}
\hello{\world \foobar }