在 \input 中使用 \csname 会产生神秘的结果

在 \input 中使用 \csname 会产生神秘的结果

我被下面的问题困扰了,我想输入一个以 为名称的文件\jobnameQ.tex

这是我从更大的图中摘录的 MWE。

\documentclass{article}

\usepackage{lipsum}

\usepackage{filecontents}

\def\csinput{\expandafter\input{\csname\jobname Q.tex\endcsname}}

\begin{document}

\begin{filecontents}{\jobname Q.tex}
  \lipsum[1]
\end{filecontents}

\csinput

\end{document}

这不会输入任何文件也不会产生任何输出。

然而,我知道如果我\csinput以这种方式定义

\def\csinput#1{\input{\jobname#1.tex}}

并像这样调用它, \csinput{Q}它就会起作用。

我想知道为什么第一种方法不起作用。(以及如何补救。)

答案1

扩展\csname \jobname Q.tex\endcsname\nameQ.tex,即未定义的控制序列。由 构造的未定义控制序列\csname...\endcsname有意义\relax\expandafter代码中的 是多余的,因为{不可扩展。\input是 LaTeX 中的宏。\input{something}扩展为原语\input something。由于something这里的 有意义\relax,因此会处理以下 TeX 原语命令:

\input \relax

因为原始命令中的文件名\input可以由另一个不可扩展的原始命令(例如\relax)分隔,所以我们在这里使用空文件名。TeX 将后缀附加到这个空文件名.tex并执行读取.tex文件。此文件存在于典型的 TeX 发行版中,内容为:\message{File ignored}

结果:读取该文件并打印消息。

笔记我尝试解释为什么.tex上述文件会出现在 TeX 发行版中。TeX 在发现错误时会停止(这\errorstopmode是常见设置),并等待用户响应。典型的用户响应只是“按 Enter 键”,然后继续处理。但还有另一种类型的错误:I can't find file ...。如果用户按 Enter 键响应,而不.tex存在,则错误会一次又一次地打印出来,因为这里只需要输入真实的文件名。这会让用户感到恼火。.tex在这种情况下,当用户按 Enter 键时,文件会被读取,然后进程继续。这与“正常”错误中的行为类似。

答案2

假设\jobname的值为test。则\csname\jobname Q.tex\endcsname表示一个名为 的宏testQ.tex,就像\csname jobname\endcsname表示一个名为 的宏一样jobname

具有名称的宏testQ.tex(如果宏名称中可以有点则会写出该\testQ.tex名称)不存在,因此\input无法获取您想要赋予它的文件名。

基本上,你不应该使用\csname在这里使用。你不需要与文件同名的宏,你需要一个宏(好吧,一个宏加上一些其他的东西),它的价值是文件名。只需这样:

\def\csinput{\input{\jobname Q.tex}}

相关内容