首先:我完全不明白,\expandafter
这\noexpand
可能是主要问题。我找到了一个问题这解释了它的作用,但我似乎仍然无法让它工作。
\csname
我只是想使用如下方法打印命令的名称:
\def\str{String}
Command: \csname str\endcsname.\par
End command.
这将打印 (String) 的内容\str
,但我想阻止最后一次扩展。我认为这会起作用:
Command: \expandafter\noexpand\csname str\endcsname.\par
这将首先扩展\csname
为\str
,然后\noexpand
应禁止下一次扩展。但显然,这会给出一个空白输出,这实际上非常奇怪。
所以我想扩大\csname
,但没有\str
。
编辑:有几件事需要考虑,我不知道它们很重要(或者只是没有仔细考虑):
- 它用于写入文件。
- 它还必须适用于非
\csname
基于的命令。
因此代码变为:
\immediate\write\file{Command: \expandafter\noexpand\csname str\endcsname}
哪个有效(正如 egreg 所说),但不适用于
\immediate\write\file{Command: \expandafter\noexpand\str}
这是必要的,因为我需要创建一个显示该命令的命令。总的来说它应该是这样的:
\newcommand\writecmd[1]{
\immediate\write\file{\expandafter\noexpand#1}
}
\def\str{Blahblah}
\writecmd{\str}
\writecmd{\csname str\endcsname}
这输出
Blahblah
\str
这几乎就是我需要的。如果有解决方法,那也很好。请注意,该命令\writecmd
在我的程序中更为广泛。
答案1
Command: \expandafter\string\csname str\endcsname.\par
\noexpand
通过使命令暂时像\relax
如果你已经走了一样来防止扩展
Command: \relax\par
它不会打印“\relax
你需要
Command: \string\relax\par
为了那个原因。
因此,首先您要执行 csname 来获取命令名称标记,然后您要使用\string
它回到您开始的地方,但要使用反斜杠,因此
Command: \expandafter\string\csname str\endcsname.\par
当然
Command: \@backslashchar str.\par
对于更新的问题,你想测试\csname
\def\foo#1{%
\ifx\csname#1%
\expandafter\expandafter\expandafter\string
\expandafter\csname
\else
\string#1%
\fi}
\immediate\write20{\foo\fffff}
\immediate\write20{\foo\csname fff99ff\endcsname}
\bye
生产
$ tex cs88
This is TeX, Version 3.1415926 (TeX Live 2012)
(./cs88.tex
\fffff
\fff99ff
)
No pages of output.