我被下面的问题困扰了,我想输入一个以 为名称的文件\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}}