\csname 中的非字母表字母...\endcsname

\csname 中的非字母表字母...\endcsname

为什么我不能在下面的代码中得到我想要的东西?MWE:

\documentclass{article}
\begin{document}
%
\def\aaa*{*}
\def\aaaAAA{AAA}
|\csname aaaAAA\endcsname|% typeset |AAA| as I desired.
|\csname aaa*\endcsname|% I want to get |*|, but get ||. So, what's wrong with my code?
%
\end{document}

答案1

这是因为\csname aaa*\endcsname不存在,因此默认为\relax不排版。为什么不存在?嗯,这个问题类似于沒有\makeatletter必須?

在 中\def\aaa*{*}*不构成定义的一部分,而是构成范围使用的文本。为了定义一个宏,*在定义中包含一个姓名你必须使用

\expandafter\def\csname aaa*\endcsname{*}% Similar to \@namedef{aaa*}{*}

答案2

考虑以下示例

\def\aaa*{*}

\show\aaa*

在其上运行 TeX(任何风格),将在控制台上报告如下

> \aaa=macro:
*->*.
l.3 \show\aaa
             *
?

我们如何读取它?原始命令\show报告以下标记的含义;问号之前的两行告诉\aaa*我们标记,因为*出现在续行中。

TeX 还告诉我们,这\aaa是一个宏,它有一个非空参数文本(之前报告的内容->),由星号组成。换句话说,\def\aaa*{*}指示 TeX\aaa 必须后面跟着*,这两个标记将被 替换*

例如,你也可以这样调用它:

\aaa *

\aaa因为从输入构建标记时会忽略后面的空格。

如果你想使用\csname,那么它应该是

\csname aaa\endcsname *

(之前的空格*是可选的)。

如果你想知道 *-variants 在 LaTeX 中是如何实现的,请看这里:

\newcommand{\foo}{\@ifstar\foostar\foonostar}
\newcommand{\foostar}{<what we want \foo* to do>}
\newcommand{\foonostar}{<what we want \foo to do>}

必须根据所需的语法通过\foostar或来获取可能的参数。\foonostar

使用的方法xparse略有不同,但命令仍然不会将*作为名称的一部分。

相关内容